From 3acae81fc0ed5081330aa6454ce0b59e3e11356c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 24 Jul 2020 15:30:21 +0200 Subject: [PATCH] Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Add command ``DzSend ,`` to send values or state to Domoticz --- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 2 + tasmota/xdrv_07_domoticz.ino | 157 +++++++++++++++++++---------------- 3 files changed, 91 insertions(+), 70 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 490280e79..e2170880c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -64,6 +64,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Change define USE_TASMOTA_SLAVE into USE_TASMOTA_CLIENT - Change commands ``SlaveSend`` and ``SlaveReset`` into ``ClientSend`` and ``ClientReset`` - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message +- Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` - Fix escape of non-JSON received serial data (#8329) - Fix exception or watchdog on rule re-entry (#8757) - Add command ``Rule0`` to change global rule parameters @@ -74,6 +75,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``SetOption99 0/1`` to enable zero cross detection on PWM dimmer - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 +- Add command ``DzSend ,`` to send values or state to Domoticz - Add command ``Module2`` to configure fallback module on fast reboot (#8464) - Add command (``S``)``SerialSend6`` \ (#8937) - Add commands ``LedPwmOn 0..255``, ``LedPwmOff 0..255`` and ``LedPwmMode1 0/1`` to control led brightness by George (#8491) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 31231a6ad..d30040e93 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -5,6 +5,8 @@ - Remove Arduino ESP8266 Core support for versions before 2.7.1 - Change to limited support of Arduino IDE as an increasing amount of features cannot be compiled with Arduino IDE - Change all timer references from ``Arm`` to ``Enable`` in GUI, ``Timer`` command and JSON message +- Change Domoticz commands prefix from ``Domoticz`` to ``Dz`` +- Add command ``DzSend ,`` to send values or state to Domoticz - Add command ``SetOption100 0/1`` to remove Zigbee ``ZbReceived`` value from ``{"ZbReceived":{xxx:yyy}}`` JSON message - Add command ``SetOption101 0/1`` to add the Zigbee source endpoint as suffix to attributes, ex `Power3` instead of `Power` if sent from endpoint 3 - Add command (``S``)``SerialSend6`` \ (#8937) diff --git a/tasmota/xdrv_07_domoticz.ino b/tasmota/xdrv_07_domoticz.ino index 556997bb9..4f26a2c8a 100644 --- a/tasmota/xdrv_07_domoticz.ino +++ b/tasmota/xdrv_07_domoticz.ino @@ -21,18 +21,20 @@ #define XDRV_07 7 -#define D_PRFX_DOMOTICZ "Domoticz" +//#define D_PRFX_DOMOTICZ "Domoticz" +#define D_PRFX_DOMOTICZ "Dz" #define D_CMND_IDX "Idx" #define D_CMND_KEYIDX "KeyIdx" #define D_CMND_SWITCHIDX "SwitchIdx" #define D_CMND_SENSORIDX "SensorIdx" #define D_CMND_UPDATETIMER "UpdateTimer" +#define D_CMND_DZSEND "Send" const char kDomoticzCommands[] PROGMEM = D_PRFX_DOMOTICZ "|" // Prefix - D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER ; + D_CMND_IDX "|" D_CMND_KEYIDX "|" D_CMND_SWITCHIDX "|" D_CMND_SENSORIDX "|" D_CMND_UPDATETIMER "|" D_CMND_DZSEND ; void (* const DomoticzCommand[])(void) PROGMEM = { - &CmndDomoticzIdx, &CmndDomoticzKeyIdx, &CmndDomoticzSwitchIdx, &CmndDomoticzSensorIdx, &CmndDomoticzUpdateTimer }; + &CmndDomoticzIdx, &CmndDomoticzKeyIdx, &CmndDomoticzSwitchIdx, &CmndDomoticzSensorIdx, &CmndDomoticzUpdateTimer, &CmndDomoticzSend }; const char DOMOTICZ_MESSAGE[] PROGMEM = "{\"idx\":%d,\"nvalue\":%d,\"svalue\":\"%s\",\"Battery\":%d,\"RSSI\":%d}"; @@ -44,6 +46,8 @@ const char kDomoticzSensors[] PROGMEM = D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT "|" D_DOMOTICZ_AIRQUALITY "|" D_DOMOTICZ_P1_SMART_METER "|" D_DOMOTICZ_SHUTTER ; +const char kDomoticzCommand[] PROGMEM = "switchlight|switchscene"; + char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; int domoticz_update_timer = 0; @@ -55,8 +59,7 @@ bool domoticz_update_flag = true; bool domoticz_is_shutter = false; #endif // USE_SHUTTER -int DomoticzBatteryQuality(void) -{ +int DomoticzBatteryQuality(void) { // Battery 0%: ESP 2.6V (minimum operating voltage is 2.5) // Battery 100%: ESP 3.6V (maximum operating voltage is 3.6) // Battery 101% to 200%: ESP over 3.6V (means over maximum operating voltage) @@ -76,16 +79,14 @@ int DomoticzBatteryQuality(void) return quality; } -int DomoticzRssiQuality(void) -{ +int DomoticzRssiQuality(void) { // RSSI range: 0% to 10% (12 means disable RSSI in Domoticz) return WifiGetRssiAsQuality(WiFi.RSSI()) / 10; } #ifdef USE_SONOFF_IFAN -void MqttPublishDomoticzFanState(void) -{ +void MqttPublishDomoticzFanState(void) { if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[1]) { // SetOption3 - Enable MQTT char svalue[8]; // Fanspeed value @@ -98,8 +99,7 @@ void MqttPublishDomoticzFanState(void) } } -void DomoticzUpdateFanState(void) -{ +void DomoticzUpdateFanState(void) { if (domoticz_update_flag) { MqttPublishDomoticzFanState(); } @@ -107,8 +107,7 @@ void DomoticzUpdateFanState(void) } #endif // USE_SONOFF_IFAN -void MqttPublishDomoticzPowerState(uint8_t device) -{ +void MqttPublishDomoticzPowerState(uint8_t device) { if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT if (device < 1) { device = 1; } if ((device > devices_present) || (device > MAX_DOMOTICZ_IDX)) { return; } @@ -138,16 +137,14 @@ void MqttPublishDomoticzPowerState(uint8_t device) } } -void DomoticzUpdatePowerState(uint8_t device) -{ +void DomoticzUpdatePowerState(uint8_t device) { if (domoticz_update_flag) { MqttPublishDomoticzPowerState(device); } domoticz_update_flag = true; } -void DomoticzMqttUpdate(void) -{ +void DomoticzMqttUpdate(void) { if (domoticz_subscribe && (Settings.domoticz_update_timer || domoticz_update_timer)) { domoticz_update_timer--; if (domoticz_update_timer <= 0) { @@ -175,8 +172,7 @@ void DomoticzMqttUpdate(void) } } -void DomoticzMqttSubscribe(void) -{ +void DomoticzMqttSubscribe(void) { uint8_t maxdev = (devices_present > MAX_DOMOTICZ_IDX) ? MAX_DOMOTICZ_IDX : devices_present; for (uint32_t i = 0; i < maxdev; i++) { if (Settings.domoticz_relay_idx[i]) { @@ -217,8 +213,7 @@ void DomoticzMqttSubscribe(void) } */ -bool DomoticzMqttData(void) -{ +bool DomoticzMqttData(void) { domoticz_update_flag = true; if (strncasecmp_P(XdrvMailbox.topic, PSTR(DOMOTICZ_OUT_TOPIC), strlen(DOMOTICZ_OUT_TOPIC)) != 0) { @@ -359,15 +354,19 @@ bool DomoticzMqttData(void) /*********************************************************************************************/ -bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg) -{ +void DomoticzSendSwitch(uint32_t type, uint32_t index, uint32_t state) { + char stemp[16]; // "switchlight" or "switchscene" + Response_P(PSTR("{\"command\":\"%s\",\"idx\":%d,\"switchcmd\":\"%s\"}"), + GetTextIndexed(stemp, sizeof(stemp), type, kDomoticzCommand), index, (state) ? (POWER_TOGGLE == state) ? "Toggle" : "On" : "Off"); // Domoticz case sensitive + MqttPublish(domoticz_in_topic); +} + +bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg) { bool result = false; if (device <= MAX_DOMOTICZ_IDX) { if ((Settings.domoticz_key_idx[device -1] || Settings.domoticz_switch_idx[device -1]) && (svalflg)) { - Response_P(PSTR("{\"command\":\"switchlight\",\"idx\":%d,\"switchcmd\":\"%s\"}"), - (key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], (state) ? (POWER_TOGGLE == state) ? "Toggle" : "On" : "Off"); - MqttPublish(domoticz_in_topic); + DomoticzSendSwitch(0, (key) ? Settings.domoticz_switch_idx[device -1] : Settings.domoticz_key_idx[device -1], state); result = true; } } @@ -391,46 +390,46 @@ bool DomoticzSendKey(uint8_t key, uint8_t device, uint8_t state, uint8_t svalflg * \*********************************************************************************************/ -uint8_t DomoticzHumidityState(float h) -{ - return (!h) ? 0 : (h < 40) ? 2 : (h > 70) ? 3 : 1; +void DomoticzSendData(uint32_t sensor_idx, uint32_t idx, char *data) { + if (DZ_AIRQUALITY == sensor_idx) { + Response_P(PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"), + idx, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); + } else { + uint8_t nvalue = 0; +#ifdef USE_SHUTTER + if (DZ_SHUTTER == sensor_idx) { + uint8_t position = atoi(data); + nvalue = position < 2 ? 0 : (position == 100 ? 1 : 2); + } +#endif // USE_SHUTTER + Response_P(DOMOTICZ_MESSAGE, + idx, nvalue, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); + } + MqttPublish(domoticz_in_topic); } -void DomoticzSensor(uint8_t idx, char *data) -{ +void DomoticzSensor(uint8_t idx, char *data) { if (Settings.domoticz_sensor_idx[idx]) { char dmess[128]; // {"idx":26700,"nvalue":0,"svalue":"22330.1;10234.4;22000.5;10243.4;1006;3000","Battery":100,"RSSI":10} memcpy(dmess, mqtt_data, sizeof(dmess)); - if (DZ_AIRQUALITY == idx) { - Response_P(PSTR("{\"idx\":%d,\"nvalue\":%s,\"Battery\":%d,\"RSSI\":%d}"), - Settings.domoticz_sensor_idx[idx], data, DomoticzBatteryQuality(), DomoticzRssiQuality()); - } else { - uint8_t nvalue = 0; -#ifdef USE_SHUTTER - if (DZ_SHUTTER == idx) { - uint8_t position = atoi(data); - nvalue = position < 2 ? 0 : (position == 100 ? 1 : 2); - } -#endif // USE_SHUTTER - Response_P(DOMOTICZ_MESSAGE, - Settings.domoticz_sensor_idx[idx], nvalue, data, DomoticzBatteryQuality(), DomoticzRssiQuality()); - } - MqttPublish(domoticz_in_topic); + DomoticzSendData(idx, Settings.domoticz_sensor_idx[idx], data); memcpy(mqtt_data, dmess, sizeof(dmess)); } } -void DomoticzSensor(uint8_t idx, uint32_t value) -{ +uint8_t DomoticzHumidityState(float h) { + return (!h) ? 0 : (h < 40) ? 2 : (h > 70) ? 3 : 1; +} + +void DomoticzSensor(uint8_t idx, uint32_t value) { char data[16]; snprintf_P(data, sizeof(data), PSTR("%d"), value); DomoticzSensor(idx, data); } //void DomoticzTempHumPressureSensor(float temp, float hum, float baro = -1); -void DomoticzTempHumPressureSensor(float temp, float hum, float baro) -{ +void DomoticzTempHumPressureSensor(float temp, float hum, float baro) { char temperature[FLOATSZ]; dtostrfd(temp, 2, temperature); char humidity[FLOATSZ]; @@ -449,15 +448,13 @@ void DomoticzTempHumPressureSensor(float temp, float hum, float baro) } } -void DomoticzSensorPowerEnergy(int power, char *energy) -{ +void DomoticzSensorPowerEnergy(int power, char *energy) { char data[16]; snprintf_P(data, sizeof(data), PSTR("%d;%s"), power, energy); DomoticzSensor(DZ_POWER_ENERGY, data); } -void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char *return2, int power) -{ +void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char *return2, int power) { //usage1 = energy usage meter tariff 1, This is an incrementing counter //usage2 = energy usage meter tariff 2, This is an incrementing counter //return1 = energy return meter tariff 1, This is an incrementing counter @@ -478,8 +475,7 @@ void DomoticzSensorP1SmartMeter(char *usage1, char *usage2, char *return1, char * Commands \*********************************************************************************************/ -void CmndDomoticzIdx(void) -{ +void CmndDomoticzIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_relay_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -489,8 +485,7 @@ void CmndDomoticzIdx(void) } } -void CmndDomoticzKeyIdx(void) -{ +void CmndDomoticzKeyIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_key_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -499,8 +494,7 @@ void CmndDomoticzKeyIdx(void) } } -void CmndDomoticzSwitchIdx(void) -{ +void CmndDomoticzSwitchIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_DOMOTICZ_IDX)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_switch_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -509,8 +503,7 @@ void CmndDomoticzSwitchIdx(void) } } -void CmndDomoticzSensorIdx(void) -{ +void CmndDomoticzSensorIdx(void) { if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= DZ_MAX_SENSORS)) { if (XdrvMailbox.payload >= 0) { Settings.domoticz_sensor_idx[XdrvMailbox.index -1] = XdrvMailbox.payload; @@ -519,14 +512,41 @@ void CmndDomoticzSensorIdx(void) } } -void CmndDomoticzUpdateTimer(void) -{ +void CmndDomoticzUpdateTimer(void) { if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 3601)) { Settings.domoticz_update_timer = XdrvMailbox.payload; } ResponseCmndNumber(Settings.domoticz_update_timer); } +void CmndDomoticzSend(void) { + // DzSend1 , - {\"idx\":,\"nvalue\":0,\"svalue\":\"\",\"Battery\":xx,\"RSSI\":yy} + // DzSend2 , - USE_SHUTTER only - {\"idx\":,\"nvalue\":,\"svalue\":\"\",\"Battery\":xx,\"RSSI\":yy} + // DzSend3 , - {\"idx\":,\"nvalue\":,\"Battery\":xx,\"RSSI\":yy} + // DzSend4 , - {\"command\":\"switchlight\",\"idx\":,\"switchcmd\":\"\"} + // DzSend5 , - {\"command\":\"switchscene\",\"idx\":,\"switchcmd\":\"\"} + + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= 5)) { + if (XdrvMailbox.data_len > 0) { + if (strstr(XdrvMailbox.data, ",") != nullptr) { // Process parameter entry + char *data; + uint32_t index = strtoul(strtok_r(XdrvMailbox.data, ",", &data), nullptr, 10); + if ((index > 0) && (data != nullptr)) { + if (XdrvMailbox.index > 3) { + uint32_t state = strtoul(data, nullptr, 10); // 0, 1 or 2 + DomoticzSendSwitch(XdrvMailbox.index -4, index, state); + } else { + uint32_t type = DZ_TEMP; + if (2 == XdrvMailbox.index) { type = DZ_SHUTTER; } + else if (3 == XdrvMailbox.index) { type = DZ_AIRQUALITY; } + DomoticzSendData(type, index, data); + } + } + } + } + } +} + /*********************************************************************************************\ * Presentation \*********************************************************************************************/ @@ -554,8 +574,7 @@ const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM = const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM = "" D_DOMOTICZ_UPDATE_TIMER " (" STR(DOMOTICZ_UPDATE_TIMER) ")"; -void HandleDomoticzConfiguration(void) -{ +void HandleDomoticzConfiguration(void) { if (!HttpCheckPriviledgedAccess()) { return; } AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ); @@ -596,8 +615,7 @@ void HandleDomoticzConfiguration(void) WSContentStop(); } -void DomoticzSaveSettings(void) -{ +void DomoticzSaveSettings(void) { char stemp[20]; char ssensor_indices[6 * MAX_DOMOTICZ_SNS_IDX]; char tmp[100]; @@ -635,8 +653,7 @@ void DomoticzSaveSettings(void) * Interface \*********************************************************************************************/ -bool Xdrv07(uint8_t function) -{ +bool Xdrv07(uint8_t function) { bool result = false; if (Settings.flag.mqtt_enabled) { // SetOption3 - Enable MQTT