mirror of https://github.com/arendst/Tasmota.git
Add DimmerRange command and support longer dimmer ranges. Fixes #6605
More and more serial dimmers are coming up with different dimming ranges, implemented DimmerRange command to make this setting generic and bring support for 2 byte dimming ranges which isn't supported by SetOptions.
This commit is contained in:
parent
70ea4bedfa
commit
01f6df9161
|
@ -1,4 +1,7 @@
|
|||
/*********************************************************************************************\
|
||||
* 6.6.0.18 20191010
|
||||
* Add command DimmerRange in Light module to support 2 byte dimming ranges from Tuya
|
||||
*
|
||||
* 6.6.0.17 20191009
|
||||
* Add command SetOption34 0..255 to set backlog delay. Default value is 200 (mSeconds) (#6562)
|
||||
* Add command Gpio 255 to show physical GPIO configuration of all non-flash pins (#6407)
|
||||
|
|
|
@ -366,6 +366,7 @@
|
|||
#define D_CMND_COLOR "Color"
|
||||
#define D_CMND_COLORTEMPERATURE "CT"
|
||||
#define D_CMND_DIMMER "Dimmer"
|
||||
#define D_CMND_DIMMER_RANGE "DimmerRange"
|
||||
#define D_CMND_HSBCOLOR "HSBColor"
|
||||
#define D_CMND_LED "Led"
|
||||
#define D_CMND_LEDTABLE "LedTable"
|
||||
|
|
|
@ -79,10 +79,10 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu
|
|||
uint32_t no_power_feedback : 1; // bit 13 (v6.5.0.9) - SetOption63 - Don't scan relay power state at restart
|
||||
uint32_t use_underscore : 1; // bit 14 (v6.5.0.12) - SetOption64 - Enable "_" instead of "-" as sensor index separator
|
||||
uint32_t ex_tuya_disable_dimmer : 1; // bit 15 (v6.5.0.15) - SetOption65 - (Enable or Disable Tuya Serial Dimmer control) - free since 6.6.0.10
|
||||
uint32_t tuya_dimmer_range_255 : 1; // bit 16 (v6.6.0.1) - SetOption66 - Enable or Disable Dimmer range 255 slider control
|
||||
uint32_t ex_tuya_dimmer_range_255 : 1; // bit 16 (v6.6.0.1) - SetOption66 - Enable or Disable Dimmer range 255 slider control
|
||||
uint32_t buzzer_enable : 1; // bit 17 (v6.6.0.1) - SetOption67 - Enable buzzer when available
|
||||
uint32_t pwm_multi_channels : 1; // bit 18 (v6.6.0.3) - SetOption68 - Enable multi-channels PWM instead of Color PWM
|
||||
uint32_t tuya_dimmer_min_limit : 1; // bit 19 (v6.6.0.5) - SetOption69 - Limits Tuya dimmers to minimum of 10% (25) when enabled.
|
||||
uint32_t ex_tuya_dimmer_min_limit : 1; // bit 19 (v6.6.0.5) - SetOption69 - Limits Tuya dimmers to minimum of 10% (25) when enabled.
|
||||
uint32_t energy_weekend : 1; // bit 20 (v6.6.0.8) - CMND_TARIFF
|
||||
uint32_t dds2382_model : 1; // bit 21 (v6.6.0.14) - SetOption71 - Select different Modbus registers for Active Energy (#6531)
|
||||
uint32_t hardware_energy_total : 1; // bit 22 (v6.6.0.15) - SetOption72 - Enable / Disable hardware energy total counter as reference (#6561)
|
||||
|
@ -384,8 +384,10 @@ struct SYSCFG {
|
|||
uint8_t shutter_position[MAX_SHUTTERS]; // E80
|
||||
uint8_t shutter_startrelay[MAX_SHUTTERS]; // E84
|
||||
uint8_t pcf8574_config[MAX_PCF8574]; // E88
|
||||
uint16_t dimmer_hw_min; // E8A
|
||||
uint16_t dimmer_hw_max; // E8C
|
||||
|
||||
uint8_t free_e90[360]; // E90
|
||||
uint8_t free_e90[356]; // E90
|
||||
|
||||
uint32_t cfg_timestamp; // FF8
|
||||
uint32_t cfg_crc32; // FFC
|
||||
|
|
|
@ -128,6 +128,11 @@
|
|||
#ifndef DEFAULT_DIMMER_MAX
|
||||
#define DEFAULT_DIMMER_MAX 100
|
||||
#endif
|
||||
#ifndef DEFAULT_DIMMER_MIN
|
||||
#define DEFAULT_DIMMER_MIN 10
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
enum WebColors {
|
||||
COL_TEXT, COL_BACKGROUND, COL_FORM,
|
||||
|
@ -776,7 +781,8 @@ void SettingsDefaultSet2(void)
|
|||
// Settings.light_rotation = 0;
|
||||
SettingsDefaultSet_5_8_1(); // Clock color
|
||||
|
||||
Settings.param[P_DIMMER_MAX] = DEFAULT_DIMMER_MAX;
|
||||
Settings.dimmer_hw_max = DEFAULT_DIMMER_MAX;
|
||||
Settings.dimmer_hw_min = DEFAULT_DIMMER_MIN;
|
||||
|
||||
// Display
|
||||
SettingsDefaultSet_5_10_1(); // Display settings
|
||||
|
@ -1085,10 +1091,10 @@ void SettingsDelta(void)
|
|||
}
|
||||
if (Settings.version < 0x06060008) {
|
||||
// Move current tuya dimmer range to the new param.
|
||||
if (Settings.flag3.tuya_dimmer_range_255) {
|
||||
Settings.param[P_DIMMER_MAX] = 100;
|
||||
if (Settings.flag3.ex_tuya_dimmer_range_255) {
|
||||
Settings.param[P_ex_DIMMER_MAX] = 100;
|
||||
} else {
|
||||
Settings.param[P_DIMMER_MAX] = 255;
|
||||
Settings.param[P_ex_DIMMER_MAX] = 255;
|
||||
}
|
||||
}
|
||||
if (Settings.version < 0x06060009) {
|
||||
|
@ -1141,6 +1147,18 @@ void SettingsDelta(void)
|
|||
Settings.param[P_BACKLOG_DELAY] = MIN_BACKLOG_DELAY;
|
||||
}
|
||||
|
||||
if (Settings.version < 0x06060012) {
|
||||
Settings.dimmer_hw_max = Settings.param[P_ex_DIMMER_MAX];
|
||||
Settings.dimmer_hw_min = DEFAULT_DIMMER_MIN;
|
||||
if (TUYA_DIMMER == Settings.module) {
|
||||
if (Settings.flag3.ex_tuya_dimmer_min_limit) {
|
||||
Settings.dimmer_hw_min = 25;
|
||||
} else {
|
||||
Settings.dimmer_hw_min = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Settings.version = VERSION;
|
||||
SettingsSave(1);
|
||||
}
|
||||
|
|
|
@ -247,7 +247,7 @@ enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER };
|
|||
|
||||
enum SettingsParamIndex { P_HOLD_TIME, P_MAX_POWER_RETRY, P_BACKLOG_DELAY, P_MDNS_DELAYED_START, P_BOOT_LOOP_OFFSET, P_RGB_REMAP, P_IR_UNKNOW_THRESHOLD, // SetOption32 .. SetOption38
|
||||
P_CSE7766_INVALID_POWER, P_HOLD_IGNORE, P_ex_TUYA_RELAYS, P_OVER_TEMP, // SetOption39 .. SetOption42
|
||||
P_DIMMER_MAX,
|
||||
P_ex_DIMMER_MAX,
|
||||
P_ex_TUYA_VOLTAGE_ID, P_ex_TUYA_CURRENT_ID, P_ex_TUYA_POWER_ID, // SetOption43 .. SetOption46
|
||||
P_ex_ENERGY_TARIFF1, P_ex_ENERGY_TARIFF2, // SetOption47 .. SetOption48
|
||||
P_MAX_PARAM8 }; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49
|
||||
|
|
|
@ -20,6 +20,6 @@
|
|||
#ifndef _SONOFF_VERSION_H_
|
||||
#define _SONOFF_VERSION_H_
|
||||
|
||||
const uint32_t VERSION = 0x06060011;
|
||||
const uint32_t VERSION = 0x06060012;
|
||||
|
||||
#endif // _SONOFF_VERSION_H_
|
||||
|
|
|
@ -711,7 +711,7 @@ void CmndSetoption(void)
|
|||
IrReceiveUpdateThreshold();
|
||||
break;
|
||||
#endif
|
||||
case P_DIMMER_MAX:
|
||||
case P_ex_DIMMER_MAX:
|
||||
restart_flag = 2; // Need a restart to update GUI
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -129,12 +129,12 @@ enum LightSchemes { LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_M
|
|||
const uint8_t LIGHT_COLOR_SIZE = 25; // Char array scolor size
|
||||
|
||||
const char kLightCommands[] PROGMEM = "|" // No prefix
|
||||
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
|
||||
D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_DIMMER_RANGE "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|"
|
||||
D_CMND_RGBWWTABLE "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|"
|
||||
D_CMND_WHITE "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ;
|
||||
|
||||
void (* const LightCommand[])(void) PROGMEM = {
|
||||
&CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndLedTable, &CmndFade,
|
||||
&CmndColor, &CmndColorTemperature, &CmndDimmer, &CmndDimmerRange, &CmndLedTable, &CmndFade,
|
||||
&CmndRgbwwTable, &CmndScheme, &CmndSpeed, &CmndWakeup, &CmndWakeupDuration,
|
||||
&CmndWhite, &CmndChannel, &CmndHsbColor, &CmndUndocA };
|
||||
|
||||
|
@ -2057,6 +2057,29 @@ void CmndDimmer(void)
|
|||
}
|
||||
}
|
||||
|
||||
void CmndDimmerRange(void)
|
||||
{
|
||||
if (XdrvMailbox.data_len > 0) {
|
||||
char *p;
|
||||
uint8_t i = 0;
|
||||
uint16_t parm[2] = { 0 };
|
||||
for (char *str = strtok_r(XdrvMailbox.data, ", ", &p); str && i < 2; str = strtok_r(nullptr, ", ", &p)) {
|
||||
parm[i] = strtoul(str, nullptr, 0);
|
||||
i++;
|
||||
}
|
||||
|
||||
if (parm[0] < parm[1]) {
|
||||
Settings.dimmer_hw_min = parm[0];
|
||||
Settings.dimmer_hw_max = parm[1];
|
||||
restart_flag = 2;
|
||||
} else {
|
||||
AddLog_P2(LOG_LEVEL_ERROR, PSTR("Light: Dimmer minimum %d should be less than maximum %d"), parm[0], parm[1]);
|
||||
}
|
||||
}
|
||||
|
||||
Response_P(PSTR("{" D_CMND_DIMMER_RANGE ":{\"min\":%d, \"max\":%d}}"), Settings.dimmer_hw_min, Settings.dimmer_hw_max);
|
||||
}
|
||||
|
||||
void CmndLedTable(void)
|
||||
{
|
||||
if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 2)) {
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
TasmotaSerial *TuyaSerial = nullptr;
|
||||
|
||||
struct TUYA {
|
||||
uint8_t new_dim = 0; // Tuya dimmer value temp
|
||||
uint16_t new_dim = 0; // Tuya dimmer value temp
|
||||
bool ignore_dim = false; // Flag to skip serial send to prevent looping when processing inbound states from the faceplate interaction
|
||||
uint8_t cmd_status = 0; // Current status of serial-read
|
||||
uint8_t cmd_checksum = 0; // Checksum of tuya command
|
||||
|
@ -124,7 +124,7 @@ void CmndTuyaMcu(void) {
|
|||
|
||||
}
|
||||
|
||||
Response_P(PSTR("["));
|
||||
Response_P(PSTR("{" D_CMND_TUYA_MCU ":["));
|
||||
bool added = false;
|
||||
for (uint8_t i = 0; i < MAX_TUYA_FUNCTIONS; i++) {
|
||||
if (Settings.tuya_fnid_map[i].fnid != 0) {
|
||||
|
@ -135,7 +135,7 @@ void CmndTuyaMcu(void) {
|
|||
added = true;
|
||||
}
|
||||
}
|
||||
ResponseAppend_P(PSTR("]"));
|
||||
ResponseAppend_P(PSTR("]}"));
|
||||
}
|
||||
|
||||
/*********************************************************************************************\
|
||||
|
@ -290,21 +290,19 @@ bool TuyaSetChannels(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void LightSerialDuty(uint8_t duty)
|
||||
void LightSerialDuty(uint16_t duty)
|
||||
{
|
||||
uint8_t dpid = TuyaGetDpId(TUYA_MCU_FUNC_DIMMER);
|
||||
if (duty > 0 && !Tuya.ignore_dim && TuyaSerial && dpid > 0) {
|
||||
if (Settings.flag3.tuya_dimmer_min_limit) { // Enable dimming limit SetOption69: Enabled by default
|
||||
if (duty < 25) { duty = 25; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
|
||||
}
|
||||
duty = changeUIntScale(duty, 0, 255, 0, Settings.param[P_DIMMER_MAX]);
|
||||
if (duty < Settings.dimmer_hw_min) { duty = Settings.dimmer_hw_min; } // dimming acts odd below 25(10%) - this mirrors the threshold set on the faceplate itself
|
||||
duty = changeUIntScale(duty, 0, 255, 0, Settings.dimmer_hw_max);
|
||||
if (Tuya.new_dim != duty) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim value=%d (id=%d)"), duty, dpid);
|
||||
TuyaSendValue(dpid, duty);
|
||||
}
|
||||
} else if (dpid > 0) {
|
||||
Tuya.ignore_dim = false; // reset flag
|
||||
duty = changeUIntScale(duty, 0, 255, 0, Settings.param[P_DIMMER_MAX]);
|
||||
duty = changeUIntScale(duty, 0, 255, 0, Settings.dimmer_hw_max);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Send dim skipped value=%d"), duty); // due to 0 or already set
|
||||
} else {
|
||||
AddLog_P(LOG_LEVEL_DEBUG, PSTR("TYA: Cannot set dimmer. Dimmer Id unknown")); //
|
||||
|
@ -373,9 +371,10 @@ void TuyaPacketProcess(void)
|
|||
}
|
||||
else if (Tuya.buffer[5] == 8) { // Long value packet
|
||||
bool tuya_energy_enabled = (XNRG_16 == energy_flg);
|
||||
uint16_t packetValue = Tuya.buffer[12] << 8 | Tuya.buffer[13];
|
||||
if (fnId == TUYA_MCU_FUNC_DIMMER) {
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), Tuya.buffer[13]);
|
||||
Tuya.new_dim = changeUIntScale((uint8_t) Tuya.buffer[13], 0, Settings.param[P_DIMMER_MAX], 0, 100);
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: RX Dim State=%d"), packetValue);
|
||||
Tuya.new_dim = changeUIntScale(packetValue, 0, Settings.dimmer_hw_max, 0, 100);
|
||||
if ((power || Settings.flag3.tuya_apply_o20) && (Tuya.new_dim > 0) && (abs(Tuya.new_dim - Settings.light_dimmer) > 1)) {
|
||||
Tuya.ignore_dim = true;
|
||||
|
||||
|
@ -386,14 +385,14 @@ void TuyaPacketProcess(void)
|
|||
|
||||
#ifdef USE_ENERGY_SENSOR
|
||||
else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_VOLTAGE) {
|
||||
Energy.voltage[0] = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
|
||||
Energy.voltage[0] = (float)packetValue / 10;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Voltage=%d"), Tuya.buffer[6], packetValue);
|
||||
} else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_CURRENT) {
|
||||
Energy.current[0] = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 1000;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
|
||||
Energy.current[0] = (float)packetValue / 1000;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Current=%d"), Tuya.buffer[6], packetValue);
|
||||
} else if (tuya_energy_enabled && fnId == TUYA_MCU_FUNC_POWER) {
|
||||
Energy.active_power[0] = (float)(Tuya.buffer[12] << 8 | Tuya.buffer[13]) / 10;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Tuya.buffer[6], (Tuya.buffer[12] << 8 | Tuya.buffer[13]));
|
||||
Energy.active_power[0] = (float)packetValue / 10;
|
||||
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("TYA: Rx ID=%d Active_Power=%d"), Tuya.buffer[6], packetValue);
|
||||
|
||||
if (Tuya.lastPowerCheckTime != 0 && Energy.active_power[0] > 0) {
|
||||
Energy.kWhtoday += (float)Energy.active_power[0] * (Rtc.utc_time - Tuya.lastPowerCheckTime) / 36;
|
||||
|
|
|
@ -82,8 +82,8 @@ void PS16DZSerialSendUpdateCommand(void)
|
|||
{
|
||||
uint8_t light_state_dimmer = light_state.getDimmer();
|
||||
// Dimming acts odd below 10% - this mirrors the threshold set on the faceplate itself
|
||||
light_state_dimmer = (light_state_dimmer < 10) ? 10 : light_state_dimmer;
|
||||
light_state_dimmer = (light_state_dimmer > Settings.param[P_DIMMER_MAX]) ? Settings.param[P_DIMMER_MAX] : light_state_dimmer;
|
||||
light_state_dimmer = (light_state_dimmer < Settings.dimmer_hw_min) ? Settings.dimmer_hw_min : light_state_dimmer;
|
||||
light_state_dimmer = (light_state_dimmer > Settings.dimmer_hw_max) ? Settings.dimmer_hw_max : light_state_dimmer;
|
||||
|
||||
snprintf_P(Ps16dz.tx_buffer, PS16DZ_BUFFER_SIZE, PSTR("AT+UPDATE=\"sequence\":\"%d%03d\",\"switch\":\"%s\",\"bright\":%d"),
|
||||
LocalTime(), millis()%1000, power?"on":"off", light_state_dimmer);
|
||||
|
|
Loading…
Reference in New Issue