From 2c138e69c2f5dd5e7853457bf97d7e1b51bffc2e Mon Sep 17 00:00:00 2001 From: Denis Taranushin Date: Tue, 13 Nov 2018 19:55:24 +0500 Subject: [PATCH 01/63] Add SDM220 Support Add some electric parameters for SDM220 --- sonoff/i18n.h | 6 +++ sonoff/language/bg-BG.h | 14 ++++++- sonoff/language/cs-CZ.h | 14 ++++++- sonoff/language/de-DE.h | 14 ++++++- sonoff/language/el-GR.h | 14 ++++++- sonoff/language/en-GB.h | 13 +++++- sonoff/language/es-AR.h | 14 ++++++- sonoff/language/fr-FR.h | 14 ++++++- sonoff/language/he-HE.h | 14 ++++++- sonoff/language/hu-HU.h | 14 ++++++- sonoff/language/it-IT.h | 14 ++++++- sonoff/language/nl-NL.h | 14 ++++++- sonoff/language/pl-PL.h | 14 ++++++- sonoff/language/pt-BR.h | 14 ++++++- sonoff/language/pt-PT.h | 14 ++++++- sonoff/language/ru-RU.h | 14 ++++++- sonoff/language/tr-TR.h | 14 ++++++- sonoff/language/uk-UK.h | 14 ++++++- sonoff/language/zh-CN.h | 14 ++++++- sonoff/language/zh-TW.h | 14 ++++++- sonoff/my_user_config.h | 3 +- sonoff/xsns_23_sdm120.ino | 88 +++++++++++++++++++++++++++++++++++---- 22 files changed, 315 insertions(+), 47 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 36d93ccd7..6e6669237 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -49,6 +49,12 @@ #define D_JSON_COUNT "Count" #define D_JSON_COUNTER "Counter" #define D_JSON_CURRENT "Current" // As in Voltage and Current +#define D_JSON_PHASE_ANGLE "Phase angle" +#define D_JSON_IMPORT_ACTIVE "Import Active Power" +#define D_JSON_EXPORT_ACTIVE "Export Active Power" +#define D_JSON_IMPORT_REACTIVE "Import Reactive Power" +#define D_JSON_EXPORT_REACTIVE "Export Reactive Power" +#define D_JSON_TOTAL_REACTIVE "Total Reactive Power" #define D_JSON_DATA "Data" #define D_JSON_DISTANCE "Distance" #define D_JSON_DNSSERVER "DNSServer" diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 1503884c3..898157a20 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_BG_BG_H_ diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 2b667cec1..29f65af85 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_CS_CZ_H_ diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 9c2f7c24e..e6293044c 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_DE_DE_H_ diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 79558615d..3ecd442a3 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -516,8 +516,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -587,4 +587,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_EN_GB_H_ diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 1a9304a7d..e93850170 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,13 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_EN_GB_H_ diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index e5c3135fe..c2d6481e9 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_ES_AR_H_ diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index 0dfb2929c..6fea65b6b 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_FR_FR_H_ diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index cb041ffba..1a6d44f7a 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_HE_HE_H_ diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 5cee46a52..2bc0d41d6 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_HU_HU_H_ diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 0eaca9337..b15b9aed2 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_IT_IT_H_ diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 0567e0849..9010722cc 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_NL_NL_H_ diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 678a7b770..f82fce1ae 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_PL_PL_D_H_ diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 712ea6a74..27e3ac64a 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_PT_BR_H_ diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 0bba501bd..58bf2cf73 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_PT_PT_H_ diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index f9062a572..bc1a6ee0e 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Угол фазы" +#define D_IMPORT_ACTIVE "Импорт активной мощности" +#define D_EXPORT_ACTIVE "Экспорт активной мощности" +#define D_IMPORT_REACTIVE "Импорт реактивной мощности" +#define D_EXPORT_REACTIVE "Экспорт реактивной мощности" +#define D_TOTAL_REACTIVE "Итого реактивная мощность" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Град" + #endif // _LANGUAGE_RU_RU_H_ diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index f892fafbb..55020e7a6 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_TR_TR_H_ diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 4c290613a..f6eb37689 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_UK_UK_H_ diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index fe6dabe8d..085460ef5 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_ZH_CN_H_ diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 92a805587..6656194ca 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -586,4 +586,14 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_ZH_TW_H_ diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index e1f6e364a..66f96b0ff 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -348,8 +348,9 @@ #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) #define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) -//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) +#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) + #define USE_SDM220 // add extra parameters for SDM220 (+0k1 code) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) #define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud) //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop diff --git a/sonoff/xsns_23_sdm120.ino b/sonoff/xsns_23_sdm120.ino index 5c2dfa630..dcbd263fa 100644 --- a/sonoff/xsns_23_sdm120.ino +++ b/sonoff/xsns_23_sdm120.ino @@ -42,6 +42,12 @@ float sdm120_reactive_power = 0; float sdm120_power_factor = 0; float sdm120_frequency = 0; float sdm120_energy_total = 0; +float sdm120_phase_angle = 0; +float sdm120_import_active = 0; +float sdm120_export_active = 0; +float sdm120_import_reactive = 0; +float sdm120_export_reactive = 0; +float sdm120_total_reactive = 0; bool SDM120_ModbusReceiveReady() { @@ -131,7 +137,17 @@ const uint16_t sdm120_start_addresses[] { 0x0018, // SDM120C_REACTIVE_POWER [VAR] 0x001E, // SDM120C_POWER_FACTOR 0x0046, // SDM120C_FREQUENCY [Hz] +#ifdef USE_SDM220 + 0x0156, // SDM120C_TOTAL_ACTIVE_ENERGY [Wh] + 0X0024, // SDM220_PHASE_ANGLE [Degre] + 0X0048, // SDM220_IMPORT_ACTIVE [kWh] + 0X004A, // SDM220_EXPORT_ACTIVE [kWh] + 0X004C, // SDM220_IMPORT_REACTIVE [kVArh] + 0X004E, // SDM220_EXPORT_REACTIVE [kVArh] + 0X0158 // SDM220 TOTAL_REACTIVE [kVArh] +#else // USE_SDM220 0x0156 // SDM120C_TOTAL_ACTIVE_ENERGY [Wh] +#endif // USE_SDM220 }; uint8_t sdm120_read_state = 0; @@ -184,6 +200,31 @@ void SDM120250ms() // Every 250 mSec case 7: sdm120_energy_total = value; break; +#ifdef USE_SDM220 + case 8: + sdm120_phase_angle = value; + break; + + case 9: + sdm120_import_active = value; + break; + + case 10: + sdm120_export_active = value; + break; + + case 11: + sdm120_import_reactive = value; + break; + + case 12: + sdm120_export_reactive = value; + break; + + case 13: + sdm120_total_reactive = value; + break; +#endif // USE_SDM220 } // end switch sdm120_read_state++; @@ -228,7 +269,16 @@ const char HTTP_SNS_SDM120_DATA[] PROGMEM = "%s" "{s}SDM120 " D_POWERUSAGE_REACTIVE "{m}%s " D_UNIT_VAR "{e}" "{s}SDM120 " D_POWER_FACTOR "{m}%s{e}" "{s}SDM120 " D_FREQUENCY "{m}%s " D_UNIT_HERTZ "{e}" - "{s}SDM120 " D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; + "{s}SDM120 " D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}" +#ifdef USE_SDM220 + "{s}SDM120 " D_PHASE_ANGLE "{m}%s " D_UNIT_ANGLE "{e}" + "{s}SDM120 " D_IMPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}" + "{s}SDM120 " D_EXPORT_ACTIVE "{m}%s " D_UNIT_KILOWATTHOUR "{e}" + "{s}SDM120 " D_IMPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}" + "{s}SDM120 " D_EXPORT_REACTIVE "{m}%s " D_UNIT_KWARH "{e}" + "{s}SDM120 " D_TOTAL_REACTIVE "{m}%s " D_UNIT_KWARH "{e}" +#endif // USE_SDM220 + ; #endif // USE_WEBSERVER void SDM120Show(boolean json) @@ -241,19 +291,37 @@ void SDM120Show(boolean json) char power_factor[10]; char frequency[10]; char energy_total[10]; + char phase_angle[10]; + char import_active[10]; + char export_active[10]; + char import_reactive[10]; + char export_reactive[10]; + char total_reactive[10]; - dtostrfd(sdm120_voltage, Settings.flag2.voltage_resolution, voltage); - dtostrfd(sdm120_current, Settings.flag2.current_resolution, current); - dtostrfd(sdm120_active_power, Settings.flag2.wattage_resolution, active_power); + dtostrfd(sdm120_voltage, Settings.flag2.voltage_resolution, voltage); + dtostrfd(sdm120_current, Settings.flag2.current_resolution, current); + dtostrfd(sdm120_active_power, Settings.flag2.wattage_resolution, active_power); dtostrfd(sdm120_apparent_power, Settings.flag2.wattage_resolution, apparent_power); dtostrfd(sdm120_reactive_power, Settings.flag2.wattage_resolution, reactive_power); - dtostrfd(sdm120_power_factor, 2, power_factor); - dtostrfd(sdm120_frequency, Settings.flag2.frequency_resolution, frequency); - dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total); - + dtostrfd(sdm120_power_factor, 2, power_factor); + dtostrfd(sdm120_frequency, Settings.flag2.frequency_resolution, frequency); + dtostrfd(sdm120_energy_total, Settings.flag2.energy_resolution, energy_total); +#ifdef USE_SDM220 + dtostrfd(sdm120_phase_angle, 2, phase_angle); + dtostrfd(sdm120_import_active, Settings.flag2.wattage_resolution, import_active); + dtostrfd(sdm120_export_active, Settings.flag2.wattage_resolution, export_active); + dtostrfd(sdm120_import_reactive,Settings.flag2.wattage_resolution, import_reactive); + dtostrfd(sdm120_export_reactive,Settings.flag2.wattage_resolution, export_reactive); + dtostrfd(sdm120_total_reactive, Settings.flag2.wattage_resolution, total_reactive); +#endif // USE_SDM220 if (json) { +#ifdef USE_SDM220 + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s,\"" D_JSON_PHASE_ANGLE "\":%s,\"" D_JSON_IMPORT_ACTIVE "\":%s,\"" D_JSON_EXPORT_ACTIVE "\":%s,\"" D_JSON_IMPORT_REACTIVE "\":%s,\"" D_JSON_EXPORT_REACTIVE "\":%s,\"" D_JSON_TOTAL_REACTIVE "\":%s}"), + mqtt_data, energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current, phase_angle, import_active, export_active, import_reactive, export_reactive, total_reactive); +#else snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_RSLT_ENERGY "\":{\"" D_JSON_TOTAL "\":%s,\"" D_JSON_ACTIVE_POWERUSAGE "\":%s,\"" D_JSON_APPARENT_POWERUSAGE "\":%s,\"" D_JSON_REACTIVE_POWERUSAGE "\":%s,\"" D_JSON_FREQUENCY "\":%s,\"" D_JSON_POWERFACTOR "\":%s,\"" D_JSON_VOLTAGE "\":%s,\"" D_JSON_CURRENT "\":%s}"), mqtt_data, energy_total, active_power, apparent_power, reactive_power, frequency, power_factor, voltage, current); +#endif // USE_SDM220 #ifdef USE_DOMOTICZ if (0 == tele_period) { DomoticzSensor(DZ_VOLTAGE, voltage); @@ -263,7 +331,11 @@ void SDM120Show(boolean json) #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { +#ifdef USE_SDM220 + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SDM120_DATA, mqtt_data, voltage, current, active_power, apparent_power, reactive_power, power_factor, frequency, energy_total, phase_angle,import_active,export_active,import_reactive,export_reactive,total_reactive); +#else snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SDM120_DATA, mqtt_data, voltage, current, active_power, apparent_power, reactive_power, power_factor, frequency, energy_total); +#endif // USE_SDM220 #endif // USE_WEBSERVER } } From b03c761eeed624dd70cfd506095f82265073fa64 Mon Sep 17 00:00:00 2001 From: Winston Ametsitsi Date: Wed, 28 Nov 2018 01:33:59 -0800 Subject: [PATCH 02/63] switch to using NewPing lib directly for sr04 add NewPing-1.9.1 lib --- lib/NewPing-1.9.1/README.md | 3 + .../NewPing15SensorsTimer.pde | 78 ++++ .../NewPing3Sensors/NewPing3Sensors.pde | 29 ++ .../NewPingEventTimer/NewPingEventTimer.pde | 46 +++ .../NewPingExample/NewPingExample.pde | 22 ++ .../NewPingTimerMedian/NewPingTimerMedian.pde | 60 +++ .../examples/TimerExample/TimerExample.pde | 25 ++ lib/NewPing-1.9.1/keywords.txt | 31 ++ lib/NewPing-1.9.1/library.properties | 10 + lib/NewPing-1.9.1/src/NewPing.cpp | 365 ++++++++++++++++++ lib/NewPing-1.9.1/src/NewPing.h | 275 +++++++++++++ sonoff/xsns_22_sr04.ino | 113 +----- 12 files changed, 962 insertions(+), 95 deletions(-) create mode 100644 lib/NewPing-1.9.1/README.md create mode 100644 lib/NewPing-1.9.1/examples/NewPing15SensorsTimer/NewPing15SensorsTimer.pde create mode 100644 lib/NewPing-1.9.1/examples/NewPing3Sensors/NewPing3Sensors.pde create mode 100644 lib/NewPing-1.9.1/examples/NewPingEventTimer/NewPingEventTimer.pde create mode 100644 lib/NewPing-1.9.1/examples/NewPingExample/NewPingExample.pde create mode 100644 lib/NewPing-1.9.1/examples/NewPingTimerMedian/NewPingTimerMedian.pde create mode 100644 lib/NewPing-1.9.1/examples/TimerExample/TimerExample.pde create mode 100644 lib/NewPing-1.9.1/keywords.txt create mode 100644 lib/NewPing-1.9.1/library.properties create mode 100644 lib/NewPing-1.9.1/src/NewPing.cpp create mode 100644 lib/NewPing-1.9.1/src/NewPing.h diff --git a/lib/NewPing-1.9.1/README.md b/lib/NewPing-1.9.1/README.md new file mode 100644 index 000000000..fe014a466 --- /dev/null +++ b/lib/NewPing-1.9.1/README.md @@ -0,0 +1,3 @@ +# NewPing Arduino Library for Arduino + +## See the [NewPing Wiki](https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home) for documentation \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/NewPing15SensorsTimer/NewPing15SensorsTimer.pde b/lib/NewPing-1.9.1/examples/NewPing15SensorsTimer/NewPing15SensorsTimer.pde new file mode 100644 index 000000000..b555c0be7 --- /dev/null +++ b/lib/NewPing-1.9.1/examples/NewPing15SensorsTimer/NewPing15SensorsTimer.pde @@ -0,0 +1,78 @@ +// --------------------------------------------------------------------------- +// Before attempting to use this sketch, please read the "Help with 15 Sensors Example Sketch": +// https://bitbucket.org/teckel12/arduino-new-ping/wiki/Help%20with%2015%20Sensors%20Example%20Sketch +// +// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust +// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the +// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor +// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results +// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project +// would normally process the sensor results in this function (for example, decide if a robot needs to +// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs +// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other +// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind. +// --------------------------------------------------------------------------- +#include + +#define SONAR_NUM 15 // Number of sensors. +#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping. +#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo). + +unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor. +unsigned int cm[SONAR_NUM]; // Where the ping distances are stored. +uint8_t currentSensor = 0; // Keeps track of which sensor is active. + +NewPing sonar[SONAR_NUM] = { // Sensor object array. + NewPing(41, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping. + NewPing(43, 44, MAX_DISTANCE), + NewPing(45, 20, MAX_DISTANCE), + NewPing(21, 22, MAX_DISTANCE), + NewPing(23, 24, MAX_DISTANCE), + NewPing(25, 26, MAX_DISTANCE), + NewPing(27, 28, MAX_DISTANCE), + NewPing(29, 30, MAX_DISTANCE), + NewPing(31, 32, MAX_DISTANCE), + NewPing(34, 33, MAX_DISTANCE), + NewPing(35, 36, MAX_DISTANCE), + NewPing(37, 38, MAX_DISTANCE), + NewPing(39, 40, MAX_DISTANCE), + NewPing(50, 51, MAX_DISTANCE), + NewPing(52, 53, MAX_DISTANCE) +}; + +void setup() { + Serial.begin(115200); + pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting. + for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor. + pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL; +} + +void loop() { + for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors. + if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping? + pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged. + if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results. + sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance). + currentSensor = i; // Sensor being accessed. + cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor. + sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo). + } + } + // Other code that *DOESN'T* analyze ping results can go here. +} + +void echoCheck() { // If ping received, set the sensor distance to array. + if (sonar[currentSensor].check_timer()) + cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM; +} + +void oneSensorCycle() { // Sensor ping cycle complete, do something with the results. + // The following code would be replaced with your code that does something with the ping results. + for (uint8_t i = 0; i < SONAR_NUM; i++) { + Serial.print(i); + Serial.print("="); + Serial.print(cm[i]); + Serial.print("cm "); + } + Serial.println(); +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/NewPing3Sensors/NewPing3Sensors.pde b/lib/NewPing-1.9.1/examples/NewPing3Sensors/NewPing3Sensors.pde new file mode 100644 index 000000000..4429fd850 --- /dev/null +++ b/lib/NewPing-1.9.1/examples/NewPing3Sensors/NewPing3Sensors.pde @@ -0,0 +1,29 @@ +// --------------------------------------------------------------------------- +// Example NewPing library sketch that pings 3 sensors 20 times a second. +// --------------------------------------------------------------------------- + +#include + +#define SONAR_NUM 3 // Number of sensors. +#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping. + +NewPing sonar[SONAR_NUM] = { // Sensor object array. + NewPing(4, 5, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping. + NewPing(6, 7, MAX_DISTANCE), + NewPing(8, 9, MAX_DISTANCE) +}; + +void setup() { + Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results. +} + +void loop() { + for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through each sensor and display results. + delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. + Serial.print(i); + Serial.print("="); + Serial.print(sonar[i].ping_cm()); + Serial.print("cm "); + } + Serial.println(); +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/NewPingEventTimer/NewPingEventTimer.pde b/lib/NewPing-1.9.1/examples/NewPingEventTimer/NewPingEventTimer.pde new file mode 100644 index 000000000..d9d26673e --- /dev/null +++ b/lib/NewPing-1.9.1/examples/NewPingEventTimer/NewPingEventTimer.pde @@ -0,0 +1,46 @@ +// --------------------------------------------------------------------------- +// This example shows how to use NewPing's ping_timer method which uses the Timer2 interrupt to get the +// ping time. The advantage of using this method over the standard ping method is that it permits a more +// event-driven sketch which allows you to appear to do two things at once. An example would be to ping +// an ultrasonic sensor for a possible collision while at the same time navigating. This allows a +// properly developed sketch to multitask. Be aware that because the ping_timer method uses Timer2, +// other features or libraries that also use Timer2 would be effected. For example, the PWM function on +// pins 3 & 11 on Arduino Uno (pins 9 and 11 on Arduino Mega) and the Tone library. Note, only the PWM +// functionality of the pins is lost (as they use Timer2 to do PWM), the pins are still available to use. +// NOTE: For Teensy/Leonardo (ATmega32U4) the library uses Timer4 instead of Timer2. +// --------------------------------------------------------------------------- +#include + +#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor. +#define ECHO_PIN 11 // Arduino pin tied to echo pin on ping sensor. +#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. + +NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. + +unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second. +unsigned long pingTimer; // Holds the next ping time. + +void setup() { + Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results. + pingTimer = millis(); // Start now. +} + +void loop() { + // Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings. + if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping. + pingTimer += pingSpeed; // Set the next ping time. + sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status. + } + // Do other stuff here, really. Think of it as multi-tasking. +} + +void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status. + // Don't do anything here! + if (sonar.check_timer()) { // This is how you check to see if the ping was received. + // Here's where you can add code. + Serial.print("Ping: "); + Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM. + Serial.println("cm"); + } + // Don't do anything here! +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/NewPingExample/NewPingExample.pde b/lib/NewPing-1.9.1/examples/NewPingExample/NewPingExample.pde new file mode 100644 index 000000000..12f6fdaaf --- /dev/null +++ b/lib/NewPing-1.9.1/examples/NewPingExample/NewPingExample.pde @@ -0,0 +1,22 @@ +// --------------------------------------------------------------------------- +// Example NewPing library sketch that does a ping about 20 times per second. +// --------------------------------------------------------------------------- + +#include + +#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor. +#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor. +#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm. + +NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. + +void setup() { + Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results. +} + +void loop() { + delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings. + Serial.print("Ping: "); + Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range) + Serial.println("cm"); +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/NewPingTimerMedian/NewPingTimerMedian.pde b/lib/NewPing-1.9.1/examples/NewPingTimerMedian/NewPingTimerMedian.pde new file mode 100644 index 000000000..93027afd7 --- /dev/null +++ b/lib/NewPing-1.9.1/examples/NewPingTimerMedian/NewPingTimerMedian.pde @@ -0,0 +1,60 @@ +// --------------------------------------------------------------------------- +// Calculate a ping median using the ping_timer() method. +// --------------------------------------------------------------------------- + +#include + +#define ITERATIONS 5 // Number of iterations. +#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor. +#define ECHO_PIN 11 // Arduino pin tied to echo pin on ping sensor. +#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping. +#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo). + +unsigned long pingTimer[ITERATIONS]; // Holds the times when the next ping should happen for each iteration. +unsigned int cm[ITERATIONS]; // Where the ping distances are stored. +uint8_t currentIteration = 0; // Keeps track of iteration step. + +NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance. + +void setup() { + Serial.begin(115200); + pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting. + for (uint8_t i = 1; i < ITERATIONS; i++) // Set the starting time for each iteration. + pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL; +} + +void loop() { + for (uint8_t i = 0; i < ITERATIONS; i++) { // Loop through all the iterations. + if (millis() >= pingTimer[i]) { // Is it this iteration's time to ping? + pingTimer[i] += PING_INTERVAL * ITERATIONS; // Set next time this sensor will be pinged. + if (i == 0 && currentIteration == ITERATIONS - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results. + sonar.timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance). + currentIteration = i; // Sensor being accessed. + cm[currentIteration] = 0; // Make distance zero in case there's no ping echo for this iteration. + sonar.ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo). + } + } + // Other code that *DOESN'T* analyze ping results can go here. +} + +void echoCheck() { // If ping received, set the sensor distance to array. + if (sonar.check_timer()) + cm[currentIteration] = sonar.ping_result / US_ROUNDTRIP_CM; +} + +void oneSensorCycle() { // All iterations complete, calculate the median. + unsigned int uS[ITERATIONS]; + uint8_t j, it = ITERATIONS; + uS[0] = NO_ECHO; + for (uint8_t i = 0; i < it; i++) { // Loop through iteration results. + if (cm[i] != NO_ECHO) { // Ping in range, include as part of median. + if (i > 0) { // Don't start sort till second ping. + for (j = i; j > 0 && uS[j - 1] < cm[i]; j--) // Insertion sort loop. + uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion. + } else j = 0; // First ping is sort starting point. + uS[j] = cm[i]; // Add last ping to array in sorted position. + } else it--; // Ping out of range, skip and don't include as part of median. + } + Serial.print(uS[it >> 1]); + Serial.println("cm"); +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/examples/TimerExample/TimerExample.pde b/lib/NewPing-1.9.1/examples/TimerExample/TimerExample.pde new file mode 100644 index 000000000..ea66039ee --- /dev/null +++ b/lib/NewPing-1.9.1/examples/TimerExample/TimerExample.pde @@ -0,0 +1,25 @@ +// --------------------------------------------------------------------------- +// While the NewPing library's primary goal is to interface with ultrasonic sensors, interfacing with +// the Timer2 interrupt was a result of creating an interrupt-based ping method. Since these Timer2 +// interrupt methods were built, the library may as well provide the functionality to use these methods +// in your sketches. This shows how simple it is (no ultrasonic sensor required). Keep in mind that +// these methods use Timer2, as does NewPing's ping_timer method for using ultrasonic sensors. You +// can't use ping_timer at the same time you're using timer_ms or timer_us as all use the same timer. +// --------------------------------------------------------------------------- + +#include + +#define LED_PIN 13 // Pin with LED attached. + +void setup() { + pinMode(LED_PIN, OUTPUT); + NewPing::timer_ms(500, toggleLED); // Create a Timer2 interrupt that calls toggleLED in your sketch once every 500 milliseconds. +} + +void loop() { + // Do anything here, the Timer2 interrupt will take care of the flashing LED without your intervention. +} + +void toggleLED() { + digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED. +} \ No newline at end of file diff --git a/lib/NewPing-1.9.1/keywords.txt b/lib/NewPing-1.9.1/keywords.txt new file mode 100644 index 000000000..dde5a73d1 --- /dev/null +++ b/lib/NewPing-1.9.1/keywords.txt @@ -0,0 +1,31 @@ +################################### +# Syntax Coloring Map For NewPing +################################### + +################################### +# Datatypes (KEYWORD1) +################################### + +NewPing KEYWORD1 + +################################### +# Methods and Functions (KEYWORD2) +################################### + +ping KEYWORD2 +ping_in KEYWORD2 +ping_cm KEYWORD2 +ping_median KEYWORD2 +ping_timer KEYWORD2 +check_timer KEYWORD2 +ping_result KEYWORD2 +timer_us KEYWORD2 +timer_ms KEYWORD2 +timer_stop KEYWORD2 +convert_in KEYWORD2 +convert_cm KEYWORD2 + +################################### +# Constants (LITERAL1) +################################### + diff --git a/lib/NewPing-1.9.1/library.properties b/lib/NewPing-1.9.1/library.properties new file mode 100644 index 000000000..2accb6c86 --- /dev/null +++ b/lib/NewPing-1.9.1/library.properties @@ -0,0 +1,10 @@ +name=NewPing +version=1.9.1 +author=Tim Eckel +maintainer=Tim Eckel +sentence=A library that makes working with ultrasonic sensors easy. +paragraph=When I first received an ultrasonic sensor I was not happy with how poorly it performed. I soon realized the problem was not the sensor, it was the available ping and ultrasonic libraries causing the problem. The NewPing library totally fixes these problems, adds many new features, and breathes new life into these very affordable distance sensors. +category=Sensors +url=https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home +architectures=avr,arm +includes=NewPing.h \ No newline at end of file diff --git a/lib/NewPing-1.9.1/src/NewPing.cpp b/lib/NewPing-1.9.1/src/NewPing.cpp new file mode 100644 index 000000000..ac0d397a4 --- /dev/null +++ b/lib/NewPing-1.9.1/src/NewPing.cpp @@ -0,0 +1,365 @@ +// --------------------------------------------------------------------------- +// Created by Tim Eckel - teckel@leethost.com +// +// See NewPing.h for license, purpose, syntax, version history, links, etc. +// --------------------------------------------------------------------------- + +#include "NewPing.h" + + +// --------------------------------------------------------------------------- +// NewPing constructor +// --------------------------------------------------------------------------- + +NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance) { +#if DO_BITWISE == true + _triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin. + _echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin. + + _triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin. + _echoInput = portInputRegister(digitalPinToPort(echo_pin)); // Get the input port register for the echo pin. + + _triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin. +#else + _triggerPin = trigger_pin; + _echoPin = echo_pin; +#endif + + set_max_distance(max_cm_distance); // Call function to set the max sensor distance. + +#if (defined (__arm__) && (defined (TEENSYDUINO) || defined(PARTICLE))) || DO_BITWISE != true + pinMode(echo_pin, INPUT); // Set echo pin to input (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode). + pinMode(trigger_pin, OUTPUT); // Set trigger pin to output (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode). +#endif + +#if defined (ARDUINO_AVR_YUN) + pinMode(echo_pin, INPUT); // Set echo pin to input for the Arduino Yun, not sure why it doesn't default this way. +#endif + +#if ONE_PIN_ENABLED != true && DO_BITWISE == true + *_triggerMode |= _triggerBit; // Set trigger pin to output. +#endif +} + + +// --------------------------------------------------------------------------- +// Standard ping methods +// --------------------------------------------------------------------------- + +unsigned int NewPing::ping(unsigned int max_cm_distance) { + if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance. + + if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function. + +#if URM37_ENABLED == true + #if DO_BITWISE == true + while (!(*_echoInput & _echoBit)) // Wait for the ping echo. + #else + while (!digitalRead(_echoPin)) // Wait for the ping echo. + #endif + if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance. +#else + #if DO_BITWISE == true + while (*_echoInput & _echoBit) // Wait for the ping echo. + #else + while (digitalRead(_echoPin)) // Wait for the ping echo. + #endif + if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance. +#endif + + return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead. +} + + +unsigned long NewPing::ping_cm(unsigned int max_cm_distance) { + unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS. +#if ROUNDING_ENABLED == false + return (echoTime / US_ROUNDTRIP_CM); // Call the ping method and returns the distance in centimeters (no rounding). +#else + return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters. +#endif +} + + +unsigned long NewPing::ping_in(unsigned int max_cm_distance) { + unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS. +#if ROUNDING_ENABLED == false + return (echoTime / US_ROUNDTRIP_IN); // Call the ping method and returns the distance in inches (no rounding). +#else + return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches. +#endif +} + + +unsigned long NewPing::ping_median(uint8_t it, unsigned int max_cm_distance) { + unsigned int uS[it], last; + uint8_t j, i = 0; + unsigned long t; + uS[0] = NO_ECHO; + + while (i < it) { + t = micros(); // Start ping timestamp. + last = ping(max_cm_distance); // Send ping. + + if (last != NO_ECHO) { // Ping in range, include as part of median. + if (i > 0) { // Don't start sort till second ping. + for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop. + uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion. + } else j = 0; // First ping is sort starting point. + uS[j] = last; // Add last ping to array in sorted position. + i++; // Move to next ping. + } else it--; // Ping out of range, skip and don't include as part of median. + + if (i < it && micros() - t < PING_MEDIAN_DELAY) + delay((PING_MEDIAN_DELAY + t - micros()) / 1000); // Millisecond delay between pings. + + } + return (uS[it >> 1]); // Return the ping distance median. +} + + +// --------------------------------------------------------------------------- +// Standard and timer interrupt ping method support functions (not called directly) +// --------------------------------------------------------------------------- + +boolean NewPing::ping_trigger() { +#if DO_BITWISE == true + #if ONE_PIN_ENABLED == true + *_triggerMode |= _triggerBit; // Set trigger pin to output. + #endif + + *_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is. + delayMicroseconds(4); // Wait for pin to go low. + *_triggerOutput |= _triggerBit; // Set trigger pin high, this tells the sensor to send out a ping. + delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS. + *_triggerOutput &= ~_triggerBit; // Set trigger pin back to low. + + #if ONE_PIN_ENABLED == true + *_triggerMode &= ~_triggerBit; // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin). + #endif + + #if URM37_ENABLED == true + if (!(*_echoInput & _echoBit)) return false; // Previous ping hasn't finished, abort. + _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) + while (*_echoInput & _echoBit) // Wait for ping to start. + if (micros() > _max_time) return false; // Took too long to start, abort. + #else + if (*_echoInput & _echoBit) return false; // Previous ping hasn't finished, abort. + _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) + while (!(*_echoInput & _echoBit)) // Wait for ping to start. + if (micros() > _max_time) return false; // Took too long to start, abort. + #endif +#else + #if ONE_PIN_ENABLED == true + pinMode(_triggerPin, OUTPUT); // Set trigger pin to output. + #endif + + digitalWrite(_triggerPin, LOW); // Set the trigger pin low, should already be low, but this will make sure it is. + delayMicroseconds(4); // Wait for pin to go low. + digitalWrite(_triggerPin, HIGH); // Set trigger pin high, this tells the sensor to send out a ping. + delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS. + digitalWrite(_triggerPin, LOW); // Set trigger pin back to low. + + #if ONE_PIN_ENABLED == true + pinMode(_triggerPin, INPUT); // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin). + #endif + + #if URM37_ENABLED == true + if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort. + _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) + while (digitalRead(_echoPin)) // Wait for ping to start. + if (micros() > _max_time) return false; // Took too long to start, abort. + #else + if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort. + _max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!) + while (!digitalRead(_echoPin)) // Wait for ping to start. + if (micros() > _max_time) return false; // Took too long to start, abort. + #endif +#endif + + _max_time = micros() + _maxEchoTime; // Ping started, set the time-out. + return true; // Ping started successfully. +} + + +void NewPing::set_max_distance(unsigned int max_cm_distance) { +#if ROUNDING_ENABLED == false + _maxEchoTime = min(max_cm_distance + 1, (unsigned int) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; // Calculate the maximum distance in uS (no rounding). +#else + _maxEchoTime = min(max_cm_distance, (unsigned int) MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS. +#endif +} + + +#if TIMER_ENABLED == true && DO_BITWISE == true + + // --------------------------------------------------------------------------- + // Timer interrupt ping methods (won't work with ATmega128, ATtiny and most non-AVR microcontrollers) + // --------------------------------------------------------------------------- + + void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) { + if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance. + + if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer. + timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS. + } + + + boolean NewPing::check_timer() { + if (micros() > _max_time) { // Outside the time-out limit. + timer_stop(); // Disable timer interrupt + return false; // Cancel ping timer. + } + + #if URM37_ENABLED == false + if (!(*_echoInput & _echoBit)) { // Ping echo received. + #else + if (*_echoInput & _echoBit) { // Ping echo received. + #endif + timer_stop(); // Disable timer interrupt + ping_result = (micros() - (_max_time - _maxEchoTime) - PING_TIMER_OVERHEAD); // Calculate ping time including overhead. + return true; // Return ping echo true. + } + + return false; // Return false because there's no ping echo yet. + } + + + // --------------------------------------------------------------------------- + // Timer2/Timer4 interrupt methods (can be used for non-ultrasonic needs) + // --------------------------------------------------------------------------- + + // Variables used for timer functions + void (*intFunc)(); + void (*intFunc2)(); + unsigned long _ms_cnt_reset; + volatile unsigned long _ms_cnt; + #if defined(__arm__) && (defined (TEENSYDUINO) || defined(PARTICLE)) + IntervalTimer itimer; + #endif + + + void NewPing::timer_us(unsigned int frequency, void (*userFunc)(void)) { + intFunc = userFunc; // User's function to call when there's a timer event. + timer_setup(); // Configure the timer interrupt. + + #if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo). + OCR4C = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit. + TIMSK4 = (1<>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit. + TIMSK2 |= (1<= 100 + #include + #else + #include + #if defined (PARTICLE) + #include + #else + #include + #endif + #endif + + #if defined (__AVR__) + #include + #include + #endif + + // Shouldn't need to change these values unless you have a specific need to do so. + #define MAX_SENSOR_DISTANCE 500 // Maximum sensor distance can be as high as 500cm, no reason to wait for ping longer than sound takes to travel this distance and back. Default=500 + #define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. Default=57 + #define US_ROUNDTRIP_IN 146 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space. Defalult=146 + #define ONE_PIN_ENABLED true // Set to "false" to disable one pin mode which saves around 14-26 bytes of binary size. Default=true + #define ROUNDING_ENABLED false // Set to "true" to enable distance rounding which also adds 64 bytes to binary size. Default=false + #define URM37_ENABLED false // Set to "true" to enable support for the URM37 sensor in PWM mode. Default=false + #define TIMER_ENABLED true // Set to "false" to disable the timer ISR (if getting "__vector_7" compile errors set this to false). Default=true + + // Probably shouldn't change these values unless you really know what you're doing. + #define NO_ECHO 0 // Value returned if there's no ping echo within the specified MAX_SENSOR_DISTANCE or max_cm_distance. Default=0 + #define MAX_SENSOR_DELAY 5800 // Maximum uS it takes for sensor to start the ping. Default=5800 + #define ECHO_TIMER_FREQ 24 // Frequency to check for a ping echo (every 24uS is about 0.4cm accuracy). Default=24 + #define PING_MEDIAN_DELAY 29000 // Microsecond delay between pings in the ping_median method. Default=29000 + #define PING_OVERHEAD 5 // Ping overhead in microseconds (uS). Default=5 + #define PING_TIMER_OVERHEAD 13 // Ping timer overhead in microseconds (uS). Default=13 + #if URM37_ENABLED == true + #undef US_ROUNDTRIP_CM + #undef US_ROUNDTRIP_IN + #define US_ROUNDTRIP_CM 50 // Every 50uS PWM signal is low indicates 1cm distance. Default=50 + #define US_ROUNDTRIP_IN 127 // If 50uS is 1cm, 1 inch would be 127uS (50 x 2.54 = 127). Default=127 + #endif + + // Conversion from uS to distance (round result to nearest cm or inch). + #define NewPingConvert(echoTime, conversionFactor) (max(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0))) + + // Detect non-AVR microcontrollers (Teensy 3.x, Arduino DUE, etc.) and don't use port registers or timer interrupts as required. + #if (defined (__arm__) && (defined (TEENSYDUINO) || defined (PARTICLE))) + #undef PING_OVERHEAD + #define PING_OVERHEAD 1 + #undef PING_TIMER_OVERHEAD + #define PING_TIMER_OVERHEAD 1 + #define DO_BITWISE true + #elif !defined (__AVR__) + #undef PING_OVERHEAD + #define PING_OVERHEAD 1 + #undef PING_TIMER_OVERHEAD + #define PING_TIMER_OVERHEAD 1 + #undef TIMER_ENABLED + #define TIMER_ENABLED false + #define DO_BITWISE false + #else + #define DO_BITWISE true + #endif + + // Disable the timer interrupts when using ATmega128 and all ATtiny microcontrollers. + #if defined (__AVR_ATmega128__) || defined (__AVR_ATtiny24__) || defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny441__) || defined (__AVR_ATtiny84__) || defined (__AVR_ATtiny841__) || defined (__AVR_ATtiny25__) || defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) || defined (__AVR_ATtiny261__) || defined (__AVR_ATtiny461__) || defined (__AVR_ATtiny861__) || defined (__AVR_ATtiny43U__) + #undef TIMER_ENABLED + #define TIMER_ENABLED false + #endif + + // Define timers when using ATmega8, ATmega16, ATmega32 and ATmega8535 microcontrollers. + #if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) + #define OCR2A OCR2 + #define TIMSK2 TIMSK + #define OCIE2A OCIE2 + #endif + + class NewPing { + public: + NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance = MAX_SENSOR_DISTANCE); + unsigned int ping(unsigned int max_cm_distance = 0); + unsigned long ping_cm(unsigned int max_cm_distance = 0); + unsigned long ping_in(unsigned int max_cm_distance = 0); + unsigned long ping_median(uint8_t it = 5, unsigned int max_cm_distance = 0); + static unsigned int convert_cm(unsigned int echoTime); + static unsigned int convert_in(unsigned int echoTime); + #if TIMER_ENABLED == true + void ping_timer(void (*userFunc)(void), unsigned int max_cm_distance = 0); + boolean check_timer(); + unsigned long ping_result; + static void timer_us(unsigned int frequency, void (*userFunc)(void)); + static void timer_ms(unsigned long frequency, void (*userFunc)(void)); + static void timer_stop(); + #endif + private: + boolean ping_trigger(); + void set_max_distance(unsigned int max_cm_distance); + #if TIMER_ENABLED == true + boolean ping_trigger_timer(unsigned int trigger_delay); + boolean ping_wait_timer(); + static void timer_setup(); + static void timer_ms_cntdwn(); + #endif + #if DO_BITWISE == true + uint8_t _triggerBit; + uint8_t _echoBit; + #if defined(PARTICLE) + #if !defined(portModeRegister) + #if defined (STM32F10X_MD) + #define portModeRegister(port) ( &(port->CRL) ) + #elif defined (STM32F2XX) + #define portModeRegister(port) ( &(port->MODER) ) + #endif + #endif + volatile uint32_t *_triggerOutput; + volatile uint32_t *_echoInput; + volatile uint32_t *_triggerMode; + #else + volatile uint8_t *_triggerOutput; + volatile uint8_t *_echoInput; + volatile uint8_t *_triggerMode; + #endif + #else + uint8_t _triggerPin; + uint8_t _echoPin; + #endif + unsigned int _maxEchoTime; + unsigned long _max_time; + }; + + +#endif diff --git a/sonoff/xsns_22_sr04.ino b/sonoff/xsns_22_sr04.ino index b361b7e96..32f09bd20 100644 --- a/sonoff/xsns_22_sr04.ino +++ b/sonoff/xsns_22_sr04.ino @@ -18,6 +18,8 @@ */ #ifdef USE_SR04 + +#include /*********************************************************************************************\ * HC-SR04, HC-SR04+, JSN-SR04T - Ultrasonic distance sensor * @@ -26,124 +28,43 @@ * - https://www.dfrobot.com/wiki/index.php/Weather-proof_Ultrasonic_Sensor_SKU_:_SEN0207 \*********************************************************************************************/ -#define XSNS_22 22 - uint8_t sr04_echo_pin = 0; uint8_t sr04_trig_pin = 0; +real64_t distance; -/*********************************************************************************************\ - * Embedded stripped and tuned NewPing library from Tim Eckel - teckel@leethost.com - * https://bitbucket.org/teckel12/arduino-new-ping -\*********************************************************************************************/ -#define US_ROUNDTRIP_CM 58 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. Default: 58 -#define US_ROUNDTRIP_IN 148 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space. Default: 148 -#define PING_MEDIAN_DELAY 29000 -#define MAX_SENSOR_DISTANCE 500 -#define PING_OVERHEAD 5 +NewPing* sonar = NULL; -// Conversion from uS to distance (round result to nearest cm or inch). -#define EchoConvert(echoTime, conversionFactor) (tmax(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0))) - -/********************************************************************************************/ - -void Sr04Init(void) +void Sr04Init() { sr04_echo_pin = pin[GPIO_SR04_ECHO]; sr04_trig_pin = pin[GPIO_SR04_TRIG]; - pinMode(sr04_trig_pin, OUTPUT); - pinMode(sr04_echo_pin, INPUT_PULLUP); -} - -boolean Sr04Read(uint16_t *distance) -{ - uint16_t duration = 0; - - *distance = 0; - - /* Send ping and get delay */ - duration = Sr04GetSamples(9, 250); - - /* Calculate the distance (in cm) based on the speed of sound. */ - *distance = EchoConvert(duration, US_ROUNDTRIP_CM); - - return 1; -} - -uint16_t Sr04Ping(uint16_t max_cm_distance) -{ - uint16_t duration = 0; - uint16_t maxEchoTime; - - maxEchoTime = tmin(max_cm_distance + 1, (uint16_t) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; - - /* The following trigPin/echoPin cycle is used to determine the - distance of the nearest object by bouncing soundwaves off of it. */ - digitalWrite(sr04_trig_pin, LOW); - delayMicroseconds(2); - digitalWrite(sr04_trig_pin, HIGH); - delayMicroseconds(10); - digitalWrite(sr04_trig_pin, LOW); - - /* Wait for the echo */ - duration = pulseIn(sr04_echo_pin, HIGH, 26000) - PING_OVERHEAD; - - return (duration > maxEchoTime) ? 0 : duration; -} - -uint16_t Sr04GetSamples(uint8_t it, uint16_t max_cm_distance) -{ - uint16_t uS[it]; - uint16_t last; - uint8_t j; - uint8_t i = 0; - uint16_t t; - uS[0] = 0; - - while (i < it) { - t = micros(); - last = Sr04Ping(max_cm_distance); - - if (last != 0) { - if (i > 0) { - for (j = i; j > 0 && uS[j - 1] < last; j--) { - uS[j] = uS[j - 1]; - } - } else { - j = 0; - } - uS[j] = last; - i++; - } else { - it--; - } - if (i < it && micros() - t < PING_MEDIAN_DELAY) { - delay((PING_MEDIAN_DELAY + t - micros()) / 1000); - } - } - - return (uS[1]); // Return the ping distance from the 2nd highest reading + sonar = new NewPing(sr04_trig_pin, sr04_echo_pin, 300); } #ifdef USE_WEBSERVER const char HTTP_SNS_DISTANCE[] PROGMEM = - "%s{s}SR04 " D_DISTANCE "{m}%d" D_UNIT_CENTIMETER "{e}"; // {s} = , {m} = , {e} = + "%s{s}SR04 " D_DISTANCE "{m}%s" D_UNIT_CENTIMETER "{e}"; // {s} = , {m} = , {e} = #endif // USE_WEBSERVER void Sr04Show(boolean json) { - uint16_t distance; + distance = (real64_t)(sonar->ping_median(5))/ US_ROUNDTRIP_CM; + + if (distance != 0) { // Check if read failed + char distance_chr[10]; + + dtostrfd(distance, 3, distance_chr); - if (Sr04Read(&distance)) { // Check if read failed if(json) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SR04\":{\"" D_JSON_DISTANCE "\":%d}"), mqtt_data, distance); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SR04\":{\"" D_JSON_DISTANCE "\":%s}"), mqtt_data, distance_chr); #ifdef USE_DOMOTICZ if (0 == tele_period) { - DomoticzSensor(DZ_COUNT, distance); // Send distance as Domoticz Counter value + DomoticzSensor(DZ_COUNT, distance_chr); // Send distance as Domoticz Counter value } #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_DISTANCE, mqtt_data, distance); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_DISTANCE, mqtt_data, distance_chr); #endif // USE_WEBSERVER } } @@ -153,6 +74,8 @@ void Sr04Show(boolean json) * Interface \*********************************************************************************************/ +#define XSNS_22 + boolean Xsns22(byte function) { boolean result = false; From 5f402c8f34affc9eaafce6fccef8e902bc9b79fd Mon Sep 17 00:00:00 2001 From: andrethomas Date: Sat, 1 Dec 2018 00:18:08 +0200 Subject: [PATCH 03/63] Fix sleep->SetOption36 transition --- sonoff/sonoff.ino | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 960d9cf25..2dfb7e213 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -766,6 +766,8 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) snprintf_P(log_data, sizeof(log_data), PSTR("*** WARNING *** - Disabling sleep in favour of SetOption36 (Dynamic Sleep)")); AddLog(LOG_LEVEL_INFO); Settings.sleep = 0; // We do not want traditional sleep to be enabled along side SetOption36 + sleep = 0; + WiFiSetSleepMode(); } } if ((payload >= param_low) && (payload <= param_high)) { @@ -1588,8 +1590,12 @@ void MqttShowState(void) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); #endif - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoopSet\":%u"), mqtt_data, (uint32_t)Settings.param[P_LOOP_SLEEP_DELAY]); // Add current loop delay target to telemetry - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoadAvg\":%u"), mqtt_data, loop_load_avg); // Add LoadAvg to telemetry data + if (Settings.param[P_LOOP_SLEEP_DELAY]) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoopSet\":%u"), mqtt_data, (uint32_t)Settings.param[P_LOOP_SLEEP_DELAY]); // Add current loop delay target to telemetry + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoadAvg\":%u"), mqtt_data, loop_load_avg); // Add LoadAvg to telemetry data + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"Sleep\":%u"), mqtt_data, (uint32_t)sleep); // Add current sleep setting so we know Dynamic Sleep is not enabled + } for (byte i = 0; i < devices_present; i++) { if (i == light_device -1) { From 6050cd40f3856043aae828058bc9485c6ab1b78c Mon Sep 17 00:00:00 2001 From: andrethomas Date: Sat, 1 Dec 2018 18:47:25 +0200 Subject: [PATCH 04/63] Merge sleep command --- sonoff/settings.h | 2 +- sonoff/settings.ino | 8 +++--- sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 56 +++++++++++++++++++++-------------------- sonoff/support_wifi.ino | 5 ++++ 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/sonoff/settings.h b/sonoff/settings.h index 033071668..10f40cdb7 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -73,7 +73,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t use_wifi_rescan : 1; // bit 7 (v6.3.0.10) uint32_t receive_raw : 1; // bit 8 (v6.3.0.11) uint32_t hass_tele_as_result : 1; // bit 9 (v6.3.0.13) - uint32_t spare10 : 1; + uint32_t sleep_normal : 1; // SetOption60 - Enable normal sleep instead of dynamic sleep uint32_t spare11 : 1; uint32_t spare12 : 1; uint32_t spare13 : 1; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index cf49c0719..960ee019c 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -417,7 +417,6 @@ void SettingsDefaultSet2(void) // Settings.flag.stop_flash_rotate = 0; Settings.save_data = SAVE_DATA; Settings.sleep = APP_SLEEP; - Settings.param[P_LOOP_SLEEP_DELAY] = LOOP_SLEEP_DELAY; // Module // Settings.flag.interlock = 0; @@ -855,9 +854,10 @@ void SettingsDelta(void) if (Settings.version < 0x06030004) { memset(&Settings.drivers, 0xFF, 32); // Enable all possible monitors, displays, drivers and sensors } - if (Settings.version < 0x0603000A) { - Settings.param[P_LOOP_SLEEP_DELAY] = LOOP_SLEEP_DELAY; - Settings.sleep = 0; // We do not want sleep enabled when SetOption36 is active + if (Settings.version < 0x0603000F) { + if (Settings.sleep < 50) { + Settings.sleep = 50; // Default to 50 for sleep, for now + } } if (Settings.version < 0x0603000E) { Settings.flag2.calc_resolution = CALC_RESOLUTION; diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index e53a7c83d..fd8beca70 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -222,7 +222,7 @@ enum ButtonStates { PRESSED, NOT_PRESSED }; enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER }; -enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_LOOP_SLEEP_DELAY, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49 +enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) - SetOption32 until SetOption49 enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS}; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 2dfb7e213..126524291 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -587,11 +587,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) } else if (CMND_SLEEP == command_code) { if ((payload >= 0) && (payload < 251)) { - if (payload > 0) { - snprintf_P(log_data, sizeof(log_data), PSTR("*** WARNING *** - Disabling SetOption36 (Dynamic Sleep) in favour of sleep")); - AddLog(LOG_LEVEL_INFO); - Settings.param[P_LOOP_SLEEP_DELAY] = 0; // We do not want SetOption36 to be active along with traditional sleep - } Settings.sleep = payload; sleep = payload; WiFiSetSleepMode(); @@ -750,6 +745,13 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if (1 == ptype) { // SetOption50 .. 81 if (payload <= 1) { bitWrite(Settings.flag3.data, pindex, payload); + if (60 == ptype) { // SetOption60 enable or disable traditional sleep + if (payload == 0) { // Dynamic Sleep + WiFiSetSleepMode(); // Update WiFi sleep mode accordingly + } else { // Traditional Sleep //AT + WiFiSetSleepMode(); // Update WiFi sleep mode accordingly + } + } } } else { // SetOption32 .. 49 @@ -761,14 +763,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) param_low = 1; param_high = 250; break; - case P_LOOP_SLEEP_DELAY: - if (payload > 0) { - snprintf_P(log_data, sizeof(log_data), PSTR("*** WARNING *** - Disabling sleep in favour of SetOption36 (Dynamic Sleep)")); - AddLog(LOG_LEVEL_INFO); - Settings.sleep = 0; // We do not want traditional sleep to be enabled along side SetOption36 - sleep = 0; - WiFiSetSleepMode(); - } } if ((payload >= param_low) && (payload <= param_high)) { Settings.param[pindex] = payload; @@ -1590,13 +1584,16 @@ void MqttShowState(void) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); #endif - if (Settings.param[P_LOOP_SLEEP_DELAY]) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoopSet\":%u"), mqtt_data, (uint32_t)Settings.param[P_LOOP_SLEEP_DELAY]); // Add current loop delay target to telemetry - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoadAvg\":%u"), mqtt_data, loop_load_avg); // Add LoadAvg to telemetry data + char _sleepmode[8]; + if (Settings.flag3.sleep_normal) { + sprintf(_sleepmode,"Normal"); } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"Sleep\":%u"), mqtt_data, (uint32_t)sleep); // Add current sleep setting so we know Dynamic Sleep is not enabled + sprintf(_sleepmode,"Dynamic"); } - + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SleepMode\":\"%s\""), mqtt_data, _sleepmode); // Add current sleep mode setting to telemetry + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"Sleep\":%u"), mqtt_data, sleep); // Add current sleep setting to telemetry + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoadAvg\":%u"), mqtt_data, loop_load_avg); // Add LoadAvg to telemetry + for (byte i = 0; i < devices_present; i++) { if (i == light_device -1) { LightState(1); @@ -2758,6 +2755,8 @@ void setup(void) XsnsCall(FUNC_INIT); } +uint32_t _counter = 0; + void loop(void) { uint32_t my_sleep = millis(); @@ -2800,22 +2799,25 @@ void loop(void) while (arduino_ota_triggered) ArduinoOTA.handle(); #endif // USE_ARDUINO_OTA -// yield(); // yield == delay(0), delay contains yield, auto yield in loop - delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 - uint32_t my_activity = millis() - my_sleep; - if (my_activity < (uint32_t)Settings.param[P_LOOP_SLEEP_DELAY]) { - delay((uint32_t)Settings.param[P_LOOP_SLEEP_DELAY] - my_activity); // Provide time for background tasks like wifi + + if (Settings.flag3.sleep_normal) { + // yield(); // yield == delay(0), delay contains yield, auto yield in loop + delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 } else { - if (global_state.wifi_down) { - delay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period + if (my_activity < (uint32_t)sleep) { + delay((uint32_t)sleep - my_activity); // Provide time for background tasks like wifi + } else { + if (global_state.wifi_down) { + delay(my_activity /2); // If wifi down and my_activity > setoption36 then force loop delay to 1/3 of my_activity period + } } } if (!my_activity) { my_activity++; } // We cannot divide by 0 - uint32_t loop_delay = Settings.param[P_LOOP_SLEEP_DELAY]; + uint32_t loop_delay = sleep; if (!loop_delay) { loop_delay++; } // We cannot divide by 0 uint32_t loops_per_second = 1000 / loop_delay; // We need to keep track of this many loops per second uint32_t this_cycle_ratio = 100 * my_activity / loop_delay; - loop_load_avg = loop_load_avg - (loop_load_avg / loops_per_second) + (this_cycle_ratio / loops_per_second); // Take away one loop average away and add the new one + loop_load_avg = loop_load_avg - (loop_load_avg / loops_per_second) + (this_cycle_ratio / loops_per_second); // Take away one loop average away and add the new one } diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 87ff4e21b..2dce4bce2 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -181,6 +181,11 @@ void WiFiSetSleepMode(void) #if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) #else // Enabled in 2.3.0, 2.4.0 and stage if (sleep) { + if (Settings.flag3.sleep_normal) { + WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times + } else { + WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) + } WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) From a1c464d34ce4b4666ae6ea1af8703ea8256c7d2d Mon Sep 17 00:00:00 2001 From: andrethomas Date: Sat, 1 Dec 2018 18:55:06 +0200 Subject: [PATCH 05/63] Bump version to 0x0603000F Bump version to 0x0603000F to make sure new sleep command takes effect on 50 as default for upgrades where sleep is < 50. --- sonoff/sonoff_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index d3df8d797..d6b82d881 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0603000E +#define VERSION 0x0603000F #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" From 0bd4ac8eea39181f14462eb820858069cf6e9e4f Mon Sep 17 00:00:00 2001 From: andrethomas Date: Sat, 1 Dec 2018 18:58:26 +0200 Subject: [PATCH 06/63] Update support_wifi.ino --- sonoff/support_wifi.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 2dce4bce2..2a1ef27d6 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -186,7 +186,6 @@ void WiFiSetSleepMode(void) } else { WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } - WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } From eb3c1a327dcc804ef2a2e75c7f460a05ef52fff1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 1 Dec 2018 18:53:42 +0100 Subject: [PATCH 07/63] 6.3.0.15 Update dynamic sleep 6.3.0.15 20181201 * Removed command SetOption36 (#4497) * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) --- sonoff/_changelog.ino | 6 +++++- sonoff/settings.h | 2 +- sonoff/settings.ino | 13 ++++++++----- sonoff/sonoff.ino | 18 +++++++----------- sonoff/support_wifi.ino | 8 ++------ 5 files changed, 23 insertions(+), 24 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index cbfb2b767..04c9afe93 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,8 @@ -/* 6.3.0.14 20181127 +/* 6.3.0.15 20181201 + * Removed command SetOption36 (#4497) + * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) + * + * 6.3.0.14 20181127 * Add Command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) * Add support for SM Smart Wifi Dimmer PS-16-DZ (#4465) * Move some static (serial) buffers to dynamic buffers diff --git a/sonoff/settings.h b/sonoff/settings.h index 10f40cdb7..39d8f5979 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -73,7 +73,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t use_wifi_rescan : 1; // bit 7 (v6.3.0.10) uint32_t receive_raw : 1; // bit 8 (v6.3.0.11) uint32_t hass_tele_as_result : 1; // bit 9 (v6.3.0.13) - uint32_t sleep_normal : 1; // SetOption60 - Enable normal sleep instead of dynamic sleep + uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep uint32_t spare11 : 1; uint32_t spare12 : 1; uint32_t spare13 : 1; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 960ee019c..7f065b626 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -417,6 +417,9 @@ void SettingsDefaultSet2(void) // Settings.flag.stop_flash_rotate = 0; Settings.save_data = SAVE_DATA; Settings.sleep = APP_SLEEP; + if (Settings.sleep < 50) { + Settings.sleep = 50; // Default to 50 for sleep, for now + } // Module // Settings.flag.interlock = 0; @@ -854,14 +857,14 @@ void SettingsDelta(void) if (Settings.version < 0x06030004) { memset(&Settings.drivers, 0xFF, 32); // Enable all possible monitors, displays, drivers and sensors } - if (Settings.version < 0x0603000F) { - if (Settings.sleep < 50) { - Settings.sleep = 50; // Default to 50 for sleep, for now - } - } if (Settings.version < 0x0603000E) { Settings.flag2.calc_resolution = CALC_RESOLUTION; } + if (Settings.version < 0x0603000F) { + if (Settings.sleep < 50) { + Settings.sleep = 50; // Default to 50 for sleep, for now + } + } Settings.version = VERSION; SettingsSave(1); diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 126524291..068c7a4a9 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -89,6 +89,8 @@ const char kTasmotaCommands[] PROGMEM = D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER "|" D_CMND_DRIVER; +const char kSleepMode[] PROGMEM = "Dynamic|Normal"; + const uint8_t kIFan02Speed[4][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6,7}}; // Global variables @@ -1579,21 +1581,15 @@ void MqttShowState(void) char stemp1[33]; snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_JSON_TIME "\":\"%s\",\"" D_JSON_UPTIME "\":\"%s\""), mqtt_data, GetDateAndTime(DT_LOCAL).c_str(), GetUptime().c_str()); + #ifdef USE_ADC_VCC dtostrfd((double)ESP.getVcc()/1000, 3, stemp1); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_JSON_VCC "\":%s"), mqtt_data, stemp1); #endif - char _sleepmode[8]; - if (Settings.flag3.sleep_normal) { - sprintf(_sleepmode,"Normal"); - } else { - sprintf(_sleepmode,"Dynamic"); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SleepMode\":\"%s\""), mqtt_data, _sleepmode); // Add current sleep mode setting to telemetry - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"Sleep\":%u"), mqtt_data, sleep); // Add current sleep setting to telemetry - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"LoadAvg\":%u"), mqtt_data, loop_load_avg); // Add LoadAvg to telemetry - + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"SleepMode\":\"%s\",\"Sleep\":%u,\"LoadAvg\":%u"), + mqtt_data, GetTextIndexed(stemp1, sizeof(stemp1), Settings.flag3.sleep_normal, kSleepMode), sleep, loop_load_avg); + for (byte i = 0; i < devices_present; i++) { if (i == light_device -1) { LightState(1); @@ -2800,7 +2796,7 @@ void loop(void) #endif // USE_ARDUINO_OTA uint32_t my_activity = millis() - my_sleep; - + if (Settings.flag3.sleep_normal) { // yield(); // yield == delay(0), delay contains yield, auto yield in loop delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 diff --git a/sonoff/support_wifi.ino b/sonoff/support_wifi.ino index 2a1ef27d6..7f2771dde 100644 --- a/sonoff/support_wifi.ino +++ b/sonoff/support_wifi.ino @@ -180,12 +180,8 @@ void WiFiSetSleepMode(void) // Sleep explanation: https://github.com/esp8266/Arduino/blob/3f0c601cfe81439ce17e9bd5d28994a7ed144482/libraries/ESP8266WiFi/src/ESP8266WiFiGeneric.cpp#L255 #if defined(ARDUINO_ESP8266_RELEASE_2_4_1) || defined(ARDUINO_ESP8266_RELEASE_2_4_2) #else // Enabled in 2.3.0, 2.4.0 and stage - if (sleep) { - if (Settings.flag3.sleep_normal) { - WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times - } else { - WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) - } + if (sleep && Settings.flag3.sleep_normal) { + WiFi.setSleepMode(WIFI_LIGHT_SLEEP); // Allow light sleep during idle times } else { WiFi.setSleepMode(WIFI_MODEM_SLEEP); // Disable sleep (Esp8288/Arduino core and sdk default) } From 2367834a64e9ac6831c4f5fe206fcd105e2e95bf Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sat, 1 Dec 2018 18:58:30 +0100 Subject: [PATCH 08/63] Update with dynamic sleep flag --- tools/decode-status.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/decode-status.py b/tools/decode-status.py index 2ab37a642..3de4dfca3 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -94,7 +94,8 @@ a_setoption = [[ "Use wifi network rescan regularly", "Add IR raw data to JSON message", "Change state topic from tele/STATE to stat/RESULT", - "","", + "Enable normal sleep instead of dynamic sleep", + "", "","","","", "","","","", "","","","", From 98a2e6e175053edb73c9edefd48a98c0516a9008 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Sat, 1 Dec 2018 16:26:15 -0300 Subject: [PATCH 09/63] Added Support for ButtonN and SwitchN --- sonoff/xdrv_11_knx.ino | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sonoff/xdrv_11_knx.ino b/sonoff/xdrv_11_knx.ino index b4fbefc18..665583767 100644 --- a/sonoff/xdrv_11_knx.ino +++ b/sonoff/xdrv_11_knx.ino @@ -483,6 +483,14 @@ void KNX_INIT(void) { if (GetUsedInModule(i, my_module.gp.io)) { device_param[i - GPIO_KEY1 + 8].show = true; } } + for (int i = GPIO_SWT1_NP; i < GPIO_SWT4_NP + 1; ++i) + { + if (GetUsedInModule(i, my_module.gp.io)) { device_param[i - GPIO_SWT1_NP + 8].show = true; } + } + for (int i = GPIO_KEY1_NP; i < GPIO_KEY4_NP + 1; ++i) + { + if (GetUsedInModule(i, my_module.gp.io)) { device_param[i - GPIO_KEY1_NP + 8].show = true; } + } if (GetUsedInModule(GPIO_DHT11, my_module.gp.io)) { device_param[KNX_TEMPERATURE-1].show = true; } if (GetUsedInModule(GPIO_DHT22, my_module.gp.io)) { device_param[KNX_TEMPERATURE-1].show = true; } if (GetUsedInModule(GPIO_SI7021, my_module.gp.io)) { device_param[KNX_TEMPERATURE-1].show = true; } From 7f2b3643f54930b14080271bbd7ca127a12e26d3 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Sat, 1 Dec 2018 18:12:33 -0300 Subject: [PATCH 10/63] RULES: Added BREAK as an alternative ENDON RULES: Added BREAK as an alternative ENDON that will stop the execution of the following rules. If a rule that ends with BREAK, is triggered, then the following rules of that set will not be executed. This is useful for cases like: https://github.com/arendst/Sonoff-Tasmota/issues/4477 --- sonoff/xdrv_10_rules.ino | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index 1fde3dff7..251c91e47 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -264,6 +264,8 @@ bool RuleSetProcess(byte rule_set, String &event_saved) rules_trigger_count[rule_set] = 0; int plen = 0; + int plen2 = 0; + bool stop_all_rules = false; while (true) { rules = rules.substring(plen); // Select relative to last rule rules.trim(); @@ -278,7 +280,14 @@ bool RuleSetProcess(byte rule_set, String &event_saved) String event_trigger = rule.substring(3, pevt); // "INA219#CURRENT>0.100" plen = rule.indexOf(" ENDON"); - if (plen == -1) { return serviced; } // Bad syntax - No endon + plen2 = rule.indexOf(" BREAK"); + if ((plen == -1) && (plen2 == -1)) { return serviced; } // Bad syntax - No ENDON neither BREAK + + if (plen == -1) { plen = 9999; } + if (plen2 == -1) { plen2 = 9999; } + plen = min(plen, plen2); + if (plen == plen2) { stop_all_rules = true; } // If BREAK was used, Stop execution of this rule set + String commands = rules.substring(pevt +4, plen); // "Backlog Dimmer 10;Color 100000" plen += 6; rules_event_value = ""; @@ -320,6 +329,7 @@ bool RuleSetProcess(byte rule_set, String &event_saved) ExecuteCommand(command, SRC_RULE); serviced = true; + if (stop_all_rules) { return serviced; } // If BREAK was used, Stop execution of this rule set } rules_trigger_count[rule_set]++; } From e37dbd1f6a0d47c002108c3b156a069fe71e74d0 Mon Sep 17 00:00:00 2001 From: andrethomas2 <43345003+andrethomas2@users.noreply.github.com> Date: Sat, 1 Dec 2018 23:15:19 +0200 Subject: [PATCH 11/63] Update xsns_22_sr04.ino --- sonoff/xsns_22_sr04.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_22_sr04.ino b/sonoff/xsns_22_sr04.ino index 32f09bd20..77ea5e829 100644 --- a/sonoff/xsns_22_sr04.ino +++ b/sonoff/xsns_22_sr04.ino @@ -34,7 +34,7 @@ real64_t distance; NewPing* sonar = NULL; -void Sr04Init() +void Sr04Init(void) { sr04_echo_pin = pin[GPIO_SR04_ECHO]; sr04_trig_pin = pin[GPIO_SR04_TRIG]; From c68fe7e7ada34f248eeb0c2ed51a8049ac5bcc64 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Sat, 1 Dec 2018 19:00:34 -0300 Subject: [PATCH 12/63] RULES: Added BREAK as an alternative ENDON --- sonoff/xdrv_10_rules.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xdrv_10_rules.ino b/sonoff/xdrv_10_rules.ino index 251c91e47..0a06fe149 100644 --- a/sonoff/xdrv_10_rules.ino +++ b/sonoff/xdrv_10_rules.ino @@ -285,7 +285,7 @@ bool RuleSetProcess(byte rule_set, String &event_saved) if (plen == -1) { plen = 9999; } if (plen2 == -1) { plen2 = 9999; } - plen = min(plen, plen2); + plen = tmin(plen, plen2); if (plen == plen2) { stop_all_rules = true; } // If BREAK was used, Stop execution of this rule set String commands = rules.substring(pevt +4, plen); // "Backlog Dimmer 10;Color 100000" From 7e09195083979a09624c7b64e946961a0f7698c7 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Sat, 1 Dec 2018 19:16:32 -0300 Subject: [PATCH 13/63] Delete duplicated min and max functions --- sonoff/xplg_wemohue.ino | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index 6c031fd94..64ac969ae 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#define min(a,b) ((a)<(b)?(a):(b)) -#define max(a,b) ((a)>(b)?(a):(b)) +//#define min(a,b) ((a)<(b)?(a):(b)) +//#define max(a,b) ((a)>(b)?(a):(b)) #if defined(USE_WEBSERVER) && defined(USE_EMULATION) /*********************************************************************************************\ @@ -692,8 +692,8 @@ void HueLights(String *path) if (hue_json.containsKey("bri")) { // Brightness is a scale from 1 (the minimum the light is capable of) to 254 (the maximum). Note: a brightness of 1 is not off. tmp = hue_json["bri"]; - tmp = max(tmp, 1); - tmp = min(tmp, 254); + tmp = tmax(tmp, 1); + tmp = tmin(tmp, 254); bri = (float)tmp / 254.0f; if (resp) { response += ","; @@ -721,8 +721,8 @@ void HueLights(String *path) } if (hue_json.containsKey("sat")) { // Saturation of the light. 254 is the most saturated (colored) and 0 is the least saturated (white). tmp = hue_json["sat"]; - tmp = max(tmp, 0); - tmp = min(tmp, 254); + tmp = tmax(tmp, 0); + tmp = tmin(tmp, 254); sat = (float)tmp / 254.0f; if (resp) { response += ","; From 2e950c589a55b83a62fabce90b84aa1e337fd401 Mon Sep 17 00:00:00 2001 From: andrethomas2 <43345003+andrethomas2@users.noreply.github.com> Date: Sun, 2 Dec 2018 11:00:01 +0200 Subject: [PATCH 14/63] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 348c06cb1..f98d92b50 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ Libraries used with Sonoff-Tasmota are: - [OneWire](https://github.com/PaulStoffregen/OneWire) - [PubSubClient](https://github.com/knolleary/pubsubclient) - [rc-switch](https://github.com/sui77/rc-switch) +- [NewPing](https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home) #### People inspiring me People helping to keep the show on the road: From f3d625d06d530ad56a620a5e6ee002f4ec37d712 Mon Sep 17 00:00:00 2001 From: andrethomas2 <43345003+andrethomas2@users.noreply.github.com> Date: Sun, 2 Dec 2018 11:18:29 +0200 Subject: [PATCH 15/63] Update _changelog.ino --- sonoff/_changelog.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 04c9afe93..535d386dd 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,7 @@ /* 6.3.0.15 20181201 * Removed command SetOption36 (#4497) * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) + * Update SR-04 driver to use NewPing library (#4488) * * 6.3.0.14 20181127 * Add Command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) From 74172f14d3c69e5c420d40f4038c7a18fdbd99e2 Mon Sep 17 00:00:00 2001 From: Erik Date: Sun, 2 Dec 2018 15:23:25 +0100 Subject: [PATCH 16/63] Further improve Hass auto discovery --- sonoff/settings.h | 2 +- sonoff/sonoff.ino | 14 +++++++++----- sonoff/xdrv_04_light.ino | 5 +++++ sonoff/xdrv_12_home_assistant.ino | 5 +++-- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/sonoff/settings.h b/sonoff/settings.h index 39d8f5979..10e67e6a2 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -72,7 +72,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t use_wifi_scan : 1; // bit 6 (v6.3.0.10) uint32_t use_wifi_rescan : 1; // bit 7 (v6.3.0.10) uint32_t receive_raw : 1; // bit 8 (v6.3.0.11) - uint32_t hass_tele_as_result : 1; // bit 9 (v6.3.0.13) + uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13) uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep uint32_t spare11 : 1; uint32_t spare12 : 1; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 068c7a4a9..be7006286 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -586,6 +586,9 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) else if (CMND_STATE == command_code) { mqtt_data[0] = '\0'; MqttShowState(); + if (Settings.flag3.hass_tele_on_power) { + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); + } } else if (CMND_SLEEP == command_code) { if ((payload >= 0) && (payload < 251)) { @@ -1393,6 +1396,11 @@ void ExecuteCommandPower(byte device, byte state, int source) #ifdef USE_KNX KnxUpdatePowerState(device, power); #endif // USE_KNX + if (publish_power && Settings.flag3.hass_tele_on_power) { + mqtt_data[0] = '\0'; + MqttShowState(); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); + } if (device <= MAX_PULSETIMERS) { // Restart PulseTime if powered On SetPulseTimer(device -1, (((POWER_ALL_OFF_PULSETIME_ON == Settings.poweronstate) ? ~power : power) & mask) ? Settings.pulse_timer[device -1] : 0); } @@ -1691,11 +1699,7 @@ void PerformEverySecond(void) mqtt_data[0] = '\0'; MqttShowState(); - if (Settings.flag3.hass_tele_as_result) { - MqttPublishPrefixTopic_P(STAT, S_RSLT_RESULT, MQTT_TELE_RETAIN); - } else { - MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); - } + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); mqtt_data[0] = '\0'; if (MqttShowSensor()) { diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index b4f10a148..829374d08 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -624,6 +624,11 @@ void LightPreparePower(void) #ifdef USE_DOMOTICZ DomoticzUpdatePowerState(light_device); #endif // USE_DOMOTICZ + if (Settings.flag3.hass_tele_on_power) { + mqtt_data[0] = '\0'; + MqttShowState(); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_STATE), MQTT_TELE_RETAIN); + } LightState(0); } diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 4a7a0ea92..78b8b4841 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -206,7 +206,8 @@ void HAssAnnounceRelayLight(void) } GetPowerDevice(value_template, i, sizeof(value_template), Settings.flag.device_index_enable); GetTopic_P(command_topic, CMND, mqtt_topic, value_template); - GetTopic_P(state_topic, STAT, mqtt_topic, S_RSLT_RESULT); + //GetTopic_P(state_topic, STAT, mqtt_topic, S_RSLT_RESULT); + GetTopic_P(state_topic, TELE, mqtt_topic, D_RSLT_STATE); GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); FindPrefix(command_topic, state_topic, prefix); if (Settings.flag3.hass_short_discovery_msg) { @@ -426,7 +427,7 @@ void HAssDiscovery(uint8_t mode) if (Settings.flag.hass_discovery) { Settings.flag.mqtt_response = 0; // Response always as RESULT and not as uppercase command Settings.flag.decimal_text = 1; // Respond with decimal color values - Settings.flag3.hass_tele_as_result = 1; // send tele/STATE message as stat/RESULT + Settings.flag3.hass_tele_on_power = 1; // send tele/STATE message as stat/RESULT // Settings.light_scheme = 0; // To just control color it needs to be Scheme 0 if (!string_ends_with(Settings.mqtt_fulltopic, "%prefix%/")) { strncpy_P(Settings.mqtt_fulltopic, PSTR("%topic%/%prefix%/"), sizeof(Settings.mqtt_fulltopic)); From a2e865bb44a7806db851abc44a89bc06c955f98a Mon Sep 17 00:00:00 2001 From: andrethomas2 <43345003+andrethomas2@users.noreply.github.com> Date: Sun, 2 Dec 2018 18:53:49 +0200 Subject: [PATCH 17/63] Add dummy soft_spi_flg to satisfy compiler @arendst Just adding this, for now, to satisfy the compiler until you get time to merge the rest of the Software SPI support. --- sonoff/sonoff.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index be7006286..0772e76f2 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -167,6 +167,7 @@ uint8_t dht_flg = 0; // DHT configured uint8_t energy_flg = 0; // Energy monitor configured uint8_t i2c_flg = 0; // I2C configured uint8_t spi_flg = 0; // SPI configured +uint8_t soft_spi_flg = 0; // Software SPI ** Temporary fix to satisfy compiler ** uint8_t light_type = 0; // Light types uint8_t ntp_force_sync = 0; // Force NTP sync byte serial_in_byte; // Received byte From 3cd89330aacdd78e8c9ae49d8d38f004991ea7ea Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Mon, 3 Dec 2018 08:33:21 +0100 Subject: [PATCH 18/63] decode-config.py: add new settings - add 6.3.0.15 setting change - adapt 6.3.0.13 setting change --- tools/decode-config.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 287f221ef..1850e2aea 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.1.0010' +VER = '2.1.0011' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -790,7 +790,7 @@ Setting_6_3_0_11['flag3'][0].update ({ # ====================================================================== Setting_6_3_0_13 = copy.deepcopy(Setting_6_3_0_11) Setting_6_3_0_13['flag3'][0].update ({ - 'hass_tele_as_result': (' Date: Mon, 3 Dec 2018 17:30:06 +0200 Subject: [PATCH 19/63] Add GPIO2 for Sonoff Basic Template Add GPIO2 for Sonoff Basic Template --- sonoff/sonoff_template.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index c4fcfb377..225d3767a 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -517,7 +517,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { { "Sonoff Basic", // Sonoff Basic (ESP8266) GPIO_KEY1, // GPIO00 Button GPIO_USER, // GPIO01 Serial RXD and Optional sensor - 0, // GPIO02 + GPIO_USER, // GPIO02 Only available on newer Sonoff Basic R2 V1 GPIO_USER, // GPIO03 Serial TXD and Optional sensor GPIO_USER, // GPIO04 Optional sensor 0, // GPIO05 From dcaf6164d443cd3cdb113f1c346944bdad542009 Mon Sep 17 00:00:00 2001 From: andrethomas Date: Mon, 3 Dec 2018 17:34:35 +0200 Subject: [PATCH 20/63] Add support for GPIO02 for newer Sonoff Basic Add support for GPIO02 for newer Sonoff Basic --- sonoff/_changelog.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 535d386dd..3709195fe 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -2,6 +2,7 @@ * Removed command SetOption36 (#4497) * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) * Update SR-04 driver to use NewPing library (#4488) + * Add support for GPIO02 for newer Sonoff Basic (#4518) * * 6.3.0.14 20181127 * Add Command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) From 24ef9ab6b87dbf6f2e5106e4b1bb57a42d1bf84e Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Mon, 3 Dec 2018 17:38:31 -0300 Subject: [PATCH 21/63] Fix Compilation issue with STAGE Core Now the Stage core has the the same STR macro defined in sonoff.h. --- sonoff/sonoff.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index fd8beca70..4a54f81be 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -152,7 +152,9 @@ typedef unsigned long power_t; // Power (Relay) type #define tmax(a,b) ((a)>(b)?(a):(b)) #define STR_HELPER(x) #x +#ifndef STR #define STR(x) STR_HELPER(x) +#endif //enum ws2812NeopixelbusFeature { NEO_RGB, NEO_GRB, NEO_BRG, NEO_RBG, NEO_3LED, NEO_RGBW, NEO_GRBW }; // Doesn't work #define NEO_RGB 0 // Neopixel RGB leds From abb6d5ee2e9eed2818ff4c9a7e5b953cf00bd633 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Tue, 4 Dec 2018 20:52:56 +0100 Subject: [PATCH 22/63] Create RF-Bridge-EFM8BB1-20181127.hex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ignore RF pulses < 100µs, increased uart RX buffer -> stopp red led flashing --- tools/RF-Bridge-EFM8BB1-20181127.hex | 506 +++++++++++++++++++++++++++ 1 file changed, 506 insertions(+) create mode 100644 tools/RF-Bridge-EFM8BB1-20181127.hex diff --git a/tools/RF-Bridge-EFM8BB1-20181127.hex b/tools/RF-Bridge-EFM8BB1-20181127.hex new file mode 100644 index 000000000..8008a0146 --- /dev/null +++ b/tools/RF-Bridge-EFM8BB1-20181127.hex @@ -0,0 +1,506 @@ +:020000040000FA +:1000000002166B8E258F26121D12AA06AB079000D2 +:1000100076E0FCA3E0FDAF26AE25121CC7EF24FF5F +:100020002222220215DB7597A522220219CB8E5BB4 +:100030008F5C8C5D8D5E121B02121D9AE55E24BFE3 +:100040009000FAF0E55D34FF9000F9F09000F5E5DE +:100050005BF0A3E55CF043910422220216FA121E23 +:100060003453D87853DAFE121DFFE4900082F02258 +:10007000D2DE22021A1ED201121C79C290C296C28E +:1000800080E4FBFD7F10121DE612068A74A4F0D2F4 +:10009000AF1219B2D2969000F2E004F07006900010 +:1000A000F1E004F09000F1E0B427E9A3E0B410E43B +:1000B000C296120026300109121BBD8E3E8F3F8072 +:1000C00006753E01753F00E53F7004E53E64017032 +:1000D000469000DAE070061219B302029A9000F11D +:1000E000E475F001120A85FED3E5F09410EE942732 +:1000F0004002D296D39000F2E094309000F1E09468 +:1001000075500302029AE4F0A3F09000DAF0900038 +:1001100095F0C29602029A1219B29000DAE01460C9 +:100120002A14700302026C14700302022A14700372 +:100130000202402404600302029AE53F64AA6003BD +:1001400002029A9000DA04F002029AE53F900095CC +:10015000F09000DA7402F0E53F120BBB0214A0012C +:1001600081A10191A501B8A601C6A701CFA801EE02 +:10017000A901D5B001DEB101A9C0029AFF000002B9 +:100180001F120641E4900094F0900074F07FA1806B +:100190006D12005E9000DA7404F09000F07408F0C4 +:1001A000E4F54175400902029A9000DA7404F0E423 +:1001B000F54175400202029A12199D7FA61206BAF5 +:1001C00074A6F002029A12068A74A4F002029A90AF +:1001D00000F07408F09000DA7403F002029A9000C4 +:1001E000747401F07FB11206BAEFF002029A12069F +:1001F00041900094E09000EFF012199D7FA9121B2E +:100200008690007AEFF07D307C757F017E00121CB5 +:100210005002029A12069C90007AEFF0E48005E406 +:10022000900095F09000DAF08070E4F541E53FF53C +:1002300040E540D394009000DA402C7404F0805ADA +:1002400074032541F582E43400F583E53FF0054170 +:10025000E541B540059000DA800DE541C39470405A +:10026000397540709000DA7402F0802EE53F6455D5 +:1002700070289000DAF0C201900095E024606018C8 +:1002800024FC600F24FE600B14600824F660042434 +:100290001070077FA0121D81D201900095E0120B13 +:1002A000BB02C3A102EDA402FFA503A4A603BEA83E +:1002B0000580A905B7B0062AB10371C00392FF00FB +:1002C0000000B2900081E030E70F7DC87C0012068C +:1002D000737FA3121ABD02059A121DF74003020094 +:1002E000B27DE87C031206737FA202062290008191 +:1002F000E020E7030200B27FA4121ABD0203B69009 +:1003000000DAE060030200B21219BA60432405600B +:10031000030200B21206C1900005E0FAA3E0FBFF61 +:10032000AE021219A9900007E0F8A3E08883858344 +:1003300049F54A85834BF54C900005E0F54DA3E067 +:10034000F54EE4F54F755018F551755206020552F9 +:100350009000F0E060111219C1500302056E120600 +:10036000A5121E2202056E12069CC2807FA0020604 +:10037000229000DAE060030200B21219A97F017E28 +:1003800000121C50D296121E22C2967FA0121D810E +:10039000800A7F02121D81E49000DAF0D201120679 +:1003A000B10200B2900081E020E7030200B2547F66 +:1003B000FD7FA6121A71E4900081F00200B2900055 +:1003C000DAE060030200B21219BA70030205582481 +:1003D0000560030200B2900003E0FF248070057501 +:1003E00042FF80028F421206C1900003E0648060E9 +:1003F0000302047BA3E0FCA3E0FD900008E0FAA365 +:10040000E0FBFFAE021209E8C006C007900006E05C +:10041000FCA3E0FDAF03AE021209E8C006C00790DE +:10042000000AE0FF7E00900008E0FCA3E0FD120956 +:10043000E8C006C00790000B121996C007C00690CE +:10044000000C121996AA06AB0790000D1219968E91 +:100450004D8F4E8A4B8B4CD049D04A90000EE0F520 +:100460004FA3E0F550A3E0F55175520ED003D00232 +:10047000D005D004D007D006020552E542F470033F +:100480000205E212198F2445F582E4341EF583E457 +:1004900093FF7E0012198F2448F582E4341EF58301 +:1004A000E493FA740193FDAC021209E8C006C00798 +:1004B00012198F2446F582E4341EF583E493121951 +:1004C00097C006C00712198F244AF582E4341E1221 +:1004D000196FC006C00712198F244BF582E4341E31 +:1004E00012196FC007C00612198F244CF582E4342C +:1004F0001E12196FAA06AB0712198F244DF582E45C +:10050000341E12196F12198F2447F582E4341EF538 +:1005100083E493FD12198F244EF582E4341EF58393 +:10052000E493FC12198F2451F582E4341EF583E420 +:1005300093F5518C508D4F8E4D8F4E8A4B8B4CD0F6 +:1005400049D04A755201D003D002D005D004D0075B +:10055000D00612177F0200B29000F0E06018E5426A +:10056000F4600B1219C140061206A5121E22E49077 +:100570000082F00200B21206B1C2807FA002062201 +:10058000900081E030E71D7DC87C00120654900089 +:1005900081E0547FFD7FAB121A71E4900081F0D2AC +:1005A000010200B2121DF740030200B27DE87C0395 +:1005B0001206547FAA806B9000DAE060030200B25A +:1005C0001219BA6051240560030200B212005E9055 +:1005D0000003E025E0900000F06007E540C39404CC +:1005E0005008E4900095F00200B2900000E0FF2473 +:1005F00005F9E43400754601F5478948C3E5409F95 +:1006000024FEF549900004E0F54A7B017A00790563 +:100610001218FF0200B290007AE0FF121B86C2801F +:100620007FA0121D81D2010200B2900081E020E77C +:10063000030200B27FB1121803E4900081F00200BF +:10064000B27D327C007F017E00121C50D296121EB9 +:1006500022C296227F017E00121C50D296121E22C8 +:10066000C2969000EFE0900094F090007AE0FF12C4 +:100670001B86227F017E00121C50D296121E22C2BF +:100680009690007AE0FF121B8622E4900094F0908E +:100690000074F07FA4121B8690007A2290007AE00A +:1006A000FF121B8622EFFD7C007F017E00121C5092 +:1006B0002290007AE0FF121B8622121B8690007A9D +:1006C000229000F0E014F012005E22EC4D6011E880 +:1006D000497017ED33EC3304600DE4FCFFFEFD229E +:1006E000E933E8330470F802099412095F58046092 +:1006F00009E4CC2481500628500902099E284003B1 +:1007000002099BC0E0EB4A7044B98006D0E0FB02CE +:10071000098AEF4E701CBD8008EBFFEAFEE9FD8000 +:10072000EBE98DF0A4FEE5F00207B4E9CDF9EAFEAD +:10073000EBFFEF89F0A4FCE5F0CE89F0A42EFFE4F6 +:1007400035F0CD89F0A42DFEE435F08067EF4E70D2 +:1007500005BD80D780C3EF8BF0A4ACF0EE8BF0A486 +:100760002CFCE435F0F8EF8AF0A42CE5F038FCE43A +:1007700033CB8DF0A42CFCE5F03BF8EE8AF0A42CF2 +:10078000FCE5F038F8E433CF89F0A42CFCE5F03830 +:10079000CF3400CE89F0A42FFFE5F03EFEE433C94C +:1007A0008DF0A42EFEE5F039CD8AF0A42FFFE5F000 +:1007B0003EFEE43DFD33D0E0FB50070BBB000F02D3 +:1007C000099EEC2CFCEF33FFEE33FEED33FD020906 +:1007D0007602099EEC5D046005E859047003020985 +:1007E0009412095F580460F6EC4860F2EC7004FD66 +:1007F000FEFF22C860DB2481C85009C39860025004 +:100800000602099B9850CAF582E9294B4A7005AB4C +:100810008202098A75F0007C1A7880C3EF9BEE9AF9 +:10082000ED99400DC3EF9BFFEE9AFEED99FDE84276 +:10083000F0DC23ACF0D0E0FFD0E0FED0E0FDAB82F6 +:1008400020E7101BEB60BAEC2CFCEF33FFEE33FE1D +:10085000ED33FD020976E803F830E705C0F075F0E6 +:1008600000EF2FFFEE33FEED33FD40B830E7C280DE +:10087000AA74F8CC6480CCC86480C8F58204604F48 +:10088000C3EB9FF5F0EA9E42F0E99D42F0E89C45FB +:10089000F0603C501DE5825FFFE582D313CB5BCB5C +:1008A000F42B5582FB50280ABA002409B90020080D +:1008B000801DE5825BFBE582D313CF5FCFF4C313CA +:1008C0002F5582FF50090EBE00050DBD00010CC35F +:1008D000EB9FF5F0EA9E42F0E99D42F0E89C45F07E +:1008E0006007CC4820E701B3EC2275F020800E753C +:1008F000F010800575F0087D007E007F003392D5F2 +:1009000030D503120BA1EC334010EF33FFEE33FE72 +:10091000ED33FDEC33FCD5F0ED22E5F0247EA2D5DD +:1009200013CC92E7CDCEFF22EDD2E7CD33EC33925C +:10093000D524814006E4FFFEFDFC22FCE4CFCECDB1 +:10094000CC24E0501174FF80EDC3CC13CCCD13CD7B +:10095000CE13CECF13CF0470F030D5DE020BA1E959 +:10096000D2E7C933E833F892D5EDD2E7CD33EC3393 +:10097000FC5002B2D522EC30E7100FBF000C0EBEC7 +:1009800000080DBD00040BEB6014A2D5EB13FCEDC9 +:1009900092E7FD2274FFFCFDFEFF22E480F8A2D561 +:1009A00074FF13FC7D80E480EFBB010CE58229F528 +:1009B00082E5833AF583E0225006E92582F8E622B3 +:1009C000BBFE06E92582F8E222E58229F582E5836D +:1009D0003AF583E49322BB010689828A83F0225090 +:1009E00002F722BBFE01F322EF8DF0A4A8F0CF8C1A +:1009F000F0A428CE8DF0A42EFE22BC000BBE002950 +:100A0000EF8DF084FFADF022E4CCF875F008EF2F05 +:100A1000FFEE33FEEC33FCEE9DEC984005FCEE9DC2 +:100A2000FE0FD5F0E9E4CEFD22EDF8F5F0EE8420DE +:100A3000D21CFEADF075F008EF2FFFED33FD40073F +:100A4000985006D5F0F222C398FD0FD5F0EA22C2E5 +:100A5000D5EC30E709B2D5E4C39DFDE49CFCEE3053 +:100A6000E715B2D5E4C39FFFE49EFE1209FAC3E482 +:100A70009DFDE49CFC80031209FA30D507C3E49F76 +:100A8000FFE49EFE22C5F0F8A3E028F0C5F0F8E5EB +:100A900082158270021583E038F022BB0110E582D6 +:100AA00029F582E5833AF583E0F5F0A3E0225009C9 +:100AB000E92582F886F008E622BBFE0AE92582F8DD +:100AC000E2F5F008E222E5832AF583E993F5F0A345 +:100AD000E9932275F008758200EF2FFFEE33FECD0B +:100AE00033CDCC33CCC58233C5829BED9AEC99E5EE +:100AF0008298400CF582EE9BFEED9AFDEC99FC0F7E +:100B0000D5F0D6E4CEFBE4CDFAE4CCF9A88222B845 +:100B100000C1B90059BA002DEC8BF084CFCECDFCCA +:100B2000E5F0CBF97818EF2FFFEE33FEED33FDEC57 +:100B300033FCEB33FB10D703994004EB99FB0FD840 +:100B4000E5E4F9FA227818EF2FFFEE33FEED33FDDE +:100B5000EC33FCC933C910D7059BE99A4007EC9BDD +:100B6000FCE99AF90FD8E0E4C9FAE4CCFB2275F06D +:100B700010EF2FFFEE33FEED33FDCC33CCC833C87E +:100B800010D7079BEC9AE899400AED9BFDEC9AFC84 +:100B9000E899F80FD5F0DAE4CDFBE4CCFAE4C8F933 +:100BA00022C3E49FFFE49EFEE49DFDE49CFC22EC56 +:100BB000F0A3EDF0A3EEF0A3EFF022D083D082F803 +:100BC000E4937012740193700DA3A393F8740193CE +:100BD000F5828883E4737402936860EFA3A3A38013 +:100BE000DFEF4E6012EF60010EEDBB010B89828AD0 +:100BF00083F0A3DFFCDEFA2289F05007F709DFFC5F +:100C0000A9F022BBFEFCF309DFFCA9F0228C228DA7 +:100C1000238A248B25AE07900082E0147003020C17 +:100C2000A2046003020E9EC290900081E060030265 +:100C30000E9EC3E5239414E5229405500EC3E525CA +:100C40009414E52494055003020E9E900094E0FF56 +:100C5000AD0685242C85252DAB23AA22121B469098 +:100C6000007FEFF064807003020E9E900001E52487 +:100C7000F0A3E525F09000857408F0E4900075F08D +:100C800090007CF0F508F509FE7F70FD7B017A008D +:100C90007903120BE1E490007BF0D2909000820483 +:100CA000F02290007FE0FD75F00DA424B7F582E4FA +:100CB000341E12108F1210B0FC7401931211379071 +:100CC000007FE075F00DA424AFF582E4341EF583B7 +:100CD000E493FFD39400400B90007CE09F5004E02D +:100CE00004F02290007FE0F96051FD121084121090 +:100CF000B012118E9000DF12110B24B3F582E43490 +:100D00001E12108F1209E89000E112110B24B4F5A5 +:100D100082E4341E12108FE91210B112118E90006D +:100D2000E312110B24B5F582E4341E12108F120960 +:100D3000E89000E5EEF0A3EFF0803E900078E0FE52 +:100D4000A3E0FF9000DFEEF0A3EFF0900083E0FC63 +:100D5000A3E0FD9000E1ECF0A3EDF0A3ECF0A3ED37 +:100D6000F0A312110B24B7F582E4341E12108F90F9 +:100D70000078E0FCA3E0121137900085E014F090B9 +:100D80000075E004F0AE22AF23E4FCFD9000E71212 +:100D90000BAFAE24AF25E4FCFD9000EB120BAF12BD +:100DA00011479000DF120E9F500E9000EB12114A77 +:100DB0009000E1120E9F400CC312117A50201210C5 +:100DC00097B5071A900078E522F0A3E523F0C290CA +:100DD000D312117C4066852208852309805E12119A +:100DE000479000E3120EB7500E9000EB12114A909C +:100DF00000E5120EB7400CD312117A40331210974F +:100E00006F702D900083E522F0A3E523F0D29012BD +:100E100010EEC083C082E0FF900085E0FE7401A860 +:100E200006088002C333D8FC4FD082D083F0800CF8 +:100E3000E4900081F0C290A312119822900085E006 +:100E400070161210EEE0FF90007BE06FFF121D3570 +:100E5000EFF09000857408F01210976F7040121D2B +:100E6000EF5005E4900080F0900080E0FF90007B60 +:100E7000E06F6023121DFF7D207C037F017E001246 +:100E80001C2790007BE0900080F090007FE09000B5 +:100E900081F04480121198C290E4900082F022FF09 +:100EA000E0FCA3E0FDC3EF9DFFEE9CFE121DB2C36C +:100EB000EF9527EE952622FFE0FCA3E0FDC3EF9D12 +:100EC000FFEE9CFE121DB2C3EF9527EE9526228EF3 +:100ED000228F23900082E024FE6034146068147036 +:100EE00003020FC22404600302105DC290900081CF +:100EF000E0600302105DAF23AE22121D73400302B7 +:100F0000105D90007612116D9000827402F0221232 +:100F1000105E501890007DE09402405CD290E4A3F3 +:100F2000F0900000F09000827403F022C3900077EC +:100F3000E09523900076E09522500412116D2290E6 +:100F4000007DE004F02212105E5030900000E0942A +:100F500000402890007EE0FF90007DE0B50719C2B8 +:100F600090E4900073F09000857404F0E490007BAE +:100F7000F09000827404F022021005C3E52394640B +:100F8000E5229400400790007EE0B4FF0280769056 +:100F9000007EE004F01211A0121540500302105D13 +:100FA000900000E0121069E522F0A3E523F0900024 +:100FB00000E004F0E0D39407500302105DE4F00277 +:100FC0001059B2901211A01214A3503C900085E069 +:100FD000B40410E524C454F0121075EFF0E490004E +:100FE00085F022121076E0FFE524540FFEEF4EF05C +:100FF000900073E004F09000857404F0900073E0BA +:10100000D394704058E48051AF23AE2212000350B5 +:1010100047900081E0703C900085E07019121076D6 +:10102000C083C082E0FF900000E0540FFEEF4ED07E +:1010300082D083F0800E900000E0C454F0440F1280 +:101040001075EFF0900073E0FF1211C3900081E083 +:101050004480F0C290E48001E4900082F022AF234B +:10106000AE2212000322FCE52A25E02486F582E464 +:101070003400F58322FF900073E02403F582E4340A +:1010800000F5832275F00DA424B2F582E4341EF538 +:1010900083E493FF7E002290007FE075F00DA4248E +:1010A000B6F582E4341EF583E493FF900075E022E8 +:1010B000ED75F00DA424B0F582E4341EF583E493BD +:1010C00022EF75F00DA424B9F582E4341EF583E413 +:1010D0009322AC3CAD3DE41208EFE4FBFA79C8780A +:1010E000421207D4E4FBFA792078410206CB900043 +:1010F00075E024FFFFE434FFFE7C007D08120A4FF8 +:1011000074032FF58274003EF58322EEF0A3EFF016 +:10111000E975F00DA422E0FCA3E0FDEC547FFAD3C6 +:10112000ED9400EA940022AC38AD391209E8AC061F +:10113000AD07AB3BAA3A22FD1209E87C007D6412A0 +:1011400009FA8E268F27229000E7A3A3E0FEA3E0F2 +:1011500022AB46AA47A948854C827583000209A99B +:10116000852C34852D35AB2BAA2AAD2922E522F01A +:10117000A3E523F0E490007DF022E5239509E52224 +:10118000950822AFFBAEFC7C007D0A0209E8FA74E8 +:101190000193FDAC020209E8F090007F7480F02218 +:1011A0007B007A007924AF23AE2222E53075F00D62 +:1011B000A422E0FEA3E0FFC322EC4480AF05F0A32D +:1011C000EFF0228F25E4F527F526E5252401FFE43D +:1011D00033FEC3E5269FEE6480F87480985039741E +:1011E00003252612107CE0C4540FFF12106912115F +:1011F000164007EF1210691211B974032526121058 +:101200007CE0540FFF1210691211164007EF121004 +:10121000691211B9052680B2E4F526900000E0FFBE +:10122000E526C39F40030212DFE526121069E03075 +:10123000E7030212D1AF26900000E0FEEFC39E400C +:10124000030212CDEF25E02488F582E43400F58313 +:10125000E0FCA3E0FDEF121069ECF0A3EDF0E4FE7A +:10126000E5252401FDE433FCEEC39DEC6480F874B5 +:101270008098505574032E12107CE0F9C4540FFD71 +:10128000EF2401FBE433FAEDB50316E4B50212E9ED +:10129000540FFDEFC454F04DFD74032E12107CED7D +:1012A000F0EF2401FDE433FC74032E12107CE0F90E +:1012B000540FB50511E4B5040DE954F04FFD740366 +:1012C0002E12107CEDF00E80970F0212370527804A +:1012D00009E526121069E0547FF0052602121B90E2 +:1012E0000000E0C39527F0228F308A328B33E4F57B +:1012F00036F5371210C16D6006E5365537FF22E529 +:10130000307014901EAE93FD7C00AE34AF351209E0 +:10131000FA8E388F39800CE5301210B1F53874012F +:1013200093F5391211AB24ADF582E4341EF583E454 +:1013300093D394004021AF33AE321213C324ADF5E2 +:1013400082E4341E12108F121127AF33AE32121CFA +:10135000C7EF60037536011211AB24AEF582E43499 +:101360001EF583E493D394004021AF35AE341213BD +:10137000C324AEF582E4341E12108F121127AF354C +:10138000AE34121CC7EF6003753701E5365537FBE5 +:101390006401702CE530121084AC38AD391209E8C4 +:1013A000900078EEF0A3EFF01211AB24B4F582E4D4 +:1013B000341E12108F1209E8900083EEF0A3EFF0B4 +:1013C000AF0322121D128E3A8F3BE53075F00DA44B +:1013D00022D3E50B9400E50A9400401F121183C349 +:1013E000EF950BFFEE950A9000DDF0A3EFF0AFFB59 +:1013F000AEFC1209E88E0A8F0B80081211838E0A48 +:101400008F0B229000DD1211B29464EE9400501103 +:10141000121199E4F50CF50DF50EF50F900082F020 +:101420002230933C8E0E8F0F900074E014602B04DA +:101430007070E50D450C606AE50F450E6064900024 +:101440007FE0FF648060071210C164016054AB0F3D +:10145000AA0EAD0DAC0CE4FF803EAF0FAE0E803F88 +:101460009000DDE0F50CA3E0F50D900074E0146051 +:101470002A04702EE50D450C6028E50F450E60220C +:1014800090007FE0FF648060051210C16014AB0D16 +:10149000AA0CAD0FAC0E7F01020C0DAF0DAE0C12FD +:1014A0000ECF228E2B8F2C8B2D8A2E892FE4F53098 +:1014B000900000E0FFE530C39F400302153EE52C9D +:1014C000AE2B7803CEC313CE13D8F9FDAC06E52CB2 +:1014D000AE2B7802CEC313CE13D8F92DF532EE3CE5 +:1014E000F531E5301210691211B29532EE95315096 +:1014F000028004AE31AF328E318F32E53012106986 +:101500001211B29532FDEE9531FCC3ED952CEC95A0 +:101510002B5026E5322FFFE5313EFEC3E52C9FE53B +:101520002B9E5015E52F452E452D600BAB2DAA2E79 +:10153000A92FE5301209D6D32205300214B0C322F8 +:101540008E258F268B278A2889291214A3500122E1 +:10155000E4F52A900000E0FFE52AC39F507B1210BB +:1015600067E0FCA3E0FDAE047803CEC313CE13D82E +:10157000F9FBAA06EDAE047802CEC313CE13D8F958 +:101580002BFDEE3A121066E0C4F854F0C868FEA3D2 +:10159000E0C4540F482DFFEC3EFEC3E5269FFDE559 +:1015A000259E121066E0FAA3E0FBD39DEA9C40243E +:1015B000E5262FFFE5253EFEC3EB9FEA9E5015E58D +:1015C0002945284527600BAB27AA28A929E52A1217 +:1015D00009D6D322052A021553C322C0E0C0F0C0A9 +:1015E00083C082C0D075D000C000C001C002C0035B +:1015F000C004C005C006C007E5985403F55FF45267 +:1016000098E55F30E017121E3D9000D9121CBCEF28 +:10161000F09000D9E004F0E0B44002E4F0E55F307F +:10162000E12E9000DCE0D39400401A9000D8E02432 +:1016300060F8E6FF121E3A9000D8E004F09000DC5B +:10164000E014F08002D2009000D8E0B42002E4F070 +:10165000D007D006D005D004D003D002D001D000EE +:10166000D0D0D082D083D0F0D0E032120022787F68 +:10167000E4F6D8FD75817F0216B5020076E493A3E7 +:10168000F8E493A34003F68001F208DFF48029E434 +:1016900093A3F85407240CC8C333C4540F4420C880 +:1016A000834004F456800146F6DFE4800B01020417 +:1016B0000810204080901885E47E019360BCA3FF51 +:1016C000543F30E509541FFEE493A360010ECF544C +:1016D000C025E060A840B8E493A3FAE493A3F8E43B +:1016E00093A3C8C582C8CAC583CAF0A3C8C582C8A7 +:1016F000CAC583CADFE9DEE780BEC0E0C0F0C083B0 +:10170000C082C0D075D000C000C001C002C003C0FC +:1017100004C005C006C007E5D85487F521F452D8A7 +:10172000E5F730E508E5F730E60312005A53F7DF36 +:10173000E52130E708E5D930E00312002AE5213041 +:10174000E008E5DA30E0031213D1E52130E108E5E5 +:10175000DB30E003121E43E52130E208E5DC30E037 +:1017600003121E44D007D006D005D004D003D00207 +:10177000D001D000D0D0D082D083D0F0D0E0328A57 +:10178000478B488D828C83AD07AC068552547555C6 +:1017900080AB82AA83AF51121BF3E54FD394004074 +:1017A0001BE4F553E553C3954F5011AB4EAA4DAD15 +:1017B0004CAC4BAF51121BF3055380E8E4F553E5F5 +:1017C00053C3955050347403255412107CE0555582 +:1017D000600AAB4EAA4DAD4CAC4B8008AB4AAA494F +:1017E000AD48AC47AF51121BF3E555C313F5557027 +:1017F000050554755580055380C5C29090008274CC +:1018000005F022AE07E4F543121CA0900000E004AE +:10181000FF121CF612187E900000E0FFE543C39F04 +:101820005012121CB0121CF2121CB0F583121CAA2A +:10183000054380E3900076E0FF121CF690007612DC +:101840001CAA12187EE4F543900073E02401FFE423 +:1018500033FEC3E5439FEE6480F87480985017749C +:10186000032543121CED0543E543541F70DA121E95 +:1018700037121E3080D27F55121CF6021E37121E00 +:1018800037121E30224200F700004200F3000042EF +:1018900000F900004200F500004100810041008293 +:1018A00000410094804100740041007F8041007A33 +:1018B0000042000100004200830000420078000066 +:1018C000410085004100750041007C00410073002B +:1018D0004100800041007B00410000004100D90030 +:1018E0004100DB004100D7004100D8004100DC008E +:1018F0004100D600C1004100DA0041009500008B94 +:10190000438A448945754B01E4F54CE54CC3954940 +:10191000502B121151C4540FFF640F600912194D5E +:1019200070027F018F4B121151FF540F640F600939 +:1019300012194D70027F018F4B054C80CEAF4A15B6 +:101940004AEF70C1C2909000827405F022AB43AAA6 +:1019500044A945EF540775F002A4F58285F083127F +:101960000A9BFDACF0AF4B121D62E54B7F0022F5E8 +:1019700083E493FF7E00E54275F00DA42448F582D0 +:10198000E4341EF583E493FC740193FD0209E8E559 +:101990004275F00DA422E0FF7E000209E890009459 +:1019A0007480F0E4900074F022900003E0FCA3E067 +:1019B000FD22E49000F1F0A3F022900082E024FBED +:1019C00022901E50E493FFD3940022C0E0C083C055 +:1019D00082C0D075D000C004C005C006C00753C87F +:1019E0007F9000F7E0FEA3E0FF4E700353C8FB902A +:1019F00000F3121B3B50099000F7E4F0A3F0800DB8 +:101A0000C39000F8E09DF09000F7E09CF0D007D084 +:101A100006D005D004D0D0D082D083D0E032C0E050 +:101A2000C083C082C0D075D000C004C005C006C04D +:101A30000753917F9000F9E0FEA3E0FF4E7003533F +:101A400091FB9000F5121B3B50099000F9E4F0A3C4 +:101A5000F0800DC39000FAE09DF09000F9E09CF05A +:101A6000D007D006D005D004D0D0D082D083D0E02B +:101A700032AE05AD07E4FCFB7FAA121CF6AF0512DF +:101A80001CF6EE75F00DA4241EF582E4341FF583D8 +:101A9000E493FFECC39F500774082CFC0B80F4EB1D +:101AA00004FF121CA2E4FCECC39B500974032C122B +:101AB0001CED0C80F27F55121CF6021E37AE07E4B7 +:101AC000FDF543121CA0900001E0FF121CF69000EF +:101AD00001121CAA900078E0FF121CF69000781208 +:101AE0001CAA900083E0FF121CF6900083121CAA2F +:101AF00074032D121CED0DBD03F67F55121CF6026A +:101B00001E37AB07AA06E4F9F87F407E427D0FFC42 +:101B1000120B0FA804A905AA06AB077F207ED77D6C +:101B2000757C01120B0FC3E49FFFE49EFE22AB07FE +:101B3000AA06E4F9F87FE87E03FD22E0FCA3E0FDBD +:101B4000C3EF9DEE9C228F288D298A2A8B2B752E20 +:101B500080E5282480701EE4F52F121160AF2F124B +:101B600012E8EF6005852F2E8019052FE52FC3940D +:101B70000840E7800E121160AF281212E8EF6003F0 +:101B800085282EAF2E228F4390007AE0F5447F0BFC +:101B9000121E4043DA011200707D0A7C007F017E34 +:101BA00000121C50121E22E4900082F0900081F07E +:101BB000900095E543F090007AF0AF44229000D970 +:101BC000E0FF9000D7E0B507057E017F002290007E +:101BD000D7121CBCE0FD7C009000D7E004F0E0B41C +:101BE0004002E4F09000D6E0FEEE4204E4F0AE04E1 +:101BF000AF05228F568C578D588A598B5AD290E553 +:101C000056640124FF92807F0A7E0012002E121E6D +:101C100022C290E55624FF9280AD5AAC597F0A7ECD +:101C20000012002E021E228E288F298C2A8D2B1244 +:101C30001B2E121B0F121D8E9000F7E52AF0A3E554 +:101C40002BF09000F3E528F0A3E529F043C8042227 +:101C50008E458F468C478D48121B2E121B0F121D6E +:101C60009A9000F9E547F0A3E548F09000F5E545C6 +:101C7000F0A3E546F043910422120021121E061241 +:101C80001E0D121DBE121E28121D4C121DDC121D2F +:101C9000C8121DD2121DA6121E14121E2C021E1BCB +:101CA0007FAA121CF6AF06021CF6A3E0FF021CF688 +:101CB000E54325E02486F582E4340022E02496F50D +:101CC00082E43400F58322C3ED9BF582EC9AF58320 +:101CD000C3E5829FE5839E5011ED2BFDEC3AFCC3DA +:101CE000EF9DEE9C50047F0180027F0022F582E48C +:101CF0003400F583E0FFC2009000DBE0B42002E492 +:101D0000F09000DBE02460F8A607E004F0A3E00414 +:101D1000F0228E3C8F3D1210D2E4FBFA79FA784320 +:101D20001208715009E4FFFE7DFA7C438003121013 +:101D3000D2120928227E1DE4FDEF30E70625E06E71 +:101D4000FF8004EF25E0FF0DBD08EE22AF88538829 +:101D5000AF758CA0758DCBEF5440FEEF54104E4202 +:101D60008822D290EF24FF92807F0A7E0012002EFC +:101D7000021E22C3EF9414EE94054003D38001C3E6 +:101D800022AE07121CA07F55121CF6021E37AD07AB +:101D9000AC06ECF5CBAF058FCA22AD07AC06ECF56F +:101DA00093AF058F9222C2DE75D90575F9FF75963E +:101DB0000122EE30E707C3E49FFFE49EFE2275E3B5 +:101DC0004075E10175E20122E59154045391FB4213 +:101DD0009122758E5475892243885022E5C8540497 +:101DE00053C8FB42C82253984FEB4F4DF59822E55C +:101DF000C8C320E201D322E591C320E201D32253DC +:101E0000C8FB53C87F2275A41175D4CF2275A54194 +:101E100075D5772253F77F75DA302275E69075A86D +:101E2000B022E59120E2FB22E4F5A922439810229A +:101E30003000FD22C2DE22D299228F9922AF992250 +:101E40008F8C222222011F00015E01030301183C36 +:101E500000000D0400017201020201283C08000884 +:101E60001700018601030301183C00001F0A00014E +:101E70002C01030301183C0000003B0701F403029E +:101E80000102403C00000712000190010303011809 +:101E90003C000017010001C201020201183C0001D0 +:101EA00024010000D2010202010C3C0001011F00CC +:101EB000015E01030301183C00000D0400017201E2 +:101EC000020201283C0800081700018601030301F3 +:101ED000183C00001F0A00012C01030301183C00FC +:101EE00000003B0701F403020102403C000007121E +:101EF00000019001030301183C000017010001C21A +:101F000001020201183C000124010000D20102027A +:101F1000010C3C0001011F00015E01030301183C9C +:101F200000000D0400017201020201283C080008B3 +:101F30001700018601030301183C00001F0A00017D +:101F40002C01030301183C0000003B0701F40302CD +:101F50000102403C00000712000190010303011838 +:101F60003C000017010001C201020201183C0001FF +:0D1F700024010000D2010202010C3C00011E +:00000001FF From be19af15e2ed65d4c9b445f159a458557289c362 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 4 Dec 2018 21:31:23 +0100 Subject: [PATCH 23/63] Announce switches --- sonoff/sonoff.ino | 3 +- sonoff/xdrv_12_home_assistant.ino | 137 ++++++++++++++++++++---------- 2 files changed, 92 insertions(+), 48 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 0772e76f2..947f5d165 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1310,7 +1310,8 @@ boolean SendKey(byte key, byte device, byte state) Format(key_topic, tmp, sizeof(key_topic)); if (Settings.flag.mqtt_enabled && MqttIsConnected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { if (!key && (device > devices_present)) device = 1; // Only allow number of buttons up to number of devices - GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), key)); // cmnd/switchtopic/POWERx + GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), + Settings.flag.device_index_enable)); // cmnd/switchtopic/POWERx if (9 == state) { mqtt_data[0] = '\0'; } else { diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 78b8b4841..b002049a2 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -33,16 +33,21 @@ const char HASS_DISCOVER_RELAY[] PROGMEM = "\"payload_available\":\"" D_ONLINE "\"," // Online "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline -const char HASS_DISCOVER_BUTTON[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM = "{\"name\":\"%s\"," // dualr2 1 BTN "\"state_topic\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",") // "\"value_template\":\"{{value_json.%s}}\"," // POWER2 - "\"payload_on\":\"%s\"," // TOGGLE + "\"payload_on\":\"%s\"," // TOGGLE / ON // "\"optimistic\":\"false\"," // false is Hass default when state_topic is set "\"availability_topic\":\"%s\"," // tele/dualr2/LWT "\"payload_available\":\"" D_ONLINE "\"," // Online - "\"payload_not_available\":\"" D_OFFLINE "\"," // Offline - "\"force_update\":true"; + "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline + +const char HASS_DISCOVER_BUTTON[] PROGMEM = + "%s,\"force_update\":true"; + +const char HASS_DISCOVER_SWITCH[] PROGMEM = + "%s,\"payload_off\":\"%s\""; // OFF const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM = "%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer @@ -92,7 +97,7 @@ const char HASS_DISCOVER_RELAY_SHORT[] PROGMEM = "\"pl_avail\":\"" D_ONLINE "\"," // Online "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline -const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM = "{\"name\":\"%s\"," // dualr2 1 BTN "\"stat_t\":\"%s\"," // cmnd/dualr2/POWER (implies "\"optimistic\":\"false\",") // "\"value_template\":\"{{value_json.%s}}\"," // POWER2 @@ -100,8 +105,14 @@ const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM = // "\"optimistic\":\"false\"," // false is Hass default when state_topic is set "\"avty_t\":\"%s\"," // tele/dualr2/LWT "\"pl_avail\":\"" D_ONLINE "\"," // Online - "\"pl_not_avail\":\"" D_OFFLINE "\"," // Offline - "\"frc_upd\":true"; + "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline + +const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM = + "%s,\"frc_upd\":true"; + +const char HASS_DISCOVER_SWITCH_SHORT[] PROGMEM = + "%s,\"pl_off\":\"%s\""; // OFF + const char HASS_DISCOVER_LIGHT_DIMMER_SHORT[] PROGMEM = "%s,\"bri_cmd_t\":\"%s\"," // cmnd/led2/Dimmer @@ -266,9 +277,75 @@ void HAssAnnounceRelayLight(void) } } -void HAssAnnounceButton(void) +void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key) { + char stopic[TOPSZ]; char sidx[8]; + + mqtt_data[0] = '\0'; // Clear retained message + + // Clear or Set topic + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s_%s_%d/config"), + topic, key?"BTN":"SW",device+1); + + if (Settings.flag.hass_discovery && present) { + char name[33]; + char value_template[33]; + char _state_topic[TOPSZ]; + char _availability_topic[TOPSZ]; + char prefix[TOPSZ]; + char *state_topic = _state_topic; + char *availability_topic = _availability_topic; + + if (device+1 > MAX_FRIENDLYNAMES) { + snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"BTN":"SW", device+1); + } else { + snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"BTN":"SW"); + } + GetPowerDevice(value_template, device+1, sizeof(value_template), Settings.flag.device_index_enable); + GetTopic_P(state_topic, CMND, topic, value_template); // State of button is sent as CMND TOGGLE, state of switch is sent as ON/OFF + GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); + FindPrefix(state_topic, availability_topic, prefix); + if (Settings.flag3.hass_short_discovery_msg) { + Shorten(&state_topic, prefix); + Shorten(&availability_topic, prefix); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_SHORT:HASS_DISCOVER_BUTTON_SWITCH, + name, state_topic, Settings.state_text[key?2:1], availability_topic); + if (key) snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SHORT:HASS_DISCOVER_BUTTON, + mqtt_data); + else snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SWITCH_SHORT:HASS_DISCOVER_SWITCH, + mqtt_data, Settings.state_text[0]); + + if (Settings.flag3.hass_short_discovery_msg) + snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); + } + MqttPublish(stopic, true); +} + +void HAssAnnounceSwitches(void) +{ + char sw_topic[sizeof(Settings.switch_topic)]; + + // Send info about buttons + char *tmp = Settings.switch_topic; + Format(sw_topic, tmp, sizeof(sw_topic)); + if ((strlen(sw_topic) != 0) && strcmp(sw_topic, "0")) { + for (byte switch_index = 0; switch_index < MAX_SWITCHES; switch_index++) { + uint8_t switch_present = 0; + + if ((pin[GPIO_SWT1 + switch_index] < 99) || (pin[GPIO_SWT1_NP + switch_index] < 99)) { + switch_present = 1; + } + + HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0); + } + } +} + +void HAssAnnounceButtons(void) +{ char stopic[TOPSZ]; char key_topic[sizeof(Settings.button_topic)]; @@ -282,47 +359,12 @@ void HAssAnnounceButton(void) if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) { button_present = 1; } else { - if (pin[GPIO_KEY1 + button_index] < 99) { + if ((pin[GPIO_KEY1 + button_index] < 99) || (pin[GPIO_KEY1_NP + button_index] < 99)) { button_present = 1; } } - mqtt_data[0] = '\0'; // Clear retained message - - // Clear or Set topic - snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), button_index+1); - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), "binary_sensor", key_topic, sidx); - - if (Settings.flag.hass_discovery && button_present) { - char name[33]; - char value_template[33]; - char _state_topic[TOPSZ]; - char _availability_topic[TOPSZ]; - char prefix[TOPSZ]; - char *state_topic = _state_topic; - char *availability_topic = _availability_topic; - - if (button_index+1 > MAX_FRIENDLYNAMES) { - snprintf_P(name, sizeof(name), PSTR("%s %d BTN"), Settings.friendlyname[0], button_index+1); - } else { - snprintf_P(name, sizeof(name), PSTR("%s BTN"), Settings.friendlyname[button_index]); - } - GetPowerDevice(value_template, button_index+1, sizeof(value_template), Settings.flag.device_index_enable); - GetTopic_P(state_topic, CMND, key_topic, value_template); // State of button is sent as CMND TOGGLE - GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); - FindPrefix(state_topic, availability_topic, prefix); - if (Settings.flag3.hass_short_discovery_msg) { - Shorten(&state_topic, prefix); - Shorten(&availability_topic, prefix); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SHORT:HASS_DISCOVER_BUTTON, - name, state_topic, Settings.state_text[2], availability_topic); - - if (Settings.flag3.hass_short_discovery_msg) - snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); - } - MqttPublish(stopic, true); + HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1); } } } @@ -440,9 +482,10 @@ void HAssDiscovery(uint8_t mode) HAssAnnounceRelayLight(); // Send info about buttons - HAssAnnounceButton(); + HAssAnnounceButtons(); - // TODO: Send info about switches + // Send info about switches + HAssAnnounceSwitches(); // Send info about sensors HAssAnnounceSensors(); From 4b287ab4cbf3f4537c93131695b4f4121678a528 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Wed, 5 Dec 2018 12:23:42 +0100 Subject: [PATCH 24/63] Final fix compile error (#4509) Final fix soft_spi_flg compile error (#4509) --- sonoff/sonoff.ino | 3 ++- tools/{ => fw_efm8bb1}/RF-Bridge-EFM8BB1-20181127.hex | 0 2 files changed, 2 insertions(+), 1 deletion(-) rename tools/{ => fw_efm8bb1}/RF-Bridge-EFM8BB1-20181127.hex (100%) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 0772e76f2..869eaf7eb 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -167,7 +167,7 @@ uint8_t dht_flg = 0; // DHT configured uint8_t energy_flg = 0; // Energy monitor configured uint8_t i2c_flg = 0; // I2C configured uint8_t spi_flg = 0; // SPI configured -uint8_t soft_spi_flg = 0; // Software SPI ** Temporary fix to satisfy compiler ** +uint8_t soft_spi_flg = 0; // Software SPI configured uint8_t light_type = 0; // Light types uint8_t ntp_force_sync = 0; // Force NTP sync byte serial_in_byte; // Received byte @@ -2498,6 +2498,7 @@ void GpioInit(void) my_module.gp.io[14] = GPIO_SPI_CLK; pin[GPIO_SPI_CLK] = 14; } + soft_spi_flg = ((pin[GPIO_SSPI_CS] < 99) && (pin[GPIO_SSPI_SCLK] < 99) && ((pin[GPIO_SSPI_MOSI] < 99) || (pin[GPIO_SSPI_MOSI] < 99))); #endif // USE_SPI #ifdef USE_I2C diff --git a/tools/RF-Bridge-EFM8BB1-20181127.hex b/tools/fw_efm8bb1/RF-Bridge-EFM8BB1-20181127.hex similarity index 100% rename from tools/RF-Bridge-EFM8BB1-20181127.hex rename to tools/fw_efm8bb1/RF-Bridge-EFM8BB1-20181127.hex From 94786d32177c62521489af25a1349a50350316d6 Mon Sep 17 00:00:00 2001 From: Erik Date: Wed, 5 Dec 2018 20:20:36 +0100 Subject: [PATCH 25/63] Fix logic for ON/OFF vs TOGGLE --- sonoff/xdrv_12_home_assistant.ino | 41 ++++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index b002049a2..b5d0c076c 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -43,10 +43,10 @@ const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM = "\"payload_available\":\"" D_ONLINE "\"," // Online "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline -const char HASS_DISCOVER_BUTTON[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM = "%s,\"force_update\":true"; -const char HASS_DISCOVER_SWITCH[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM = "%s,\"payload_off\":\"%s\""; // OFF const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM = @@ -107,10 +107,10 @@ const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM = "\"pl_avail\":\"" D_ONLINE "\"," // Online "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline -const char HASS_DISCOVER_BUTTON_SHORT[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT[] PROGMEM = "%s,\"frc_upd\":true"; -const char HASS_DISCOVER_SWITCH_SHORT[] PROGMEM = +const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT[] PROGMEM = "%s,\"pl_off\":\"%s\""; // OFF @@ -277,7 +277,7 @@ void HAssAnnounceRelayLight(void) } } -void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key) +void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, byte toggle) { char stopic[TOPSZ]; char sidx[8]; @@ -311,10 +311,12 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key) Shorten(&availability_topic, prefix); } snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_SHORT:HASS_DISCOVER_BUTTON_SWITCH, - name, state_topic, Settings.state_text[key?2:1], availability_topic); - if (key) snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SHORT:HASS_DISCOVER_BUTTON, + name, state_topic, Settings.state_text[toggle?2:1], availability_topic); + if (toggle) snprintf_P(mqtt_data, sizeof(mqtt_data), + Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT:HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, mqtt_data); - else snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SWITCH_SHORT:HASS_DISCOVER_SWITCH, + else snprintf_P(mqtt_data, sizeof(mqtt_data), + Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT:HASS_DISCOVER_BUTTON_SWITCH_ONOFF, mqtt_data, Settings.state_text[0]); if (Settings.flag3.hass_short_discovery_msg) @@ -333,13 +335,21 @@ void HAssAnnounceSwitches(void) Format(sw_topic, tmp, sizeof(sw_topic)); if ((strlen(sw_topic) != 0) && strcmp(sw_topic, "0")) { for (byte switch_index = 0; switch_index < MAX_SWITCHES; switch_index++) { - uint8_t switch_present = 0; + byte switch_present = 0; + byte toggle = 1; if ((pin[GPIO_SWT1 + switch_index] < 99) || (pin[GPIO_SWT1_NP + switch_index] < 99)) { switch_present = 1; } - HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0); + // Check if MQTT message will be ON/OFF or TOGGLE + if (Settings.switchmode[switch_index] == FOLLOW || Settings.switchmode[switch_index] == FOLLOW_INV || + !strcmp(mqtt_topic, sw_topic) || !strcmp(Settings.mqtt_grptopic, sw_topic)) + { + toggle = 0; + } + + HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0, toggle); } } } @@ -354,7 +364,8 @@ void HAssAnnounceButtons(void) Format(key_topic, tmp, sizeof(key_topic)); if ((strlen(key_topic) != 0) && strcmp(key_topic, "0")) { for (byte button_index = 0; button_index < MAX_KEYS; button_index++) { - uint8_t button_present = 0; + byte button_present = 0; + byte toggle = 1; if (!button_index && ((SONOFF_DUAL == Settings.module) || (CH4 == Settings.module))) { button_present = 1; @@ -364,7 +375,13 @@ void HAssAnnounceButtons(void) } } - HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1); + // Check if MQTT message will be ON/OFF or TOGGLE + if (!strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic)) + { + toggle = 0; + } + + HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1, toggle); } } } From a36ead52fa547ea31b6c269770eb2da67f2537b1 Mon Sep 17 00:00:00 2001 From: Gunnar Norin Date: Wed, 5 Dec 2018 23:25:25 +0100 Subject: [PATCH 26/63] Initial translation to Swedish --- sonoff/language/sv-SE.h | 597 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 597 insertions(+) create mode 100644 sonoff/language/sv-SE.h diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h new file mode 100644 index 000000000..271f3d649 --- /dev/null +++ b/sonoff/language/sv-SE.h @@ -0,0 +1,597 @@ +/* + sv-SE.h - localization for Swedish - Svenska for Sonoff-Tasmota + + Copyright (C) 2018 Gunnar Norin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _LANGUAGE_SV_SE_H_ +#define _LANGUAGE_SV_SE_H_ + +/*************************** ATTENTION *******************************\ + * + * Due to memory constraints only UTF-8 is supported. + * To save code space keep text as short as possible. + * Time and Date provided by SDK can not be localized (yet). + * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. + * Use online command Prefix to translate cmnd, stat and tele. + * + * Updated until v6.2.1.11 +\*********************************************************************/ + +//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) +// https://www.science.co.il/language/Locale-codes.php +#define LANGUAGE_LCID 1053 +// HTML (ISO 639-1) Language Code +#define D_HTML_LANGUAGE "sv" + +// "2017-03-07T11:08:02" - ISO8601:2004 +#define D_YEAR_MONTH_SEPARATOR "-" +#define D_MONTH_DAY_SEPARATOR "-" +#define D_DATE_TIME_SEPARATOR "T" +#define D_HOUR_MINUTE_SEPARATOR ":" +#define D_MINUTE_SECOND_SEPARATOR ":" + +#define D_DAY3LIST "MånTisOnsTorFreLörSön" +#define D_MONTH3LIST "JanFebMarAprMajJunJulAugSepOktNovDec" + +// Non JSON decimal separator +#define D_DECIMAL_SEPARATOR "," + +// Common +#define D_ADMIN "Admin" +#define D_AIR_QUALITY "Luftkvalitet" +#define D_AP "AP" // Access Point +#define D_AS "som" +#define D_AUTO "AUTO" +#define D_BLINK "Blinka" +#define D_BLINKOFF "BlinkaAv" +#define D_BOOT_COUNT "Uppstartsräknare" +#define D_BRIGHTLIGHT "Ljust" +#define D_BSSID "BSSId" +#define D_BUTTON "Knapp" +#define D_BY "av" // Written by me +#define D_BYTES "Bytes" +#define D_CELSIUS "Celsius" +#define D_CHANNEL "Kanal" +#define D_CO2 "Koldioxid" +#define D_CODE "kod" // Button code +#define D_COLDLIGHT "Kallt" +#define D_COMMAND "Kommando" +#define D_CONNECTED "Ansluten" +#define D_COUNT "Räkna" +#define D_COUNTER "Räknare" +#define D_CURRENT "Ström" // As in Voltage and Current +#define D_DATA "Data" +#define D_DARKLIGHT "Mörkt" +#define D_DEBUG "Debug" +#define D_DISABLED "Inaktiverad" +#define D_DISTANCE "Distans" +#define D_DNS_SERVER "DNS-server" +#define D_DONE "Gjort" +#define D_DST_TIME "DST" +#define D_ECO2 "eCO2" +#define D_EMULATION "Emulation" +#define D_ENABLED "Aktiverad" +#define D_ERASE "Ta bort" +#define D_ERROR "Fel" +#define D_FAHRENHEIT "Fahrenheit" +#define D_FAILED "Misslyckades" +#define D_FALLBACK "Reserv" +#define D_FALLBACK_TOPIC "Reservämne" +#define D_FALSE "Falskt" +#define D_FILE "Fil" +#define D_FREE_MEMORY "Ledigt minne" +#define D_FREQUENCY "Frekvens" +#define D_GAS "Gas" +#define D_GATEWAY "Gateway" +#define D_GROUP "Grupp" +#define D_HOST "Värd" +#define D_HOSTNAME "Värdnamn" +#define D_HUMIDITY "Fuktighet" +#define D_ILLUMINANCE "Belysnings" +#define D_IMMEDIATE "Omedelbar" // Button immediate +#define D_INDEX "Index" +#define D_INFO "Info" +#define D_INFRARED "Infraröd" +#define D_INITIALIZED "Initialiserad" +#define D_IP_ADDRESS "IP-adress" +#define D_LIGHT "Ljus" +#define D_LWT "LWT" +#define D_MODULE "Modul" +#define D_MQTT "MQTT" +#define D_MULTI_PRESS "fler tryck" +#define D_NOISE "Oväsen" +#define D_NONE "Ingen" +#define D_OFF "Av" +#define D_OFFLINE "Off-line" +#define D_OK "Ok" +#define D_ON "På" +#define D_ONLINE "Ansluten" +#define D_PASSWORD "Lösenord" +#define D_PORT "Port" +#define D_POWER_FACTOR "Spänningsfaktor" +#define D_POWERUSAGE "Spänning" +#define D_POWERUSAGE_ACTIVE "Aktiv spänning" +#define D_POWERUSAGE_APPARENT "Skenbar spänning" +#define D_POWERUSAGE_REACTIVE "Responsiv spänning" +#define D_PRESSURE "Tryck" +#define D_PRESSUREATSEALEVEL "Havstryck" +#define D_PROGRAM_FLASH_SIZE "Program-flashstorlek" +#define D_PROGRAM_SIZE "Programstorlek" +#define D_PROJECT "Projekt" +#define D_RECEIVED "Mottagen" +#define D_RESTART "Omstart" +#define D_RESTARTING "Startar om" +#define D_RESTART_REASON "Restart Reason" +#define D_RESTORE "återställ" +#define D_RETAINED "bevarad" +#define D_RULE "Regel" +#define D_SAVE "Spara" +#define D_SENSOR "Sensor" +#define D_SSID "SSId" +#define D_START "Starta" +#define D_STD_TIME "STD" +#define D_STOP "Stoppa" +#define D_SUBNET_MASK "Nätmask" +#define D_SUBSCRIBE_TO "Prenumera på" +#define D_SUCCESSFUL "Lyckat" +#define D_SUNRISE "Soluppgång" +#define D_SUNSET "Solnedgång" +#define D_TEMPERATURE "Temperatur" +#define D_TO "till" +#define D_TOGGLE "Växla" +#define D_TOPIC "Ämne" +#define D_TRANSMIT "Sänd" +#define D_TRUE "Sant" +#define D_TVOC "TVOC" +#define D_UPGRADE "uppgradera" +#define D_UPLOAD "Ladda upp" +#define D_UPTIME "Upptid" +#define D_USER "Användare" +#define D_UTC_TIME "UTC" +#define D_UV_INDEX "UV Index" +#define D_UV_INDEX_1 "Låg" +#define D_UV_INDEX_2 "Med" +#define D_UV_INDEX_3 "Hög" +#define D_UV_INDEX_4 "Farligt" +#define D_UV_INDEX_5 "BurnL1/2" +#define D_UV_INDEX_6 "BurnL3" +#define D_UV_INDEX_7 "OoR" // Out of Range +#define D_UV_LEVEL "UV nivå" +#define D_UV_POWER "UV kraft" +#define D_VERSION "Version" +#define D_VOLTAGE "Voltage" +#define D_WEIGHT "Vikt" +#define D_WARMLIGHT "Varm" +#define D_WEB_SERVER "Webbserver" + +// sonoff.ino +#define D_WARNING_MINIMAL_VERSION "VARNING Denna version supporterar inte beständiga inställningar" +#define D_LEVEL_10 "nivå 1-0" +#define D_LEVEL_01 "nivå 0-1" +#define D_SERIAL_LOGGING_DISABLED "Seriell loggning inaktiverad" +#define D_SYSLOG_LOGGING_REENABLED "Syslog återaktiverad" + +#define D_SET_BAUDRATE_TO "Ange Baudrate till" +#define D_RECEIVED_TOPIC "Mottaget ämne" +#define D_DATA_SIZE "Datastorlek" +#define D_ANALOG_INPUT "Analog" + +// support.ino +#define D_OSWATCH "osWatch" +#define D_BLOCKED_LOOP "Blockerad loop" +#define D_WPS_FAILED_WITH_STATUS "WPS-konfigurering MISSLYCKADES med status" +#define D_ACTIVE_FOR_3_MINUTES "aktiv för 3 minuter" +#define D_FAILED_TO_START "misslyckades att starta" +#define D_PATCH_ISSUE_2186 "Patch issue 2186" +#define D_CONNECTING_TO_AP "Ansluter till AP" +#define D_IN_MODE "i läge" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Anslutning misslyckades mottog ingen IP-adress" +#define D_CONNECT_FAILED_AP_NOT_REACHED "Anslutning misslyckades, kunde inte nå AP" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Anslutning misslyckades, fel lösenord för AP" +#define D_CONNECT_FAILED_AP_TIMEOUT "Anslutning misslyckadess med AP, timeout" +#define D_ATTEMPTING_CONNECTION "Försöker ansluta..." +#define D_CHECKING_CONNECTION "Kontrollerar anslutning..." +#define D_QUERY_DONE "Fråga utförd. MQTT-tjänster hittades" +#define D_MQTT_SERVICE_FOUND "MQTT-tjänst hittades på" +#define D_FOUND_AT "hittades vid" +#define D_SYSLOG_HOST_NOT_FOUND "Syslog-värd hittades inte" + +// settings.ino +#define D_SAVED_TO_FLASH_AT "Sparade till flash vid" +#define D_LOADED_FROM_FLASH_AT "Laddade från flash vid" +#define D_USE_DEFAULTS "Använd standard" +#define D_ERASED_SECTOR "Rensade sektor" + +// xdrv_02_webserver.ino +#define D_NOSCRIPT "För att använda Tasmota, aktivera JavaScript" +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware - var god uppgradera" +#define D_WEBSERVER_ACTIVE_ON "Webbserver aktiv på" +#define D_WITH_IP_ADDRESS "med IP-adress" +#define D_WEBSERVER_STOPPED "Webbserver stoppad" +#define D_FILE_NOT_FOUND "Filen hittades inte" +#define D_REDIRECTED "Omdirigerad till fångstportal" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifihanterare ange accesspunkt och behåll station" +#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifihanterare ange accesspunkt" +#define D_TRYING_TO_CONNECT "Försöker att ansluta enheten till nätverk" + +#define D_RESTART_IN "Omstart om" +#define D_SECONDS "sekunder" +#define D_DEVICE_WILL_RESTART "Enheten kommer att starta om inom ett antal sekunder" +#define D_BUTTON_TOGGLE "Växla" +#define D_CONFIGURATION "Konfigurering" +#define D_INFORMATION "Information" +#define D_FIRMWARE_UPGRADE "Uppgradera firmware" +#define D_CONSOLE "Konsol" +#define D_CONFIRM_RESTART "Bekräfta omstart" + +#define D_CONFIGURE_MODULE "Konfigurera modul" +#define D_CONFIGURE_WIFI "Konfigurera WiFi" +#define D_CONFIGURE_MQTT "Konfigurera MQTT" +#define D_CONFIGURE_DOMOTICZ "Konfigurera Domoticz" +#define D_CONFIGURE_LOGGING "Konfigurera loggning" +#define D_CONFIGURE_OTHER "Konfigurera annat" +#define D_CONFIRM_RESET_CONFIGURATION "Bekräfta nollställning av konfiguration" +#define D_RESET_CONFIGURATION "Nollställ konfiguration" +#define D_BACKUP_CONFIGURATION "Säkerhetskopiera konfiguration" +#define D_RESTORE_CONFIGURATION "Återställ konfiguration" +#define D_MAIN_MENU "Huvudmeny" + +#define D_MODULE_PARAMETERS "Modulparameterar" +#define D_MODULE_TYPE "Modultyp" +#define D_GPIO "GPIO" +#define D_SERIAL_IN "Seriell in" +#define D_SERIAL_OUT "Seriell ut" + +#define D_WIFI_PARAMETERS "Wifi-parameterar" +#define D_SCAN_FOR_WIFI_NETWORKS "Skanna efter wifi-nätverk" +#define D_SCAN_DONE "Skanning slutförd" +#define D_NO_NETWORKS_FOUND "Inga nätverk hittades" +#define D_REFRESH_TO_SCAN_AGAIN "Uppdatera för att skanna igen" +#define D_DUPLICATE_ACCESSPOINT "Dubblett accesspunkt" +#define D_SKIPPING_LOW_QUALITY "Hoppa över pga dålig kvalitet" +#define D_RSSI "RSSI" +#define D_WEP "WEP" +#define D_WPA_PSK "WPA PSK" +#define D_WPA2_PSK "WPA2 PSK" +#define D_AP1_SSID "AP1 SSId" +#define D_AP1_PASSWORD "AP1 lösenord" +#define D_AP2_SSID "AP2 SSId" +#define D_AP2_PASSWORD "AP2 lösenord" + +#define D_MQTT_PARAMETERS "MQTT-parameterar" +#define D_CLIENT "Klient" +#define D_FULL_TOPIC "Fullt ämne" + +#define D_LOGGING_PARAMETERS "Loggningsparametrar" +#define D_SERIAL_LOG_LEVEL "Seriell loggnivå" +#define D_WEB_LOG_LEVEL "Webb loggnivå" +#define D_SYS_LOG_LEVEL "Syslog-nivp" +#define D_MORE_DEBUG "Mer debugging" +#define D_SYSLOG_HOST "Syslog-värd" +#define D_SYSLOG_PORT "Syslog-port" +#define D_TELEMETRY_PERIOD "Telemetriperiod" + +#define D_OTHER_PARAMETERS "Andra parametrar" +#define D_WEB_ADMIN_PASSWORD "Webbadmin-lösenord" +#define D_MQTT_ENABLE "MQTT aktivera" +#define D_FRIENDLY_NAME "Läsbart namn" +#define D_BELKIN_WEMO "Belkin WeMo" +#define D_HUE_BRIDGE "Hue Bridge" +#define D_SINGLE_DEVICE "soloenhet" +#define D_MULTI_DEVICE "multienhet" + +#define D_SAVE_CONFIGURATION "Spara konfiguration" +#define D_CONFIGURATION_SAVED "Konfiguration sparad" +#define D_CONFIGURATION_RESET "Konfiguration nollställd" + +#define D_PROGRAM_VERSION "Programversion" +#define D_BUILD_DATE_AND_TIME "Build datum & tid" +#define D_CORE_AND_SDK_VERSION "Core/SDK Version" +#define D_FLASH_WRITE_COUNT "Flash-skrivningsräknare" +#define D_MAC_ADDRESS "MAC-adress" +#define D_MQTT_HOST "MQTT-värd" +#define D_MQTT_PORT "MQTT-port" +#define D_MQTT_CLIENT "MQTT-klient" +#define D_MQTT_USER "MQTT-användare" +#define D_MQTT_TOPIC "MQTT-ämne" +#define D_MQTT_GROUP_TOPIC "MQTT gruppämne" +#define D_MQTT_FULL_TOPIC "MQTT fullt ämne" +#define D_MDNS_DISCOVERY "mDNS upptäckning" +#define D_MDNS_ADVERTISE "mDNS annonsering" +#define D_ESP_CHIP_ID "ESP Chip Id" +#define D_FLASH_CHIP_ID "Flash Chip Id" +#define D_FLASH_CHIP_SIZE "Flash-storlek" +#define D_FREE_PROGRAM_SPACE "Ledigt programutrymme" + +#define D_UPGRADE_BY_WEBSERVER "Uppgradering via webbserver" +#define D_OTA_URL "OTA Url" +#define D_START_UPGRADE "Starta uppdatering" +#define D_UPGRADE_BY_FILE_UPLOAD "Uppgradering via filuppladdning" +#define D_UPLOAD_STARTED "Uppladdning startad" +#define D_UPGRADE_STARTED "Uppgradeing startad" +#define D_UPLOAD_DONE "Uppladdning klar" +#define D_UPLOAD_ERR_1 "Ingen fil vald" +#define D_UPLOAD_ERR_2 "Inte tillräckligt med ledigt utrymme" +#define D_UPLOAD_ERR_3 "Magisk byte är inte 0xE9" +#define D_UPLOAD_ERR_4 "Programmets flashstorlek är större än den verkliga flashstorleken" +#define D_UPLOAD_ERR_5 "Uppladdningbuffert stämmer inte överens" +#define D_UPLOAD_ERR_6 "Uppladdning misslyckad. Aktivera loggning 3" +#define D_UPLOAD_ERR_7 "Uppladdning avbruten" +#define D_UPLOAD_ERR_8 "Ogiltig fil" +#define D_UPLOAD_ERR_9 "För stor fil" +#define D_UPLOAD_ERR_10 "Misslyckades initera RF chip" +#define D_UPLOAD_ERR_11 "Misslyckades rensa RF chip" +#define D_UPLOAD_ERR_12 "Misslyckades skriva till RF chip" +#define D_UPLOAD_ERR_13 "Misslyckades avkoda RF firmware" +#define D_UPLOAD_ERROR_CODE "Upladdningsfelkod" + +#define D_ENTER_COMMAND "Ange kommando" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Aktivera weblog 2 om svar förväntas" +#define D_NEED_USER_AND_PASSWORD "Behöver användarnamn=&lösenord=" + +// xdrv_01_mqtt.ino +#define D_FINGERPRINT "Verifierar TLS fingeravtryck..." +#define D_TLS_CONNECT_FAILED_TO "TLS-anslutning misslyckades" +#define D_RETRY_IN "Försöker igen om" +#define D_VERIFIED "Verifierad med fingeravtryck" +#define D_INSECURE "Osäker anslutning pga ogiltigt fingeravtryck" +#define D_CONNECT_FAILED_TO "Anslutning misslyckades" + +// xplg_wemohue.ino +#define D_MULTICAST_DISABLED "Multicast inaktiverad" +#define D_MULTICAST_REJOINED "Multicast (åter)anslöt" +#define D_MULTICAST_JOIN_FAILED "Multicast anslutning misslyckades" +#define D_FAILED_TO_SEND_RESPONSE "Misslyckades skicka svar" + +#define D_WEMO "WeMo" +#define D_WEMO_BASIC_EVENT "WeMo standardhändelse" +#define D_WEMO_EVENT_SERVICE "WeMo händelsetjänst" +#define D_WEMO_META_SERVICE "WeMo metatjänst" +#define D_WEMO_SETUP "WeMo installation" +#define D_RESPONSE_SENT "Svar skickat" + +#define D_HUE "Hue" +#define D_HUE_BRIDGE_SETUP "Hue installation" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API inte implementerat" +#define D_HUE_API "Hue API" +#define D_HUE_POST_ARGS "Hue POST args" +#define D_3_RESPONSE_PACKETS_SENT "3 svarspaket skickade" + +// xdrv_07_domoticz.ino +#define D_DOMOTICZ_PARAMETERS "Domoticz parametetrar" +#define D_DOMOTICZ_IDX "Idx" +#define D_DOMOTICZ_KEY_IDX "Nyckel idx" +#define D_DOMOTICZ_SWITCH_IDX "Switch idx" +#define D_DOMOTICZ_SENSOR_IDX "Sensor idx" + #define D_DOMOTICZ_TEMP "Temp" + #define D_DOMOTICZ_TEMP_HUM "Temp,Fuk" + #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Fuk,Baro" + #define D_DOMOTICZ_POWER_ENERGY "Spänning,Energi" + #define D_DOMOTICZ_ILLUMINANCE "Belysningsstyrka" + #define D_DOMOTICZ_COUNT "Antal/PM1" + #define D_DOMOTICZ_VOLTAGE "Volt/PM2.5" + #define D_DOMOTICZ_CURRENT "Ström/PM10" + #define D_DOMOTICZ_AIRQUALITY "Luftkvalitet" +#define D_DOMOTICZ_UPDATE_TIMER "Uppdatera timer" + +// xdrv_09_timers.ino +#define D_CONFIGURE_TIMER "Konfigurera timer" +#define D_TIMER_PARAMETERS "timerparametrar" +#define D_TIMER_ENABLE "Aktivera timer" +#define D_TIMER_ARM "Aktivera" +#define D_TIMER_TIME "Tid" +#define D_TIMER_DAYS "Dagar" +#define D_TIMER_REPEAT "Repetera" +#define D_TIMER_OUTPUT "Output" +#define D_TIMER_ACTION "Action" + +// xdrv_10_knx.ino +#define D_CONFIGURE_KNX "Konfigurera KNX" +#define D_KNX_PARAMETERS "KNX Parametrar" +#define D_KNX_GENERAL_CONFIG "Allmänt" +#define D_KNX_PHYSICAL_ADDRESS "Fysisk adress" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Måste vara unik på KNX-nätverket )" +#define D_KNX_ENABLE "Aktivera KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data att skicka till gruppadresser" +#define D_ADD "Lägg till" +#define D_DELETE "Ta bort" +#define D_REPLY "Svara" +#define D_KNX_GROUP_ADDRESS_TO_READ "Gruppadresser att ta emot data från" +#define D_LOG_KNX "KNX: " +#define D_RECEIVED_FROM "Mottagen från" +#define D_KNX_COMMAND_WRITE "Skriv" +#define D_KNX_COMMAND_READ "Läs" +#define D_KNX_COMMAND_OTHER "Andra" +#define D_SENT_TO "skickad till" +#define D_KNX_WARNING "Gruppadressen ( 0 / 0 / 0 ) är reserverad och kan inte användas." +#define D_KNX_ENHANCEMENT "Kommuniceringsförbättring" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" + +// xdrv_03_energy.ino +#define D_ENERGY_TODAY "Energi idag" +#define D_ENERGY_YESTERDAY "Energi igår" +#define D_ENERGY_TOTAL "Energi totalt" + +// xsns_05_ds18b20.ino +#define D_SENSOR_BUSY "Sensor upptagen" +#define D_SENSOR_CRC_ERROR "Sensor CRC-fel" +#define D_SENSORS_FOUND "Sensorer hittades" + +// xsns_06_dht.ino +#define D_TIMEOUT_WAITING_FOR "Timeout under väntan +#define D_START_SIGNAL_LOW "startsignal låg +#define D_START_SIGNAL_HIGH "startsignal hög +#define D_PULSE "puls" +#define D_CHECKSUM_FAILURE "Fel kontrollsumma + +// xsns_07_sht1x.ino +#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor besvarade inte med ACK kommando +#define D_SHT1X_FOUND "SHT1X hittades" + +// xsns_18_pms5003.ino +#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter +#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter +#define D_PARTICALS_BEYOND "Partiklar" + +// xsns_32_mpu6050.ino +#define D_AX_AXIS "Accel. X-Axel" +#define D_AY_AXIS "Accel. Y-Axel" +#define D_AZ_AXIS "Accel. Z-Axel" +#define D_GX_AXIS "Gyro X-Axel" +#define D_GY_AXIS "Gyro Y-Axel" +#define D_GZ_AXIS "Gyro Z-Axel" + +// xsns_34_hx711.ino +#define D_HX_CAL_REMOVE "Ta bort vikter" +#define D_HX_CAL_REFERENCE "Ladda referensvikt" +#define D_HX_CAL_DONE "Kalibrerad" +#define D_HX_CAL_FAIL "Kalibrering misslyckad" +#define D_RESET_HX711 "Återställ våg" +#define D_CONFIGURE_HX711 "Konfigurera våg" +#define D_HX711_PARAMETERS "Vågparametrar" +#define D_ITEM_WEIGHT "Objektsvikt" +#define D_REFERENCE_WEIGHT "Referensvikt" +#define D_CALIBRATE "Kalibrera" +#define D_CALIBRATION "Kalibrering" + +//xsns_35_tx20.ino +#define D_TX20_WIND_DIRECTION "Vindriktning" +#define D_TX20_WIND_SPEED "Vindstyrka" +#define D_TX20_WIND_SPEED_AVG "Vindstyrka medel" +#define D_TX20_WIND_SPEED_MAX "Vindstyrka max" +#define D_TX20_NORTH "N" +#define D_TX20_EAST "E" +#define D_TX20_SOUTH "S" +#define D_TX20_WEST "W" + +// sonoff_template.h +#define D_SENSOR_NONE "Ingen" +#define D_SENSOR_DHT11 "DHT11" +#define D_SENSOR_AM2301 "AM2301" +#define D_SENSOR_SI7021 "SI7021" +#define D_SENSOR_DS18X20 "DS18x20" +#define D_SENSOR_I2C_SCL "I2C SCL" +#define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3-spelare" +#define D_SENSOR_IRSEND "IRsend" +#define D_SENSOR_SWITCH "Omkopplare" // Suffix "1" +#define D_SENSOR_BUTTON "Knapp" // Suffix "1" +#define D_SENSOR_RELAY "Relä" // Suffix "1i" +#define D_SENSOR_LED "Led" // Suffix "1i" +#define D_SENSOR_PWM "PWM" // Suffix "1" +#define D_SENSOR_COUNTER "Räknare" // Suffix "1" +#define D_SENSOR_IRRECV "IRrecv" +#define D_SENSOR_MHZ_RX "MHZ Rx" +#define D_SENSOR_MHZ_TX "MHZ Tx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" +#define D_SENSOR_SAIR_RX "SAir Rx" +#define D_SENSOR_SAIR_TX "SAir Tx" +#define D_SENSOR_SPI_CS "SPI CS" +#define D_SENSOR_SPI_DC "SPI DC" +#define D_SENSOR_BACKLIGHT "BkLight" +#define D_SENSOR_PMS5003 "PMS5003" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" +#define D_SENSOR_SBR_RX "SerBr Rx" +#define D_SENSOR_SBR_TX "SerBr Tx" +#define D_SENSOR_SR04_TRIG "SR04 Tri" +#define D_SENSOR_SR04_ECHO "SR04 Ech" +#define D_SENSOR_SDM120_TX "SDM120 Tx" +#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM630_TX "SDM630 Tx" +#define D_SENSOR_SDM630_RX "SDM630 Rx" +#define D_SENSOR_TM1638_CLK "TM16 CLK" +#define D_SENSOR_TM1638_DIO "TM16 DIO" +#define D_SENSOR_TM1638_STB "TM16 STB" +#define D_SENSOR_HX711_SCK "HX711 SCK" +#define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_TX20_TX "TX20" +#define D_SENSOR_RFSEND "RFSend" +#define D_SENSOR_RFRECV "RFrecv" +#define D_SENSOR_TUYA_TX "Tuya Tx" +#define D_SENSOR_TUYA_RX "Tuya Rx" +#define D_SENSOR_MGC3130_XFER "MGC3130 Xfer" +#define D_SENSOR_MGC3130_RESET "MGC3130 Reset" +#define D_SENSOR_SSPI_MISO "SSPI MISO" +#define D_SENSOR_SSPI_MOSI "SSPI MOSI" +#define D_SENSOR_SSPI_SCLK "SSPI SCLK" +#define D_SENSOR_SSPI_CS "SSPI CS" +#define D_SENSOR_SSPI_DC "SSPI DC" + + +// Units +#define D_UNIT_AMPERE "A" +#define D_UNIT_CENTIMETER "cm" +#define D_UNIT_HERTZ "Hz" +#define D_UNIT_HOUR "Hr" +#define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KILOGRAM "kg" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" +#define D_UNIT_KILOOHM "kOhm" +#define D_UNIT_KILOWATTHOUR "kWh" +#define D_UNIT_LUX "lx" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "ug/m3" +#define D_UNIT_MICROMETER "um" +#define D_UNIT_MICROSECOND "us" +#define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER_MERCURY "mmHg" +#define D_UNIT_MILLISECOND "ms" +#define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" +#define D_UNIT_PARTS_PER_DECILITER "ppd" +#define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_PRESSURE "hPa" +#define D_UNIT_SECOND "sek" +#define D_UNIT_SECTORS "sektorer" +#define D_UNIT_VA "VA" +#define D_UNIT_VAR "VAr" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" +#define D_UNIT_WATT_METER_QUADRAT "W/m²" + +// Log message prefix +#define D_LOG_APPLICATION "APP: " // Application +#define D_LOG_BRIDGE "BRG: " // Bridge +#define D_LOG_CONFIG "CFG: " // Settings +#define D_LOG_COMMAND "CMD: " // Command +#define D_LOG_DEBUG "DBG: " // Debug +#define D_LOG_DHT "DHT: " // DHT sensor +#define D_LOG_DOMOTICZ "DOM: " // Domoticz +#define D_LOG_DSB "DSB: " // DS18xB20 sensor +#define D_LOG_HTTP "HTP: " // HTTP webserver +#define D_LOG_I2C "I2C: " // I2C +#define D_LOG_IRR "IRR: " // Infra Red Received +#define D_LOG_LOG "LOG: " // Logging +#define D_LOG_MODULE "MOD: " // Module +#define D_LOG_MDNS "DNS: " // mDNS +#define D_LOG_MQTT "MQT: " // MQTT +#define D_LOG_OTHER "OTH: " // Other +#define D_LOG_RESULT "RSL: " // Result +#define D_LOG_RFR "RFR: " // RF Received +#define D_LOG_SERIAL "SER: " // Serial +#define D_LOG_SHT1 "SHT: " // SHT1x sensor +#define D_LOG_UPLOAD "UPL: " // Upload +#define D_LOG_UPNP "UPP: " // UPnP +#define D_LOG_WIFI "WIF: " // Wifi + +#endif // _LANGUAGE_SV_SE_H_ From eda86acaa048bca2f111c94a0d2e9817b892161d Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 5 Dec 2018 20:01:45 -0300 Subject: [PATCH 27/63] Added Key to select Swedish Translation --- sonoff/my_user_config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index e1f6e364a..288c80d30 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -205,6 +205,7 @@ //#define MY_LANGUAGE pt-BR // Portuguese in Brazil //#define MY_LANGUAGE pt-PT // Portuguese in Portugal //#define MY_LANGUAGE ru-RU // Russian in Russia +//#define MY_LANGUAGE sv-SE // Swedish in Sweden //#define MY_LANGUAGE tr-TR // Turkish in Turkey //#define MY_LANGUAGE uk-UK // Ukrainian in Ukrain //#define MY_LANGUAGE zh-CN // Chinese (Simplified) in China From 33f27feb5fe7d249867d7f6b0a49fd2d3f6aca3d Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 5 Dec 2018 20:04:22 -0300 Subject: [PATCH 28/63] Added Swedish to Precompiled bins --- platformio.ini | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platformio.ini b/platformio.ini index bb68e981f..fe4893b69 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,6 +33,7 @@ env_default = sonoff ;env_default = sonoff-PL ;env_default = sonoff-PT ;env_default = sonoff-RU +;env_default = sonoff-SV ;env_default = sonoff-TR ;env_default = sonoff-TW ;env_default = sonoff-UK @@ -409,6 +410,20 @@ upload_resetmethod = ${common.upload_resetmethod} upload_speed = ${common.upload_speed} extra_scripts = ${common.extra_scripts} +[env:sonoff-SV] +platform = ${common.platform} +framework = ${common.framework} +board = ${common.board} +board_build.flash_mode = ${common.board_build.flash_mode} +board_build.f_cpu = ${common.board_build.f_cpu} +build_unflags = ${common.build_unflags} +build_flags = ${common.build_flags} -DMY_LANGUAGE=sv-SE +monitor_speed = ${common.monitor_speed} +upload_port = ${common.upload_port} +upload_resetmethod = ${common.upload_resetmethod} +upload_speed = ${common.upload_speed} +extra_scripts = ${common.extra_scripts} + [env:sonoff-TR] platform = ${common.platform} framework = ${common.framework} From 5f35f7ebae89c99c49a298201b1f0deac0771a3a Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 5 Dec 2018 20:11:54 -0300 Subject: [PATCH 29/63] Added missing " --- sonoff/language/sv-SE.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 271f3d649..bcffdab58 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -433,14 +433,14 @@ #define D_SENSORS_FOUND "Sensorer hittades" // xsns_06_dht.ino -#define D_TIMEOUT_WAITING_FOR "Timeout under väntan -#define D_START_SIGNAL_LOW "startsignal låg -#define D_START_SIGNAL_HIGH "startsignal hög +#define D_TIMEOUT_WAITING_FOR "Timeout under väntan" +#define D_START_SIGNAL_LOW "startsignal låg" +#define D_START_SIGNAL_HIGH "startsignal hög" #define D_PULSE "puls" -#define D_CHECKSUM_FAILURE "Fel kontrollsumma +#define D_CHECKSUM_FAILURE "Fel kontrollsumma" // xsns_07_sht1x.ino -#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor besvarade inte med ACK kommando +#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor besvarade inte med ACK kommando" #define D_SHT1X_FOUND "SHT1X hittades" // xsns_18_pms5003.ino From 3b68d606ab21fbadae7bb91aaf5f3ff6446e497c Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Wed, 5 Dec 2018 20:14:11 -0300 Subject: [PATCH 30/63] Matched the order of days with Tasmota Timers --- sonoff/language/sv-SE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index bcffdab58..db8f663a1 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -44,7 +44,7 @@ #define D_HOUR_MINUTE_SEPARATOR ":" #define D_MINUTE_SECOND_SEPARATOR ":" -#define D_DAY3LIST "MånTisOnsTorFreLörSön" +#define D_DAY3LIST "SönMånTisOnsTorFreLör" #define D_MONTH3LIST "JanFebMarAprMajJunJulAugSepOktNovDec" // Non JSON decimal separator From 9af72977db26f40540635eea3c1505d06fc00c95 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Thu, 6 Dec 2018 08:48:20 +0100 Subject: [PATCH 31/63] Update platformio.ini Support for enable / disable exceptions code in firmware for esp8266 core 2.5.0 (stage) or up --- platformio.ini | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/platformio.ini b/platformio.ini index bb68e981f..0a9bb65b9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -80,6 +80,15 @@ build_flags = ; VTABLES in IRAM ; -DVTABLES_IN_IRAM +; if using esp8266 core 2.5.0 (stage) or up +; enable one option set -> No exception recommended +; No exception code in firmware +; -fno-exceptions +; -lstdc++-nox +; Exception code in firmware /needs much space! 90k +; -fexceptions +; -lstdc++ + ; *** Serial Monitor options monitor_speed = 115200 From 3777dbe45c965c87a9ac2ed80b5664f825a91acb Mon Sep 17 00:00:00 2001 From: Andrzej Date: Thu, 6 Dec 2018 09:52:02 +0100 Subject: [PATCH 32/63] localization for Polish - KNX, timers, etc. --- sonoff/language/pl-PL.h | 130 ++++++++++++++++++++-------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index aee1b99a0..f2ef0c05c 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -62,10 +62,10 @@ #define D_BRIGHTLIGHT "Jasny" #define D_BSSID "BSSId" #define D_BUTTON "Przycisk" -#define D_BY "by" // Written by me +#define D_BY "przez" // Written by me #define D_BYTES "Bajtow" #define D_CELSIUS "Celsiusza" -#define D_CHANNEL "Channel" +#define D_CHANNEL "Kanał" #define D_CO2 "Dwutlenku węgla" #define D_CODE "kod" // Button code #define D_COLDLIGHT "Zimny" @@ -78,8 +78,8 @@ #define D_DARKLIGHT "Ciemny" #define D_DEBUG "Debug" #define D_DISABLED "Zablokowany" -#define D_DISTANCE "Distance" -#define D_DNS_SERVER "Server DNS" +#define D_DISTANCE "Odległość" +#define D_DNS_SERVER "Serwer DNS" #define D_DONE "Wykonane" #define D_DST_TIME "DST" #define D_ECO2 "eCO2" @@ -105,7 +105,7 @@ #define D_IMMEDIATE "Natychmiastowe" // Button immediate #define D_INDEX "Indeks" #define D_INFO "Informacja" -#define D_INFRARED "Infrared" +#define D_INFRARED "Podczerwień" #define D_INITIALIZED "Zainicjowany" #define D_IP_ADDRESS "Adres IP" #define D_LIGHT "Światło" @@ -124,9 +124,9 @@ #define D_PORT "Port" #define D_POWER_FACTOR "Współczynik mocy" #define D_POWERUSAGE "Moc" -#define D_POWERUSAGE_ACTIVE "Active Power" -#define D_POWERUSAGE_APPARENT "Apparent Power" -#define D_POWERUSAGE_REACTIVE "Reactive Power" +#define D_POWERUSAGE_ACTIVE "Czynna Moc" +#define D_POWERUSAGE_APPARENT "Pozorna Moc" +#define D_POWERUSAGE_REACTIVE "Reaktywna Moc" #define D_PRESSURE "Ciśnienie" #define D_PRESSUREATSEALEVEL "Ciśnienie na poziomie morza" #define D_PROGRAM_FLASH_SIZE "Wielkość programu flash" @@ -148,8 +148,8 @@ #define D_SUBNET_MASK "Maska podsieci" #define D_SUBSCRIBE_TO "Subskrybuj do" #define D_SUCCESSFUL "Powodzenie" -#define D_SUNRISE "Sunrise" -#define D_SUNSET "Sunset" +#define D_SUNRISE "Wschód słońca" +#define D_SUNSET "Zachód słońca" #define D_TEMPERATURE "Temperatura" #define D_TO "do" #define D_TOGGLE "Przełącz" @@ -159,14 +159,14 @@ #define D_TVOC "TVOC" #define D_UPGRADE "aktualizacji" #define D_UPLOAD "Wgraj" -#define D_UPTIME "Uptime" +#define D_UPTIME "Czas pracy" #define D_USER "Użytkownik" #define D_UTC_TIME "UTC" #define D_UV_INDEX "UV Index" -#define D_UV_INDEX_1 "Low" -#define D_UV_INDEX_2 "Mid" -#define D_UV_INDEX_3 "High" -#define D_UV_INDEX_4 "Danger" +#define D_UV_INDEX_1 "Niski" +#define D_UV_INDEX_2 "Średni" +#define D_UV_INDEX_3 "Wysoki" +#define D_UV_INDEX_4 "Niebezpieczny" #define D_UV_INDEX_5 "BurnL1/2" #define D_UV_INDEX_6 "BurnL3" #define D_UV_INDEX_7 "OoR" @@ -176,10 +176,10 @@ #define D_VOLTAGE "Napięcie" #define D_WEIGHT "Weight" #define D_WARMLIGHT "Nagrzanie" -#define D_WEB_SERVER "Web Server" +#define D_WEB_SERVER "Web Serwer" // sonoff.ino -#define D_WARNING_MINIMAL_VERSION "WARNING This version does not support persistent settings" +#define D_WARNING_MINIMAL_VERSION "UWAGA Ta wersja nie obsługuje zapisu ustawień" #define D_LEVEL_10 "poziom 1-0" #define D_LEVEL_01 "poziom 0-1" #define D_SERIAL_LOGGING_DISABLED "Wyłączony dziennik na porcie szeregowym" @@ -217,7 +217,7 @@ #define D_ERASED_SECTOR "Wymazany sektor" // xdrv_02_webserver.ino -#define D_NOSCRIPT "To use Tasmota, please enable JavaScript" +#define D_NOSCRIPT "Aby korzystać z Tasmota, włącz obsługę JavaScript" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Oprogramowanie MINIMAL - proszę uaktualnić" #define D_WEBSERVER_ACTIVE_ON "Aktywny serwer Web" #define D_WITH_IP_ADDRESS "z adresem IP" @@ -333,10 +333,10 @@ #define D_UPLOAD_ERR_7 "Wgrywanie przerwane" #define D_UPLOAD_ERR_8 "Błędny plik" #define D_UPLOAD_ERR_9 "Plik jest za duży" -#define D_UPLOAD_ERR_10 "Failed to init RF chip" -#define D_UPLOAD_ERR_11 "Failed to erase RF chip" -#define D_UPLOAD_ERR_12 "Failed to write to RF chip" -#define D_UPLOAD_ERR_13 "Failed to decode RF firmware" +#define D_UPLOAD_ERR_10 "Błąd inicjacji układu RF" +#define D_UPLOAD_ERR_11 "Błąd kasowania układu RF" +#define D_UPLOAD_ERR_12 "Błąd zapisu układu RF" +#define D_UPLOAD_ERR_13 "Błąd dekodowania oprrogramowania układu RF" #define D_UPLOAD_ERROR_CODE "Błąd wgrywania" #define D_ENTER_COMMAND "Wprowadź polecenie" @@ -389,36 +389,36 @@ #define D_DOMOTICZ_UPDATE_TIMER "Zaktualizuj czasomierz" // xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Configure Timer" -#define D_TIMER_PARAMETERS "Timer parameters" -#define D_TIMER_ENABLE "Enable Timers" -#define D_TIMER_ARM "Arm" -#define D_TIMER_TIME "Time" -#define D_TIMER_DAYS "Days" -#define D_TIMER_REPEAT "Repeat" -#define D_TIMER_OUTPUT "Output" -#define D_TIMER_ACTION "Action" +#define D_CONFIGURE_TIMER "Skonfiguruj harmonogram" +#define D_TIMER_PARAMETERS "Parametry harmonogramów" +#define D_TIMER_ENABLE "Włącz Harmonogramy" +#define D_TIMER_ARM "Włącz" +#define D_TIMER_TIME "Czas" +#define D_TIMER_DAYS "Dni" +#define D_TIMER_REPEAT "Powtarzaj" +#define D_TIMER_OUTPUT "Wyjście" +#define D_TIMER_ACTION "Akcja" // xdrv_10_knx.ino -#define D_CONFIGURE_KNX "Configure KNX" -#define D_KNX_PARAMETERS "KNX Parameters" -#define D_KNX_GENERAL_CONFIG "General" -#define D_KNX_PHYSICAL_ADDRESS "Physical Address" -#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Must be unique on the KNX network )" -#define D_KNX_ENABLE "Enable KNX" -#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data to Send to Group Addresses" -#define D_ADD "Add" -#define D_DELETE "Delete" -#define D_REPLY "Reply" -#define D_KNX_GROUP_ADDRESS_TO_READ "Group Addresses to Receive Data from" +#define D_CONFIGURE_KNX "Skonfiguruj KNX" +#define D_KNX_PARAMETERS "Parametry KNX" +#define D_KNX_GENERAL_CONFIG "Ogólne" +#define D_KNX_PHYSICAL_ADDRESS "Adres Fizyczny" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Musi być unikalny w sieci KNX )" +#define D_KNX_ENABLE "Włącz KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "Dane do wysłania do adresów grupowych" +#define D_ADD "Dodaj" +#define D_DELETE "Usuń" +#define D_REPLY "Odpowiedz" +#define D_KNX_GROUP_ADDRESS_TO_READ "Adresy grupowe do odbioru danych z" #define D_LOG_KNX "KNX: " -#define D_RECEIVED_FROM "Received from" -#define D_KNX_COMMAND_WRITE "Write" -#define D_KNX_COMMAND_READ "Read" -#define D_KNX_COMMAND_OTHER "Other" -#define D_SENT_TO "sent to" -#define D_KNX_WARNING "The group address ( 0 / 0 / 0 ) is reserved and can not be used." -#define D_KNX_ENHANCEMENT "Communication Enhancement" +#define D_RECEIVED_FROM "Otrzymane od" +#define D_KNX_COMMAND_WRITE "Zapisz" +#define D_KNX_COMMAND_READ "Czytaj" +#define D_KNX_COMMAND_OTHER "Inne" +#define D_SENT_TO "wysłane do" +#define D_KNX_WARNING "Adres grupy (0/0/0) jest zarezerwowany i nie można go użyć." +#define D_KNX_ENHANCEMENT "Usprawnienie Komunikacji" #define D_KNX_TX_SLOT "KNX TX" #define D_KNX_RX_SLOT "KNX RX" @@ -446,7 +446,7 @@ // xsns_18_pms5003.ino #define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter -#define D_PARTICALS_BEYOND "Particals" +#define D_PARTICALS_BEYOND "Cząstki" // xsns_32_mpu6050.ino #define D_AX_AXIS "Accel. X-Axis" @@ -457,23 +457,23 @@ #define D_GZ_AXIS "Gyro Z-Axis" // xsns_34_hx711.ino -#define D_HX_CAL_REMOVE "Remove weigth" -#define D_HX_CAL_REFERENCE "Load reference weigth" -#define D_HX_CAL_DONE "Calibrated" -#define D_HX_CAL_FAIL "Calibration failed" -#define D_RESET_HX711 "Reset Scale" -#define D_CONFIGURE_HX711 "Configure Scale" -#define D_HX711_PARAMETERS "Scale parameters" -#define D_ITEM_WEIGHT "Item weight" -#define D_REFERENCE_WEIGHT "Reference weigth" -#define D_CALIBRATE "Calibrate" -#define D_CALIBRATION "Calibration" +#define D_HX_CAL_REMOVE "Usuń wagę" +#define D_HX_CAL_REFERENCE "Załaduj masę referencyjną" +#define D_HX_CAL_DONE "Skalibrowany" +#define D_HX_CAL_FAIL "Błąd Kalibracji" +#define D_RESET_HX711 "Zresetuj Skalę" +#define D_CONFIGURE_HX711 "Skonfiguruj Skalę" +#define D_HX711_PARAMETERS "Parametry Skali" +#define D_ITEM_WEIGHT "Waga przedmiotu" +#define D_REFERENCE_WEIGHT "Waga referencyjna" +#define D_CALIBRATE "Skalibruj" +#define D_CALIBRATION "Kalibrowanie" //xsns_35_tx20.ino -#define D_TX20_WIND_DIRECTION "Wind Direction" -#define D_TX20_WIND_SPEED "Wind Speed" -#define D_TX20_WIND_SPEED_AVG "Wind Speed Avg" -#define D_TX20_WIND_SPEED_MAX "Wind Speed Max" +#define D_TX20_WIND_DIRECTION "Kierunek wiatru" +#define D_TX20_WIND_SPEED "Prędkość wiatru" +#define D_TX20_WIND_SPEED_AVG "Średnia prędkość wiatru" +#define D_TX20_WIND_SPEED_MAX "Maksymalna prędkość wiatru" #define D_TX20_NORTH "N" #define D_TX20_EAST "E" #define D_TX20_SOUTH "S" From dfa0d2ef11d539c5c78bcf5d8d1bfaf76c3b6aca Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Dec 2018 10:49:49 +0100 Subject: [PATCH 33/63] Add Domoticz Selector for Fanspeed Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) --- sonoff/_changelog.ino | 1 + sonoff/sonoff.h | 8 ++++-- sonoff/sonoff.ino | 10 +++----- sonoff/xdrv_01_webserver.ino | 2 +- sonoff/xdrv_02_mqtt.ino | 2 +- sonoff/xdrv_07_domoticz.ino | 49 ++++++++++++++++++++++++++---------- 6 files changed, 49 insertions(+), 23 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 3709195fe..22641b3bc 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -3,6 +3,7 @@ * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) * Update SR-04 driver to use NewPing library (#4488) * Add support for GPIO02 for newer Sonoff Basic (#4518) + * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) * * 6.3.0.14 20181127 * Add Command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 4a54f81be..71c761b28 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -74,6 +74,8 @@ typedef unsigned long power_t; // Power (Relay) type #define MAX_RULE_TIMERS 8 // Max number of rule timers (4 bytes / timer) #define MAX_RULE_VARS 5 // Max number of rule variables (10 bytes / variable) +#define MAX_FAN_SPEED 4 // Max number of iFan02 fan speeds (0 .. 3) + #define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x] #define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic #define MQTT_TOKEN_HOSTNAME "%hostname%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic @@ -245,12 +247,14 @@ enum XsnsFunctions {FUNC_SETTINGS_OVERRIDE, FUNC_MODULE_INIT, FUNC_PRE_INIT, FUN FUNC_RULES_PROCESS, FUNC_SERIAL, FUNC_FREE_MEM, FUNC_BUTTON_PRESSED, FUNC_WEB_ADD_BUTTON, FUNC_WEB_ADD_MAIN_BUTTON, FUNC_WEB_ADD_HANDLER}; -const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; - enum CommandSource { SRC_IGNORE, SRC_MQTT, SRC_RESTART, SRC_BUTTON, SRC_SWITCH, SRC_BACKLOG, SRC_SERIAL, SRC_WEBGUI, SRC_WEBCOMMAND, SRC_WEBCONSOLE, SRC_PULSETIMER, SRC_TIMER, SRC_RULE, SRC_MAXPOWER, SRC_MAXENERGY, SRC_LIGHT, SRC_KNX, SRC_DISPLAY, SRC_WEMO, SRC_HUE, SRC_RETRY, SRC_MAX }; const char kCommandSource[] PROGMEM = "I|MQTT|Restart|Button|Switch|Backlog|Serial|WebGui|WebCommand|WebConsole|PulseTimer|Timer|Rule|MaxPower|MaxEnergy|Light|Knx|Display|Wemo|Hue|Retry"; +const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; + +const uint8_t kIFan02Speed[MAX_FAN_SPEED][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6,7}}; // Do not use PROGMEM as it fails + /*********************************************************************************************\ * Extern global variables \*********************************************************************************************/ diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 869eaf7eb..379cc1d12 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -91,8 +91,6 @@ const char kTasmotaCommands[] PROGMEM = const char kSleepMode[] PROGMEM = "Dynamic|Normal"; -const uint8_t kIFan02Speed[4][3] = {{6,6,6}, {7,6,6}, {7,7,6}, {7,6,7}}; - // Global variables SerialConfig serial_config = SERIAL_8N1; // Serial interface configuration 8 data bits, No parity, 1 stop bit @@ -390,7 +388,7 @@ uint8_t GetFanspeed(void) void SetFanspeed(uint8_t fanspeed) { - for (byte i = 0; i < 3; i++) { + for (byte i = 0; i < MAX_FAN_SPEED -1; i++) { uint8_t state = kIFan02Speed[fanspeed][i]; // uint8_t state = pgm_read_byte(kIFan02Speed +(speed *3) +i); ExecuteCommandPower(i +2, state, SRC_IGNORE); // Use relay 2, 3 and 4 @@ -566,14 +564,14 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) if (data_len > 0) { if ('-' == dataBuf[0]) { payload = (int16_t)GetFanspeed() -1; - if (payload < 0) { payload = 3; } + if (payload < 0) { payload = MAX_FAN_SPEED -1; } } else if ('+' == dataBuf[0]) { payload = GetFanspeed() +1; - if (payload > 3) { payload = 0; } + if (payload > MAX_FAN_SPEED -1) { payload = 0; } } } - if ((payload >= 0) && (payload <= 3) && (payload != GetFanspeed())) { + if ((payload >= 0) && (payload < MAX_FAN_SPEED) && (payload != GetFanspeed())) { SetFanspeed(payload); } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, GetFanspeed()); diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index cd0204a48..b5c73aea5 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -628,7 +628,7 @@ void HandleRoot(void) if (SONOFF_IFAN02 == Settings.module) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_DEVICE_CONTROL, 36, 1, D_BUTTON_TOGGLE, ""); page += mqtt_data; - for (byte i = 0; i < 4; i++) { + for (byte i = 0; i < MAX_FAN_SPEED; i++) { snprintf_P(stemp, sizeof(stemp), PSTR("%d"), i); snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_DEVICE_CONTROL, 16, i +2, stemp, ""); page += mqtt_data; diff --git a/sonoff/xdrv_02_mqtt.ino b/sonoff/xdrv_02_mqtt.ino index 2e026c71f..77153abfd 100644 --- a/sonoff/xdrv_02_mqtt.ino +++ b/sonoff/xdrv_02_mqtt.ino @@ -334,7 +334,7 @@ void MqttPublishPowerState(byte device) if ((device < 1) || (device > devices_present)) { device = 1; } if ((SONOFF_IFAN02 == Settings.module) && (device > 1)) { - if (GetFanspeed() < 4) { // 4 occurs when fanspeed is 3 and RC button 2 is pressed + if (GetFanspeed() < MAX_FAN_SPEED) { // 4 occurs when fanspeed is 3 and RC button 2 is pressed snprintf_P(scommand, sizeof(scommand), PSTR(D_CMND_FANSPEED)); GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, scommand, GetFanspeed()); diff --git a/sonoff/xdrv_07_domoticz.ino b/sonoff/xdrv_07_domoticz.ino index 40c3127ec..3e2170701 100644 --- a/sonoff/xdrv_07_domoticz.ino +++ b/sonoff/xdrv_07_domoticz.ino @@ -73,16 +73,25 @@ int DomoticzRssiQuality(void) void MqttPublishDomoticzPowerState(byte device) { - char sdimmer[8]; + char svalue[8]; // Dimmer or Fanspeed value - if ((device < 1) || (device > devices_present)) { - device = 1; - } - if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[device -1]) { - snprintf_P(sdimmer, sizeof(sdimmer), PSTR("%d"), Settings.light_dimmer); - snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, - Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? sdimmer : "", DomoticzBatteryQuality(), DomoticzRssiQuality()); - MqttPublish(domoticz_in_topic); + if (Settings.flag.mqtt_enabled) { + if ((device < 1) || (device > devices_present)) { device = 1; } + if ((SONOFF_IFAN02 == Settings.module) && Settings.domoticz_relay_idx[1] && (device > 1)) { // device (relay) 1 handled below + if (4 == device) { // Wait for device (relay) 4 to get valid GetFanspeed + uint8_t fan_speed = GetFanspeed(); + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), (int)fan_speed * 10); + snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, + Settings.domoticz_relay_idx[1], (0 == fan_speed) ? 0 : 2, svalue, DomoticzBatteryQuality(), DomoticzRssiQuality()); + MqttPublish(domoticz_in_topic); + } + } + else if (Settings.domoticz_relay_idx[device -1]) { + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer); + snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, + Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality()); + MqttPublish(domoticz_in_topic); + } } } @@ -182,7 +191,18 @@ boolean DomoticzMqttData(void) if (idx == Settings.domoticz_relay_idx[i]) { bool iscolordimmer = strcmp_P(domoticz["dtype"],PSTR("Color Switch")) == 0; snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), i +1); - if (iscolordimmer && 10 == nvalue) { // Color_SetColor + if ((SONOFF_IFAN02 == Settings.module) && (1 == i)) { // Idx 2 is fanspeed + int16_t svalue = 0; + if (domoticz.containsKey("svalue1")) { + svalue = domoticz["svalue1"]; + } else { + return 1; + } + snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_FANSPEED)); + snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), (nvalue == 2) ? svalue / 10 : 0); + found = 1; + } + else if (iscolordimmer && 10 == nvalue) { // Color_SetColor JsonObject& color = domoticz["Color"]; uint16_t level = nvalue = domoticz["svalue1"]; uint16_t r = color["r"]; r = r * level / 100; @@ -193,8 +213,9 @@ boolean DomoticzMqttData(void) snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_COLOR)); snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%02x%02x%02x%02x%02x"), r, g, b, cw, ww); found = 1; - } else if ((!iscolordimmer && 2 == nvalue) || // gswitch_sSetLevel - (iscolordimmer && 15 == nvalue)) { // Color_SetBrightnessLevel + } + else if ((!iscolordimmer && 2 == nvalue) || // gswitch_sSetLevel + (iscolordimmer && 15 == nvalue)) { // Color_SetBrightnessLevel if (domoticz.containsKey("svalue1")) { nvalue = domoticz["svalue1"]; } else { @@ -206,7 +227,8 @@ boolean DomoticzMqttData(void) snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_DIMMER)); snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), nvalue); found = 1; - } else if (1 == nvalue || 0 == nvalue) { + } + else if (1 == nvalue || 0 == nvalue) { if (((power >> i) &1) == (power_t)nvalue) { return 1; } @@ -422,6 +444,7 @@ void HandleDomoticzConfiguration(void) page.replace("{4", String((int)Settings.domoticz_switch_idx[i])); } page.replace("{1", String(i +1)); + if ((SONOFF_IFAN02 == Settings.module) && (1 == i)) { break; } } for (int i = 0; i < DZ_MAX_SENSORS; i++) { page += FPSTR(HTTP_FORM_DOMOTICZ_SENSOR); From e64c8d61c92d9fcd3e3963948fad040f3b607681 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Dec 2018 11:01:57 +0100 Subject: [PATCH 34/63] Update sonoff.ino --- sonoff/sonoff.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 947f5d165..2132a09b2 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1311,7 +1311,7 @@ boolean SendKey(byte key, byte device, byte state) if (Settings.flag.mqtt_enabled && MqttIsConnected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { if (!key && (device > devices_present)) device = 1; // Only allow number of buttons up to number of devices GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), - Settings.flag.device_index_enable)); // cmnd/switchtopic/POWERx + (key + Settings.flag.device_index_enable))); // cmnd/switchtopic/POWERx if (9 == state) { mqtt_data[0] = '\0'; } else { From 61aa428646b50fba4bf4d7a80ab9dd2683faaf4b Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Dec 2018 11:17:25 +0100 Subject: [PATCH 35/63] 6.3.0.16 - Bump version 6.3.0.16 20181201 * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) * Add Announce Switches to MQTT Discovery (#4531) --- sonoff/_changelog.ino | 9 ++++++--- sonoff/sonoff.ino | 6 +++--- sonoff/sonoff_version.h | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 22641b3bc..b962b13de 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,12 +1,15 @@ -/* 6.3.0.15 20181201 +/* 6.3.0.16 20181201 + * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) + * Add Announce Switches to MQTT Discovery (#4531) + * + * 6.3.0.15 20181201 * Removed command SetOption36 (#4497) * Add command SetOption60 0/1 to select dynamic sleep (0) or sleep (1) (#4497) * Update SR-04 driver to use NewPing library (#4488) * Add support for GPIO02 for newer Sonoff Basic (#4518) - * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) * * 6.3.0.14 20181127 - * Add Command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) + * Add command CalcRes to set number of decimals (0 - 7) used in commands ADD, SUB, MULT and SCALE (#4420) * Add support for SM Smart Wifi Dimmer PS-16-DZ (#4465) * Move some static (serial) buffers to dynamic buffers * Update display and epaper drivers diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index c9882902a..5260900a3 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1307,9 +1307,9 @@ boolean SendKey(byte key, byte device, byte state) char *tmp = (key) ? Settings.switch_topic : Settings.button_topic; Format(key_topic, tmp, sizeof(key_topic)); if (Settings.flag.mqtt_enabled && MqttIsConnected() && (strlen(key_topic) != 0) && strcmp(key_topic, "0")) { - if (!key && (device > devices_present)) device = 1; // Only allow number of buttons up to number of devices - GetTopic_P(stopic, CMND, key_topic, GetPowerDevice(scommand, device, sizeof(scommand), - (key + Settings.flag.device_index_enable))); // cmnd/switchtopic/POWERx + if (!key && (device > devices_present)) { device = 1; } // Only allow number of buttons up to number of devices + GetTopic_P(stopic, CMND, key_topic, + GetPowerDevice(scommand, device, sizeof(scommand), (key + Settings.flag.device_index_enable))); // cmnd/switchtopic/POWERx if (9 == state) { mqtt_data[0] = '\0'; } else { diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index d6b82d881..9c41f0220 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x0603000F +#define VERSION 0x06030010 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" From 9a3c3895fbc9cf1d98e3ca795a2d029b5e744c9c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Thu, 6 Dec 2018 15:03:42 +0100 Subject: [PATCH 36/63] Fix Domoticz Fanspeed Fix Domoticz Fanspeed --- sonoff/sonoff.ino | 3 ++ sonoff/xdrv_02_mqtt.ino | 5 ++- sonoff/xdrv_07_domoticz.ino | 67 +++++++++++++++++++++++++++---------- 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5260900a3..f979e15c5 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -393,6 +393,9 @@ void SetFanspeed(uint8_t fanspeed) // uint8_t state = pgm_read_byte(kIFan02Speed +(speed *3) +i); ExecuteCommandPower(i +2, state, SRC_IGNORE); // Use relay 2, 3 and 4 } +#ifdef USE_DOMOTICZ + DomoticzUpdateFanState(); // Command FanSpeed feedback +#endif // USE_DOMOTICZ } void SetPulseTimer(uint8_t index, uint16_t time) diff --git a/sonoff/xdrv_02_mqtt.ino b/sonoff/xdrv_02_mqtt.ino index 77153abfd..bc969d3f2 100644 --- a/sonoff/xdrv_02_mqtt.ino +++ b/sonoff/xdrv_02_mqtt.ino @@ -335,6 +335,9 @@ void MqttPublishPowerState(byte device) if ((SONOFF_IFAN02 == Settings.module) && (device > 1)) { if (GetFanspeed() < MAX_FAN_SPEED) { // 4 occurs when fanspeed is 3 and RC button 2 is pressed +#ifdef USE_DOMOTICZ + DomoticzUpdateFanState(); // RC Button feedback +#endif // USE_DOMOTICZ snprintf_P(scommand, sizeof(scommand), PSTR(D_CMND_FANSPEED)); GetTopic_P(stopic, STAT, mqtt_topic, (Settings.flag.mqtt_response) ? scommand : S_RSLT_RESULT); snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, scommand, GetFanspeed()); @@ -425,7 +428,7 @@ void MqttConnected(void) MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_INFO "3")); for (byte i = 1; i <= devices_present; i++) { MqttPublishPowerState(i); - if (SONOFF_IFAN02 == Settings.module) { break; } // Only report status of light relay + if (SONOFF_IFAN02 == Settings.module) { break; } // Report status of light relay only } if (Settings.tele_period) { tele_period = Settings.tele_period -9; } // Enable TelePeriod in 9 seconds rules_flag.system_boot = 1; diff --git a/sonoff/xdrv_07_domoticz.ino b/sonoff/xdrv_07_domoticz.ino index 3e2170701..3eb3fa275 100644 --- a/sonoff/xdrv_07_domoticz.ino +++ b/sonoff/xdrv_07_domoticz.ino @@ -42,8 +42,9 @@ char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC; char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC; boolean domoticz_subscribe = false; -int domoticz_update_timer = 0; byte domoticz_update_flag = 1; +int domoticz_update_timer = 0; +unsigned long fan_debounce = 0; // iFan02 state debounce timer int DomoticzBatteryQuality(void) { @@ -71,27 +72,45 @@ int DomoticzRssiQuality(void) return WifiGetRssiAsQuality(WiFi.RSSI()) / 10; } +void MqttPublishDomoticzFanState() +{ + if (Settings.flag.mqtt_enabled && Settings.domoticz_relay_idx[1]) { + char svalue[8]; // Fanspeed value + + int fan_speed = GetFanspeed(); + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), fan_speed * 10); + snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, + Settings.domoticz_relay_idx[1], (0 == fan_speed) ? 0 : 2, svalue, DomoticzBatteryQuality(), DomoticzRssiQuality()); + MqttPublish(domoticz_in_topic); + + fan_debounce = millis(); + } +} + +void DomoticzUpdateFanState() +{ + if (domoticz_update_flag) { + MqttPublishDomoticzFanState(); + } + domoticz_update_flag = 1; +} + void MqttPublishDomoticzPowerState(byte device) { - char svalue[8]; // Dimmer or Fanspeed value - if (Settings.flag.mqtt_enabled) { if ((device < 1) || (device > devices_present)) { device = 1; } - if ((SONOFF_IFAN02 == Settings.module) && Settings.domoticz_relay_idx[1] && (device > 1)) { // device (relay) 1 handled below - if (4 == device) { // Wait for device (relay) 4 to get valid GetFanspeed - uint8_t fan_speed = GetFanspeed(); - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), (int)fan_speed * 10); + if (Settings.domoticz_relay_idx[device -1]) { + if ((SONOFF_IFAN02 == Settings.module) && (device > 1)) { + // Fan handled by MqttPublishDomoticzFanState + } else { + char svalue[8]; // Dimmer value + + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer); snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, - Settings.domoticz_relay_idx[1], (0 == fan_speed) ? 0 : 2, svalue, DomoticzBatteryQuality(), DomoticzRssiQuality()); + Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality()); MqttPublish(domoticz_in_topic); } } - else if (Settings.domoticz_relay_idx[device -1]) { - snprintf_P(svalue, sizeof(svalue), PSTR("%d"), Settings.light_dimmer); - snprintf_P(mqtt_data, sizeof(mqtt_data), DOMOTICZ_MESSAGE, - Settings.domoticz_relay_idx[device -1], (power & (1 << (device -1))) ? 1 : 0, (light_type) ? svalue : "", DomoticzBatteryQuality(), DomoticzRssiQuality()); - MqttPublish(domoticz_in_topic); - } } } @@ -110,7 +129,12 @@ void DomoticzMqttUpdate(void) if (domoticz_update_timer <= 0) { domoticz_update_timer = Settings.domoticz_update_timer; for (byte i = 1; i <= devices_present; i++) { - MqttPublishDomoticzPowerState(i); + if ((SONOFF_IFAN02 == Settings.module) && (i > 1)) { + MqttPublishDomoticzFanState(); + break; + } else { + MqttPublishDomoticzPowerState(i); + } } } } @@ -192,14 +216,21 @@ boolean DomoticzMqttData(void) bool iscolordimmer = strcmp_P(domoticz["dtype"],PSTR("Color Switch")) == 0; snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), i +1); if ((SONOFF_IFAN02 == Settings.module) && (1 == i)) { // Idx 2 is fanspeed - int16_t svalue = 0; + uint8_t svalue = 0; if (domoticz.containsKey("svalue1")) { svalue = domoticz["svalue1"]; } else { return 1; } + svalue = (nvalue == 2) ? svalue / 10 : 0; + if (GetFanspeed() == svalue) { + return 1; // Stop loop as already set + } + if (TimePassedSince(fan_debounce) < 1000) { + return 1; // Stop loop if device in limbo + } snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_FANSPEED)); - snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), (nvalue == 2) ? svalue / 10 : 0); + snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), svalue); found = 1; } else if (iscolordimmer && 10 == nvalue) { // Color_SetColor @@ -230,7 +261,7 @@ boolean DomoticzMqttData(void) } else if (1 == nvalue || 0 == nvalue) { if (((power >> i) &1) == (power_t)nvalue) { - return 1; + return 1; // Stop loop } snprintf_P(XdrvMailbox.topic, XdrvMailbox.index, PSTR("/" D_CMND_POWER "%s"), (devices_present > 1) ? stemp1 : ""); snprintf_P(XdrvMailbox.data, XdrvMailbox.data_len, PSTR("%d"), nvalue); From 46816f2f07e930011fc4470756598d75908aa53b Mon Sep 17 00:00:00 2001 From: andrethomas Date: Fri, 7 Dec 2018 00:55:44 +0200 Subject: [PATCH 37/63] MCP230xx - Add Interrupt Retain --- sonoff/settings.h | 2 +- sonoff/xsns_29_mcp230xx.ino | 84 +++++++++++++++++++++++++++++++++++-- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/sonoff/settings.h b/sonoff/settings.h index 10e67e6a2..c773b3b86 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -156,7 +156,7 @@ typedef union { uint16_t int_report_mode : 2; // Interrupt reporting mode 0 = immediate telemetry & event, 1 = immediate event only, 2 = immediate telemetry only uint16_t int_report_defer : 4; // Number of interrupts to ignore until reporting (default 0, max 15) uint16_t int_count_en : 1; // Enable interrupt counter for this pin - uint16_t spare12 : 1; + uint16_t int_retain_flag : 1; // Report if interrupt occured for pin in next teleperiod uint16_t spare13 : 1; uint16_t spare14 : 1; uint16_t spare15 : 1; diff --git a/sonoff/xsns_29_mcp230xx.ino b/sonoff/xsns_29_mcp230xx.ino index 867fa54ec..64f3351a5 100644 --- a/sonoff/xsns_29_mcp230xx.ino +++ b/sonoff/xsns_29_mcp230xx.ino @@ -47,12 +47,15 @@ uint8_t mcp230xx_pincount = 0; uint8_t mcp230xx_int_en = 0; uint8_t mcp230xx_int_prio_counter = 0; uint8_t mcp230xx_int_counter_en = 0; +uint8_t mcp230xx_int_retainer_en = 0; uint8_t mcp230xx_int_sec_counter = 0; uint8_t mcp230xx_int_report_defer_counter[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; uint16_t mcp230xx_int_counter[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +uint8_t mcp230xx_int_retainer[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // Used to store if an interrupt occured that needs to be retained until teleperiod + unsigned long int_millis[16]; // To keep track of millis() since last interrupt const char MCP230XX_SENSOR_RESPONSE[] PROGMEM = "{\"Sensor29_D%i\":{\"MODE\":%i,\"PULL_UP\":\"%s\",\"INT_MODE\":\"%s\",\"STATE\":\"%s\"}}"; @@ -79,6 +82,20 @@ void MCP230xx_CheckForIntCounter(void) { } } +void MCP230xx_CheckForIntRetainer(void) { + uint8_t en = 0; + for (uint8_t ca=0;ca<16;ca++) { + if (Settings.mcp230xx_config[ca].int_retain_flag) { + en=1; + } + } + mcp230xx_int_retainer_en=en; + if (!mcp230xx_int_retainer_en) { // Interrupt counters are disabled, so we clear all the counters + for (uint8_t ca=0;ca<16;ca++) { + mcp230xx_int_retainer[ca] = 0; + } + } +} const char* ConvertNumTxt(uint8_t statu, uint8_t pinmod=0) { #ifdef USE_MCP230xx_OUTPUT @@ -177,7 +194,8 @@ void MCP230xx_ApplySettings(void) { int_millis[idx]=millis(); } mcp230xx_int_en = int_en; - MCP230xx_CheckForIntCounter(); // update register on whether or not we should be counting interrupts + MCP230xx_CheckForIntCounter(); // update register on whether or not we should be counting interrupts + MCP230xx_CheckForIntRetainer(); // update register on whether or not we should be retaining interrupt events for teleperiod } void MCP230xx_Detect(void) @@ -258,6 +276,13 @@ void MCP230xx_CheckForInterrupt(void) { } } } + // check if interrupt retain is used, if it is for this pin then we do not report immediately as it will be reported in teleperiod + if (report_int) { + if (Settings.mcp230xx_config[intp+(mcp230xx_port*8)].int_retain_flag) { + mcp230xx_int_retainer[intp+(mcp230xx_port*8)] = 1; + report_int = 0; // do not report for now + } + } if (Settings.mcp230xx_config[intp+(mcp230xx_port*8)].int_count_en) { // We do not want to report via tele or event if counting is enabled report_int = 0; } @@ -382,8 +407,8 @@ void MCP230xx_Reset(uint8_t pinmode) { Settings.mcp230xx_config[pinx].int_report_mode=3; // Disabled for pinmode 1, 5 and 6 (No interrupts there) } Settings.mcp230xx_config[pinx].int_report_defer=0; // Disabled - Settings.mcp230xx_config[pinx].int_count_en=0; // Disabled - Settings.mcp230xx_config[pinx].spare12=0; + Settings.mcp230xx_config[pinx].int_count_en=0; // Disabled by default + Settings.mcp230xx_config[pinx].int_retain_flag=0; // Disabled by default Settings.mcp230xx_config[pinx].spare13=0; Settings.mcp230xx_config[pinx].spare14=0; Settings.mcp230xx_config[pinx].spare15=0; @@ -544,6 +569,41 @@ bool MCP230xx_Command(void) { } } + if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 1),"INTRETAIN")) { + if (paramcount > 1) { + uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 2)); + if (pin < mcp230xx_pincount) { + if (pin == 0) { + if (!strcmp(subStr(sub_string, XdrvMailbox.data, ",", 2), "0")) validpin=true; + } else { + validpin = true; + } + } + if (validpin) { + if (paramcount > 2) { + uint8_t int_retain = atoi(subStr(sub_string, XdrvMailbox.data, ",", 3)); + if ((int_retain >= 0) && (int_retain <= 1)) { + Settings.mcp230xx_config[pin].int_retain_flag=int_retain; + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_INTCFG_RESPONSE,"INT_RETAIN",pin,Settings.mcp230xx_config[pin].int_retain_flag); + MCP230xx_CheckForIntRetainer(); + return serviced; + } else { + serviced=false; + return serviced; + } + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), MCP230XX_INTCFG_RESPONSE,"INT_RETAIN",pin,Settings.mcp230xx_config[pin].int_retain_flag); + return serviced; + } + } + serviced = false; + return serviced; + } else { + serviced = false; + return serviced; + } + } + uint8_t pin = atoi(subStr(sub_string, XdrvMailbox.data, ",", 1)); if (pin < mcp230xx_pincount) { @@ -703,6 +763,19 @@ void MCP230xx_Interrupt_Counter_Report(void) { mcp230xx_int_sec_counter = 0; } +void MCP230xx_Interrupt_Retain_Report(void) { + uint16_t retainresult = 0; + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_JSON_TIME "\":\"%s\",\"MCP_INTRETAIN\": {"), GetDateAndTime(DT_LOCAL).c_str()); + for (uint8_t pinx = 0;pinx < mcp230xx_pincount;pinx++) { + if (Settings.mcp230xx_config[pinx].int_retain_flag) { + snprintf_P(mqtt_data,sizeof(mqtt_data), PSTR("%s\"D%i\":%i,"),mqtt_data,pinx,mcp230xx_int_retainer[pinx]); + retainresult |= (((mcp230xx_int_retainer[pinx])&1) << pinx); + mcp230xx_int_retainer[pinx]=0; + } + } + snprintf_P(mqtt_data,sizeof(mqtt_data),PSTR("%s\"Value\":%u}}"),mqtt_data,retainresult); + MqttPublishPrefixTopic_P(TELE, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain); +} /*********************************************************************************************\ Interface @@ -724,6 +797,11 @@ boolean Xsns29(byte function) MCP230xx_Interrupt_Counter_Report(); } } + if (tele_period == 0) { + if (mcp230xx_int_retainer_en) { // We have pins configured for interrupt retain reporting + MCP230xx_Interrupt_Retain_Report(); + } + } #ifdef USE_MCP230xx_OUTPUT if (tele_period == 0) { MCP230xx_OutputTelemetry(); From 99e6d7f2ffbdbb6460ad23762fcb10a44657d1e0 Mon Sep 17 00:00:00 2001 From: Andre Thomas Date: Fri, 7 Dec 2018 01:09:33 +0200 Subject: [PATCH 38/63] MCP230xx driver - add interrupt retention MCP230xx driver - add interrupt retention over teleperiod. --- sonoff/_changelog.ino | 1 + 1 file changed, 1 insertion(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index b962b13de..cbad2b3c2 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,7 @@ /* 6.3.0.16 20181201 * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) * Add Announce Switches to MQTT Discovery (#4531) + * Update MCP230xx driver to support interrupt retention over teleperiod (#4547) * * 6.3.0.15 20181201 * Removed command SetOption36 (#4497) From fe9103eb684dd28cf8c16a88a51c0dc2c8e6e599 Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 7 Dec 2018 17:19:14 +0100 Subject: [PATCH 39/63] Fix HASS discovery of switches --- sonoff/xdrv_12_home_assistant.ino | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index b5d0c076c..2972d39ea 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -302,7 +302,8 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, } else { snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"BTN":"SW"); } - GetPowerDevice(value_template, device+1, sizeof(value_template), Settings.flag.device_index_enable); + GetPowerDevice(value_template, device+1, sizeof(value_template), + key + Settings.flag.device_index_enable); // Force index for Switch 1, Index on Button1 is controlled by Settings.flag.device_index_enable GetTopic_P(state_topic, CMND, topic, value_template); // State of button is sent as CMND TOGGLE, state of switch is sent as ON/OFF GetTopic_P(availability_topic, TELE, mqtt_topic, S_LWT); FindPrefix(state_topic, availability_topic, prefix); From d8cf001304fbdba5f5f4898fc7cb90bfaacbad7f Mon Sep 17 00:00:00 2001 From: Erik Date: Fri, 7 Dec 2018 21:32:01 +0100 Subject: [PATCH 40/63] Announce RGBW light, add 'White' command --- sonoff/i18n.h | 1 + sonoff/xdrv_04_light.ino | 12 +++++++++--- sonoff/xdrv_12_home_assistant.ino | 22 ++++++++++++++++++++++ 3 files changed, 32 insertions(+), 3 deletions(-) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 317e78712..40312fc5c 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -330,6 +330,7 @@ #define D_CMND_SPEED "Speed" #define D_CMND_WAKEUP "Wakeup" #define D_CMND_WAKEUPDURATION "WakeUpDuration" +#define D_CMND_WHITE "White" #define D_CMND_WIDTH "Width" // Commands xdrv_05_irremote.ino diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 829374d08..919657f56 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -58,11 +58,11 @@ enum LightCommands { CMND_COLOR, CMND_COLORTEMPERATURE, CMND_DIMMER, CMND_LED, CMND_LEDTABLE, CMND_FADE, CMND_PIXELS, CMND_RGBWWTABLE, CMND_ROTATION, CMND_SCHEME, CMND_SPEED, CMND_WAKEUP, CMND_WAKEUPDURATION, - CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA }; + CMND_WHITE, CMND_WIDTH, CMND_CHANNEL, CMND_HSBCOLOR, CMND_UNDOCA }; const char kLightCommands[] PROGMEM = D_CMND_COLOR "|" D_CMND_COLORTEMPERATURE "|" D_CMND_DIMMER "|" D_CMND_LED "|" D_CMND_LEDTABLE "|" D_CMND_FADE "|" D_CMND_PIXELS "|" D_CMND_RGBWWTABLE "|" D_CMND_ROTATION "|" D_CMND_SCHEME "|" D_CMND_SPEED "|" D_CMND_WAKEUP "|" D_CMND_WAKEUPDURATION "|" - D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ; + D_CMND_WHITE "|" D_CMND_WIDTH "|" D_CMND_CHANNEL "|" D_CMND_HSBCOLOR "|UNDOCA" ; struct LRgbColor { uint8_t R, G, B; @@ -1098,7 +1098,13 @@ boolean LightCommand(void) if (-1 == command_code) { serviced = false; // Unknown command } - else if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { + else if ((CMND_WHITE == command_code) && (light_subtype == LST_RGBW) && (XdrvMailbox.index == 1)) { + command_code = CMND_COLOR; + uint8_t value = atoi(XdrvMailbox.data); + snprintf_P(scolor, sizeof(scolor), PSTR("0,0,0,%d"), value*255/100); + XdrvMailbox.data = scolor; + } + if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { if (XdrvMailbox.data_len > 0) { valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len); if (valid_entry) { diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 2972d39ea..b000f0460 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -61,6 +61,12 @@ const char HASS_DISCOVER_LIGHT_COLOR[] PROGMEM = "\"rgb_state_topic\":\"%s\"," // stat/led2/RESULT "\"rgb_value_template\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\""; +const char HASS_DISCOVER_LIGHT_WHITE[] PROGMEM = + "%s,\"white_value_command_topic\":\"%s\"," // cmnd/led2/White + "\"white_value_state_topic\":\"%s\"," // stat/led2/RESULT + "\"white_value_scale\":100," + "\"white_value_template\":\"{{ value_json.Channel[3] }}\""; + const char HASS_DISCOVER_LIGHT_CT[] PROGMEM = "%s,\"color_temp_command_topic\":\"%s\"," // cmnd/led2/CT "\"color_temp_state_topic\":\"%s\"," // stat/led2/RESULT @@ -126,6 +132,12 @@ const char HASS_DISCOVER_LIGHT_COLOR_SHORT[] PROGMEM = "\"rgb_stat_t\":\"%s\"," // stat/led2/RESULT "\"rgb_val_tpl\":\"{{value_json." D_CMND_COLOR ".split(',')[0:3]|join(',')}}\""; +const char HASS_DISCOVER_LIGHT_WHITE_SHORT[] PROGMEM = + "%s,\"whit_val_cmd_t\":\"%s\"," // cmnd/led2/White + "\"whit_val_stat_t\":\"%s\"," // stat/led2/RESULT + "\"white_value_scale\":100," // (No abbreviation defined) + "\"whit_val_tpl\":\"{{ value_json.Channel[3] }}\""; + const char HASS_DISCOVER_LIGHT_CT_SHORT[] PROGMEM = "%s,\"clr_temp_cmd_t\":\"%s\"," // cmnd/led2/CT "\"clr_temp_stat_t\":\"%s\"," // stat/led2/RESULT @@ -258,6 +270,16 @@ void HAssAnnounceRelayLight(void) } } + if (LST_RGBW == light_subtype) { + char _white_temp_command_topic[TOPSZ]; + char *white_temp_command_topic = _white_temp_command_topic; + + GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE); + if (Settings.flag3.hass_short_discovery_msg) + Shorten(&white_temp_command_topic, prefix); + snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_LIGHT_WHITE_SHORT:HASS_DISCOVER_LIGHT_WHITE, + mqtt_data, white_temp_command_topic, state_topic); + } if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) { char _color_temp_command_topic[TOPSZ]; char *color_temp_command_topic = _color_temp_command_topic; From a65041fee50f960026d4f4dcd0efd826f01f0c62 Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 8 Dec 2018 08:44:59 +0100 Subject: [PATCH 41/63] Enabled forced local operation when button- or switchtopic is set --- sonoff/my_user_config.h | 1 + sonoff/settings.h | 2 +- sonoff/settings.ino | 1 + sonoff/sonoff.ino | 4 ++-- 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index ef81066f3..043a81111 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -96,6 +96,7 @@ #define MQTT_BUTTON_RETAIN 0 // [ButtonRetain] Button may send retain flag (0 = off, 1 = on) #define MQTT_POWER_RETAIN 0 // [PowerRetain] Power status message may send retain flag (0 = off, 1 = on) #define MQTT_SWITCH_RETAIN 0 // [SwitchRetain] Switch may send retain flag (0 = off, 1 = on) +#define MQTT_BUTTON_SWITCH_FORCE_LOCAL 0 // [SetOption61] Force local operation when button/switch topic is set (0 = off, 1 = on) #define MQTT_STATUS_OFF "OFF" // [StateText1] Command or Status result when turned off (needs to be a string like "0" or "Off") #define MQTT_STATUS_ON "ON" // [StateText2] Command or Status result when turned on (needs to be a string like "1" or "On") diff --git a/sonoff/settings.h b/sonoff/settings.h index c773b3b86..d18ab6886 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -74,7 +74,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t receive_raw : 1; // bit 8 (v6.3.0.11) uint32_t hass_tele_on_power : 1; // bit 9 (v6.3.0.13) uint32_t sleep_normal : 1; // bit 10 (v6.3.0.15) - SetOption60 - Enable normal sleep instead of dynamic sleep - uint32_t spare11 : 1; + uint32_t button_switch_force_local : 1;// bit 11 uint32_t spare12 : 1; uint32_t spare13 : 1; uint32_t spare14 : 1; diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 7f065b626..46c1d849d 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -486,6 +486,7 @@ void SettingsDefaultSet2(void) Settings.flag.mqtt_power_retain = MQTT_POWER_RETAIN; Settings.flag.mqtt_button_retain = MQTT_BUTTON_RETAIN; Settings.flag.mqtt_switch_retain = MQTT_SWITCH_RETAIN; + Settings.flag3.button_switch_force_local = MQTT_BUTTON_SWITCH_FORCE_LOCAL; // Settings.flag.mqtt_sensor_retain = 0; // Settings.flag.mqtt_offline = 0; // Settings.flag.mqtt_serial = 0; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index f979e15c5..ad14aeccd 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -1316,7 +1316,7 @@ boolean SendKey(byte key, byte device, byte state) if (9 == state) { mqtt_data[0] = '\0'; } else { - if ((!strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic)) && (2 == state)) { + if ((Settings.flag3.button_switch_force_local || !strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic)) && (2 == state)) { state = ~(power >> (device -1)) &1; } snprintf_P(mqtt_data, sizeof(mqtt_data), GetStateText(state)); @@ -1328,7 +1328,7 @@ boolean SendKey(byte key, byte device, byte state) #else MqttPublishDirect(stopic, (key) ? Settings.flag.mqtt_switch_retain : Settings.flag.mqtt_button_retain); #endif // USE_DOMOTICZ - result = true; + result = !Settings.flag3.button_switch_force_local; } else { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s%d\":{\"State\":%d}}"), (key) ? "Switch" : "Button", device, state); result = XdrvRulesProcess(); From ebf74ab424efc07624e28ffcf400f79d2b52929f Mon Sep 17 00:00:00 2001 From: Erik Date: Sat, 8 Dec 2018 09:43:48 +0100 Subject: [PATCH 42/63] Update Hass discovery --- sonoff/xdrv_12_home_assistant.ino | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 2972d39ea..a57de717b 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -345,9 +345,10 @@ void HAssAnnounceSwitches(void) // Check if MQTT message will be ON/OFF or TOGGLE if (Settings.switchmode[switch_index] == FOLLOW || Settings.switchmode[switch_index] == FOLLOW_INV || + Settings.flag3.button_switch_force_local || !strcmp(mqtt_topic, sw_topic) || !strcmp(Settings.mqtt_grptopic, sw_topic)) { - toggle = 0; + toggle = 0; // MQTT message will be ON/OFF } HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0, toggle); @@ -377,9 +378,10 @@ void HAssAnnounceButtons(void) } // Check if MQTT message will be ON/OFF or TOGGLE - if (!strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic)) + if (Settings.flag3.button_switch_force_local || + !strcmp(mqtt_topic, key_topic) || !strcmp(Settings.mqtt_grptopic, key_topic)) { - toggle = 0; + toggle = 0; // MQTT message will be ON/OFF } HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1, toggle); From ee35a949ca09fe627730f8419ef99d05a7fdcd18 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Sat, 8 Dec 2018 10:28:12 +0100 Subject: [PATCH 43/63] v2.1.0012 decode-config.py: add new settings - add 6.3.0.16 setting change --- tools/decode-config.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 1850e2aea..1691b455b 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.1.0011' +VER = '2.1.0012' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -803,7 +803,13 @@ Setting_6_3_0_15['flag3'][0].update ({ 'sleep_normal': (' Date: Sat, 8 Dec 2018 10:28:12 +0100 Subject: [PATCH 44/63] decode-config.py: add new settings - add 6.3.0.16 setting change --- tools/decode-config.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 1850e2aea..1691b455b 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.1.0011' +VER = '2.1.0012' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -803,7 +803,13 @@ Setting_6_3_0_15['flag3'][0].update ({ 'sleep_normal': (' Date: Sat, 8 Dec 2018 15:24:16 +0100 Subject: [PATCH 45/63] Fix reversed logic when announcing buttons / switches --- sonoff/xdrv_12_home_assistant.ino | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index 00492463e..a3b9bb659 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -301,6 +301,8 @@ void HAssAnnounceRelayLight(void) void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, byte toggle) { +// key 0 = button +// key 1 = switch char stopic[TOPSZ]; char sidx[8]; @@ -308,7 +310,7 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, // Clear or Set topic snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s_%s_%d/config"), - topic, key?"BTN":"SW",device+1); + topic, key?"SW":"BTN",device+1); if (Settings.flag.hass_discovery && present) { char name[33]; @@ -320,9 +322,9 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, char *availability_topic = _availability_topic; if (device+1 > MAX_FRIENDLYNAMES) { - snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"BTN":"SW", device+1); + snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"SW":"BTN", device+1); } else { - snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"BTN":"SW"); + snprintf_P(name, sizeof(name), PSTR("%s %s"), Settings.friendlyname[device], key?"SW":"BTN"); } GetPowerDevice(value_template, device+1, sizeof(value_template), key + Settings.flag.device_index_enable); // Force index for Switch 1, Index on Button1 is controlled by Settings.flag.device_index_enable @@ -373,7 +375,7 @@ void HAssAnnounceSwitches(void) toggle = 0; // MQTT message will be ON/OFF } - HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 0, toggle); + HAssAnnounceButtonSwitch(switch_index, sw_topic, switch_present, 1, toggle); } } } @@ -406,7 +408,7 @@ void HAssAnnounceButtons(void) toggle = 0; // MQTT message will be ON/OFF } - HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 1, toggle); + HAssAnnounceButtonSwitch(button_index, key_topic, button_present, 0, toggle); } } } From 140aa8780ac73d4b216fd731416238fe74478ae0 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 9 Dec 2018 09:34:22 +0100 Subject: [PATCH 46/63] add DMP mode to MPU-6050 --- sonoff/xsns_32_mpu6050.ino | 82 +++++++++++++++++++++++++++++++------- 1 file changed, 68 insertions(+), 14 deletions(-) diff --git a/sonoff/xsns_32_mpu6050.ino b/sonoff/xsns_32_mpu6050.ino index 0c6f50f09..7115800dd 100644 --- a/sonoff/xsns_32_mpu6050.ino +++ b/sonoff/xsns_32_mpu6050.ino @@ -19,6 +19,7 @@ #ifdef USE_I2C #ifdef USE_MPU6050 +#define USE_MPU6050_DMP // Use the DMP on the chip, should create better results /*********************************************************************************************\ * MPU6050 3 axis gyroscope and temperature sensor * @@ -42,11 +43,49 @@ int16_t MPU_6050_ax = 0, MPU_6050_ay = 0, MPU_6050_az = 0; int16_t MPU_6050_gx = 0, MPU_6050_gy = 0, MPU_6050_gz = 0; int16_t MPU_6050_temperature = 0; -#include +#ifdef USE_MPU6050_DMP + #include "MPU6050_6Axis_MotionApps20.h" + #include "I2Cdev.h" + #include + typedef struct MPU6050_DMP{ + uint8_t devStatus; // return status after each device operation (0 = success, !0 = error) + uint16_t packetSize; // expected DMP packet size (default is 42 bytes) + uint16_t fifoCount; // count of all bytes currently in FIFO + uint8_t fifoBuffer[64]; // FIFO storage buffer + Quaternion q; // [w, x, y, z] quaternion container + VectorInt16 aa; // [x, y, z] accel sensor measurements + VectorInt16 aaReal; // [x, y, z] gravity-free accel sensor measurements + VectorFloat gravity; // [x, y, z] gravity vector + float euler[3]; // [psi, theta, phi] Euler angle container + } MPU6050_DMP; + + MPU6050_DMP MPU6050_dmp; +#else + #include +#endif //USE_MPU6050_DMP MPU6050 mpu6050; void MPU_6050PerformReading(void) { +#ifdef USE_MPU6050_DMP + mpu6050.resetFIFO(); // with a default dampling rate of 200Hz, we create a delay of approx. 5ms with a complete read cycle + MPU6050_dmp.fifoCount = mpu6050.getFIFOCount(); + while (MPU6050_dmp.fifoCount < MPU6050_dmp.packetSize) MPU6050_dmp.fifoCount = mpu6050.getFIFOCount(); + mpu6050.getFIFOBytes(MPU6050_dmp.fifoBuffer, MPU6050_dmp.packetSize); + MPU6050_dmp.fifoCount -= MPU6050_dmp.packetSize; + // calculate euler and acceleration with the DMP + mpu6050.dmpGetQuaternion(&MPU6050_dmp.q, MPU6050_dmp.fifoBuffer); + mpu6050.dmpGetEuler(MPU6050_dmp.euler, &MPU6050_dmp.q); + mpu6050.dmpGetAccel(&MPU6050_dmp.aa, MPU6050_dmp.fifoBuffer); + mpu6050.dmpGetGravity(&MPU6050_dmp.gravity, &MPU6050_dmp.q); + mpu6050.dmpGetLinearAccel(&MPU6050_dmp.aaReal, &MPU6050_dmp.aa, &MPU6050_dmp.gravity); + MPU_6050_gx = MPU6050_dmp.euler[0] * 180/M_PI; + MPU_6050_gy = MPU6050_dmp.euler[1] * 180/M_PI; + MPU_6050_gz = MPU6050_dmp.euler[2] * 180/M_PI; + MPU_6050_ax = MPU6050_dmp.aaReal.x; + MPU_6050_ay = MPU6050_dmp.aaReal.y; + MPU_6050_az = MPU6050_dmp.aaReal.z; +#else mpu6050.getMotion6( &MPU_6050_ax, &MPU_6050_ay, @@ -55,7 +94,7 @@ void MPU_6050PerformReading(void) &MPU_6050_gy, &MPU_6050_gz ); - +#endif //USE_MPU6050_DMP MPU_6050_temperature = mpu6050.getTemperature(); } @@ -84,14 +123,30 @@ void MPU_6050Detect(void) for (byte i = 0; i < sizeof(MPU_6050_addresses); i++) { + if(!I2cDevice(MPU_6050_addresses[i])) + { + break; + } MPU_6050_address = MPU_6050_addresses[i]; + mpu6050.setAddr(MPU_6050_addresses[i]); - mpu6050.setAddr(MPU_6050_address); +#ifdef USE_MPU6050_DMP + MPU6050_dmp.devStatus = mpu6050.dmpInitialize(); + mpu6050.setXGyroOffset(220); + mpu6050.setYGyroOffset(76); + mpu6050.setZGyroOffset(-85); + mpu6050.setZAccelOffset(1788); + if (MPU6050_dmp.devStatus == 0) { + mpu6050.setDMPEnabled(true); + MPU6050_dmp.packetSize = mpu6050.dmpGetFIFOPacketSize(); + MPU_6050_found = true; + } +#else mpu6050.initialize(); - + MPU_6050_found = mpu6050.testConnection(); +#endif //USE_MPU6050_DMP Settings.flag2.axis_resolution = 2; // Need to be services by command Sensor32 - MPU_6050_found = mpu6050.testConnection(); } if (MPU_6050_found) @@ -119,11 +174,10 @@ const char HTTP_SNS_GZ_AXIS[] PROGMEM = "%s{s}%s " D_GZ_AXIS "{m}%s{e}"; void MPU_6050Show(boolean json) { - double tempConv = (MPU_6050_temperature / 340.0 + 35.53); - if (MPU_6050_found) { MPU_6050PerformReading(); + double tempConv = (MPU_6050_temperature / 340.0 + 35.53); char temperature[10]; dtostrfd(tempConv, Settings.flag2.temperature_resolution, temperature); char axis_ax[10]; @@ -140,20 +194,20 @@ void MPU_6050Show(boolean json) dtostrfd(MPU_6050_gz, Settings.flag2.axis_resolution, axis_gz); if (json) { - char json_axis_ax[40]; + char json_axis_ax[25]; snprintf_P(json_axis_ax, sizeof(json_axis_ax), PSTR(",\"" D_JSON_AXIS_AX "\":%s"), axis_ax); - char json_axis_ay[40]; + char json_axis_ay[25]; snprintf_P(json_axis_ay, sizeof(json_axis_ay), PSTR(",\"" D_JSON_AXIS_AY "\":%s"), axis_ay); - char json_axis_az[40]; + char json_axis_az[25]; snprintf_P(json_axis_az, sizeof(json_axis_az), PSTR(",\"" D_JSON_AXIS_AZ "\":%s"), axis_az); - char json_axis_gx[40]; + char json_axis_gx[25]; snprintf_P(json_axis_gx, sizeof(json_axis_gx), PSTR(",\"" D_JSON_AXIS_GX "\":%s"), axis_gx); - char json_axis_gy[40]; + char json_axis_gy[25]; snprintf_P(json_axis_gy, sizeof(json_axis_gy), PSTR(",\"" D_JSON_AXIS_GY "\":%s"), axis_gy); - char json_axis_gz[40]; + char json_axis_gz[25]; snprintf_P(json_axis_gz, sizeof(json_axis_gz), PSTR(",\"" D_JSON_AXIS_GZ "\":%s"), axis_gz); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s%s%s%s%s%s}"), - mqtt_data, D_SENSOR_MPU6050, temperature, json_axis_ax, json_axis_ay, json_axis_az, json_axis_gx, json_axis_gy, json_axis_gz); + mqtt_data, D_SENSOR_MPU6050, temperature, json_axis_ax, json_axis_ay, json_axis_az, json_axis_gx, json_axis_gy, json_axis_gz); #ifdef USE_DOMOTICZ DomoticzTempHumSensor(temperature, 0); #endif // USE_DOMOTICZ From aab716798a2abe1c83bac0b6eab2b0f4f6094970 Mon Sep 17 00:00:00 2001 From: Staars Date: Sun, 9 Dec 2018 09:35:23 +0100 Subject: [PATCH 47/63] fix compile issue on ESP8266 --- lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h b/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h index 1f7b88589..46920438a 100644 --- a/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h +++ b/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h @@ -46,7 +46,11 @@ THE SOFTWARE. // Tom Carpenter's conditional PROGMEM code // http://forum.arduino.cc/index.php?topic=129407.0 #ifndef __arm__ - #include + #if (defined(__AVR__)) + #include + #else + #include + #endif #else // Teensy 3.0 library conditional PROGMEM code from Paul Stoffregen #ifndef __PGMSPACE_H_ @@ -402,7 +406,7 @@ uint8_t MPU6050::dmpInitialize() { setIntEnabled(0x12); DEBUG_PRINTLN(F("Setting sample rate to 200Hz...")); - setRate(4); // 1khz / (1 + 4) = 200 Hz + setRate(1); // 1khz / (1 + 4) = 200 Hz DEBUG_PRINTLN(F("Setting external frame sync to TEMP_OUT_L[0]...")); setExternalFrameSync(MPU6050_EXT_SYNC_TEMP_OUT_L); From a516b25c1bb6452ab7d5c31882936eb011784050 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 9 Dec 2018 16:45:26 +0100 Subject: [PATCH 48/63] Clean and shrink lights Clean and shrink lights --- sonoff/xdrv_04_light.ino | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/sonoff/xdrv_04_light.ino b/sonoff/xdrv_04_light.ino index 919657f56..6fad79fe3 100644 --- a/sonoff/xdrv_04_light.ino +++ b/sonoff/xdrv_04_light.ino @@ -590,7 +590,7 @@ void LightState(uint8_t append) // Add status for each channel snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_CMND_CHANNEL "\":[" ), mqtt_data); for (byte i = 0; i < light_subtype; i++) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d" ), mqtt_data, (i > 0 ? "," : ""), round(light_current_color[i]/2.55)); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s%s%d" ), mqtt_data, (i > 0 ? "," : ""), light_current_color[i] * 100 / 255); } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s]" ), mqtt_data); } @@ -1084,7 +1084,6 @@ boolean LightColorEntry(char *buffer, uint8_t buffer_length) /********************************************************************************************/ -//boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t XdrvMailbox.data_len, int16_t XdrvMailbox.payload) boolean LightCommand(void) { char command [CMDSZ]; @@ -1098,13 +1097,17 @@ boolean LightCommand(void) if (-1 == command_code) { serviced = false; // Unknown command } - else if ((CMND_WHITE == command_code) && (light_subtype == LST_RGBW) && (XdrvMailbox.index == 1)) { - command_code = CMND_COLOR; - uint8_t value = atoi(XdrvMailbox.data); - snprintf_P(scolor, sizeof(scolor), PSTR("0,0,0,%d"), value*255/100); - XdrvMailbox.data = scolor; - } - if ((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) { + else if (((CMND_COLOR == command_code) && (light_subtype > LST_SINGLE) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= 6)) || + ((CMND_WHITE == command_code) && (light_subtype == LST_RGBW) && (XdrvMailbox.index == 1))) { + if (CMND_WHITE == command_code) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { + snprintf_P(scolor, sizeof(scolor), PSTR("0,0,0,%d"), XdrvMailbox.payload * 255 / 100); + XdrvMailbox.data = scolor; + XdrvMailbox.data_len = strlen(scolor); + } else { + XdrvMailbox.data_len = 0; + } + } if (XdrvMailbox.data_len > 0) { valid_entry = LightColorEntry(XdrvMailbox.data, XdrvMailbox.data_len); if (valid_entry) { @@ -1142,12 +1145,11 @@ boolean LightCommand(void) else if ((CMND_CHANNEL == command_code) && (XdrvMailbox.index > 0) && (XdrvMailbox.index <= light_subtype ) ) { // Set "Channel" directly - this allows Color and Direct PWM control to coexist if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 100)) { - uint8_t level = XdrvMailbox.payload; - light_current_color[XdrvMailbox.index-1] = round(level * 2.55); + light_current_color[XdrvMailbox.index-1] = XdrvMailbox.payload * 255 / 100; LightSetColor(); coldim = true; } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, round(light_current_color[XdrvMailbox.index -1] / 2.55)); + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_NVALUE, command, XdrvMailbox.index, light_current_color[XdrvMailbox.index -1] * 100 / 255); } else if ((CMND_HSBCOLOR == command_code) && ( light_subtype >= LST_RGB)) { bool validHSB = (XdrvMailbox.data_len > 0); From 9f515c6c08e02931f94f38cacb1a450a0f282baf Mon Sep 17 00:00:00 2001 From: Erik Date: Mon, 10 Dec 2018 19:51:47 +0100 Subject: [PATCH 49/63] Add support for device registry --- sonoff/xdrv_12_home_assistant.ino | 113 +++++++++++++++++------------- 1 file changed, 66 insertions(+), 47 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index a3b9bb659..c21749dc2 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -44,7 +44,7 @@ const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM = "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM = - "%s,\"force_update\":true"; + "%s,\"off_delay\":1"; const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM = "%s,\"payload_off\":\"%s\""; // OFF @@ -114,7 +114,7 @@ const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM = "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT[] PROGMEM = - "%s,\"frc_upd\":true"; + "%s,\"off_delay\":1"; const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT[] PROGMEM = "%s,\"pl_off\":\"%s\""; // OFF @@ -168,6 +168,14 @@ const char HASS_DISCOVER_SENSOR_HUM_SHORT[] PROGMEM = const char HASS_DISCOVER_SENSOR_ANY_SHORT[] PROGMEM = "%s,\"val_tpl\":\"{{value_json['%s'].%s}}\""; // "COUNTER":{"C1":0} -> {{ value_json['COUNTER'].C1 }} +const char HASS_DISCOVER_DEVICE_INFO_SHORT[] PROGMEM = + "%s,\"uniq_id\":\"%s\"," + "\"device\":{\"identifiers\":[\"%06X\"]," + "\"name\":\"%s\"," + "\"model\":\"%s\"," + "\"sw_version\":\"%s%s\"," + "\"manufacturer\":\"%s\"}"; + const char HASS_DISCOVER_TOPIC_PREFIX[] PROGMEM = "%s, \"~\":\"%s\""; @@ -193,8 +201,11 @@ static void Shorten(char** s, char *prefix) void HAssAnnounceRelayLight(void) { - char sidx[8]; char stopic[TOPSZ]; + char stemp1[TOPSZ]; + char stemp2[TOPSZ]; + char stemp3[TOPSZ]; + char unique_id[30]; bool is_light = false; bool is_topic_light = false; @@ -204,23 +215,21 @@ void HAssAnnounceRelayLight(void) mqtt_data[0] = '\0'; // Clear retained message - snprintf_P(sidx, sizeof(sidx), PSTR("_%d"), i); - // Clear "other" topic first in case the device has been reconfigured - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_topic_light) ? "switch" : "light", mqtt_topic, sidx); + // Clear "other" topic first in case the device has been reconfigured from ligth to switch or vice versa + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "RL" : "LI", i); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "switch" : "light", unique_id); MqttPublish(stopic, true); // Clear or Set topic - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s%s/config"), (is_topic_light) ? "light" : "switch", mqtt_topic, sidx); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), (is_topic_light) ? "LI" : "RL", i); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/%s/%s/config"), (is_topic_light) ? "light" : "switch", unique_id); if (Settings.flag.hass_discovery && (i <= devices_present)) { char name[33]; char value_template[33]; - char _command_topic[TOPSZ]; - char _state_topic[TOPSZ]; - char _availability_topic[TOPSZ]; char prefix[TOPSZ]; - char *command_topic = _command_topic; - char *state_topic = _state_topic; - char *availability_topic = _availability_topic; + char *command_topic = stemp1; + char *state_topic = stemp2; + char *availability_topic = stemp3; if (i > MAX_FRIENDLYNAMES) { snprintf_P(name, sizeof(name), PSTR("%s %d"), Settings.friendlyname[0], i); @@ -242,8 +251,7 @@ void HAssAnnounceRelayLight(void) name, command_topic, state_topic, value_template, Settings.state_text[0], Settings.state_text[1], availability_topic); if (is_light) { - char _brightness_command_topic[TOPSZ]; - char *brightness_command_topic = _brightness_command_topic; + char *brightness_command_topic = stemp1; GetTopic_P(brightness_command_topic, CMND, mqtt_topic, D_CMND_DIMMER); if (Settings.flag3.hass_short_discovery_msg) @@ -252,8 +260,7 @@ void HAssAnnounceRelayLight(void) mqtt_data, brightness_command_topic, state_topic); if (light_subtype >= LST_RGB) { - char _rgb_command_topic[TOPSZ]; - char *rgb_command_topic = _rgb_command_topic; + char *rgb_command_topic = stemp1; GetTopic_P(rgb_command_topic, CMND, mqtt_topic, D_CMND_COLOR); if (Settings.flag3.hass_short_discovery_msg) @@ -261,8 +268,7 @@ void HAssAnnounceRelayLight(void) snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_LIGHT_COLOR_SHORT:HASS_DISCOVER_LIGHT_COLOR, mqtt_data, rgb_command_topic, state_topic); - char _effect_command_topic[TOPSZ]; - char *effect_command_topic = _effect_command_topic; + char *effect_command_topic = stemp1; GetTopic_P(effect_command_topic, CMND, mqtt_topic, D_CMND_SCHEME); if (Settings.flag3.hass_short_discovery_msg) { Shorten(&effect_command_topic, prefix); @@ -271,8 +277,7 @@ void HAssAnnounceRelayLight(void) } if (LST_RGBW == light_subtype) { - char _white_temp_command_topic[TOPSZ]; - char *white_temp_command_topic = _white_temp_command_topic; + char *white_temp_command_topic = stemp1; GetTopic_P(white_temp_command_topic, CMND, mqtt_topic, D_CMND_WHITE); if (Settings.flag3.hass_short_discovery_msg) @@ -281,8 +286,7 @@ void HAssAnnounceRelayLight(void) mqtt_data, white_temp_command_topic, state_topic); } if ((LST_COLDWARM == light_subtype) || (LST_RGBWC == light_subtype)) { - char _color_temp_command_topic[TOPSZ]; - char *color_temp_command_topic = _color_temp_command_topic; + char *color_temp_command_topic = stemp1; GetTopic_P(color_temp_command_topic, CMND, mqtt_topic, D_CMND_COLORTEMPERATURE); if (Settings.flag3.hass_short_discovery_msg) @@ -291,8 +295,13 @@ void HAssAnnounceRelayLight(void) mqtt_data, color_temp_command_topic, state_topic); } } - if (Settings.flag3.hass_short_discovery_msg) + if (Settings.flag3.hass_short_discovery_msg) { + snprintf_P(stemp1, sizeof(stemp1), kModules[Settings.module].name); + snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId(), + Settings.friendlyname[0], stemp1, my_version, my_image, "Tasmota"); snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); @@ -304,22 +313,22 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, // key 0 = button // key 1 = switch char stopic[TOPSZ]; - char sidx[8]; + char stemp1[TOPSZ]; + char stemp2[TOPSZ]; + char unique_id[30]; mqtt_data[0] = '\0'; // Clear retained message // Clear or Set topic - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s_%s_%d/config"), - topic, key?"SW":"BTN",device+1); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%d"), ESP.getChipId(), key?"SW":"BTN", device+1); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/binary_sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery && present) { char name[33]; char value_template[33]; - char _state_topic[TOPSZ]; - char _availability_topic[TOPSZ]; char prefix[TOPSZ]; - char *state_topic = _state_topic; - char *availability_topic = _availability_topic; + char *state_topic = stemp1; + char *availability_topic = stemp2; if (device+1 > MAX_FRIENDLYNAMES) { snprintf_P(name, sizeof(name), PSTR("%s %s %d"), Settings.friendlyname[0], key?"SW":"BTN", device+1); @@ -338,14 +347,19 @@ void HAssAnnounceButtonSwitch(byte device, char* topic, byte present, byte key, snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_SHORT:HASS_DISCOVER_BUTTON_SWITCH, name, state_topic, Settings.state_text[toggle?2:1], availability_topic); if (toggle) snprintf_P(mqtt_data, sizeof(mqtt_data), - Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT:HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, - mqtt_data); - else snprintf_P(mqtt_data, sizeof(mqtt_data), - Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT:HASS_DISCOVER_BUTTON_SWITCH_ONOFF, - mqtt_data, Settings.state_text[0]); + Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT:HASS_DISCOVER_BUTTON_SWITCH_TOGGLE, + mqtt_data); + if (!toggle) snprintf_P(mqtt_data, sizeof(mqtt_data), + Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT:HASS_DISCOVER_BUTTON_SWITCH_ONOFF, + mqtt_data, Settings.state_text[0]); - if (Settings.flag3.hass_short_discovery_msg) + if (Settings.flag3.hass_short_discovery_msg) { + snprintf_P(stemp1, sizeof(stemp1), kModules[Settings.module].name); + snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId(), + Settings.friendlyname[0], stemp1, my_version, my_image, "Tasmota"); snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); @@ -382,7 +396,6 @@ void HAssAnnounceSwitches(void) void HAssAnnounceButtons(void) { - char stopic[TOPSZ]; char key_topic[sizeof(Settings.button_topic)]; // Send info about buttons @@ -416,21 +429,22 @@ void HAssAnnounceButtons(void) void HAssAnnounceSensor(const char* sensorname, const char* subsensortype) { char stopic[TOPSZ]; + char stemp1[TOPSZ]; + char stemp2[TOPSZ]; + char unique_id[30]; // Announce sensor, special handling of temperature and humidity sensors mqtt_data[0] = '\0'; // Clear retained message // Clear or Set topic - snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s_%s_%s/config"), - mqtt_topic, sensorname, subsensortype); + snprintf_P(unique_id, sizeof(unique_id), PSTR("%06X_%s_%s"), ESP.getChipId(), sensorname, subsensortype); + snprintf_P(stopic, sizeof(stopic), PSTR(HOME_ASSISTANT_DISCOVERY_PREFIX "/sensor/%s/config"), unique_id); if (Settings.flag.hass_discovery) { char name[33]; - char _state_topic[TOPSZ]; - char _availability_topic[TOPSZ]; char prefix[TOPSZ]; - char *state_topic = _state_topic; - char *availability_topic = _availability_topic; + char *state_topic = stemp1; + char *availability_topic = stemp2; snprintf_P(name, sizeof(name), PSTR("%s %s %s"), Settings.friendlyname[0], sensorname, subsensortype); GetTopic_P(state_topic, TELE, mqtt_topic, PSTR(D_RSLT_SENSOR)); @@ -442,18 +456,23 @@ void HAssAnnounceSensor(const char* sensorname, const char* subsensortype) } snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SENSOR_SHORT:HASS_DISCOVER_SENSOR, name, state_topic, availability_topic); - if (!strcmp(subsensortype, "Temperature")) { + if (!strcmp_P(subsensortype, PSTR(D_JSON_HUMIDITY))) { snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SENSOR_TEMP_SHORT:HASS_DISCOVER_SENSOR_TEMP, mqtt_data, TempUnit(), sensorname); - } else if (!strcmp(subsensortype, "Humidity")) { + } else if (!strcmp_P(subsensortype, PSTR(D_JSON_HUMIDITY))) { snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SENSOR_HUM_SHORT:HASS_DISCOVER_SENSOR_HUM, mqtt_data, sensorname); } else { snprintf_P(mqtt_data, sizeof(mqtt_data), Settings.flag3.hass_short_discovery_msg?HASS_DISCOVER_SENSOR_ANY_SHORT:HASS_DISCOVER_SENSOR_ANY, mqtt_data, sensorname, subsensortype); } - if (Settings.flag3.hass_short_discovery_msg) + if (Settings.flag3.hass_short_discovery_msg) { + snprintf_P(stemp1, sizeof(stemp1), kModules[Settings.module].name); + snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_DEVICE_INFO_SHORT, mqtt_data, + unique_id, ESP.getChipId(), + Settings.friendlyname[0], stemp1, my_version, my_image, "Tasmota"); snprintf_P(mqtt_data, sizeof(mqtt_data), HASS_DISCOVER_TOPIC_PREFIX, mqtt_data, prefix); + } snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data); } MqttPublish(stopic, true); From 4fb6773ffbed6a1f6f00cf8cc76e913a8320d5f6 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Mon, 10 Dec 2018 19:28:22 +0000 Subject: [PATCH 50/63] Update my_user_config.h --- sonoff/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index ef81066f3..cade32e94 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -312,7 +312,7 @@ // #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz // #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) // #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) -// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+2k6 code) +// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+12KB of code and 188 Bytes RAM) // #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) // #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 // #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) From a75bc93634dd54a8b6b2b3f0b3c05394e2c6aaf0 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Mon, 10 Dec 2018 19:43:19 +0000 Subject: [PATCH 51/63] Fix Warning in Platformio if building MPU and KNX together --- lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h b/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h index 46920438a..90704f0c7 100644 --- a/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h +++ b/lib/I2Cdevlib-MPU6050/MPU6050_6Axis_MotionApps20.h @@ -113,11 +113,19 @@ THE SOFTWARE. #define DEBUG_PRINTLN(x) Serial.println(x) #define DEBUG_PRINTLNF(x, y) Serial.println(x, y) #else +#ifndef DEBUG_PRINT #define DEBUG_PRINT(x) +#endif +#ifndef DEBUG_PRINTF #define DEBUG_PRINTF(x, y) +#endif +#ifndef DEBUG_PRINTLN #define DEBUG_PRINTLN(x) +#endif +#ifndef DEBUG_PRINTLNF #define DEBUG_PRINTLNF(x, y) #endif +#endif #define MPU6050_DMP_CODE_SIZE 1929 // dmpMemory[] #define MPU6050_DMP_CONFIG_SIZE 192 // dmpConfig[] From 384cc5cb16838e4845a4ade9bf792a117eafd716 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Mon, 10 Dec 2018 20:03:36 +0000 Subject: [PATCH 52/63] USE_MPU6050_DMP moved to my_user_config.h --- sonoff/my_user_config.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index cade32e94..048519bb2 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -312,7 +312,8 @@ // #define USE_PCA9685_FREQ 50 // Define default PWM frequency in Hz to be used (must be within 24 to 1526) - If other value is used, it will rever to 50Hz // #define USE_MPR121 // Enable MPR121 controller (I2C addresses 0x5A, 0x5B, 0x5C and 0x5D) in input mode for touch buttons (+1k3 code) // #define USE_CCS811 // Enable CCS811 sensor (I2C address 0x5A) (+2k2 code) -// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+12KB of code and 188 Bytes RAM) +// #define USE_MPU6050 // Enable MPU6050 sensor (I2C address 0x68 AD0 low or 0x69 AD0 high) (+3K3 of code and 188 Bytes of RAM) +// #define USE_MPU6050_DMP // Enable in MPU6050 to use the DMP on the chip, should create better results (+8k6 of code) // #define USE_DS3231 // Enable DS3231 external RTC in case no Wifi is avaliable. See docs in the source file (+1k2 code) // #define USE_RTC_ADDR 0x68 // Default I2C address 0x68 // #define USE_MGC3130 // Enable MGC3130 Electric Field Effect Sensor (I2C address 0x42) (+2k7 code, 0k3 mem) From e5d3c3b793680e16cde728a149c2bc7efc339955 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Mon, 10 Dec 2018 20:04:48 +0000 Subject: [PATCH 53/63] USE_MPU6050_DMP moved to my_user_config.h --- sonoff/xsns_32_mpu6050.ino | 1 - 1 file changed, 1 deletion(-) diff --git a/sonoff/xsns_32_mpu6050.ino b/sonoff/xsns_32_mpu6050.ino index 7115800dd..6a6d5a1df 100644 --- a/sonoff/xsns_32_mpu6050.ino +++ b/sonoff/xsns_32_mpu6050.ino @@ -19,7 +19,6 @@ #ifdef USE_I2C #ifdef USE_MPU6050 -#define USE_MPU6050_DMP // Use the DMP on the chip, should create better results /*********************************************************************************************\ * MPU6050 3 axis gyroscope and temperature sensor * From bc30a18adee249703847a0a4a143dd5cea430dc2 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <39969427+ascillato2@users.noreply.github.com> Date: Tue, 11 Dec 2018 00:57:41 +0000 Subject: [PATCH 54/63] Corrected Domoticz Temp published from MPU6050 --- sonoff/xsns_32_mpu6050.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_32_mpu6050.ino b/sonoff/xsns_32_mpu6050.ino index 6a6d5a1df..b80366194 100644 --- a/sonoff/xsns_32_mpu6050.ino +++ b/sonoff/xsns_32_mpu6050.ino @@ -208,7 +208,7 @@ void MPU_6050Show(boolean json) snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s%s%s%s%s%s}"), mqtt_data, D_SENSOR_MPU6050, temperature, json_axis_ax, json_axis_ay, json_axis_az, json_axis_gx, json_axis_gy, json_axis_gz); #ifdef USE_DOMOTICZ - DomoticzTempHumSensor(temperature, 0); + DomoticzSensor(DZ_TEMP, temperature); #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { From 9c69701af3fb401f3044cf529f3d169c9b58b117 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Tue, 11 Dec 2018 08:19:04 +0100 Subject: [PATCH 55/63] decode-config.py: add new settings - add SetOption61 from PR #4562 --- tools/decode-config.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 1691b455b..d03e9eaee 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.1.0012' +VER = '2.1.0013' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -807,6 +807,9 @@ Setting_6_3_0_16 = copy.deepcopy(Setting_6_3_0_15) Setting_6_3_0_16['mcp230xx_config'][0].update ({ 'int_retain_flag': (' Date: Tue, 11 Dec 2018 13:12:19 +0100 Subject: [PATCH 56/63] Update my_user_config.h --- sonoff/my_user_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 987b3ca32..24c35a91b 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -354,7 +354,7 @@ #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) #define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) -#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) +//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) #define USE_SDM220 // add extra parameters for SDM220 (+0k1 code) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) From a913c4459aa39d41186504bc9e6fd6ec69d697bc Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 11 Dec 2018 13:58:37 +0100 Subject: [PATCH 57/63] Fix language file Fix language file --- sonoff/language/sv-SE.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index db8f663a1..abaa994db 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -515,8 +515,8 @@ #define D_SENSOR_SBR_TX "SerBr Tx" #define D_SENSOR_SR04_TRIG "SR04 Tri" #define D_SENSOR_SR04_ECHO "SR04 Ech" -#define D_SENSOR_SDM120_TX "SDM120 Tx" -#define D_SENSOR_SDM120_RX "SDM120 Rx" +#define D_SENSOR_SDM120_TX "SDM120/220 Tx" +#define D_SENSOR_SDM120_RX "SDM120/220 Rx" #define D_SENSOR_SDM630_TX "SDM630 Tx" #define D_SENSOR_SDM630_RX "SDM630 Rx" #define D_SENSOR_TM1638_CLK "TM16 CLK" @@ -594,4 +594,13 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +#define D_PHASE_ANGLE "Phase Angle" +#define D_IMPORT_ACTIVE "Import Active" +#define D_EXPORT_ACTIVE "Export Active" +#define D_IMPORT_REACTIVE "Import Reactive" +#define D_EXPORT_REACTIVE "Export Reactive" +#define D_TOTAL_REACTIVE "Total Reactive" +#define D_UNIT_KWARH "kVArh" +#define D_UNIT_ANGLE "Deg" + #endif // _LANGUAGE_SV_SE_H_ From 67ec0678a3ea07c8b3d5aca1fecdbe30bd54bb16 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 11 Dec 2018 14:24:52 +0100 Subject: [PATCH 58/63] 6.3.0.17 Add features 6.3.0.17 20181211 * Add support for TheoV2 sensors as documented on https://sidweb.nl * Add support for SDM220 (#3610) * Enhance support for MPU6050 using DMP (#4581) --- sonoff/_changelog.ino | 7 +- sonoff/i18n.h | 13 +- sonoff/language/bg-BG.h | 1 + sonoff/language/cs-CZ.h | 1 + sonoff/language/de-DE.h | 1 + sonoff/language/el-GR.h | 1 + sonoff/language/en-GB.h | 3 +- sonoff/language/es-AR.h | 1 + sonoff/language/fr-FR.h | 1 + sonoff/language/he-HE.h | 1 + sonoff/language/hu-HU.h | 1 + sonoff/language/it-IT.h | 1 + sonoff/language/nl-NL.h | 1 + sonoff/language/pl-PL.h | 1 + sonoff/language/pt-BR.h | 1 + sonoff/language/pt-PT.h | 2 +- sonoff/language/ru-RU.h | 1 + sonoff/language/sv-SE.h | 3 +- sonoff/language/tr-TR.h | 1 + sonoff/language/uk-UK.h | 1 + sonoff/language/zh-CN.h | 1 + sonoff/language/zh-TW.h | 1 + sonoff/my_user_config.h | 6 +- sonoff/sonoff.ino | 1 + sonoff/sonoff_template.h | 7 +- sonoff/sonoff_version.h | 2 +- sonoff/support_features.ino | 13 +- sonoff/support_rtc.ino | 40 +-- sonoff/xsns_10_bh1750.ino | 5 - sonoff/xsns_37_rfsensor.ino | 634 ++++++++++++++++++++++++++++++++++++ tools/decode-status.py | 4 +- 31 files changed, 714 insertions(+), 43 deletions(-) create mode 100644 sonoff/xsns_37_rfsensor.ino diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index cbad2b3c2..4ca0e0dd7 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,9 @@ -/* 6.3.0.16 20181201 +/* 6.3.0.17 20181211 + * Add support for TheoV2 sensors as documented on https://sidweb.nl + * Add support for SDM220 (#3610) + * Enhance support for MPU6050 using DMP (#4581) + * + * 6.3.0.16 20181201 * Add support for iFan02 Fanspeed in Domoticz using a selector (#4517) * Add Announce Switches to MQTT Discovery (#4531) * Update MCP230xx driver to support interrupt retention over teleperiod (#4547) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 66ee5e490..b1bec3289 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -49,12 +49,6 @@ #define D_JSON_COUNT "Count" #define D_JSON_COUNTER "Counter" #define D_JSON_CURRENT "Current" // As in Voltage and Current -#define D_JSON_PHASE_ANGLE "Phase angle" -#define D_JSON_IMPORT_ACTIVE "Import Active Power" -#define D_JSON_EXPORT_ACTIVE "Export Active Power" -#define D_JSON_IMPORT_REACTIVE "Import Reactive Power" -#define D_JSON_EXPORT_REACTIVE "Export Reactive Power" -#define D_JSON_TOTAL_REACTIVE "Total Reactive Power" #define D_JSON_DATA "Data" #define D_JSON_DISTANCE "Distance" #define D_JSON_DNSSERVER "DNSServer" @@ -65,6 +59,8 @@ #define D_JSON_ERASE "Erase" #define D_JSON_ERROR "Error" #define D_JSON_EVERY "Every" +#define D_JSON_EXPORT_ACTIVE "ExportActivePower" +#define D_JSON_EXPORT_REACTIVE "ExportReactivePower" #define D_JSON_FAILED "Failed" #define D_JSON_FALLBACKTOPIC "FallbackTopic" #define D_JSON_FEATURES "Features" @@ -86,6 +82,8 @@ #define D_JSON_I2CSCAN_NO_DEVICES_FOUND "No devices found" #define D_JSON_ID "Id" #define D_JSON_ILLUMINANCE "Illuminance" +#define D_JSON_IMPORT_ACTIVE "ImportActivePower" +#define D_JSON_IMPORT_REACTIVE "ImportReactivePower" #define D_JSON_INFRARED "Infrared" #define D_JSON_UNKNOWN "Unknown" #define D_JSON_LIGHT "Light" @@ -99,6 +97,7 @@ #define D_JSON_NONE "None" #define D_JSON_OR "or" #define D_JSON_PERIOD "Period" +#define D_JSON_PHASE_ANGLE "PhaseAngle" #define D_JSON_POWERFACTOR "Factor" #define D_JSON_POWERUSAGE "Power" #define D_JSON_ACTIVE_POWERUSAGE "ActivePower" @@ -135,6 +134,7 @@ #define D_JSON_TIME "Time" #define D_JSON_TODAY "Today" #define D_JSON_TOTAL "Total" +#define D_JSON_TOTAL_REACTIVE "TotalReactivePower" #define D_JSON_TOTAL_START_TIME "TotalStartTime" #define D_JSON_TVOC "TVOC" #define D_JSON_TYPE "Type" @@ -546,6 +546,7 @@ const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%%{e}"; const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s %s{e}"; // {s} = , {m} = , {e} = const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s %s{e}"; // {s} = , {m} = , {e} = const char HTTP_SNS_ANALOG[] PROGMEM = "%s{s}%s " D_ANALOG_INPUT "%d{m}%d{e}"; // {s} = , {m} = , {e} = +const char HTTP_SNS_ILLUMINANCE[] PROGMEM = "%s{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = , {m} = , {e} = #if defined(USE_MHZ19) || defined(USE_SENSEAIR) const char HTTP_SNS_CO2[] PROGMEM = "%s{s}%s " D_CO2 "{m}%d " D_UNIT_PARTS_PER_MILLION "{e}"; // {s} = , {m} = , {e} = diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 9cad9f63f..9ed4734a8 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index ffd69a714..8bcde604b 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 69f12e56e..21f7e5dd8 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index bafc460c4..e59855a24 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 4cb1d381e..a38664d2f 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -536,7 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" - +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" @@ -594,6 +594,7 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 #define D_PHASE_ANGLE "Phase Angle" #define D_IMPORT_ACTIVE "Import Active" #define D_EXPORT_ACTIVE "Export Active" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index c0d8885a5..7039d66a6 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index b6dc5132f..a038153c9 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 2039683a4..6f3612fb7 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 8fefbfa7d..82c911fb1 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index da2f91107..b971d1c02 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index c8a32a463..73a201448 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 2a26afa78..e4728bda8 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 4bad901e7..487f4793d 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index a0ec3643b..4b2366758 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -536,7 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" - +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index ac7b5ea16..e2e6079cd 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index abaa994db..9ec54c62b 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -536,7 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" - +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" @@ -594,6 +594,7 @@ #define D_LOG_UPNP "UPP: " // UPnP #define D_LOG_WIFI "WIF: " // Wifi +//SDM220 #define D_PHASE_ANGLE "Phase Angle" #define D_IMPORT_ACTIVE "Import Active" #define D_EXPORT_ACTIVE "Export Active" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index cee31869f..4425431ee 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "A" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 281975c07..82449858e 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "А" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index f882765a5..f1ba0c93d 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 6a9b9bd52..3a9d12336 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -536,6 +536,7 @@ #define D_SENSOR_SSPI_SCLK "SSPI SCLK" #define D_SENSOR_SSPI_CS "SSPI CS" #define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" // Units #define D_UNIT_AMPERE "安" diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index a9caabdb8..3a35b7d33 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -357,7 +357,7 @@ #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) //#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) - #define USE_SDM220 // add extra parameters for SDM220 (+0k1 code) + #define USE_SDM220 // Add extra parameters for SDM220 (+0k1 code) //#define USE_SDM630 // Add support for Eastron SDM630-Modbus energy meter (+2k code) #define SDM630_SPEED 9600 // SDM630-Modbus RS485 serial speed (default: 9600 baud) //#define USE_MP3_PLAYER // Use of the DFPlayer Mini MP3 Player RB-DFR-562 commands: play, volume and stop @@ -399,6 +399,10 @@ #define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) +//#define USE_RF_SENSOR // Add support for RF (434MHz or 868MHz) receiver (+2k code) +// #define USE_THEO_V2 // Add support for 434MHz Theo V2 sensors as documented on https://sidweb.nl +// #define USE_ALECTO_V2 // Add support for 868MHz Alecto V2 sensors like ACH2010, WS3000 and DKW2012 + /*********************************************************************************************\ * Debug features are only supported in development branch \*********************************************************************************************/ diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index ad14aeccd..8e4006ca1 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -2766,6 +2766,7 @@ void loop(void) uint32_t my_sleep = millis(); XdrvCall(FUNC_LOOP); + XsnsCall(FUNC_LOOP); OsWatchLoop(); diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 225d3767a..f3b366d38 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -140,6 +140,7 @@ enum UserSelectablePins { GPIO_SSPI_SCLK, // Software SPI Serial Clock GPIO_SSPI_CS, // Software SPI Chip Select GPIO_SSPI_DC, // Software SPI Data or Command + GPIO_RF_SENSOR, // Rf receiver with sensor decoding GPIO_SENSOR_END }; // Programmer selectable GPIO functionality offset by user selectable GPIOs @@ -199,7 +200,8 @@ const char kSensorNames[] PROGMEM = D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|" D_SENSOR_TUYA_TX "|" D_SENSOR_TUYA_RX "|" D_SENSOR_MGC3130_XFER "|" D_SENSOR_MGC3130_RESET "|" - D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC; + D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" + D_SENSOR_RF_SENSOR; /********************************************************************************************/ @@ -382,6 +384,9 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_RFSEND, // RF transmitter GPIO_RFRECV, // RF receiver #endif +#ifdef USE_RF_SENSOR + GPIO_RF_SENSOR, // Rf receiver with sensor decoding +#endif #ifdef USE_SR04 GPIO_SR04_TRIG, // SR04 Trigger pin GPIO_SR04_ECHO, // SR04 Echo pin diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 9c41f0220..ed771e734 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06030010 +#define VERSION 0x06030011 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support_features.ino b/sonoff/support_features.ino index 8859cca55..652116b2f 100644 --- a/sonoff/support_features.ino +++ b/sonoff/support_features.ino @@ -361,10 +361,15 @@ void GetFeatures(void) #ifdef USE_MGC3130 feature_sns2 |= 0x00004000; // xsns_36_mgc3130.ino #endif - -// feature_sns2 |= 0x00008000; -// feature_sns2 |= 0x00010000; -// feature_sns2 |= 0x00020000; +#ifdef USE_RF_SENSOR + feature_sns2 |= 0x00008000; // xsns_37_rfsensor.ino +#endif +#ifdef USE_THEO_V2 + feature_sns2 |= 0x00010000; +#endif +#ifdef USE_ALECTO_V2 + feature_sns2 |= 0x00020000; +#endif // feature_sns2 |= 0x00040000; // feature_sns2 |= 0x00080000; // feature_sns2 |= 0x00100000; diff --git a/sonoff/support_rtc.ino b/sonoff/support_rtc.ino index 4ba0747a5..b09c593e2 100644 --- a/sonoff/support_rtc.ino +++ b/sonoff/support_rtc.ino @@ -87,6 +87,20 @@ String GetTimeZone(void) return String(tz); // -03:45 } +String GetDT(uint32_t time) +{ + // "2017-03-07T11:08:02" - ISO8601:2004 + + char dt[20]; + TIME_T tmpTime; + + BreakTime(time, tmpTime); + snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"), + tmpTime.year +1970, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); + + return String(dt); // 2017-03-07T11:08:02 +} + /* * timestamps in https://en.wikipedia.org/wiki/ISO_8601 format * @@ -101,39 +115,27 @@ String GetTimeZone(void) String GetDateAndTime(byte time_type) { // "2017-03-07T11:08:02-07:00" - ISO8601:2004 - char dt[27]; - TIME_T tmpTime; + uint32_t time = local_time; switch (time_type) { case DT_ENERGY: - BreakTime(Settings.energy_kWhtotal_time, tmpTime); - tmpTime.year += 1970; + time = Settings.energy_kWhtotal_time; break; case DT_UTC: - BreakTime(utc_time, tmpTime); - tmpTime.year += 1970; + time = utc_time; break; case DT_RESTART: if (restart_time == 0) { return ""; } - BreakTime(restart_time, tmpTime); - tmpTime.year += 1970; + time = restart_time; break; - default: - tmpTime = RtcTime; } - - - snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"), - tmpTime.year, tmpTime.month, tmpTime.day_of_month, tmpTime.hour, tmpTime.minute, tmpTime.second); - + String dt = GetDT(time); // 2017-03-07T11:08:02 if (Settings.flag3.time_append_timezone && (DT_LOCAL == time_type)) { -// if (Settings.flag3.time_append_timezone && ((DT_LOCAL == time_type) || (DT_ENERGY == time_type))) { - strncat(dt, GetTimeZone().c_str(), sizeof(dt) - strlen(dt) -1); + dt += GetTimeZone(); // 2017-03-07T11:08:02-07:00 } - - return String(dt); // 2017-03-07T11:08:02-07:00 + return dt; // 2017-03-07T11:08:02-07:00 } String GetTime(int type) diff --git a/sonoff/xsns_10_bh1750.ino b/sonoff/xsns_10_bh1750.ino index c93a3513f..af0d1aebb 100644 --- a/sonoff/xsns_10_bh1750.ino +++ b/sonoff/xsns_10_bh1750.ino @@ -89,11 +89,6 @@ void Bh1750EverySecond(void) } } -#ifdef USE_WEBSERVER -const char HTTP_SNS_ILLUMINANCE[] PROGMEM = - "%s{s}%s " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = , {m} = , {e} = -#endif // USE_WEBSERVER - void Bh1750Show(boolean json) { if (bh1750_valid) { diff --git a/sonoff/xsns_37_rfsensor.ino b/sonoff/xsns_37_rfsensor.ino new file mode 100644 index 000000000..63c567839 --- /dev/null +++ b/sonoff/xsns_37_rfsensor.ino @@ -0,0 +1,634 @@ +/* + xsns_37_rfsensor.ino - RF sensor receiver for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_RF_SENSOR +/*********************************************************************************************\ + * RF receive based on work by Paul Tonkes (www.nodo-domotica.nl) + * + * USE_THEO_V2 Add support for 434MHz Theo V2 sensors as documented on https://sidweb.nl + * USE_ALECTO_V2 Add support for 868MHz Alecto V2 sensors like ACH2010, WS3000 and DKW2012 +\*********************************************************************************************/ + +#define XSNS_37 37 + +//#define USE_THEO_V2 // Add support for 434MHz Theo V2 sensors as documented on https://sidweb.nl +//#define USE_ALECTO_V2 // Add support for 868MHz Alecto V2 sensors like ACH2010, WS3000 and DKW2012 + +#define RFSNS_VALID_WINDOW 1800 // Number of seconds for sensor to respond (1800 = 30 minutes) + +#define RFSNS_LOOPS_PER_MILLI 1900 // (345 voor 16MHz ATMega) Voor 80MHz NodeMCU (ESP-12E). Getest met TheoV2 Protocol. +#define RFSNS_RAW_BUFFER_SIZE 180 // (256) Maximum number of RF pulses that can be captured +#define RFSNS_MIN_RAW_PULSES 112 // (16) =8 bits. Minimaal aantal ontvangen bits*2 alvorens cpu tijd wordt besteed aan decodering, etc. + // Zet zo hoog mogelijk om CPU-tijd te sparen en minder 'onzin' te ontvangen. +#define RFSNS_MIN_PULSE_LENGTH 300 // (50) Pulsen korter dan deze tijd uSec. worden als stoorpulsen beschouwd. +#define RFSNS_RAWSIGNAL_SAMPLE 50 // Sample grootte / Resolutie in uSec waarmee ontvangen Rawsignalen pulsen worden opgeslagen +#define RFSNS_SIGNAL_TIMEOUT 10 // Pulse timings in mSec. Beyond this value indicate end of message +#define RFSNS_SIGNAL_REPEAT_TIME 500 // (500) Tijd in mSec. waarbinnen hetzelfde event niet nogmaals via RF mag binnenkomen. Onderdrukt ongewenste herhalingen van signaal + +struct RawSignalStruct // Variabelen geplaatst in struct zodat deze later eenvoudig kunnen worden weggeschreven naar SDCard +{ + int Number; // aantal bits, maal twee omdat iedere bit een mark en een space heeft. + byte Repeats; // Aantal maal dat de pulsreeks verzonden moet worden bij een zendactie. + byte Multiply; // Pulses[] * Multiply is de echte tijd van een puls in microseconden + unsigned long Time; // Tijdstempel wanneer signaal is binnengekomen (millis()) + byte Pulses[RFSNS_RAW_BUFFER_SIZE+2]; // Tabel met de gemeten pulsen in microseconden gedeeld door rfsns_raw_signal.Multiply. Dit scheelt helft aan RAM geheugen. + // Om legacy redenen zit de eerste puls in element 1. Element 0 wordt dus niet gebruikt. +} rfsns_raw_signal = {0, 0, 0, 0L}; + +uint8_t rfsns_rf_bit; +uint8_t rfsns_rf_port; + +/*********************************************************************************************\ + * Fetch signals from RF pin +\*********************************************************************************************/ + +boolean RfSnsFetchSignal(byte DataPin, boolean StateSignal) +{ + uint8_t Fbit = digitalPinToBitMask(DataPin); + uint8_t Fport = digitalPinToPort(DataPin); + uint8_t FstateMask = (StateSignal ? Fbit : 0); + + if ((*portInputRegister(Fport) & Fbit) == FstateMask) { // Als er signaal is + const unsigned long LoopsPerMilli = RFSNS_LOOPS_PER_MILLI; + + // Als het een herhalend signaal is, dan is de kans groot dat we binnen hele korte tijd weer in deze + // routine terugkomen en dan midden in de volgende herhaling terecht komen. Daarom wordt er in dit + // geval gewacht totdat de pulsen voorbij zijn en we met het capturen van data beginnen na een korte + // rust tussen de signalen. Op deze wijze wordt het aantal zinloze captures teruggebracht. + + unsigned long PulseLength = 0; + if (rfsns_raw_signal.Time) { // Eerst een snelle check, want dit bevindt zich in een tijdkritisch deel... + if (rfsns_raw_signal.Repeats && (rfsns_raw_signal.Time + RFSNS_SIGNAL_REPEAT_TIME) > millis()) { // ...want deze check duurt enkele micro's langer! + PulseLength = micros() + RFSNS_SIGNAL_TIMEOUT *1000; // Wachttijd + while (((rfsns_raw_signal.Time + RFSNS_SIGNAL_REPEAT_TIME) > millis()) && (PulseLength > micros())) { + if ((*portInputRegister(Fport) & Fbit) == FstateMask) { + PulseLength = micros() + RFSNS_SIGNAL_TIMEOUT *1000; + } + } + while (((rfsns_raw_signal.Time + RFSNS_SIGNAL_REPEAT_TIME) > millis()) && ((*portInputRegister(Fport) & Fbit) != FstateMask)); + } + } + + int RawCodeLength = 1; // We starten bij 1, dit om legacy redenen. Vroeger had element 0 een speciaal doel. + bool Ftoggle = false; + unsigned long numloops = 0; + unsigned long maxloops = RFSNS_SIGNAL_TIMEOUT * LoopsPerMilli; + rfsns_raw_signal.Multiply = RFSNS_RAWSIGNAL_SAMPLE; // Ingestelde sample groote. + do { // lees de pulsen in microseconden en plaats deze in de tijdelijke buffer rfsns_raw_signal + numloops = 0; + while(((*portInputRegister(Fport) & Fbit) == FstateMask) ^ Ftoggle) { // while() loop *A* + if (numloops++ == maxloops) { break; } // timeout opgetreden + } + PulseLength = (numloops *1000) / LoopsPerMilli; // Bevat nu de pulslengte in microseconden + if (PulseLength < RFSNS_MIN_PULSE_LENGTH) { break; } + Ftoggle = !Ftoggle; + rfsns_raw_signal.Pulses[RawCodeLength++] = PulseLength / (unsigned long)rfsns_raw_signal.Multiply; // sla op in de tabel rfsns_raw_signal + } + while(RawCodeLength < RFSNS_RAW_BUFFER_SIZE && numloops <= maxloops); // Zolang nog ruimte in de buffer, geen timeout en geen stoorpuls + + if ((RawCodeLength >= RFSNS_MIN_RAW_PULSES) && (RawCodeLength < RFSNS_RAW_BUFFER_SIZE -1)) { + rfsns_raw_signal.Repeats = 0; // Op dit moment weten we nog niet het type signaal, maar de variabele niet ongedefinieerd laten. + rfsns_raw_signal.Number = RawCodeLength -1; // Aantal ontvangen tijden (pulsen *2) + rfsns_raw_signal.Pulses[rfsns_raw_signal.Number] = 0; // Laatste element bevat de timeout. Niet relevant. + rfsns_raw_signal.Time = millis(); + return true; + } + else + rfsns_raw_signal.Number = 0; + } + + return false; +} + +#ifdef USE_THEO_V2 +/*********************************************************************************************\ + * Theo V2 protocol + * Dit protocol zorgt voor ontvangst van Theo sensoren met protocol V2 + * + * Auteur : Theo Arends + * Support : www.sidweb.nl + * Datum : 17 Apr 2014 + * Versie : 0.1 - Initiele versie + ********************************************************************************************** + * Technische informatie: + * + * Theo Sensor V2 type 1 Message Format (7 Bytes, 57 bits): + * Checksum Type Chl BsVoltag Temperature Light + * S AAAAAAAA BBBBBCCC DEFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH HHHHHHHH + * idx: 0 1 2 3 4 5 6 + * + * Theo Sensor V2 type 2 Message Format (7 Bytes, 57 bits): + * Checksum Type Chl BsVoltag Temperature Humidity + * S AAAAAAAA BBBBBCCC DEFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH HHHHHHHH + * idx: 0 1 2 3 4 5 6 +\*********************************************************************************************/ + +#define RFSNS_THEOV2_MAX_CHANNEL 2 // Max number of ATTiny sensor channels supported + +#define RFSNS_THEOV2_PULSECOUNT 114 +#define RFSNS_THEOV2_RF_PULSE_MID 1000 // PWM: Pulsen langer zijn '1' + +typedef struct { + uint32_t time; + int16_t temp; + uint16_t lux; + uint8_t volt; +} theo_v2_t1_t; + +theo_v2_t1_t rfsns_theo_v2_t1[RFSNS_THEOV2_MAX_CHANNEL]; + +typedef struct { + uint32_t time; + int16_t temp; + uint16_t hum; + uint8_t volt; +} theo_v2_t2_t; + +theo_v2_t2_t rfsns_theo_v2_t2[RFSNS_THEOV2_MAX_CHANNEL]; + +boolean RfSnsAnalyzeTheov2(void) +{ + if (rfsns_raw_signal.Number != RFSNS_THEOV2_PULSECOUNT) return false; + + byte Checksum; // 8 bits Checksum over following bytes + byte Channel; // 3 bits channel + byte Type; // 5 bits type + byte Voltage; // 8 bits Vcc like 45 = 4.5V, bit 8 is batt low + int Payload1; // 16 bits + int Payload2; // 16 bits + + byte b, bytes, bits, id; + char log[128]; + + byte idx = 3; + byte chksum = 0; + for (bytes = 0; bytes < 7; bytes++) { + b = 0; + for (bits = 0; bits <= 7; bits++) + { + if ((rfsns_raw_signal.Pulses[idx] * rfsns_raw_signal.Multiply) > RFSNS_THEOV2_RF_PULSE_MID) { + b |= 1 << bits; + } + idx += 2; + } + if (bytes > 0) { chksum += b; } // bereken checksum + + switch (bytes) { + case 0: + Checksum = b; + break; + case 1: + id = b; + Channel = b & 0x7; + Type = (b >> 3) & 0x1f; + break; + case 2: + Voltage = b; + break; + case 3: + Payload1 = b; + break; + case 4: + Payload1 = (b << 8) | Payload1; + break; + case 5: + Payload2 = b; + break; + case 6: + Payload2 = (b << 8) | Payload2; + break; + } + } + + if (Checksum != chksum) { return false; } + if (Channel == 0) { return false; } + + rfsns_raw_signal.Repeats = 1; // het is een herhalend signaal. Bij ontvangst herhalingen onderdukken + + int Payload3 = Voltage & 0x3f; + Channel--; + + switch (Type) { + case 1: // Temp / Lux + rfsns_theo_v2_t1[Channel].time = LocalTime(); + rfsns_theo_v2_t1[Channel].volt = Payload3; + rfsns_theo_v2_t1[Channel].temp = Payload1; + rfsns_theo_v2_t1[Channel].lux = Payload2; + break; + case 2: // Temp / Hum + rfsns_theo_v2_t2[Channel].time = LocalTime(); + rfsns_theo_v2_t2[Channel].volt = Payload3; + rfsns_theo_v2_t2[Channel].temp = Payload1; + rfsns_theo_v2_t2[Channel].hum = Payload2; + break; + } + + snprintf_P(log_data, sizeof(log_data), PSTR("RFS: TheoV2, ChkCalc %d, Chksum %d, id %d, Type %d, Ch %d, Volt %d, BattLo %d, Pld1 %d, Pld2 %d"), + chksum, Checksum, id, Type, Channel +1, Payload3, (Voltage & 0x80) >> 7, Payload1, Payload2); + AddLog(LOG_LEVEL_DEBUG); + + return true; +} + +void RfSnsTheoV2Show(boolean json) +{ + bool sensor_once = false; + + for (uint8_t i = 0; i < RFSNS_THEOV2_MAX_CHANNEL; i++) { + if (rfsns_theo_v2_t1[i].time) { + char sensor[10]; + snprintf_P(sensor, sizeof(sensor), PSTR("TV2T1C%d"), i +1); + char voltage[10]; + dtostrfd((float)rfsns_theo_v2_t1[i].volt / 10, 1, voltage); + + if (rfsns_theo_v2_t1[i].time < LocalTime() - RFSNS_VALID_WINDOW) { + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_RFRECEIVED "\":\"%s\",\"" D_JSON_VOLTAGE "\":%s}"), + mqtt_data, sensor, GetDT(rfsns_theo_v2_t1[i].time).c_str(), voltage); + } + } else { + char temperature[10]; + dtostrfd(ConvertTemp((float)rfsns_theo_v2_t1[i].temp / 100), Settings.flag2.temperature_resolution, temperature); + + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_ILLUMINANCE "\":%d,\"" D_JSON_VOLTAGE "\":%s}"), + mqtt_data, sensor, temperature, rfsns_theo_v2_t1[i].lux, voltage); +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && !sensor_once) { + DomoticzSensor(DZ_TEMP, temperature); + DomoticzSensor(DZ_ILLUMINANCE, rfsns_theo_v2_t1[i].lux); + sensor_once = true; + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, sensor, temperature, TempUnit()); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, sensor, rfsns_theo_v2_t1[i].lux); +#endif // USE_WEBSERVER + } + } + } + } + + sensor_once = false; + for (uint8_t i = 0; i < RFSNS_THEOV2_MAX_CHANNEL; i++) { + if (rfsns_theo_v2_t2[i].time) { + char sensor[10]; + snprintf_P(sensor, sizeof(sensor), PSTR("TV2T2C%d"), i +1); + char voltage[10]; + dtostrfd((float)rfsns_theo_v2_t2[i].volt / 10, 1, voltage); + + if (rfsns_theo_v2_t2[i].time < LocalTime() - RFSNS_VALID_WINDOW) { + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_RFRECEIVED" \":\"%s\",\"" D_JSON_VOLTAGE "\":%s}"), + mqtt_data, sensor, GetDT(rfsns_theo_v2_t2[i].time).c_str(), voltage); + } + } else { + float temp = ConvertTemp((float)rfsns_theo_v2_t2[i].temp / 100); + char temperature[10]; + dtostrfd(temp, Settings.flag2.temperature_resolution, temperature); + float humi = (float)rfsns_theo_v2_t2[i].hum / 100; + char humidity[10]; + dtostrfd(humi, Settings.flag2.humidity_resolution, humidity); + + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"" D_JSON_VOLTAGE "\":%s}"), + mqtt_data, sensor, temperature, humidity, voltage); + if ((0 == tele_period) && !sensor_once) { +#ifdef USE_DOMOTICZ + DomoticzTempHumSensor(temperature, humidity); +#endif // USE_DOMOTICZ +#ifdef USE_KNX + KnxSensor(KNX_TEMPERATURE, temp); + KnxSensor(KNX_HUMIDITY, humi); +#endif // USE_KNX + sensor_once = true; + } +#ifdef USE_WEBSERVER + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, sensor, temperature, TempUnit()); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, sensor, humidity); +#endif // USE_WEBSERVER + } + } + } + } +} + +#endif // USE_THEO_V2 ************************************************************************ + +#ifdef USE_ALECTO_V2 +/*********************************************************************************************\ + * Alecto V2 protocol + * Dit protocol zorgt voor ontvangst van Alecto weerstation buitensensoren + * + * Auteur : Nodo-team (Martinus van den Broek) www.nodo-domotica.nl + * Support ACH2010 en code optimalisatie door forumlid: Arendst + * Support : www.nodo-domotica.nl + * Datum : 25 Jan 2013 + * Versie : 1.3 + ********************************************************************************************** + * Technische informatie: + * DKW2012 Message Format: (11 Bytes, 88 bits): + * AAAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH IIIIIIII + * Temperature Humidity Windspd_ Windgust Rain____ ________ Winddir Checksum + * A = start/unknown, first 8 bits are always 11111111 + * B = Rolling code + * C = Temperature (10 bit value with -400 base) + * D = Humidity + * E = windspeed (* 0.3 m/s, correction for webapp = 3600/1000 * 0.3 * 100 = 108)) + * F = windgust (* 0.3 m/s, correction for webapp = 3600/1000 * 0.3 * 100 = 108)) + * G = Rain ( * 0.3 mm) + * H = winddirection (0 = north, 4 = east, 8 = south 12 = west) + * I = Checksum, calculation is still under investigation + * + * WS3000 and ACH2010 systems have no winddirection, message format is 8 bit shorter + * Message Format: (10 Bytes, 80 bits): + * AAAAAAAA AAAABBBB BBBB__CC CCCCCCCC DDDDDDDD EEEEEEEE FFFFFFFF GGGGGGGG GGGGGGGG HHHHHHHH + * Temperature Humidity Windspd_ Windgust Rain____ ________ Checksum + * + * DCF Time Message Format: (NOT DECODED!) + * AAAAAAAA BBBBCCCC DDDDDDDD EFFFFFFF GGGGGGGG HHHHHHHH IIIIIIII JJJJJJJJ KKKKKKKK LLLLLLLL MMMMMMMM + * 11 Hours Minutes Seconds Year Month Day ? Checksum + * B = 11 = DCF + * C = ? + * D = ? + * E = ? + * F = Hours BCD format (7 bits only for this byte, MSB could be '1') + * G = Minutes BCD format + * H = Seconds BCD format + * I = Year BCD format (only two digits!) + * J = Month BCD format + * K = Day BCD format + * L = ? + * M = Checksum +\*********************************************************************************************/ + +#define RFSNS_DKW2012_PULSECOUNT 176 +#define RFSNS_ACH2010_MIN_PULSECOUNT 160 // reduce this value (144?) in case of bad reception +#define RFSNS_ACH2010_MAX_PULSECOUNT 160 + +typedef struct { + uint32_t time; + float temp; + float rain; + float wind; + float gust; + uint8_t type; + uint8_t humi; + uint8_t wdir; +} alecto_v2_t; + +alecto_v2_t rfsns_alecto_v2; + +uint16_t rfsns_alecto_rain_base = 0; +//unsigned long rfsns_alecto_time = 60000; + +boolean RfSnsAnalyzeAlectov2() +{ + if (!(((rfsns_raw_signal.Number >= RFSNS_ACH2010_MIN_PULSECOUNT) && + (rfsns_raw_signal.Number <= RFSNS_ACH2010_MAX_PULSECOUNT)) || (rfsns_raw_signal.Number == RFSNS_DKW2012_PULSECOUNT))) { return false; } + + byte c = 0; + byte rfbit; + byte data[9]; + byte msgtype = 0; + byte rc = 0; + int temp; + byte checksum = 0; + byte checksumcalc = 0; + byte maxidx = 8; + unsigned long atime; + float factor; + char buf1[16]; + + if (rfsns_raw_signal.Number > RFSNS_ACH2010_MAX_PULSECOUNT) { maxidx = 9; } + // Get message back to front as the header is almost never received complete for ACH2010 + byte idx = maxidx; + for (byte x = rfsns_raw_signal.Number; x > 0; x = x-2) { + if (rfsns_raw_signal.Pulses[x-1] * rfsns_raw_signal.Multiply < 0x300) { + rfbit = 0x80; + } else { + rfbit = 0; + } + data[idx] = (data[idx] >> 1) | rfbit; + c++; + if (c == 8) { + if (idx == 0) { break; } + c = 0; + idx--; + } + } + + checksum = data[maxidx]; + checksumcalc = RfSnsAlectoCRC8(data, maxidx); + + msgtype = (data[0] >> 4) & 0xf; + rc = (data[0] << 4) | (data[1] >> 4); + + if (checksum != checksumcalc) { return false; } + if ((msgtype != 10) && (msgtype != 5)) { return true; } + + rfsns_raw_signal.Repeats = 1; // het is een herhalend signaal. Bij ontvangst herhalingen onderdukken + + factor = 1.22; // (1.08) +// atime = rfsns_raw_signal.Time - rfsns_alecto_time; +// if ((atime > 10000) && (atime < 60000)) factor = (float)60000 / atime; +// rfsns_alecto_time = rfsns_raw_signal.Time; +// Serial.printf("atime %d, rfsns_alecto_time %d\n", atime, rfsns_alecto_time); + + rfsns_alecto_v2.time = LocalTime(); + rfsns_alecto_v2.type = (rfsns_raw_signal.Number == RFSNS_DKW2012_PULSECOUNT); + rfsns_alecto_v2.temp = (float)(((data[1] & 0x3) * 256 + data[2]) - 400) / 10; + rfsns_alecto_v2.humi = data[3]; + uint16_t rain = (data[6] * 256) + data[7]; + // check if rain unit has been reset! + if (rain < rfsns_alecto_rain_base) { rfsns_alecto_rain_base = rain; } + if (rfsns_alecto_rain_base > 0) { + rfsns_alecto_v2.rain += ((float)rain - rfsns_alecto_rain_base) * 0.30; + } + rfsns_alecto_rain_base = rain; + rfsns_alecto_v2.wind = (float)data[4] * factor; + rfsns_alecto_v2.gust = (float)data[5] * factor; + if (rfsns_alecto_v2.type) { + rfsns_alecto_v2.wdir = data[8] & 0xf; + } + + snprintf_P(log_data, sizeof(log_data), PSTR("RFS: AlectoV2, ChkCalc %d, Chksum %d, rc %d, Temp %d, Hum %d, Rain %d, Wind %d, Gust %d, Dir %d, Factor %s"), + checksumcalc, checksum, rc, ((data[1] & 0x3) * 256 + data[2]) - 400, data[3], (data[6] * 256) + data[7], data[4], data[5], data[8] & 0xf, dtostrfd(factor, 3, buf1)); + AddLog(LOG_LEVEL_DEBUG); + + return true; +} + +void RfSnsAlectoResetRain(void) +{ + if ((RtcTime.hour == 0) && (RtcTime.minute == 0) && (RtcTime.second == 5)) { + rfsns_alecto_v2.rain = 0; // Reset Rain + } +} + +/*********************************************************************************************\ + * Calculates CRC-8 checksum + * reference http://lucsmall.com/2012/04/29/weather-station-hacking-part-2/ + * http://lucsmall.com/2012/04/30/weather-station-hacking-part-3/ + * https://github.com/lucsmall/WH2-Weather-Sensor-Library-for-Arduino/blob/master/WeatherSensorWH2.cpp + \*********************************************************************************************/ +uint8_t RfSnsAlectoCRC8(uint8_t *addr, uint8_t len) +{ + uint8_t crc = 0; + while (len--) { + uint8_t inbyte = *addr++; + for (uint8_t i = 8; i; i--) { + uint8_t mix = (crc ^ inbyte) & 0x80; + crc <<= 1; + if (mix) { crc ^= 0x31; } + inbyte <<= 1; + } + } + return crc; +} + +void RfSnsAlectoV2Show(boolean json) +{ + if (rfsns_alecto_v2.time) { + char sensor[10]; + snprintf_P(sensor, sizeof(sensor), PSTR("AlectoV2")); + + if (rfsns_alecto_v2.time < LocalTime() - RFSNS_VALID_WINDOW) { + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_RFRECEIVED "\":\"%s\"}"), + mqtt_data, sensor, GetDT(rfsns_alecto_v2.time).c_str()); + } + } else { + float temp = ConvertTemp(rfsns_alecto_v2.temp); + char temperature[10]; + dtostrfd(temp, Settings.flag2.temperature_resolution, temperature); + float humi = (float)rfsns_alecto_v2.humi; + char humidity[10]; + dtostrfd(humi, Settings.flag2.humidity_resolution, humidity); + char rain[10]; + dtostrfd(rfsns_alecto_v2.rain, 2, rain); + char wind[10]; + dtostrfd(rfsns_alecto_v2.wind, 2, wind); + char gust[10]; + dtostrfd(rfsns_alecto_v2.gust, 2, gust); + + if (json) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s, \"Rain\":%s,\"Wind\":%s,\"Gust\":%s}"), + mqtt_data, sensor, temperature, humidity, rain, wind, gust); + if (0 == tele_period) { +#ifdef USE_DOMOTICZ + DomoticzTempHumSensor(temperature, humidity); +#endif // USE_DOMOTICZ +#ifdef USE_KNX +// KnxSensor(KNX_TEMPERATURE, temp); +// KnxSensor(KNX_HUMIDITY, humi); +#endif // USE_KNX + } +#ifdef USE_WEBSERVER + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, sensor, temperature, TempUnit()); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, sensor, humidity); +#endif // USE_WEBSERVER + } + } + } +} +#endif // USE_ALECTO_V2 ********************************************************************** + +void RfSnsInit(void) +{ + rfsns_rf_bit = digitalPinToBitMask(pin[GPIO_RF_SENSOR]); + rfsns_rf_port = digitalPinToPort(pin[GPIO_RF_SENSOR]); + pinMode(pin[GPIO_RF_SENSOR], INPUT); +} + +void RfSnsAnalyzeRawSignal(void) +{ + snprintf_P(log_data, sizeof(log_data), PSTR("RFS: Pulses %d"), (int)rfsns_raw_signal.Number); + AddLog(LOG_LEVEL_DEBUG); + +// if (Settings.flag3.rf_type) { +#ifdef USE_THEO_V2 + RfSnsAnalyzeTheov2(); +#endif +// } else { +#ifdef USE_ALECTO_V2 + RfSnsAnalyzeAlectov2(); +#endif +// } +} + +void RfSnsEverySecond(void) +{ +#ifdef USE_ALECTO_V2 + RfSnsAlectoResetRain(); +#endif +} + +void RfSnsShow(boolean json) +{ +#ifdef USE_THEO_V2 + RfSnsTheoV2Show(json); +#endif + +#ifdef USE_ALECTO_V2 + RfSnsAlectoV2Show(json); +#endif +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +boolean Xsns37(byte function) +{ + boolean result = false; + + if (pin[GPIO_RF_SENSOR] < 99) { + switch (function) { + case FUNC_INIT: + RfSnsInit(); + break; + case FUNC_LOOP: + if ((*portInputRegister(rfsns_rf_port) &rfsns_rf_bit) == rfsns_rf_bit) { + if (RfSnsFetchSignal(pin[GPIO_RF_SENSOR], HIGH)) { + RfSnsAnalyzeRawSignal(); + } + } + sleep = 0; + break; + case FUNC_EVERY_SECOND: + RfSnsEverySecond(); + break; + case FUNC_JSON_APPEND: + RfSnsShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_APPEND: + RfSnsShow(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_RF_SENSOR diff --git a/tools/decode-status.py b/tools/decode-status.py index 3de4dfca3..fa108bc02 100644 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -134,8 +134,8 @@ a_features = [[ "USE_MCP230xx","USE_MPR121","USE_CCS811","USE_MPU6050", "USE_MCP230xx_OUTPUT","USE_MCP230xx_DISPLAYOUTPUT","USE_HLW8012","USE_CSE7766", "USE_MCP39F501","USE_PZEM_AC","USE_DS3231","USE_HX711", - "USE_PZEM_DC","USE_TX20_WIND_SENSOR","USE_MGC3130","", - "","","","", + "USE_PZEM_DC","USE_TX20_WIND_SENSOR","USE_MGC3130","USE_RF_SENSOR", + "USE_THEO_V2","USE_ALECTO_V2","","", "","","","", "","","","", "","","",""]] From 808e2c073fd011382b8a5fa7b7b0eabc1f36135e Mon Sep 17 00:00:00 2001 From: Ikarulus Date: Tue, 11 Dec 2018 14:49:58 +0100 Subject: [PATCH 59/63] add manzuko "power strip" --- sonoff/sonoff_template.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index f3b366d38..1177d0f3d 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -266,6 +266,7 @@ enum SupportedModules { SK03_TUYA, PS_16_DZ, TECKIN_US, + MANZOKU_EU_4, MAXMODULE }; /********************************************************************************************/ @@ -499,6 +500,7 @@ const uint8_t kModuleNiceList[MAXMODULE] PROGMEM = { SK03_TUYA, NEO_COOLCAM, // Socket Relay Devices OBI, + MANZOKU_EU_4, ESP_SWITCH, // Switch Devices TUYA_DIMMER, // Dimmer Devices ARMTRONIX_DIMMERS, @@ -1324,6 +1326,21 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_KEY1, // GPIO13 Button GPIO_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage 0, 0, 0 + }, + { "Manzoku strip", // "MANZOKU" labeled power strip, EU version + 0, // GPIO00 + 0, // GPIO01 Serial RXD + 0, + GPIO_KEY1, // GPIO03 Serial TXD + Button + GPIO_REL2, // GPIO04 Relay 2 + GPIO_REL1, // GPIO05 Relay 1 + 0, 0, 0, 0, 0, 0, + GPIO_REL3, // GPIO12 Relay 3 + GPIO_REL4, // GPIO13 Relay 4 + GPIO_USER, // GPIO14 + 0, + GPIO_USER, // GPIO16 + 0 } }; From b3e5e35cea6d6e05e8ddd1a14d569d983f44cf98 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Tue, 11 Dec 2018 18:00:12 +0100 Subject: [PATCH 60/63] Add more support * Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver * Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver * Add support for Manzoku Power Strip (#4590) --- sonoff/_changelog.ino | 4 ++- sonoff/language/bg-BG.h | 2 ++ sonoff/language/cs-CZ.h | 2 ++ sonoff/language/de-DE.h | 2 ++ sonoff/language/el-GR.h | 2 ++ sonoff/language/en-GB.h | 2 ++ sonoff/language/es-AR.h | 2 ++ sonoff/language/fr-FR.h | 2 ++ sonoff/language/he-HE.h | 2 ++ sonoff/language/hu-HU.h | 2 ++ sonoff/language/it-IT.h | 2 ++ sonoff/language/nl-NL.h | 2 ++ sonoff/language/pl-PL.h | 2 ++ sonoff/language/pt-BR.h | 2 ++ sonoff/language/pt-PT.h | 2 ++ sonoff/language/ru-RU.h | 2 ++ sonoff/language/sv-SE.h | 2 ++ sonoff/language/tr-TR.h | 2 ++ sonoff/language/uk-UK.h | 2 ++ sonoff/language/zh-CN.h | 2 ++ sonoff/language/zh-TW.h | 2 ++ sonoff/my_user_config.h | 6 ++-- sonoff/sonoff_template.h | 6 ++-- sonoff/xsns_37_rfsensor.ino | 71 +++++++++++++++++++++++++++---------- 24 files changed, 103 insertions(+), 24 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 4ca0e0dd7..0f601ec0b 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,8 @@ /* 6.3.0.17 20181211 - * Add support for TheoV2 sensors as documented on https://sidweb.nl + * Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver + * Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver * Add support for SDM220 (#3610) + * Add support for Manzoku Power Strip (#4590) * Enhance support for MPU6050 using DMP (#4581) * * 6.3.0.16 20181201 diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 9ed4734a8..621a0fdb7 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Размер на флаш паметта за програми" #define D_PROGRAM_SIZE "Размер на програмата" #define D_PROJECT "Проект" +#define D_RAIN "Rain" #define D_RECEIVED "Получено" #define D_RESTART "Рестарт" #define D_RESTARTING "Рестартиране" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "µm" #define D_UNIT_MICROSECOND "µs" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "min" diff --git a/sonoff/language/cs-CZ.h b/sonoff/language/cs-CZ.h index 8bcde604b..461de3a4d 100644 --- a/sonoff/language/cs-CZ.h +++ b/sonoff/language/cs-CZ.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Velikost paměti flash" #define D_PROGRAM_SIZE "Velikost programu" #define D_PROJECT "Projekt" +#define D_RAIN "Rain" #define D_RECEIVED "Přijatý" #define D_RESTART "Restart" #define D_RESTARTING "Restartování" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "min" diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 21f7e5dd8..16c3f886f 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Ges. Flash Speicher" #define D_PROGRAM_SIZE "Ben. Flash Speicher" #define D_PROJECT "Projekt" +#define D_RAIN "Regen" #define D_RECEIVED "erhalten" #define D_RESTART "Neustart" #define D_RESTARTING "starte neu" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "µm" #define D_UNIT_MICROSECOND "µs" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "min" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index e59855a24..2148baf42 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Μέγεθος προγράμματος στη Flash" #define D_PROGRAM_SIZE "Μέγεθος προγράμματος" #define D_PROJECT "Έργο" +#define D_RAIN "Rain" #define D_RECEIVED "Ελήφθη" #define D_RESTART "Επανεκκίνηση" #define D_RESTARTING "Επανεκκινεί" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index a38664d2f..70825c5e3 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Program Flash Size" #define D_PROGRAM_SIZE "Program Size" #define D_PROJECT "Project" +#define D_RAIN "Rain" #define D_RECEIVED "Received" #define D_RESTART "Restart" #define D_RESTARTING "Restarting" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 7039d66a6..2ad9551e7 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Tamaño de Flash de Programa" #define D_PROGRAM_SIZE "Tamaño Programa" #define D_PROJECT "Proyecto" +#define D_RAIN "Rain" #define D_RECEIVED "Recibido" #define D_RESTART "Reiniciar" #define D_RESTARTING "Reiniciando" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index a038153c9..312c5d015 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Taille Flash Programme" #define D_PROGRAM_SIZE "Taille programme" #define D_PROJECT "Projet" +#define D_RAIN "Plui" #define D_RECEIVED "Reçu" #define D_RESTART "Redémarrage" #define D_RESTARTING "Redémarre" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "µm" #define D_UNIT_MICROSECOND "µs" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index 6f3612fb7..7dc8585db 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "גודל תוכנית פלאש" #define D_PROGRAM_SIZE "גודל תוכנית" #define D_PROJECT "פרויקט" +#define D_RAIN "Rain" #define D_RECEIVED "התקבל" #define D_RESTART "איתחול" #define D_RESTARTING "הפעלה מחדש" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 82c911fb1..707bb24ec 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Program Flash Méret" #define D_PROGRAM_SIZE "Program Méret" #define D_PROJECT "Projekt" +#define D_RAIN "Rain" #define D_RECEIVED "Érkezett" #define D_RESTART "Újraindítás" #define D_RESTARTING "Újraindítás" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "µs" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "p" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index b971d1c02..4e1481cec 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Dimensione Flash Programma" #define D_PROGRAM_SIZE "Dimensione Programma" #define D_PROJECT "Progetto" +#define D_RAIN "Rain" #define D_RECEIVED "Ricevuto" #define D_RESTART "Riavvio" #define D_RESTARTING "Riavviando" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index 73a201448..3383228ed 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte" #define D_PROGRAM_SIZE "Programma Grootte" #define D_PROJECT "Project" +#define D_RAIN "Regen" #define D_RECEIVED "Ontvangen" #define D_RESTART "Herstart" #define D_RESTARTING "Herstarten" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index e4728bda8..0019c8d53 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Wielkość programu flash" #define D_PROGRAM_SIZE "Wielkość programu" #define D_PROJECT "Projekt" +#define D_RAIN "Rain" #define D_RECEIVED "Otrzymany" #define D_RESTART "Restart" #define D_RESTARTING "Restartowanie" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index 487f4793d..e8e536606 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Tamanho do programa na memória" #define D_PROGRAM_SIZE "Tamanho do programa" #define D_PROJECT "Projeto" +#define D_RAIN "Rain" #define D_RECEIVED "Recebido" #define D_RESTART "Reiniciar" #define D_RESTARTING "Reiniciando" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "M" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index 4b2366758..58a39fff0 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Tamanho do Programa na Flash" #define D_PROGRAM_SIZE "Tamanho do Programa" #define D_PROJECT "Projeto" +#define D_RAIN "Rain" #define D_RECEIVED "Recebido" #define D_RESTART "Reiniciar" #define D_RESTARTING "A reiniciar" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index e2e6079cd..85813373a 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Размер Flash для программ" #define D_PROGRAM_SIZE "Размер программы " #define D_PROJECT "Проект" +#define D_RAIN "Rain" #define D_RECEIVED "Получено" #define D_RESTART "Перезапуск" #define D_RESTARTING "Перезапуск" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "мкм" #define D_UNIT_MICROSECOND "мкс" #define D_UNIT_MILLIAMPERE "мА" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "мм рт.ст." #define D_UNIT_MILLISECOND "мс" #define D_UNIT_MINUTE "мин" diff --git a/sonoff/language/sv-SE.h b/sonoff/language/sv-SE.h index 9ec54c62b..4ae68e78c 100644 --- a/sonoff/language/sv-SE.h +++ b/sonoff/language/sv-SE.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Program-flashstorlek" #define D_PROGRAM_SIZE "Programstorlek" #define D_PROJECT "Projekt" +#define D_RAIN "Rain" #define D_RECEIVED "Mottagen" #define D_RESTART "Omstart" #define D_RESTARTING "Startar om" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index 4425431ee..43acbaa77 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Yazılım Flash Boyutu" #define D_PROGRAM_SIZE "Yazılım Boyutu" #define D_PROJECT "Proje" +#define D_RAIN "Rain" #define D_RECEIVED "Alınan" #define D_RESTART "Yeniden Başlat" #define D_RESTARTING "Yeniden Başlatılıyor" @@ -552,6 +553,7 @@ #define D_UNIT_MICROMETER "um" #define D_UNIT_MICROSECOND "us" #define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "ms" #define D_UNIT_MINUTE "Min" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index 82449858e..a924a6cf4 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Розмір Flash для програм" #define D_PROGRAM_SIZE "Розмір програм " #define D_PROJECT "Проект" +#define D_RAIN "Rain" #define D_RECEIVED "Отримано" #define D_RESTART "Перезавантаження" #define D_RESTARTING "Перезавантаження" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "мкм" #define D_UNIT_MICROSECOND "мкс" #define D_UNIT_MILLIAMPERE "мА" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "мс" #define D_UNIT_MINUTE "хв" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index f1ba0c93d..dfd5662e0 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "固件 Flash 大小" #define D_PROGRAM_SIZE "固件大小" #define D_PROJECT "项目:" +#define D_RAIN "Rain" #define D_RECEIVED "已接收" #define D_RESTART "重启" #define D_RESTARTING "正在重启" @@ -552,6 +553,7 @@ #define D_UNIT_MICROMETER "微米" #define D_UNIT_MICROSECOND "微秒" #define D_UNIT_MILLIAMPERE "毫安" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "毫秒" #define D_UNIT_MINUTE "分" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 3a9d12336..abc3df93d 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -132,6 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "韌體 Flash 大小" #define D_PROGRAM_SIZE "韌體大小" #define D_PROJECT "項目:" +#define D_RAIN "Rain" #define D_RECEIVED "已接收" #define D_RESTART "重啟" #define D_RESTARTING "正在重啟" @@ -553,6 +554,7 @@ #define D_UNIT_MICROMETER "微米" #define D_UNIT_MICROSECOND "微秒" #define D_UNIT_MILLIAMPERE "毫安" +#define D_UNIT_MILLIMETER "mm" #define D_UNIT_MILLIMETER_MERCURY "mmHg" #define D_UNIT_MILLISECOND "毫秒" #define D_UNIT_MINUTE "分" diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 3a35b7d33..32821365f 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -399,9 +399,9 @@ #define USE_RC_SWITCH // Add support for RF transceiver using library RcSwitch (+2k7 code, 460 iram) -//#define USE_RF_SENSOR // Add support for RF (434MHz or 868MHz) receiver (+2k code) -// #define USE_THEO_V2 // Add support for 434MHz Theo V2 sensors as documented on https://sidweb.nl -// #define USE_ALECTO_V2 // Add support for 868MHz Alecto V2 sensors like ACH2010, WS3000 and DKW2012 +//#define USE_RF_SENSOR // Add support for RF sensor receiver (434MHz or 868MHz) (+0k8 code) +// #define USE_THEO_V2 // Add support for decoding Theo V2 sensors as documented on https://sidweb.nl using 434MHz RF sensor receiver (+1k4 code) +// #define USE_ALECTO_V2 // Add support for decoding Alecto V2 sensors like ACH2010, WS3000 and DKW2012 using 868MHz RF sensor receiver (+1k7 code) /*********************************************************************************************\ * Debug features are only supported in development branch diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 1177d0f3d..91eec21c7 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -1327,14 +1327,16 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage 0, 0, 0 }, - { "Manzoku strip", // "MANZOKU" labeled power strip, EU version + { "Manzoku strip", // "MANZOKU" labeled power strip, EU version + // https://www.amazon.de/Steckdosenleiste-AOFO-Mehrfachsteckdose-Überspannungsschutz-Sprachsteuerung/dp/B07GBSD11P/ + // https://www.amazon.de/Steckdosenleiste-Geekbes-USB-Anschluss-Kompatibel-gesteuert/dp/B078W23BW9/ 0, // GPIO00 0, // GPIO01 Serial RXD 0, GPIO_KEY1, // GPIO03 Serial TXD + Button GPIO_REL2, // GPIO04 Relay 2 GPIO_REL1, // GPIO05 Relay 1 - 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, // Flash connection GPIO_REL3, // GPIO12 Relay 3 GPIO_REL4, // GPIO13 Relay 4 GPIO_USER, // GPIO14 diff --git a/sonoff/xsns_37_rfsensor.ino b/sonoff/xsns_37_rfsensor.ino index 63c567839..4829a71b1 100644 --- a/sonoff/xsns_37_rfsensor.ino +++ b/sonoff/xsns_37_rfsensor.ino @@ -312,7 +312,7 @@ void RfSnsTheoV2Show(boolean json) mqtt_data, sensor, temperature, humidity, voltage); if ((0 == tele_period) && !sensor_once) { #ifdef USE_DOMOTICZ - DomoticzTempHumSensor(temperature, humidity); + DomoticzTempHumSensor(temperature, humidity); // #endif // USE_DOMOTICZ #ifdef USE_KNX KnxSensor(KNX_TEMPERATURE, temp); @@ -384,6 +384,25 @@ void RfSnsTheoV2Show(boolean json) #define RFSNS_ACH2010_MIN_PULSECOUNT 160 // reduce this value (144?) in case of bad reception #define RFSNS_ACH2010_MAX_PULSECOUNT 160 +#define D_ALECTOV2 "AlectoV2" + +const char kAlectoV2Directions[] PROGMEM = D_TX20_NORTH "|" + D_TX20_NORTH D_TX20_NORTH D_TX20_EAST "|" + D_TX20_NORTH D_TX20_EAST "|" + D_TX20_EAST D_TX20_NORTH D_TX20_EAST "|" + D_TX20_EAST "|" + D_TX20_EAST D_TX20_SOUTH D_TX20_EAST "|" + D_TX20_SOUTH D_TX20_EAST "|" + D_TX20_SOUTH D_TX20_SOUTH D_TX20_EAST "|" + D_TX20_SOUTH "|" + D_TX20_SOUTH D_TX20_SOUTH D_TX20_WEST "|" + D_TX20_SOUTH D_TX20_WEST "|" + D_TX20_WEST D_TX20_SOUTH D_TX20_WEST "|" + D_TX20_WEST "|" + D_TX20_WEST D_TX20_NORTH D_TX20_WEST "|" + D_TX20_NORTH D_TX20_WEST "|" + D_TX20_NORTH D_TX20_NORTH D_TX20_WEST; + typedef struct { uint32_t time; float temp; @@ -407,7 +426,7 @@ boolean RfSnsAnalyzeAlectov2() byte c = 0; byte rfbit; - byte data[9]; + byte data[9] = { 0 }; byte msgtype = 0; byte rc = 0; int temp; @@ -447,6 +466,10 @@ boolean RfSnsAnalyzeAlectov2() rfsns_raw_signal.Repeats = 1; // het is een herhalend signaal. Bij ontvangst herhalingen onderdukken +// Test set +// rfsns_raw_signal.Number = RFSNS_DKW2012_PULSECOUNT; // DKW2012 +// data[8] = 11; // WSW + factor = 1.22; // (1.08) // atime = rfsns_raw_signal.Time - rfsns_alecto_time; // if ((atime > 10000) && (atime < 60000)) factor = (float)60000 / atime; @@ -454,7 +477,7 @@ boolean RfSnsAnalyzeAlectov2() // Serial.printf("atime %d, rfsns_alecto_time %d\n", atime, rfsns_alecto_time); rfsns_alecto_v2.time = LocalTime(); - rfsns_alecto_v2.type = (rfsns_raw_signal.Number == RFSNS_DKW2012_PULSECOUNT); + rfsns_alecto_v2.type = (RFSNS_DKW2012_PULSECOUNT == rfsns_raw_signal.Number); rfsns_alecto_v2.temp = (float)(((data[1] & 0x3) * 256 + data[2]) - 400) / 10; rfsns_alecto_v2.humi = data[3]; uint16_t rain = (data[6] * 256) + data[7]; @@ -470,7 +493,7 @@ boolean RfSnsAnalyzeAlectov2() rfsns_alecto_v2.wdir = data[8] & 0xf; } - snprintf_P(log_data, sizeof(log_data), PSTR("RFS: AlectoV2, ChkCalc %d, Chksum %d, rc %d, Temp %d, Hum %d, Rain %d, Wind %d, Gust %d, Dir %d, Factor %s"), + snprintf_P(log_data, sizeof(log_data), PSTR("RFS: " D_ALECTOV2 ", ChkCalc %d, Chksum %d, rc %d, Temp %d, Hum %d, Rain %d, Wind %d, Gust %d, Dir %d, Factor %s"), checksumcalc, checksum, rc, ((data[1] & 0x3) * 256 + data[2]) - 400, data[3], (data[6] * 256) + data[7], data[4], data[5], data[8] & 0xf, dtostrfd(factor, 3, buf1)); AddLog(LOG_LEVEL_DEBUG); @@ -505,16 +528,22 @@ uint8_t RfSnsAlectoCRC8(uint8_t *addr, uint8_t len) return crc; } +#ifdef USE_WEBSERVER +const char HTTP_SNS_ALECTOV2[] PROGMEM = "%s" + "{s}" D_ALECTOV2 " " D_RAIN "{m}%s " D_UNIT_MILLIMETER "{e}" + "{s}" D_ALECTOV2 " " D_TX20_WIND_SPEED "{m}%s " D_UNIT_KILOMETER_PER_HOUR "{e}" + "{s}" D_ALECTOV2 " " D_TX20_WIND_SPEED_MAX "{m}%s " D_UNIT_KILOMETER_PER_HOUR "{e}"; +const char HTTP_SNS_ALECTOV2_WDIR[] PROGMEM = "%s" + "{s}" D_ALECTOV2 " " D_TX20_WIND_DIRECTION "{m}%s{e}"; +#endif + void RfSnsAlectoV2Show(boolean json) { if (rfsns_alecto_v2.time) { - char sensor[10]; - snprintf_P(sensor, sizeof(sensor), PSTR("AlectoV2")); - if (rfsns_alecto_v2.time < LocalTime() - RFSNS_VALID_WINDOW) { if (json) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_RFRECEIVED "\":\"%s\"}"), - mqtt_data, sensor, GetDT(rfsns_alecto_v2.time).c_str()); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_ALECTOV2 "\":{\"" D_JSON_RFRECEIVED "\":\"%s\"}"), + mqtt_data, GetDT(rfsns_alecto_v2.time).c_str()); } } else { float temp = ConvertTemp(rfsns_alecto_v2.temp); @@ -529,23 +558,29 @@ void RfSnsAlectoV2Show(boolean json) dtostrfd(rfsns_alecto_v2.wind, 2, wind); char gust[10]; dtostrfd(rfsns_alecto_v2.gust, 2, gust); + char wdir[4]; + char direction[20]; + if (rfsns_alecto_v2.type) { + GetTextIndexed(wdir, sizeof(wdir), rfsns_alecto_v2.wdir, kAlectoV2Directions); + snprintf_P(direction, sizeof(direction), PSTR(",\"Direction\":\"%s\""), wdir); + } if (json) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s, \"Rain\":%s,\"Wind\":%s,\"Gust\":%s}"), - mqtt_data, sensor, temperature, humidity, rain, wind, gust); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_ALECTOV2 "\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"Rain\":%s,\"Wind\":%s,\"Gust\":%s%s}"), + mqtt_data, temperature, humidity, rain, wind, gust, (rfsns_alecto_v2.type) ? direction : ""); if (0 == tele_period) { #ifdef USE_DOMOTICZ - DomoticzTempHumSensor(temperature, humidity); + // Use a rule #endif // USE_DOMOTICZ -#ifdef USE_KNX -// KnxSensor(KNX_TEMPERATURE, temp); -// KnxSensor(KNX_HUMIDITY, humi); -#endif // USE_KNX } #ifdef USE_WEBSERVER } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, sensor, temperature, TempUnit()); - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, sensor, humidity); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, D_ALECTOV2, temperature, TempUnit()); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, D_ALECTOV2, humidity); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ALECTOV2, mqtt_data, rain, wind, gust); + if (rfsns_alecto_v2.type) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ALECTOV2_WDIR, mqtt_data, wdir); + } #endif // USE_WEBSERVER } } From 0c90db5d857ba213445f8a283b0689b3b375b714 Mon Sep 17 00:00:00 2001 From: Adrian Scillato <35405447+ascillato@users.noreply.github.com> Date: Tue, 11 Dec 2018 17:30:51 +0000 Subject: [PATCH 61/63] Updated Spanish Translation --- sonoff/language/es-AR.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index 2ad9551e7..011c7a248 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v6.2.1.11 + * Updated until v6.3.0.17 \*********************************************************************/ #define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -132,7 +132,7 @@ #define D_PROGRAM_FLASH_SIZE "Tamaño de Flash de Programa" #define D_PROGRAM_SIZE "Tamaño Programa" #define D_PROJECT "Proyecto" -#define D_RAIN "Rain" +#define D_RAIN "Lluvia" #define D_RECEIVED "Recibido" #define D_RESTART "Reiniciar" #define D_RESTARTING "Reiniciando" @@ -438,7 +438,7 @@ #define D_START_SIGNAL_LOW "iniciar señal baja" #define D_START_SIGNAL_HIGH "iniciar señal alta" #define D_PULSE "pulso" -#define D_CHECKSUM_FAILURE "Checksum fallido" +#define D_CHECKSUM_FAILURE "Falló Checksum" // xsns_07_sht1x.ino #define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor no ha enviado el comando ACK" @@ -597,13 +597,13 @@ #define D_LOG_WIFI "WIF: " // Wifi //SDM220 -#define D_PHASE_ANGLE "Phase Angle" -#define D_IMPORT_ACTIVE "Import Active" -#define D_EXPORT_ACTIVE "Export Active" -#define D_IMPORT_REACTIVE "Import Reactive" -#define D_EXPORT_REACTIVE "Export Reactive" -#define D_TOTAL_REACTIVE "Total Reactive" -#define D_UNIT_KWARH "kVArh" -#define D_UNIT_ANGLE "Deg" +#define D_PHASE_ANGLE "Ángulo de Fase" +#define D_IMPORT_ACTIVE "P. Activa Entrante" +#define D_EXPORT_ACTIVE "P. Activa Saliente" +#define D_IMPORT_REACTIVE "P. Reactiva Entrante" +#define D_EXPORT_REACTIVE "P. Reactiva Saliente" +#define D_TOTAL_REACTIVE "P. Reactiva Total" +#define D_UNIT_KWARH "kVArH" +#define D_UNIT_ANGLE "Grados" #endif // _LANGUAGE_ES_AR_H_ From 4df23beab1f18cec0bbf8a77bbe59a408c5d4ced Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Tue, 11 Dec 2018 20:27:37 +0100 Subject: [PATCH 62/63] Update de-DE.h --- sonoff/language/de-DE.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 16c3f886f..293de0830 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -28,7 +28,7 @@ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command Prefix to translate cmnd, stat and tele. * - * Updated until v5.12.0l + * Updated until v6.3.0.17 \*********************************************************************/ //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) @@ -597,13 +597,13 @@ #define D_LOG_WIFI "WIF: " // Wifi //SDM220 -#define D_PHASE_ANGLE "Phase Angle" -#define D_IMPORT_ACTIVE "Import Active" -#define D_EXPORT_ACTIVE "Export Active" -#define D_IMPORT_REACTIVE "Import Reactive" -#define D_EXPORT_REACTIVE "Export Reactive" -#define D_TOTAL_REACTIVE "Total Reactive" +#define D_PHASE_ANGLE "Phasenwinkel" +#define D_IMPORT_ACTIVE "Importiere Wirk" +#define D_EXPORT_ACTIVE "Exportiere Wirk" +#define D_IMPORT_REACTIVE "Importiere Blind" +#define D_EXPORT_REACTIVE "Exportiere Blind" +#define D_TOTAL_REACTIVE "Total Blind" #define D_UNIT_KWARH "kVArh" -#define D_UNIT_ANGLE "Deg" +#define D_UNIT_ANGLE "Grad" #endif // _LANGUAGE_DE_DE_H_ From 85c515cc973472c64301f0f6e582734d85b6f95a Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 11 Dec 2018 22:00:34 +0100 Subject: [PATCH 63/63] More tweak of Hass switch/button --- sonoff/xdrv_12_home_assistant.ino | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sonoff/xdrv_12_home_assistant.ino b/sonoff/xdrv_12_home_assistant.ino index c21749dc2..20c2a9038 100644 --- a/sonoff/xdrv_12_home_assistant.ino +++ b/sonoff/xdrv_12_home_assistant.ino @@ -44,10 +44,11 @@ const char HASS_DISCOVER_BUTTON_SWITCH[] PROGMEM = "\"payload_not_available\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE[] PROGMEM = - "%s,\"off_delay\":1"; + "%s,\"off_delay\":1"; // Hass has no support for TOGGLE, fake it by resetting to OFF after 1s const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF[] PROGMEM = - "%s,\"payload_off\":\"%s\""; // OFF + "%s,\"force_update\":true," // In ON/OFF case, enable force_update to make automations work + "\"payload_off\":\"%s\""; // OFF const char HASS_DISCOVER_LIGHT_DIMMER[] PROGMEM = "%s,\"brightness_command_topic\":\"%s\"," // cmnd/led2/Dimmer @@ -114,10 +115,11 @@ const char HASS_DISCOVER_BUTTON_SWITCH_SHORT[] PROGMEM = "\"pl_not_avail\":\"" D_OFFLINE "\""; // Offline const char HASS_DISCOVER_BUTTON_SWITCH_TOGGLE_SHORT[] PROGMEM = - "%s,\"off_delay\":1"; + "%s,\"off_delay\":1"; // Hass has no support for TOGGLE, fake it by resetting to OFF after 1s const char HASS_DISCOVER_BUTTON_SWITCH_ONOFF_SHORT[] PROGMEM = - "%s,\"pl_off\":\"%s\""; // OFF + "%s,\"frc_upd\":true," // In ON/OFF case, enable force_update to make automations work + "\"pl_off\":\"%s\""; // OFF const char HASS_DISCOVER_LIGHT_DIMMER_SHORT[] PROGMEM =