diff --git a/tasmota/i18n.h b/tasmota/i18n.h
index 7b6d50fe1..580f68d5d 100644
--- a/tasmota/i18n.h
+++ b/tasmota/i18n.h
@@ -52,6 +52,7 @@
#define D_JSON_CURRENT "Current" // As in Voltage and Current
#define D_JSON_DARKNESS "Darkness"
#define D_JSON_DATA "Data"
+#define D_JSON_DEWPOINT "DewPoint"
#define D_JSON_DISTANCE "Distance"
#define D_JSON_DNSSERVER "DNSServer"
#define D_JSON_DONE "Done"
@@ -631,6 +632,7 @@ const char S_JSON_DRIVER_INDEX_SVALUE[] PROGMEM = "{\"" D_CMND_DRIVE
const char JSON_SNS_TEMP[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s}";
const char JSON_SNS_TEMPHUM[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s}";
+const char JSON_SNS_TEMPHUMDEW[] PROGMEM = ",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_HUMIDITY "\":%s,\"" D_JSON_DEWPOINT "\":%s}";
const char JSON_SNS_ILLUMINANCE[] PROGMEM = ",\"%s\":{\"" D_JSON_ILLUMINANCE "\":%d}";
const char JSON_SNS_MOISTURE[] PROGMEM = ",\"%s\":{\"" D_JSON_MOISTURE "\":%d}";
@@ -667,6 +669,7 @@ const float kSpeedConversionFactor[] = {1, // none
// {s} =
, {m} = | , {e} = |
const char HTTP_SNS_TEMP[] PROGMEM = "{s}%s " D_TEMPERATURE "{m}%s°%c{e}";
const char HTTP_SNS_HUM[] PROGMEM = "{s}%s " D_HUMIDITY "{m}%s%%{e}";
+const char HTTP_SNS_DEW[] PROGMEM = "{s}%s " D_DEWPOINT "{m}%s°%c{e}";
const char HTTP_SNS_PRESSURE[] PROGMEM = "{s}%s " D_PRESSURE "{m}%s %s{e}";
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "{s}%s " D_PRESSUREATSEALEVEL "{m}%s %s{e}";
const char HTTP_SNS_ANALOG[] PROGMEM = "{s}%s " D_ANALOG_INPUT "%d{m}%d{e}";
diff --git a/tasmota/language/bg-BG.h b/tasmota/language/bg-BG.h
index 9adc5c820..37e1468ab 100644
--- a/tasmota/language/bg-BG.h
+++ b/tasmota/language/bg-BG.h
@@ -79,6 +79,7 @@
#define D_DATA "Данни"
#define D_DARKLIGHT "Тъмна"
#define D_DEBUG "Дебъгване"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Забранен"
#define D_DISTANCE "Разстояние"
#define D_DNS_SERVER "DNS Сървър"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "Ю"
#define D_TX20_WEST "З"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/cs-CZ.h b/tasmota/language/cs-CZ.h
index 94e58067f..6ea1707a7 100644
--- a/tasmota/language/cs-CZ.h
+++ b/tasmota/language/cs-CZ.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Tmavý"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Zablokováno"
#define D_DISTANCE "Distance"
#define D_DNS_SERVER "Server DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "J"
#define D_TX20_WEST "Z"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/de-DE.h b/tasmota/language/de-DE.h
index f93c272a7..cc5dbd09c 100644
--- a/tasmota/language/de-DE.h
+++ b/tasmota/language/de-DE.h
@@ -79,6 +79,7 @@
#define D_DATA "Daten"
#define D_DARKLIGHT "dunkel"
#define D_DEBUG "debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "deaktiviert"
#define D_DISTANCE "Abstand"
#define D_DNS_SERVER "DNS-Server"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Verbrauch"
#define D_TPWROUT "Einspeisung"
#define D_TPWRCURR "Aktueller Verbrauch"
diff --git a/tasmota/language/el-GR.h b/tasmota/language/el-GR.h
index acb1cedd8..5b13e6342 100644
--- a/tasmota/language/el-GR.h
+++ b/tasmota/language/el-GR.h
@@ -79,6 +79,7 @@
#define D_DATA "Δεδομένα"
#define D_DARKLIGHT "Σκοτεινό"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Ανενεργό"
#define D_DISTANCE "Απόσταση"
#define D_DNS_SERVER "Διακομιστής DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "Ν"
#define D_TX20_WEST "Δ"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/en-GB.h b/tasmota/language/en-GB.h
index 6d3e8da3f..c394c706d 100644
--- a/tasmota/language/en-GB.h
+++ b/tasmota/language/en-GB.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Dark"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Disabled"
#define D_DISTANCE "Distance"
#define D_DNS_SERVER "DNS Server"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Total-In"
#define D_TPWROUT "Total-Out"
#define D_TPWRCURR "Current-In/Out"
diff --git a/tasmota/language/es-ES.h b/tasmota/language/es-ES.h
index 3f1c1c934..1f7e33914 100644
--- a/tasmota/language/es-ES.h
+++ b/tasmota/language/es-ES.h
@@ -79,6 +79,7 @@
#define D_DATA "Datos"
#define D_DARKLIGHT "Oscuro"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Deshabilitado"
#define D_DISTANCE "Distancia"
#define D_DNS_SERVER "Servidor DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "O"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energía Total-Entrada"
#define D_TPWROUT "Energía Total-Salida"
#define D_TPWRCURR "Potencia-En/Sal"
diff --git a/tasmota/language/fr-FR.h b/tasmota/language/fr-FR.h
index 8eea225ad..9aa4efba8 100644
--- a/tasmota/language/fr-FR.h
+++ b/tasmota/language/fr-FR.h
@@ -79,6 +79,7 @@
#define D_DATA "Donnée"
#define D_DARKLIGHT "Sombre"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Désactivé"
#define D_DISTANCE "Distance"
#define D_DNS_SERVER "Serveur DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "O"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/he-HE.h b/tasmota/language/he-HE.h
index 5463f6ba1..64d1b38b2 100644
--- a/tasmota/language/he-HE.h
+++ b/tasmota/language/he-HE.h
@@ -79,6 +79,7 @@
#define D_DATA "נתונים"
#define D_DARKLIGHT "חושך"
#define D_DEBUG "באגים"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "מבוטל"
#define D_DISTANCE "מרחק"
#define D_DNS_SERVER "DNS שרת"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/hu-HU.h b/tasmota/language/hu-HU.h
index 16762b19a..d4797a90a 100644
--- a/tasmota/language/hu-HU.h
+++ b/tasmota/language/hu-HU.h
@@ -79,6 +79,7 @@
#define D_DATA "Adat"
#define D_DARKLIGHT "Min. fényerő"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Letiltva"
#define D_DISTANCE "Távolság"
#define D_DNS_SERVER "DNS szerver"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "D"
#define D_TX20_WEST "NY"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/it-IT.h b/tasmota/language/it-IT.h
index 1c13a8679..7f41ad7fa 100644
--- a/tasmota/language/it-IT.h
+++ b/tasmota/language/it-IT.h
@@ -79,6 +79,7 @@
#define D_DATA "Dati"
#define D_DARKLIGHT "Scuro"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Disabilitato"
#define D_DISTANCE "Distanza"
#define D_DNS_SERVER "DNS Server"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "O"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/ko-KO.h b/tasmota/language/ko-KO.h
index e586f70a8..fe1ca5b3b 100644
--- a/tasmota/language/ko-KO.h
+++ b/tasmota/language/ko-KO.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "어둡게"
#define D_DEBUG "디버그"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "사용안함"
#define D_DISTANCE "거리"
#define D_DNS_SERVER "DNS 서버"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/nl-NL.h b/tasmota/language/nl-NL.h
index c97c0d3cc..474cc7150 100644
--- a/tasmota/language/nl-NL.h
+++ b/tasmota/language/nl-NL.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Donker"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dauwpunt"
#define D_DISABLED "Uitgeschakeld"
#define D_DISTANCE "Afstand"
#define D_DNS_SERVER "DNS Server"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/pl-PL.h b/tasmota/language/pl-PL.h
index ce1926694..5652de045 100644
--- a/tasmota/language/pl-PL.h
+++ b/tasmota/language/pl-PL.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Ciemny"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Wyłączony"
#define D_DISTANCE "Odległość"
#define D_DNS_SERVER "Serwer DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/pt-BR.h b/tasmota/language/pt-BR.h
index 880057472..858be76f0 100644
--- a/tasmota/language/pt-BR.h
+++ b/tasmota/language/pt-BR.h
@@ -79,6 +79,7 @@
#define D_DATA "Dados"
#define D_DARKLIGHT "Luz escura"
#define D_DEBUG "Depurar"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Desabilitado"
#define D_DISTANCE "Distância"
#define D_DNS_SERVER "Servidor DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "O"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/pt-PT.h b/tasmota/language/pt-PT.h
index 2648198ef..6bbfc0fa6 100644
--- a/tasmota/language/pt-PT.h
+++ b/tasmota/language/pt-PT.h
@@ -79,6 +79,7 @@
#define D_DATA "Dados"
#define D_DARKLIGHT "Luz Escura"
#define D_DEBUG "Depurar"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Disabilitado"
#define D_DISTANCE "Distância"
#define D_DNS_SERVER "Servidor DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "O"
-//xsns_53_sml.ino
+//xsns_53_sml.ino
#define D_TPWRIN "Energia-Consumo"
#define D_TPWROUT "Energia-Geração"
#define D_TPWRCURR "Potência Ativa-Consumo/Geração"
@@ -527,7 +528,7 @@
#define D_Spannung_L3 "Tensão F3"
#define D_METERNR "Número_Contador"
#define D_METERSID "ID Serviço"
-#define D_GasIN "Contagem"
+#define D_GasIN "Contagem"
#define D_H2oIN "Contagem"
#define D_StL1L2L3 "Corrente F1+F2+F3"
#define D_SpL1L2L3 "Tensão F1+F2+F3/3"
diff --git a/tasmota/language/ro-RO.h b/tasmota/language/ro-RO.h
index 2d010317d..8970bbd29 100644
--- a/tasmota/language/ro-RO.h
+++ b/tasmota/language/ro-RO.h
@@ -79,6 +79,7 @@
#define D_DATA "Date"
#define D_DARKLIGHT "Întunecat"
#define D_DEBUG "Depanare"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Dezactivat"
#define D_DISTANCE "Distanță"
#define D_DNS_SERVER "Server DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "V"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/ru-RU.h b/tasmota/language/ru-RU.h
index 1e2de831f..990c3d9d1 100644
--- a/tasmota/language/ru-RU.h
+++ b/tasmota/language/ru-RU.h
@@ -79,6 +79,7 @@
#define D_DATA "Данные"
#define D_DARKLIGHT "Темный"
#define D_DEBUG "Отладка"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Блокирован"
#define D_DISTANCE "Distance"
#define D_DNS_SERVER "DNS Сервер"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/sk-SK.h b/tasmota/language/sk-SK.h
index 54391e41f..d9eae653d 100644
--- a/tasmota/language/sk-SK.h
+++ b/tasmota/language/sk-SK.h
@@ -80,6 +80,7 @@
#define D_FLOW_RATE "Flow rate"
#define D_DARKLIGHT "Tmavý"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Zablokované"
#define D_DISTANCE "Vzdialenosť"
#define D_DNS_SERVER "Server DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "J"
#define D_TX20_WEST "Z"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/sv-SE.h b/tasmota/language/sv-SE.h
index 490636206..302dac80c 100644
--- a/tasmota/language/sv-SE.h
+++ b/tasmota/language/sv-SE.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Mörkt"
#define D_DEBUG "Debug"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Inaktiverad"
#define D_DISTANCE "Distans"
#define D_DNS_SERVER "DNS-server"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "V"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/tr-TR.h b/tasmota/language/tr-TR.h
index 16d3e8a80..bb48f6d0e 100644
--- a/tasmota/language/tr-TR.h
+++ b/tasmota/language/tr-TR.h
@@ -79,6 +79,7 @@
#define D_DATA "Data"
#define D_DARKLIGHT "Karanlık"
#define D_DEBUG "Hata Ayıklama"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Etkin Değil"
#define D_DISTANCE "Mesage"
#define D_DNS_SERVER "DNS Sunucu"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/uk-UA.h b/tasmota/language/uk-UA.h
index a9bfd503f..895269639 100644
--- a/tasmota/language/uk-UA.h
+++ b/tasmota/language/uk-UA.h
@@ -79,6 +79,7 @@
#define D_DATA "Дані"
#define D_DARKLIGHT "Темний"
#define D_DEBUG "Налагодження"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "Вимкнено"
#define D_DISTANCE "Відстань"
#define D_DNS_SERVER "Сервер DNS"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "Пд"
#define D_TX20_WEST "Зх"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/zh-CN.h b/tasmota/language/zh-CN.h
index bd424d921..e1517e21e 100644
--- a/tasmota/language/zh-CN.h
+++ b/tasmota/language/zh-CN.h
@@ -79,6 +79,7 @@
#define D_DATA "数据:"
#define D_DARKLIGHT "暗"
#define D_DEBUG "调试"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "禁用"
#define D_DISTANCE "距离"
#define D_DNS_SERVER "DNS服务器"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "南"
#define D_TX20_WEST "西"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/language/zh-TW.h b/tasmota/language/zh-TW.h
index 04bcea868..f3c31c0b6 100644
--- a/tasmota/language/zh-TW.h
+++ b/tasmota/language/zh-TW.h
@@ -79,6 +79,7 @@
#define D_DATA "數據:"
#define D_DARKLIGHT "Dark"
#define D_DEBUG "除錯"
+#define D_DEWPOINT "Dew point"
#define D_DISABLED "停用"
#define D_DISTANCE "Distance"
#define D_DNS_SERVER "DNS伺服器"
@@ -512,7 +513,7 @@
#define D_TX20_SOUTH "S"
#define D_TX20_WEST "W"
-// xsns_53_sml.ino
+// xsns_53_sml.ino
#define D_TPWRIN "Energy Total-In"
#define D_TPWROUT "Energy Total-Out"
#define D_TPWRCURR "Active Power-In/Out"
diff --git a/tasmota/support.ino b/tasmota/support.ino
index d9693a3a4..984b4312f 100644
--- a/tasmota/support.ino
+++ b/tasmota/support.ino
@@ -623,6 +623,24 @@ float ConvertHumidity(float h)
return h;
}
+float CalcTempHumToDew(float t, float h)
+{
+ if (isnan(h) || isnan(t)) { return 0.0; }
+
+ if (Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
+ t = (t - 32) / 1.8; // Celsius
+ }
+
+// float gamma = log(h / 100) + 17.62 * t / (243.5 + t);
+ float gamma = TaylorLog(h / 100) + 17.62 * t / (243.5 + t);
+ float result = (243.5 * gamma / (17.62 - gamma));
+
+ if (Settings.flag.temperature_conversion) { // SetOption8 - Switch between Celsius or Fahrenheit
+ result = result * 1.8 + 32; // Fahrenheit
+ }
+ return result;
+}
+
float ConvertPressure(float p)
{
float result = p;
diff --git a/tasmota/support_tasmota.ino b/tasmota/support_tasmota.ino
index eab6f136b..4e8a3fa54 100644
--- a/tasmota/support_tasmota.ino
+++ b/tasmota/support_tasmota.ino
@@ -667,6 +667,38 @@ void MqttPublishTeleState(void)
#endif // USE_SCRIPT
}
+void TempHumDewShow(bool json, bool pass_on, const char *types, float f_temperature, float f_humidity)
+{
+ char temperature[33];
+ dtostrfd(f_temperature, Settings.flag2.temperature_resolution, temperature);
+ char humidity[33];
+ dtostrfd(f_humidity, Settings.flag2.humidity_resolution, humidity);
+ float f_dewpoint = CalcTempHumToDew(f_temperature, f_humidity);
+ char dewpoint[33];
+ dtostrfd(f_dewpoint, Settings.flag2.temperature_resolution, dewpoint);
+
+ if (json) {
+ ResponseAppend_P(JSON_SNS_TEMPHUMDEW, types, temperature, humidity, dewpoint);
+#ifdef USE_DOMOTICZ
+ if (pass_on) {
+ DomoticzTempHumSensor(temperature, humidity);
+ }
+#endif // USE_DOMOTICZ
+#ifdef USE_KNX
+ if (pass_on) {
+ KnxSensor(KNX_TEMPERATURE, f_temperature);
+ KnxSensor(KNX_HUMIDITY, f_humidity);
+ }
+#endif // USE_KNX
+#ifdef USE_WEBSERVER
+ } else {
+ WSContentSend_PD(HTTP_SNS_TEMP, types, temperature, TempUnit());
+ WSContentSend_PD(HTTP_SNS_HUM, types, humidity);
+ WSContentSend_PD(HTTP_SNS_DEW, types, dewpoint, TempUnit());
+#endif // USE_WEBSERVER
+ }
+}
+
bool MqttShowSensor(void)
{
ResponseAppendTime();
diff --git a/tasmota/xsns_06_dht.ino b/tasmota/xsns_06_dht.ino
index 9c7003970..e8488a96f 100644
--- a/tasmota/xsns_06_dht.ino
+++ b/tasmota/xsns_06_dht.ino
@@ -240,7 +240,7 @@ void DhtEverySecond(void)
}
}
}
-
+/*
void DhtShow(bool json)
{
for (uint32_t i = 0; i < dht_sensors; i++) {
@@ -270,6 +270,13 @@ void DhtShow(bool json)
}
}
}
+*/
+void DhtShow(bool json)
+{
+ for (uint32_t i = 0; i < dht_sensors; i++) {
+ TempHumDewShow(json, ((0 == tele_period) && (0 == i)), Dht[i].stype, Dht[i].t, Dht[i].h);
+ }
+}
/*********************************************************************************************\
* Interface
diff --git a/tasmota/xsns_07_sht1x.ino b/tasmota/xsns_07_sht1x.ino
index 9679728f8..e4b1796cb 100644
--- a/tasmota/xsns_07_sht1x.ino
+++ b/tasmota/xsns_07_sht1x.ino
@@ -179,7 +179,7 @@ void ShtEverySecond(void)
}
}
}
-
+/*
void ShtShow(bool json)
{
if (sht_valid) {
@@ -209,6 +209,13 @@ void ShtShow(bool json)
}
}
}
+*/
+void ShtShow(bool json)
+{
+ if (sht_valid) {
+ TempHumDewShow(json, (0 == tele_period), sht_types, sht_temperature, sht_humidity);
+ }
+}
/*********************************************************************************************\
* Interface
diff --git a/tasmota/xsns_08_htu21.ino b/tasmota/xsns_08_htu21.ino
index 704952a4b..2cfaa0a59 100644
--- a/tasmota/xsns_08_htu21.ino
+++ b/tasmota/xsns_08_htu21.ino
@@ -237,7 +237,7 @@ void HtuEverySecond(void)
}
}
}
-
+/*
void HtuShow(bool json)
{
if (htu_valid) {
@@ -267,6 +267,13 @@ void HtuShow(bool json)
}
}
}
+*/
+void HtuShow(bool json)
+{
+ if (htu_valid) {
+ TempHumDewShow(json, (0 == tele_period), htu_types, htu_temperature, htu_humidity);
+ }
+}
/*********************************************************************************************\
* Interface
diff --git a/tasmota/xsns_14_sht3x.ino b/tasmota/xsns_14_sht3x.ino
index 521231d50..65bd1a4cf 100644
--- a/tasmota/xsns_14_sht3x.ino
+++ b/tasmota/xsns_14_sht3x.ino
@@ -91,7 +91,7 @@ void Sht3xDetect(void)
}
}
}
-
+/*
void Sht3xShow(bool json)
{
for (uint32_t i = 0; i < sht3x_count; i++) {
@@ -129,6 +129,19 @@ void Sht3xShow(bool json)
}
}
}
+*/
+void Sht3xShow(bool json)
+{
+ for (uint32_t i = 0; i < sht3x_count; i++) {
+ float t;
+ float h;
+ if (Sht3xRead(t, h, sht3x_sensors[i].address)) {
+ char types[11];
+ snprintf_P(types, sizeof(types), PSTR("%s%c0x%02X"), sht3x_sensors[i].types, IndexSeparator(), sht3x_sensors[i].address); // "SHT3X-0xXX"
+ TempHumDewShow(json, ((0 == tele_period) && (0 == i)), types, t, h);
+ }
+ }
+}
/*********************************************************************************************\
* Interface
diff --git a/tasmota/xsns_55_hih_series.ino b/tasmota/xsns_55_hih_series.ino
index 5ebcdea93..aef74dcf1 100644
--- a/tasmota/xsns_55_hih_series.ino
+++ b/tasmota/xsns_55_hih_series.ino
@@ -92,7 +92,7 @@ void Hih6EverySecond(void)
}
}
}
-
+/*
void Hih6Show(bool json)
{
if (Hih6.valid) {
@@ -122,6 +122,13 @@ void Hih6Show(bool json)
}
}
}
+*/
+void Hih6Show(bool json)
+{
+ if (Hih6.valid) {
+ TempHumDewShow(json, (0 == tele_period), Hih6.types, Hih6.temperature, Hih6.humidity);
+ }
+}
/*********************************************************************************************\
* Interface
diff --git a/tasmota/xsns_63_aht1x.ino b/tasmota/xsns_63_aht1x.ino
index 0d4083605..d99457a44 100644
--- a/tasmota/xsns_63_aht1x.ino
+++ b/tasmota/xsns_63_aht1x.ino
@@ -26,11 +26,11 @@
* I2C Address: 0x38
*
* Attention: this Sensor is incompatible with other I2C devices on I2C bus.
- *
+ *
* The Datasheet write:
- * "Only a single AHT10 can be connected to the I2C bus and no other I2C
+ * "Only a single AHT10 can be connected to the I2C bus and no other I2C
* devices can be connected".
- *
+ *
* after lot of search and tests, now is confirmed that works only reliable with one sensor
* on I2C Bus
\*********************************************************************************************/
@@ -38,129 +38,178 @@
#define XSNS_63 63
#define XI2C_43 43 // See I2CDEVICES.md
-#define AHT10_ADDR 0x38
+#define AHT1X_ADDR1 0x38
+#define AHT1X_ADDR2 0x39
-uint8_t eSensorCalibrateCmd[3] = {0xE1, 0x08, 0x00};
-uint8_t eSensorMeasureCmd[3] = {0xAC, 0x33, 0x00};
-uint8_t eSensorResetCmd = 0xBA;
+#define AHT1X_MAX_SENSORS 2
-struct AHT10 {
+#define AHT_HUMIDITY_CONST 100
+#define AHT_TEMPERATURE_CONST 200
+#define AHT_TEMPERATURE_OFFSET 50
+#define KILOBYTE_CONST 1048576.0f
+
+#define AHT1X_CMD_DELAY 40
+#define AHT1X_RST_DELAY 30
+#define AHT1X_MEAS_DELAY 80 // over 75ms in datasheet
+
+uint8_t AHTSetCalCmd[3] = {0xE1, 0x08, 00}; //load factory calibration coeff
+uint8_t AHTSetCycleCmd[3] = {0xE1, 0x28, 00}; //enable cycle mode
+uint8_t AHTMeasureCmd[3] = {0xAC, 0x33, 00}; //start measurment command
+uint8_t AHTResetCmd = 0xBA; //soft reset command
+
+const char ahtTypes[] PROGMEM = "AHT1X|AHT1X";
+uint8_t aht1x_addresses[] = { AHT1X_ADDR1, AHT1X_ADDR2 };
+uint8_t aht1x_count = 0;
+uint8_t aht1x_Pcount = 0;
+
+struct AHT1XSTRUCT
+{
float humidity = NAN;
float temperature = NAN;
- uint8_t valid = 0;
- uint8_t count = 0;
- char name[6] = "AHT1x";
-} AHT10;
+ uint8_t address; // bus address
+ char types[6]; // Sensor type name and address -
+} aht1x_sensors[AHT1X_MAX_SENSORS];
-bool AHT10Read(void)
+bool AHT1XWrite(uint8_t aht1x_idx)
{
- if (AHT10.valid) { AHT10.valid--; }
+ Wire.beginTransmission(aht1x_sensors[aht1x_idx].address);
+ Wire.write(AHTMeasureCmd, 3);
+ if (Wire.endTransmission() != 0)
+ return false;
+}
+bool AHT1XRead(uint8_t aht1x_idx)
+{
uint8_t data[6];
+ Wire.requestFrom(aht1x_sensors[aht1x_idx].address, (uint8_t) 6);
+ for(uint8_t i = 0; Wire.available() > 0; i++){
+ data[i] = Wire.read();
+ }
+ if ((data[0] & 0x80) == 0x80) return false; //device is busy
- Wire.beginTransmission(AHT10_ADDR);
- Wire.write(eSensorMeasureCmd, 3);
- Wire.endTransmission();
- delay(80);
+ aht1x_sensors[aht1x_idx].humidity = (((data[1] << 12)| (data[2] << 4) | data[3] >> 4) * AHT_HUMIDITY_CONST / KILOBYTE_CONST);
+ aht1x_sensors[aht1x_idx].temperature = ((AHT_TEMPERATURE_CONST * (((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5]) / KILOBYTE_CONST) - AHT_TEMPERATURE_OFFSET);
- Wire.requestFrom(AHT10_ADDR, 6);
- for (uint32_t i = 0; Wire.available() > 0; i++) {
- data[i] = Wire.read();
- }
-
- uint32_t result_h = ((data[1] << 16) | (data[2] << 8) | data[3]) >> 4;
- uint32_t result_t = ((data[3] & 0x0F) << 16) | (data[4] << 8) | data[5];
-
- float humidity = result_h * 100 / 1048576;
- float temperature = ((200 * result_t) / 1048576) - 50;
-
- if (isnan(temperature) || isnan(humidity)) { return false; }
-
- AHT10.humidity = ConvertHumidity(humidity);
- AHT10.temperature = ConvertTemp(temperature);
-
- AHT10.valid = SENSOR_MAX_MISS;
- return true;
+ return (!isnan(aht1x_sensors[aht1x_idx].temperature) && !isnan(aht1x_sensors[aht1x_idx].humidity) && (aht1x_sensors[aht1x_idx].humidity != 0));
}
/********************************************************************************************/
-bool AHT10Init(void)
+// Test for Polling the device without delays
+// Incompatible with other devices on I2C bus
+void AHT1XPoll(void) // We have 100ms for read. Sensor needs 80-95 ms
{
- Wire.begin(AHT10_ADDR);
- Wire.beginTransmission(AHT10_ADDR);
- Wire.write(eSensorCalibrateCmd, 3); // init with internal temp coef.
- Wire.endTransmission();
-
- delay(40); // after tests, its ok
-
- return (0x08 == (AHT10ReadStatus() & 0x68));
+ aht1x_Pcount++;
+ switch (aht1x_Pcount) {
+ case 10:
+ AHT1XWrite(0);
+ break;
+ case 11:
+ if (AHT1XRead(0)){
+ ConvertTemp(aht1x_sensors[0].temperature); // Set global temperature
+ ConvertHumidity(aht1x_sensors[0].humidity); // Set global humidity
+ }
+ aht1x_Pcount = 0;
+ break;
+ }
}
-uint8_t AHT10ReadStatus(void)
+unsigned char AHT1XReadStatus(uint8_t aht1x_address)
{
- Wire.requestFrom(AHT10_ADDR, 1);
- uint8_t result = Wire.read();
+ uint8_t result = 0;
+ Wire.requestFrom(aht1x_address, (uint8_t) 1);
+ result = Wire.read();
return result;
}
-void AHT10Reset(void)
+void AHT1XReset(uint8_t aht1x_address)
{
- Wire.beginTransmission(AHT10_ADDR);
- Wire.write(eSensorResetCmd);
+ Wire.beginTransmission(aht1x_address);
+ Wire.write(AHTResetCmd);
Wire.endTransmission();
- delay(20);
+ delay(AHT1X_RST_DELAY);
}
/********************************************************************************************/
-
-void AHT10Detect(void)
+bool AHT1XInit(uint8_t aht1x_address)
{
- if (I2cActive(AHT10_ADDR)) { return; }
-
- if (AHT10Init()) {
- I2cSetActiveFound(AHT10_ADDR, AHT10.name);
- AHT10.count = 1;
- }
+ Wire.beginTransmission(aht1x_address);
+ Wire.write(AHTSetCalCmd, 3);
+ if (Wire.endTransmission() != 0) return false;
+ delay(AHT1X_CMD_DELAY);
+ if((AHT1XReadStatus(aht1x_address) & 0x68) == 0x08) // Sensor calcoef aktiv
+ return true;
+ return false;
}
-void AHT10EverySecond(void)
+void AHT1XDetect(void)
{
- if (uptime &1) {
- // AHT10: 55mS
- if (!AHT10Read()) {
- AddLogMissed(AHT10.name, AHT10.valid);
+ for (uint8_t i = 0; i < AHT1X_MAX_SENSORS; i++) {
+ if (I2cActive(aht1x_addresses[i])) { continue; }
+ if (AHT1XInit(aht1x_addresses[i]))
+ {
+ aht1x_sensors[aht1x_count].address = aht1x_addresses[i];
+ GetTextIndexed(aht1x_sensors[aht1x_count].types, sizeof(aht1x_sensors[aht1x_count].types), i, ahtTypes);
+ I2cSetActiveFound(aht1x_sensors[aht1x_count].address, aht1x_sensors[aht1x_count].types);
+ aht1x_count = 1;
+ break; // Only one Sensor allowed at the moment (I2C Sensor-Bug)
}
}
}
-
-void AHT10Show(bool json)
+/*
+void AHT1XShow(bool json)
{
- if (AHT10.valid) {
+ for (uint8_t i = 0; i < aht1x_count; i++)
+ {
+ float tem = ConvertTemp(aht1x_sensors[i].temperature);
+ float hum = ConvertHumidity(aht1x_sensors[i].humidity);
+ float dew = CalcTemHumToDew(aht1x_sensors[i].humidity, aht1x_sensors[i].temperature);
+
+ char types[11]; // AHT1X-0x38
+ snprintf_P(types, sizeof(types), PSTR("%s%c0x%02X"), aht1x_sensors[i].types, IndexSeparator(), aht1x_sensors[i].address); // "X-0xXX"
char temperature[33];
- dtostrfd(AHT10.temperature, Settings.flag2.temperature_resolution, temperature);
+ dtostrfd(tem, Settings.flag2.temperature_resolution, temperature);
char humidity[33];
- dtostrfd(AHT10.humidity, Settings.flag2.humidity_resolution, humidity);
+ dtostrfd(hum, Settings.flag2.humidity_resolution, humidity);
+ char dewpoint[33];
+ dtostrfd(dew, Settings.flag2.temperature_resolution, dewpoint);
if (json) {
- ResponseAppend_P(JSON_SNS_TEMPHUM, AHT10.name, temperature, humidity);
-#ifdef USE_DOMOTICZ
- if ((0 == tele_period)) {
- DomoticzTempHumSensor(temperature, humidity);
- }
-#endif // USE_DOMOTICZ
-#ifdef USE_KNX
- if (0 == tele_period) {
- KnxSensor(KNX_TEMPERATURE, AHT10.temperature);
- KnxSensor(KNX_HUMIDITY, AHT10.humidity);
- }
-#endif // USE_KNX
-#ifdef USE_WEBSERVER
- } else {
- WSContentSend_PD(HTTP_SNS_TEMP, AHT10.name, temperature, TempUnit());
- WSContentSend_PD(HTTP_SNS_HUM, AHT10.name, humidity);
-#endif // USE_WEBSERVER
+ //ResponseAppend_P(JSON_SNS_TEMPHUM, types, temperature, humidity);
+ ResponseAppend_P(JSON_SNS_TEMPHUMDEW, types, temperature, humidity, dewpoint);
+ #ifdef USE_DOMOTICZ
+ if ((0 == tele_period) && (0 == i)); // <-- fails
+ {
+ DomoticzTempHumSensor(temperature, humidity);
}
+ #endif // USE_DOMOTICZ
+ #ifdef USE_KNX
+ if (0 == tele_period)
+ {
+ KnxSensor(KNX_TEMPERATURE, tem);
+ KnxSensor(KNX_HUMIDITY, hum);
+ }
+ #endif // USE_KNX
+ #ifdef USE_WEBSERVER
+ }
+ else
+ {
+ WSContentSend_PD(HTTP_SNS_TEMP, types, temperature, TempUnit());
+ WSContentSend_PD(HTTP_SNS_HUM, types, humidity);
+ WSContentSend_PD(HTTP_SNS_DEW, types, dewpoint,TempUnit());
+ #endif // USE_WEBSERVER
+ }
+ }
+}
+*/
+void AHT1XShow(bool json)
+{
+ for (uint32_t i = 0; i < aht1x_count; i++) {
+ float tem = ConvertTemp(aht1x_sensors[i].temperature);
+ float hum = ConvertHumidity(aht1x_sensors[i].humidity);
+ char types[11]; // AHT1X-0x38
+ snprintf_P(types, sizeof(types), PSTR("%s%c0x%02X"), aht1x_sensors[i].types, IndexSeparator(), aht1x_sensors[i].address); // "X-0xXX"
+ TempHumDewShow(json, ((0 == tele_period) && (0 == i)), types, tem, hum);
}
}
@@ -171,29 +220,28 @@ void AHT10Show(bool json)
bool Xsns63(uint8_t function)
{
if (!I2cEnabled(XI2C_43)) { return false; }
-
bool result = false;
if (FUNC_INIT == function) {
- AHT10Detect();
+ AHT1XDetect();
}
- else if (AHT10.count) {
+ else if (aht1x_count){
switch (function) {
- case FUNC_EVERY_SECOND:
- AHT10EverySecond();
- break;
- case FUNC_JSON_APPEND:
- AHT10Show(1);
- break;
-#ifdef USE_WEBSERVER
- case FUNC_WEB_SENSOR:
- AHT10Show(0);
- break;
-#endif // USE_WEBSERVER
+ case FUNC_EVERY_100_MSECOND:
+ AHT1XPoll();
+ break;
+ case FUNC_JSON_APPEND:
+ AHT1XShow(1);
+ break;
+ #ifdef USE_WEBSERVER
+ case FUNC_WEB_SENSOR:
+ AHT1XShow(0);
+ break;
+ #endif // USE_WEBSERVER
}
}
return result;
}
-#endif // USE_AHT10
-#endif // USE_I2C
+#endif // USE_AHT1X
+#endif // USE_I2C
\ No newline at end of file