diff --git a/docs/devices/H5140.md b/docs/devices/H5140.md new file mode 100644 index 00000000..31927157 --- /dev/null +++ b/docs/devices/H5140.md @@ -0,0 +1,12 @@ +# Govee H5140 + +|Model Id|[H5140](https://github.com/theengs/decoder/blob/development/src/devices/H5140_json.h)| +|-|-| +|Brand|Govee| +|Model|Smart CO2 Monitor| +|Short Description|Air quality monitor with temperature, humidity and CO2| +|Communication|BLE broadcast| +|Frequency|2.4Ghz| +|Power Source|USB-C| +|Exchanged Data|temperature, humidity, CO2| +|Encrypted|No| diff --git a/src/decoder.h b/src/decoder.h index 4772d73f..6a2c048b 100644 --- a/src/decoder.h +++ b/src/decoder.h @@ -92,6 +92,7 @@ class TheengsDecoder { H5074, H5102, H5106, + H5140, H5179, H5179_N, HHCCJCY10, diff --git a/src/devices.h b/src/devices.h index 7763e683..869b6c7f 100644 --- a/src/devices.h +++ b/src/devices.h @@ -36,6 +36,7 @@ #include "devices/H5074_json.h" #include "devices/H5102_json.h" #include "devices/H5106_json.h" +#include "devices/H5140_json.h" #include "devices/H5179_json.h" #include "devices/HHCCJCY10_json.h" #include "devices/HHCCJCY01HHCC_json.h" @@ -188,6 +189,7 @@ const char* _devices[][2] = { {_H5074_json, _H5074_json_props}, {_H5102_json, _H5102_json_props}, {_H5106_json, _H5106_json_props}, + {_H5140_json, _H5140_json_props}, {_H5179_json, _H5179_json_props}, {_H5179_json_N, _H5179_json_props}, {_HHCCJCY10_json, _HHCCJCY10_json_props}, diff --git a/src/devices/H5140_json.h b/src/devices/H5140_json.h new file mode 100644 index 00000000..2bf472ff --- /dev/null +++ b/src/devices/H5140_json.h @@ -0,0 +1,69 @@ +const char* _H5140_json = "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"tag\":\"0f03\",\"condition\":[\"name\",\"contain\",\"GV5140\",\"&\",\"manufacturerdata\",\">=\",20,\"index\",0,\"01000101\"],\"properties\":{\"tempc\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,6,false,false],\"post_proc\":[\"/\",10000]},\"hum\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",8,6,false,false],\"post_proc\":[\"&\",2147483647,\"%\",1000,\"/\",10]},\"co2\":{\"decoder\":[\"value_from_hex_data\",\"manufacturerdata\",14,4,false,false]}}}"; +/* R""""( +{ + "brand":"Govee", + "model":"Smart CO2 Monitor", + "model_id":"H5140", + "tag":"0f03", + "condition":["name", "contain", "GV5140", "&", "manufacturerdata", ">=", 20, "index", 0, "01000101"], + "properties":{ + "tempc":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 6, false, false], + "post_proc":["/", 10000] + }, + "hum":{ + "decoder":["value_from_hex_data", "manufacturerdata", 8, 6, false, false], + "post_proc":["&", 2147483647, "%", 1000, "/", 10] + }, + "co2":{ + "decoder":["value_from_hex_data", "manufacturerdata", 14, 4, false, false] + } + } +})"""";*/ + +/* + * Govee H5140 Smart CO2 Monitor - BLE Manufacturer Data Format + * ============================================================= + * + * Advertisement name pattern: GV5140XXXX (where XXXX is device suffix) + * Manufacturer data: 20 hex characters (10 bytes) + * + * Byte layout: + * Positions 0-7: 01000101 (constant header) + * Positions 8-13: XXXXXX (24-bit combined temp/humidity) + * Positions 14-17: YYYY (16-bit CO2 in ppm, big-endian) + * Positions 18-19: 00 (padding/unknown) + * + * Decoding formulas: + * - temp_celsius = 24bit_value / 10000 + * - humidity_percent = (24bit_value % 1000) / 10 + * - co2_ppm = 16bit_value + * + * Example: 0100010103fcbf044c00 + * - Header: 01000101 + * - Temp/Hum: 03fcbf = 261311 decimal + * - Temperature: 261311 / 10000 = 26.13°C (79.04°F) + * - Humidity: (261311 % 1000) / 10 = 31.1% + * - CO2: 044c = 1100 ppm + * + * Tested with OpenMQTTGateway on ESP32 + */ + +const char* _H5140_json_props = "{\"properties\":{\"tempc\":{\"unit\":\"°C\",\"name\":\"temperature\"},\"hum\":{\"unit\":\"%\",\"name\":\"humidity\"},\"co2\":{\"unit\":\"ppm\",\"name\":\"carbon_dioxide\"}}}"; +/*R""""( +{ + "properties":{ + "tempc":{ + "unit":"°C", + "name":"temperature" + }, + "hum":{ + "unit":"%", + "name":"humidity" + }, + "co2":{ + "unit":"ppm", + "name":"carbon_dioxide" + } + } +})"""";*/ diff --git a/tests/BLE/test_ble.cpp b/tests/BLE/test_ble.cpp index 833dad55..bf2b444f 100644 --- a/tests/BLE/test_ble.cpp +++ b/tests/BLE/test_ble.cpp @@ -237,6 +237,9 @@ const char* expected_mfg[] = { "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"volt\":12.99,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"volt\":14.01,\"tempc\":17.5,\"tempf\":63.5,\"alarm_reason\":0}", "{\"brand\":\"Victron Energy\",\"model\":\"Smart Battery Sense\",\"model_id\":\"VICTSBS\",\"type\":\"ENRG\",\"track\":true,\"volt\":12.22,\"tempc\":22.5,\"tempf\":72.5,\"alarm_reason\":0}", + "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":26.1311,\"tempf\":79.03598,\"hum\":31.1,\"co2\":1100}", + "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":15.56,\"tempf\":60.008,\"hum\":60,\"co2\":500}", + "{\"brand\":\"Govee\",\"model\":\"Smart CO2 Monitor\",\"model_id\":\"H5140\",\"type\":\"AIR\",\"cidc\":false,\"acts\":true,\"tempc\":23.8048,\"tempf\":74.84864,\"hum\":4.8,\"co2\":1700}", }; const char* expected_name_uuid_mfgsvcdata[] = { @@ -828,6 +831,9 @@ const char* test_mfgdata[][3] = { {"Victron Smart Battery Sense", "", "e1021180a5a302ffff7bffff130500008971feff7fffffffff"}, {"Victron Smart Battery Sense", "", "e1021180a5a302ffff7bffff790500008971feff7fffffffff"}, {"Victron Smart Battery Sense", "", "e1021100a4a302ffff7cffffc60400007d73feff7fffffffff"}, + {"H5140", "GV5140_1234", "0100010103fcbf044c00"}, + {"H5140", "GV5140_1234", "01000101025fd001f400"}, + {"H5140", "GV5140_1234", "0100010103a1e006a400"}, }; TheengsDecoder::BLE_ID_NUM test_mfgdata_id_num[]{ @@ -1048,6 +1054,9 @@ TheengsDecoder::BLE_ID_NUM test_mfgdata_id_num[]{ TheengsDecoder::BLE_ID_NUM::VICTSBS, TheengsDecoder::BLE_ID_NUM::VICTSBS, TheengsDecoder::BLE_ID_NUM::VICTSBS, + TheengsDecoder::BLE_ID_NUM::H5140, + TheengsDecoder::BLE_ID_NUM::H5140, + TheengsDecoder::BLE_ID_NUM::H5140, }; // uuid test input [test name] [device name] [uuid] [manufacturer data] [service data]