diff --git a/I2CDEVICES.md b/I2CDEVICES.md
index c572f50a1..c4c95ded0 100644
--- a/I2CDEVICES.md
+++ b/I2CDEVICES.md
@@ -83,3 +83,4 @@ Index | Define | Driver | Device | Address(es) | Description
55 | USE_EZOHUM | xsns_78 | EZOHUM | 0x61 - 0x70 | Humidity sensor
55 | USE_EZOEC | xsns_78 | EZOEC | 0x61 - 0x70 | Electric conductivity sensor
55 | USE_EZOCO2 | xsns_78 | EZOCO2 | 0x61 - 0x70 | CO2 sensor
+ 55 | USE_EZOO2 | xsns_78 | EZOO2 | 0x61 - 0x70 | O2 sensor
diff --git a/tasmota/i18n.h b/tasmota/i18n.h
index a21734ae9..ac4107daa 100644
--- a/tasmota/i18n.h
+++ b/tasmota/i18n.h
@@ -113,6 +113,7 @@
#define D_JSON_NONE "None"
#define D_JSON_OR "or"
#define D_JSON_ORP "ORP"
+#define D_JSON_O2 "Oxygen"
#define D_JSON_PERIOD "Period"
#define D_JSON_PH "pH"
#define D_JSON_PHASE_ANGLE "PhaseAngle"
@@ -775,6 +776,7 @@ const char HTTP_SNS_ENERGY_TOTAL[] PROGMEM = "{s}" D_ENERGY_TOTAL "{
const char HTTP_SNS_PH[] PROGMEM = "{s}%s " D_PH "{m}%s " "{e}";
const char HTTP_SNS_ORP[] PROGMEM = "{s}%s " D_ORP "{m}%s " D_UNIT_MILLIVOLT "{e}";
const char HTTP_SNS_EC[] PROGMEM = "{s}%s " D_EC "{m}%s " D_UNIT_MICROSIEMENS_PER_CM "{e}";
+const char HTTP_SNS_O2[] PROGMEM = "{s}%s " D_O2 "{m}%s " D_UNIT_PERCENT "{e}";
const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
diff --git a/tasmota/language/bg_BG.h b/tasmota/language/bg_BG.h
index 59663bfa2..2a3e93e5d 100644
--- a/tasmota/language/bg_BG.h
+++ b/tasmota/language/bg_BG.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "неколкократно натискане"
#define D_NOISE "Шум"
#define D_NONE "Няма"
+#define D_O2 "Oxygen"
#define D_OFF "Изкл."
#define D_OFFLINE "Офлайн"
#define D_OK "Ок"
diff --git a/tasmota/language/cs_CZ.h b/tasmota/language/cs_CZ.h
index ca1efaf6b..df9f31290 100644
--- a/tasmota/language/cs_CZ.h
+++ b/tasmota/language/cs_CZ.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "několikeré-stisknutí"
#define D_NOISE "Hluk"
#define D_NONE "Žádný"
+#define D_O2 "Oxygen"
#define D_OFF "Vyp."
#define D_OFFLINE "Offline" // Don't translate, LWT message! Nepředkládat, LWT zpráva!
#define D_OK "OK"
diff --git a/tasmota/language/de_DE.h b/tasmota/language/de_DE.h
index f7d17cced..310359dd3 100644
--- a/tasmota/language/de_DE.h
+++ b/tasmota/language/de_DE.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "Mehrfachdruck"
#define D_NOISE "Lautstärke"
#define D_NONE "keine"
+#define D_O2 "Oxygen"
#define D_OFF "aus"
#define D_OFFLINE "Offline"
#define D_OK "OK"
diff --git a/tasmota/language/el_GR.h b/tasmota/language/el_GR.h
index e516c5348..44db54b36 100644
--- a/tasmota/language/el_GR.h
+++ b/tasmota/language/el_GR.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "ανίχνευση για πολλαπλά πατήματα"
#define D_NOISE "Θόρυβος"
#define D_NONE "Κανένα"
+#define D_O2 "Oxygen"
#define D_OFF "Off"
#define D_OFFLINE "Offline"
#define D_OK "Ok"
diff --git a/tasmota/language/en_GB.h b/tasmota/language/en_GB.h
index bf78441af..efaac7f76 100644
--- a/tasmota/language/en_GB.h
+++ b/tasmota/language/en_GB.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-press"
#define D_NOISE "Noise"
#define D_NONE "None"
+#define D_O2 "Oxygen"
#define D_OFF "Off"
#define D_OFFLINE "Offline"
#define D_OK "Ok"
diff --git a/tasmota/language/es_ES.h b/tasmota/language/es_ES.h
index 3d9fe8472..7c05c0398 100644
--- a/tasmota/language/es_ES.h
+++ b/tasmota/language/es_ES.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-press"
#define D_NOISE "Ruido"
#define D_NONE "Ninguno"
+#define D_O2 "Oxygen"
#define D_OFF "Apagado"
#define D_OFFLINE "Offline"
#define D_OK "Ok"
diff --git a/tasmota/language/fr_FR.h b/tasmota/language/fr_FR.h
index 0ec56b863..a6013f54f 100644
--- a/tasmota/language/fr_FR.h
+++ b/tasmota/language/fr_FR.h
@@ -121,6 +121,7 @@
#define D_MULTI_PRESS "multi-pression"
#define D_NOISE "Bruit"
#define D_NONE "Aucun"
+#define D_O2 "Oxygen"
#define D_OFF "Arrêt"
#define D_OFFLINE "Déconnecté"
#define D_OK "Ok"
diff --git a/tasmota/language/he_HE.h b/tasmota/language/he_HE.h
index d4a4a9f4d..3ca9774cd 100644
--- a/tasmota/language/he_HE.h
+++ b/tasmota/language/he_HE.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "לחיצה מרובה"
#define D_NOISE "רעש"
#define D_NONE "כלום"
+#define D_O2 "Oxygen"
#define D_OFF "כבוי"
#define D_OFFLINE "מנותק"
#define D_OK "אוקיי"
diff --git a/tasmota/language/hu_HU.h b/tasmota/language/hu_HU.h
index a32f4ea24..2d4f55cf8 100644
--- a/tasmota/language/hu_HU.h
+++ b/tasmota/language/hu_HU.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "több lenyomás"
#define D_NOISE "Zaj"
#define D_NONE "nincs"
+#define D_O2 "Oxygen"
#define D_OFF "Ki"
#define D_OFFLINE "Offline"
#define D_OK "OK"
diff --git a/tasmota/language/it_IT.h b/tasmota/language/it_IT.h
index d169e7ae0..30f2502c4 100644
--- a/tasmota/language/it_IT.h
+++ b/tasmota/language/it_IT.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-pressione"
#define D_NOISE "Rumore"
#define D_NONE "Nessuno"
+#define D_O2 "Oxygen"
#define D_OFF "OFF"
#define D_OFFLINE "Offline"
#define D_OK "OK"
diff --git a/tasmota/language/ko_KO.h b/tasmota/language/ko_KO.h
index 08eddb3fa..13c77db2e 100644
--- a/tasmota/language/ko_KO.h
+++ b/tasmota/language/ko_KO.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-press"
#define D_NOISE "소음"
#define D_NONE "없음"
+#define D_O2 "Oxygen"
#define D_OFF "꺼짐"
#define D_OFFLINE "오프라인"
#define D_OK "Ok"
diff --git a/tasmota/language/nl_NL.h b/tasmota/language/nl_NL.h
index 9ce3012fa..c98e4296d 100644
--- a/tasmota/language/nl_NL.h
+++ b/tasmota/language/nl_NL.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "meervoudig"
#define D_NOISE "Lawaai"
#define D_NONE "Geen"
+#define D_O2 "Oxygen"
#define D_OFF "Uit"
#define D_OFFLINE "Offline"
#define D_OK "Ok"
diff --git a/tasmota/language/pl_PL.h b/tasmota/language/pl_PL.h
index 2f5e6b72e..1d70d89a9 100644
--- a/tasmota/language/pl_PL.h
+++ b/tasmota/language/pl_PL.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "Wielokrotne naciśnięcie"
#define D_NOISE "Szum"
#define D_NONE "Brak"
+#define D_O2 "Oxygen"
#define D_OFF "Wyłączony"
#define D_OFFLINE "Nieaktywny"
#define D_OK "Ok"
diff --git a/tasmota/language/pt_BR.h b/tasmota/language/pt_BR.h
index f1f900acf..1768cdf86 100644
--- a/tasmota/language/pt_BR.h
+++ b/tasmota/language/pt_BR.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-pressão"
#define D_NOISE "Ruído"
#define D_NONE "Nenhum"
+#define D_O2 "Oxygen"
#define D_OFF "Desligado"
#define D_OFFLINE "Desconectado"
#define D_OK "Ok"
diff --git a/tasmota/language/pt_PT.h b/tasmota/language/pt_PT.h
index 94daa7603..c730a7292 100644
--- a/tasmota/language/pt_PT.h
+++ b/tasmota/language/pt_PT.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-pressão"
#define D_NOISE "Ruído"
#define D_NONE "Nenhum"
+#define D_O2 "Oxygen"
#define D_OFF "Off"
#define D_OFFLINE "Desconetado"
#define D_OK "Ok"
diff --git a/tasmota/language/ro_RO.h b/tasmota/language/ro_RO.h
index 432e66877..ac1e2de26 100644
--- a/tasmota/language/ro_RO.h
+++ b/tasmota/language/ro_RO.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "selectare multiplă"
#define D_NOISE "Zgomot"
#define D_NONE "Lipsă"
+#define D_O2 "Oxygen"
#define D_OFF "Închis"
#define D_OFFLINE "Offline"
#define D_OK "Ok"
diff --git a/tasmota/language/ru_RU.h b/tasmota/language/ru_RU.h
index 83292385c..6eb49aecb 100644
--- a/tasmota/language/ru_RU.h
+++ b/tasmota/language/ru_RU.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "многократное нажатие"
#define D_NOISE "Шум"
#define D_NONE "Нет"
+#define D_O2 "Oxygen"
#define D_OFF "Выкл"
#define D_OFFLINE "Офф-лайн"
#define D_OK "Ок"
diff --git a/tasmota/language/sk_SK.h b/tasmota/language/sk_SK.h
index 7e8df3c03..873baf2ca 100644
--- a/tasmota/language/sk_SK.h
+++ b/tasmota/language/sk_SK.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-stlačenie"
#define D_NOISE "Hluk"
#define D_NONE "Žiadny"
+#define D_O2 "Oxygen"
#define D_OFF "Vyp."
#define D_OFFLINE "Neaktívny"
#define D_OK "OK"
diff --git a/tasmota/language/sv_SE.h b/tasmota/language/sv_SE.h
index 58283b3d5..90fd47d4c 100644
--- a/tasmota/language/sv_SE.h
+++ b/tasmota/language/sv_SE.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "fler tryck"
#define D_NOISE "Oväsen"
#define D_NONE "Ingen"
+#define D_O2 "Oxygen"
#define D_OFF "Av"
#define D_OFFLINE "Off-line"
#define D_OK "Ok"
diff --git a/tasmota/language/tr_TR.h b/tasmota/language/tr_TR.h
index 37564aa84..f8d13e8f6 100644
--- a/tasmota/language/tr_TR.h
+++ b/tasmota/language/tr_TR.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "multi-press"
#define D_NOISE "Noise"
#define D_NONE "None"
+#define D_O2 "Oxygen"
#define D_OFF "Off"
#define D_OFFLINE "Çevirimdışı"
#define D_OK "Tamam"
diff --git a/tasmota/language/uk_UA.h b/tasmota/language/uk_UA.h
index b926afada..499f42c1b 100644
--- a/tasmota/language/uk_UA.h
+++ b/tasmota/language/uk_UA.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "Багаторазове натискання"
#define D_NOISE "Шум"
#define D_NONE "Нічого"
+#define D_O2 "Oxygen"
#define D_OFF "Вимкнено"
#define D_OFFLINE "Неактивний"
#define D_OK "Ок"
diff --git a/tasmota/language/vi_VN.h b/tasmota/language/vi_VN.h
index eee00907c..42b95d930 100644
--- a/tasmota/language/vi_VN.h
+++ b/tasmota/language/vi_VN.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "bấm nhiều lần"
#define D_NOISE "Nhiễu"
#define D_NONE "Không"
+#define D_O2 "Oxygen"
#define D_OFF "Tắt"
#define D_OFFLINE "Ngoại tuyến"
#define D_OK "Ok"
diff --git a/tasmota/language/zh_CN.h b/tasmota/language/zh_CN.h
index 9a232796a..e475e360c 100644
--- a/tasmota/language/zh_CN.h
+++ b/tasmota/language/zh_CN.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "多次按键"
#define D_NOISE "嘈杂"
#define D_NONE "无"
+#define D_O2 "Oxygen"
#define D_OFF "关"
#define D_OFFLINE "离线"
#define D_OK "好"
diff --git a/tasmota/language/zh_TW.h b/tasmota/language/zh_TW.h
index fb93ef634..21a7d2d14 100644
--- a/tasmota/language/zh_TW.h
+++ b/tasmota/language/zh_TW.h
@@ -125,6 +125,7 @@
#define D_MULTI_PRESS "多重點擊"
#define D_NOISE "雜訊"
#define D_NONE "無"
+#define D_O2 "Oxygen"
#define D_OFF "關閉"
#define D_OFFLINE "離線"
#define D_OK "好"
diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h
index e1497d93a..d78bd097f 100644
--- a/tasmota/my_user_config.h
+++ b/tasmota/my_user_config.h
@@ -568,6 +568,7 @@
// #define USE_EZOHUM // [I2cDriver55] Enable support for EZO's HUM sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
// #define USE_EZOEC // [I2cDriver55] Enable support for EZO's EC sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
// #define USE_EZOCO2 // [I2cDriver55] Enable support for EZO's CO2 sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code)
+// #define USE_EZOO2 // [I2cDriver55] Enable support for EZO's O2 sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
// #define USE_DISPLAY // Add I2C Display Support (+2k code)
#define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0
diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h
index ed425a645..8391d696f 100644
--- a/tasmota/tasmota_configurations.h
+++ b/tasmota/tasmota_configurations.h
@@ -133,6 +133,7 @@
//#define USE_EZOHUM // [I2cDriver55] Enable support for EZO's HUM sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
//#define USE_EZOEC // [I2cDriver55] Enable support for EZO's EC sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
//#define USE_EZOCO2 // [I2cDriver55] Enable support for EZO's CO2 sensor (+0k2 code) - Shared EZO code required for any EZO device (+1k2 code)
+//#define USE_EZOO2 // [I2cDriver55] Enable support for EZO's O2 sensor (+0k3 code) - Shared EZO code required for any EZO device (+1k2 code)
#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code)
#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code)
diff --git a/tasmota/xsns_78_ezo.ino b/tasmota/xsns_78_ezo.ino
index 36fcea423..a970f8ddd 100644
--- a/tasmota/xsns_78_ezo.ino
+++ b/tasmota/xsns_78_ezo.ino
@@ -18,7 +18,7 @@
*/
#ifdef USE_I2C
-#if defined(USE_EZOPH) || defined(USE_EZOORP) || defined(USE_EZORTD) || defined(USE_EZOHUM) || defined(USE_EZOEC) || defined(USE_EZOCO2)
+#if defined(USE_EZOPH) || defined(USE_EZOORP) || defined(USE_EZORTD) || defined(USE_EZOHUM) || defined(USE_EZOEC) || defined(USE_EZOCO2) || defined(USE_EZOO2)
#define USE_EZO
#endif
#if defined(USE_EZO)
diff --git a/tasmota/xsns_78_ezoo2.ino b/tasmota/xsns_78_ezoo2.ino
new file mode 100644
index 000000000..bc98fe00c
--- /dev/null
+++ b/tasmota/xsns_78_ezoo2.ino
@@ -0,0 +1,60 @@
+/*
+ xsns_78_ezoo2.ino - EZO O2 I2C O2 sensor support for Tasmota
+
+ Copyright (C) 2020 Christopher Tremblay
+
+ 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_I2C
+#ifdef USE_EZOO2
+
+#define EZO_O2_READ_LATENCY 900
+
+struct EZOO2 : public EZOStruct {
+ EZOO2(uint32_t addr) : EZOStruct(addr), O2(0) {}
+
+ virtual void ProcessMeasurement(void)
+ {
+ char data[D_EZO_MAX_BUF];
+
+ EZOStruct::ProcessMeasurement(data, sizeof(data), EZO_O2_READ_LATENCY);
+ O2 = CharToFloat(data);
+ }
+
+ virtual void Show(bool json, const char *name)
+ {
+ char str[8];
+ dtostrfd(O2, 2, str);
+
+ if (json) {
+ ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_O2 "\":%d}" ), name, str);
+ }
+#ifdef USE_WEBSERVER
+ else {
+ WSContentSend_PD(HTTP_SNS_O2, name, str);
+#endif // USE_WEBSERVER
+ }
+ }
+
+ static const char id[] PROGMEM;
+
+private:
+ float O2;
+};
+
+const char EZOO2::id[] PROGMEM = "O2";
+
+#endif // USE_EZOO2
+#endif // USE_I2C
diff --git a/tasmota/xsns_78_xezo.ino b/tasmota/xsns_78_xezo.ino
index 0415c335d..db384adbb 100644
--- a/tasmota/xsns_78_xezo.ino
+++ b/tasmota/xsns_78_xezo.ino
@@ -49,29 +49,51 @@ enum {
-// Creates a complex preprocessor macro to fetch a specified class OR EZOStruct if it wasn't defined
-template struct IsComplete : std::false_type {};
-template struct IsComplete< T, decltype(void(sizeof(T))) > : std::true_type {};
-
-#define GET_EZO_CLASS(CLASS) std::conditional::value, CLASS, EZOStruct>::type
-
// The order of the EZO devices must map with the enum declared above
const char *const EZOSupport[EZO_ADDR_n] PROGMEM = {
EZOStruct::id, // "DO"
- GET_EZO_CLASS(EZOORP)::id,
- GET_EZO_CLASS(EZOPH)::id,
- GET_EZO_CLASS(EZOEC)::id,
+#ifdef USE_EZOORP
+ EZOORP::id,
+#else
EZOStruct::id,
- GET_EZO_CLASS(EZORTD)::id,
+#endif
+#ifdef USE_EZOPH
+ EZOPH::id,
+#else
+ EZOStruct::id,
+#endif
+#ifdef USE_EZOEC
+ EZOEC::id,
+#else
+ EZOStruct::id,
+#endif
+ EZOStruct::id,
+#ifdef USE_EZORTD
+ EZORTD::id,
+#else
+ EZOStruct::id,
+#endif
EZOStruct::id, // "PMP"
EZOStruct::id, // "FLO"
- GET_EZO_CLASS(EZOCO2)::id,
+#ifdef USE_EZOCO2
+ EZOCO2::id,
+#else
+ EZOStruct::id,
+#endif
EZOStruct::id, // "PRS"
EZOStruct::id,
- EZOStruct::id, // "O2"
+#ifdef USE_EZOO2
+ EZOO2::id,
+#else
+ EZOStruct::id,
+#endif
EZOStruct::id,
EZOStruct::id,
- GET_EZO_CLASS(EZOHUM)::id,
+#ifdef USE_EZOHUM
+ EZOHUM::id,
+#else
+ EZOStruct::id,
+#endif
EZOStruct::id, // "RGB"
};
@@ -219,11 +241,13 @@ private:
#ifdef USE_EZOCO2
CREATE_EZO_CLASS(CO2)
#endif
+#ifdef USE_EZOO2
+ CREATE_EZO_CLASS(O2)
+#endif
#ifdef USE_EZOHUM
CREATE_EZO_CLASS(HUM)
#endif
}
-
count++;
}
}