Skip to content

HC8 sensor support #19714

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 13, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions tasmota/include/tasmota_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ enum UserSelectablePins {
GPIO_DSB, GPIO_DSB_OUT, // DS18B20 or DS18S20
GPIO_WS2812, // WS2812 Led string
GPIO_MHZ_TXD, GPIO_MHZ_RXD, // MH-Z19 Serial interface
GPIO_HC8_RXD, // HC8 Serial interface
GPIO_PZEM0XX_TX, GPIO_PZEM004_RX, GPIO_PZEM016_RX, GPIO_PZEM017_RX, // PZEM Serial Modbus interface
GPIO_SAIR_TX, GPIO_SAIR_RX, // SenseAir Serial interface
GPIO_PMS5003_TX, GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface
Expand Down Expand Up @@ -302,6 +303,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "_o|"
D_SENSOR_WS2812 "|"
D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|"
D_SENSOR_HC8_RX "|"
D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|"
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
D_SENSOR_PMS5003_TX "|" D_SENSOR_PMS5003_RX "|"
Expand Down Expand Up @@ -959,6 +961,9 @@ const uint16_t kGpioNiceList[] PROGMEM = {
AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface
AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface
#endif
#ifdef USE_HC8
AGPIO(GPIO_HC8_RXD), // HC8 Serial interface
#endif
#ifdef USE_SENSEAIR
AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface
AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/af_AF.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRontvanger"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/bg_BG.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/ca_AD.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "Receptor IR"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/cs_CZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/de_DE.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/el_GR.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/en_GB.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/es_ES.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IR Rx"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/fr_FR.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IR Rx"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/fy_NL.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/he_HE.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/hu_HU.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IR vevő"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/it_IT.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IR - RX"
#define D_SENSOR_MHZ_RX "MHZ - RX"
#define D_SENSOR_MHZ_TX "MHZ - TX"
#define D_SENSOR_HC8_RX "HC8 - Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 - RX"
#define D_SENSOR_PZEM016_RX "PZEM016 - RX"
#define D_SENSOR_PZEM017_RX "PZEM017 - RX"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/ko_KO.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/nl_NL.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/pl_PL.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/pt_BR.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/pt_PT.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/ro_RO.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/ru_RU.h
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/sk_SK.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/sv_SE.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/tr_TR.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/uk_UA.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/vi_VN.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/zh_CN.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
1 change: 1 addition & 0 deletions tasmota/language/zh_TW.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,7 @@
#define D_SENSOR_IRRECV "IRrecv"
#define D_SENSOR_MHZ_RX "MHZ Rx"
#define D_SENSOR_MHZ_TX "MHZ Tx"
#define D_SENSOR_HC8_RX "HC8 Rx"
#define D_SENSOR_PZEM004_RX "PZEM004 Rx"
#define D_SENSOR_PZEM016_RX "PZEM016 Rx"
#define D_SENSOR_PZEM017_RX "PZEM017 Rx"
Expand Down
146 changes: 146 additions & 0 deletions tasmota/tasmota_xsns_sensor/xsns_113_hc8.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*
xsns_113_hc8.ino - HC8 CO2 sensor support for Tasmota

Copyright (C) 2023 Daniel Maier

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 <http://www.gnu.org/licenses/>.
*/

#ifdef USE_HC8
/*********************************************************************************************\
* HC8 - CO2 sensor
*
* Hardware Serial will be selected if GPIO1 = [HC8 Rx]
*/

#define XSNS_113 113


/*********************************************************************************************\
* Source: https://spezifisch.codeberg.page/posts/2022-08-23/co2-sensor-reverse-engineering/
*
\*********************************************************************************************/

#include <TasmotaSerial.h>

TasmotaSerial *Hc8Serial;

uint16_t hc8_last_ppm = 0;
bool Hc8Initialized = false;

/*********************************************************************************************/


uint8_t Hc8CalculateChecksum(uint8_t *array) {
uint8_t checksum = 0;
for(int i = 0; i < 15; i++) {
checksum += array[i];
}
return checksum;
}

void Hc8EverySecond(void)
{
if(!Hc8Initialized)
return;

uint8_t hc8_response[16];
if(Hc8Serial->available() >= 16) {
while(Hc8Serial->available()) {
hc8_response[0] = Hc8Serial->read();
if(hc8_response[0] == 0x42)
break;
}

for(int i = 1; i < 16; i++) {
hc8_response[i] = Hc8Serial->read();
}

if(*(uint16_t*)hc8_response != 0x4d42) {
return;
}

uint8_t checksum = Hc8CalculateChecksum(hc8_response);
if(hc8_response[15] != checksum) {
return;
}

hc8_last_ppm = (hc8_response[6]<<8) | hc8_response[7];
}
}

void Hc8Init(void)
{
if (PinUsed(GPIO_HC8_RXD)) {
Hc8Serial = new TasmotaSerial(Pin(GPIO_HC8_RXD), -1, 1);
if (Hc8Serial->begin(9600)) {
if (Hc8Serial->hardwareSerial()) { ClaimSerial(); }
Hc8Initialized = true;
}
}
}

void Hc8Show(bool json)
{
char types[4] = "HC8";
char model[4] = "HC8";

if (json) {
ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_MODEL "\":\"%s\",\"" D_JSON_CO2 "\":\"%d\"}"),
types, model, hc8_last_ppm);
#ifdef USE_DOMOTICZ
if (0 == TasmotaGlobal.tele_period) {
DomoticzSensor(DZ_AIRQUALITY, hc8_last_ppm);
}
#endif // USE_DOMOTICZ
#ifdef USE_WEBSERVER
} else {
WSContentSend_PD(HTTP_SNS_CO2, types, hc8_last_ppm);
#endif // USE_WEBSERVER
}
}


/*********************************************************************************************\
* Interface
\*********************************************************************************************/

bool Xsns113(uint32_t function)
{
bool result = false;
switch (function) {
case FUNC_INIT:
Hc8Init();
break;
case FUNC_EVERY_SECOND:
Hc8EverySecond();
break;
case FUNC_COMMAND_SENSOR:
if (XSNS_113 == XdrvMailbox.index) {
result = true;
}
break;
case FUNC_JSON_APPEND:
Hc8Show(1);
break;
#ifdef USE_WEBSERVER
case FUNC_WEB_SENSOR:
Hc8Show(0);
break;
#endif // USE_WEBSERVER
}
return result;
}

#endif // USE_HC8