diff --git a/BUILDS.md b/BUILDS.md index 53ebba456..18f25042b 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -113,6 +113,7 @@ | USE_DHT12 | - | - | - | - | x | - | - | | USE_DS1624 | - | - | - | - | x | - | - | | USE_AHT1x | - | - | - | - | - | - | - | +| USE_HDC1080 | - | - | - | - | - | - | - | | USE_WEMOS_MOTOR_V1 | - | - | - | - | x | - | - | | | | | | | | | | | Feature or Sensor | minimal | lite | tasmota | knx | sensors | ir | display | Remarks diff --git a/I2CDEVICES.md b/I2CDEVICES.md index f9cf5b0e3..75c0a1a9a 100644 --- a/I2CDEVICES.md +++ b/I2CDEVICES.md @@ -66,3 +66,4 @@ Index | Define | Driver | Device | Address(es) | Description 42 | USE_DS1624 | xsns_59 | DS1624 | 0x48 - 0x4F | Temperature sensor 43 | USE_AHT1x | xsns_63 | AHT10/15 | 0x38 | Temperature and humidity sensor 44 | USE_WEMOS_MOTOR_V1 | xdrv_34 | | 0x2D - 0x30 | WEMOS motor shield v1.0.0 (6612FNG) + 45 | USE_HDC1080 | xsns_65 | HDC1080 | 0x40 | Temperature and Humidity sensor diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 0a6e1fbcb..a2757b96f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -87,6 +87,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add command ``ShutterButton `` to control shutter(s) by to-scho (#7403) - Add commands ``SwitchMode 8`` ToggleMulti, ``SwitchMode 9`` FollowMulti and ``SwitchMode 10`` FollowMultiInverted (#7522) - Add commands ``SwitchMode 11`` PushHoldMulti and ``SwitchMode 12`` PushHoldInverted (#7603) +- Add commands ``SwitchMode 13`` PushOn and ``SwitchMode 14`` PushOnInverted (#7912) - Add command ``Buzzer -1`` for infinite mode and command ``Buzzer -2`` for following led mode (#7623) - Add SerialConfig to ``Status 1`` - Add WifiPower to ``Status 5`` @@ -117,3 +118,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for MaxBotix HRXL-MaxSonar ultrasonic range finders by Jon Little (#7814) - Add support for Romanian language translations by Augustin Marti - Add HAss Discovery support for Button and Switch triggers by Federico Leoni (#7901) +- Add support for HDC1080 Temperature and Humidity sensor by Luis Teixeira (#7888) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 11d730543..2c23efc42 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,8 @@ ### 8.1.0.11 20200313 - Add HAss Discovery support for Button and Switch triggers by Federico Leoni (#7901) +- Add support for HDC1080 Temperature and Humidity sensor by Luis Teixeira (#7888) +- Add commands ``SwitchMode 13`` PushOn and ``SwitchMode 14`` PushOnInverted (#7912) ### 8.1.0.10 20200227 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index d7bbc8900..94af8e750 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -496,6 +496,7 @@ // #define USE_WEMOS_MOTOR_V1 // [I2cDriver44] Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) // #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 // #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency +// #define USE_HDC1080 // [I2cDriver45] Enable HDC1080 temperature/humidity sensor (I2C address 0x40) (+1k5 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/support_device_groups.ino b/tasmota/support_device_groups.ino index fe1e94482..ed751fca1 100644 --- a/tasmota/support_device_groups.ino +++ b/tasmota/support_device_groups.ino @@ -335,7 +335,7 @@ void _SendDeviceGroupMessage(uint8_t device_group_index, DeviceGroupMessageType if (item > DGR_ITEM_MAX_16BIT) { value >>= 8; *message_ptr++ = value & 0xff; - *message_ptr++ = value >> 8; + *message_ptr++ = (item == DGR_ITEM_POWER ? devices_present : value >> 8); } } } @@ -591,6 +591,8 @@ void ProcessDeviceGroupMessage(char * packet, int packet_length) if (DeviceGroupItemShared(true, item)) { if (item == DGR_ITEM_POWER) { + uint8_t mask_devices = value >> 24; + if (mask_devices > devices_present) mask_devices = devices_present; for (uint32_t i = 0; i < devices_present; i++) { uint32_t mask = 1 << i; bool on = (value & mask); diff --git a/tasmota/support_features.ino b/tasmota/support_features.ino index 961dd1091..201711e48 100644 --- a/tasmota/support_features.ino +++ b/tasmota/support_features.ino @@ -539,7 +539,9 @@ void GetFeatures(void) #ifdef USE_SONOFF_D1 feature6 |= 0x00000004; // xdrv_37_sonoff_d1.ino #endif -// feature6 |= 0x00000008; +#ifdef USE_HDC1080 + feature6 |= 0x00000008; // xsns_65_hdc1080.ino +#endif // feature6 |= 0x00000010; // feature6 |= 0x00000020; diff --git a/tasmota/support_switch.ino b/tasmota/support_switch.ino index e873ea200..7acdda409 100644 --- a/tasmota/support_switch.ino +++ b/tasmota/support_switch.ino @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#define SWITCH_V2 -#ifdef SWITCH_V2 +#define SWITCH_V3 +#ifdef SWITCH_V3 /*********************************************************************************************\ * Switch support with input filter * @@ -166,20 +166,20 @@ void SwitchHandler(uint8_t mode) switchflag = ~button &1; // Follow inverted wall switch state after hold break; case PUSHHOLDMULTI: - if (NOT_PRESSED == button){ + if (NOT_PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25; SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT - } - else + } else { SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT + } break; case PUSHHOLDMULTI_INV: - if (PRESSED == button){ + if (PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 25; SendKey(KEY_SWITCH, i +1, POWER_INCREMENT); // Execute command via MQTT - } - else + } else { SendKey(KEY_SWITCH, i +1, POWER_CLEAR); // Execute command via MQTT + } break; default: SendKey(KEY_SWITCH, i +1, POWER_HOLD); // Execute command via MQTT @@ -188,9 +188,7 @@ void SwitchHandler(uint8_t mode) } } -// enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, MAX_SWITCH_OPTION}; - - if (button != Switch.last_state[i]) { + if (button != Switch.last_state[i]) { // This implies if ((PRESSED == button) then (NOT_PRESSED == Switch.last_state[i])) switch (Settings.switchmode[i]) { case TOGGLE: case PUSHBUTTON_TOGGLE: @@ -203,29 +201,35 @@ void SwitchHandler(uint8_t mode) switchflag = ~button &1; // Follow inverted wall switch state break; case PUSHBUTTON: - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { +// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { + if (PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with pushbutton to Gnd } break; case PUSHBUTTON_INV: - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { +// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { + if (NOT_PRESSED == button) { switchflag = POWER_TOGGLE; // Toggle with releasing pushbutton from Gnd } break; case PUSHBUTTONHOLD: - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { +// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { + if (PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press } - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { +// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { + if ((NOT_PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer... switchflag = POWER_TOGGLE; // ...and Toggle } break; case PUSHBUTTONHOLD_INV: - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { +// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { + if (NOT_PRESSED == button) { Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; // Start timer on button press... } - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { +// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i]) && (Switch.hold_timer[i])) { + if ((PRESSED == button) && (Switch.hold_timer[i])) { Switch.hold_timer[i] = 0; // Button released and hold timer not expired : stop timer. switchflag = POWER_TOGGLE; // ...and Toggle } @@ -253,29 +257,47 @@ void SwitchHandler(uint8_t mode) } break; case PUSHHOLDMULTI: - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - if(Switch.hold_timer[i]!=0) +// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { + if (NOT_PRESSED == button) { + if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT + } Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - if(Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) +// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { + if (PRESSED == button) { + if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } break; case PUSHHOLDMULTI_INV: - if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { - if(Switch.hold_timer[i]!=0) +// if ((PRESSED == button) && (NOT_PRESSED == Switch.last_state[i])) { + if (PRESSED == button) { + if (Switch.hold_timer[i] != 0) { SendKey(KEY_SWITCH, i +1, POWER_INV); // Execute command via MQTT + } Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } - if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { - if(Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) +// if ((NOT_PRESSED == button) && (PRESSED == Switch.last_state[i])) { + if (NOT_PRESSED == button) { + if (Switch.hold_timer[i] > loops_per_second * Settings.param[P_HOLD_TIME] / 25) { switchflag = POWER_TOGGLE; // Toggle with pushbutton + } Switch.hold_timer[i] = loops_per_second * Settings.param[P_HOLD_TIME] / 10; } break; + case PUSHON: + if (PRESSED == button) { + switchflag = POWER_ON; // Power ON with pushbutton to Gnd + } + break; + case PUSHON_INV: + if (NOT_PRESSED == button) { + switchflag = POWER_ON; // Power ON with releasing pushbutton from Gnd + } + break; } Switch.last_state[i] = button; } @@ -298,4 +320,4 @@ void SwitchLoop(void) } } -#endif // SWITCH_V2 +#endif // SWITCH_V3 diff --git a/tasmota/tasmota.h b/tasmota/tasmota.h index 8585bc020..a1c7d1082 100644 --- a/tasmota/tasmota.h +++ b/tasmota/tasmota.h @@ -233,7 +233,7 @@ enum LoggingLevels {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_D enum WifiConfigOptions {WIFI_RESTART, EX_WIFI_SMARTCONFIG, WIFI_MANAGER, EX_WIFI_WPSCONFIG, WIFI_RETRY, WIFI_WAIT, WIFI_SERIAL, WIFI_MANAGER_RESET_ONLY, MAX_WIFI_OPTION}; enum SwitchModeOptions {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTONHOLD, PUSHBUTTONHOLD_INV, PUSHBUTTON_TOGGLE, TOGGLEMULTI, - FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, MAX_SWITCH_OPTION}; + FOLLOWMULTI, FOLLOWMULTI_INV, PUSHHOLDMULTI, PUSHHOLDMULTI_INV, PUSHON, PUSHON_INV, MAX_SWITCH_OPTION}; enum LedStateOptions {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION}; @@ -317,7 +317,7 @@ enum DeviceGroupItem { DGR_ITEM_EOL, DGR_ITEM_STATUS, DGR_ITEM_LAST_16BIT, DGR_ITEM_MAX_16BIT = 127, DGR_ITEM_POWER, DGR_ITEM_DIMMER_RANGE, // Add new 32-bit items before this line - DGR_ITEM_LAST_32BIT, DGR_ITEM_MAX_32BIT = 191, + DGR_ITEM_LAST_32BIT, DGR_ITEM_MAX_32BIT = 191, // Add new string items before this line DGR_ITEM_LAST_STRING, DGR_ITEM_MAX_STRING = 223, DGR_ITEM_LIGHT_CHANNELS }; diff --git a/tasmota/tasmota_post.h b/tasmota/tasmota_post.h index 7cf0fff75..1abd371ff 100644 --- a/tasmota/tasmota_post.h +++ b/tasmota/tasmota_post.h @@ -185,6 +185,7 @@ extern "C" void custom_crash_callback(struct rst_info * rst_info, uint32_t stack #define USE_WEMOS_MOTOR_V1 // Enable Wemos motor driver V1 (I2C addresses 0x2D - 0x30) (+0k7 code) #define WEMOS_MOTOR_V1_ADDR 0x30 // Default I2C address 0x30 #define WEMOS_MOTOR_V1_FREQ 1000 // Default frequency +//#define USE_HDC1080 // Enable HDC1080 temperature/humidity sensor #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_65_hdc1080.ino b/tasmota/xsns_65_hdc1080.ino new file mode 100644 index 000000000..59f0f75f2 --- /dev/null +++ b/tasmota/xsns_65_hdc1080.ino @@ -0,0 +1,349 @@ +/* + xsns_65_hdc1080.ino - Texas Instruments HDC1080 temperature and humidity sensor support for Tasmota + + Copyright (C) 2020 Luis Teixeira + + 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_HDC1080 + +/*********************************************************************************************\ + * HDC1080 - Temperature and Humidy sensor + * + * Source: Luis Teixeira + * + * I2C Address: 0x40 +\*********************************************************************************************/ + +#define XSNS_65 65 +#define XI2C_45 45 // See I2CDEVICES.md + +#define HDC1080_ADDR 0x40 + +// Registers: + +#define HDC_REG_TEMP 0x00 // Temperature register +#define HDC_REG_RH 0x01 // Humidity register +#define HDC_REG_CONFIG 0x02 // Configuration register +#define HDC_REG_SERIAL1 0xFB // First 2 bytes of the serial ID +#define HDC_REG_SERIAL2 0xFC // Mid 2 bytes of the serial ID +#define HDC_REG_SERIAL3 0xFD // Last bits of the serial ID +#define HDC_REG_MAN_ID 0xFE // Manufacturer ID +#define HDC_REG_DEV_ID 0xFF // Device ID + +// Expected constant values of some of the registers: + +#define HDC1080_MAN_ID 0x5449 // Manufacturer ID (Texas Instruments) +#define HDC1080_DEV_ID 0x1050 // Device ID (valid for the HDC1080) + +// Possible values for the configuration register fields: + +#define HDC1080_RST_ON 0x8000 +#define HDC1080_HEAT_ON 0x2000 +#define HDC1080_MODE_ON 0x1000 // acquision mode (temperature + humidity) +#define HDC1080_TRES_11 0x400 +#define HDC1080_HRES_11 0x100 +#define HDC1080_HRES_8 0x80 + +// Constants: + +#define HDC1080_CONV_TIME 15 // Assume 6.50 + 6.35 ms + x of conversion delay for this device +#define HDC1080_TEMP_MULT 0.0025177 +#define HDC1080_RH_MULT 0.0025177 +#define HDC1080_TEMP_OFFSET 40.0 + +const char* hdc_type_name = "HDC1080"; +uint16_t hdc_manufacturer_id = 0; +uint16_t hdc_device_id = 0; + +float hdc_temperature = 0.0; +float hdc_humidity = 0.0; + +uint8_t hdc_valid = 0; + +bool is_reading = false; +uint32_t hdc_next_read; + +/** + * Reads the device ID register. + * + */ +uint16_t HdcReadDeviceId(void) { + return I2cRead16(HDC1080_ADDR, HDC_REG_DEV_ID); +} + +/** + * Reads the manufacturer ID register. + * + */ +uint16_t HdcReadManufacturerId(void) { + return I2cRead16(HDC1080_ADDR, HDC_REG_MAN_ID); +} + +/** + * Overwrites the configuration register with the provided config + */ +void HdcConfig(uint16_t config) { + I2cWrite16(HDC1080_ADDR, HDC_REG_CONFIG, config); +} + +/** + * Performs a soft reset on the device. + * + * RST = 1 -> software reset + * + */ +void HdcReset(void) { + uint16_t current = I2cRead16(HDC1080_ADDR, HDC_REG_CONFIG); + + // bit 15 of the configuration register contains the RST flag + // so we set it to 1: + + current |= 0x8000; + + I2cWrite16(HDC1080_ADDR, HDC_REG_CONFIG, current); + + delay(HDC1080_CONV_TIME); // Not sure how long it takes to reset. Assuming this value. +} + +/** + * Performs the write portion of the HDC1080 sensor transaction. This + * action of writing to a register signals the beginning of the operation + * (e.g. data acquisition). + * + * addr: the address of the I2C device we are talking to. + * reg: the register where we are writing to. + * + * returns: 0 if the transmission was successfully completed, != 0 otherwise. + */ +int8_t HdcTransactionOpen(uint8_t addr, uint8_t reg) { + Wire.beginTransmission((uint8_t) addr); + Wire.write((uint8_t) reg); + return Wire.endTransmission(); +} + +/** + * Performs the read portion of the HDC1080 sensor transaction. + * + * addr: the address of the I2C device we are talking to. + * reg_data: the pointer to the memory location where we will place the bytes that were read from the device + * len: the number of bytes we expect to read + * + * returns: if the read operation was successful. != 0 otherwise. + */ +int8_t HdcTransactionClose(uint8_t addr, uint8_t *reg_data, uint16_t len) { + if (len != Wire.requestFrom((uint8_t) addr, (uint8_t) len)) { + return 1; + } + + while (len--) { + *reg_data = (uint8_t)Wire.read(); + reg_data++; + } + + return 0; +} + +/** + * The various initialization steps for this sensor. + * + */ +void HdcInit(void) { + HdcReset(); + HdcConfig(HDC1080_MODE_ON); +} + +/** + * Triggers the single transaction read of the T/RH sensor. + * + */ +bool HdcTriggerRead(void) { + int8_t status = HdcTransactionOpen(HDC1080_ADDR, HDC_REG_TEMP); + + hdc_next_read = millis() + HDC1080_CONV_TIME; + + if(status) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("HdcTriggerRead: failed to open the transaction for HDC_REG_TEMP. Status = %d"), status); + + return false; + } + + is_reading = true; + + return true; +} + +/** + * Performs a temperature and humidity measurement, and calls + * the conversion function providing the results in the correct + * unit according to the device settings. + * + * returns: false if something failed during the read process. + * + */ +bool HdcRead(void) { + int8_t status = 0; + uint8_t sensor_data[4]; + uint16_t temp_data = 0; + uint16_t rh_data = 0; + + is_reading = false; + + status = HdcTransactionClose(HDC1080_ADDR, sensor_data, 4); + + if(status) { + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("HdcRead: failed to read HDC_REG_TEMP. Status = %d"), status); + + return false; + } + + temp_data = (uint16_t) ((sensor_data[0] << 8) | sensor_data[1]); + rh_data = (uint16_t) ((sensor_data[2] << 8) | sensor_data[3]); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("HdcRead: temperature raw data: 0x%04x; humidity raw data: 0x%04x"), temp_data, rh_data); + + // read the temperature from the first 16 bits of the result + + hdc_temperature = ConvertTemp(HDC1080_TEMP_MULT * (float) (temp_data) - HDC1080_TEMP_OFFSET); + + hdc_humidity = HDC1080_RH_MULT * (float) (rh_data); + + if (hdc_humidity > 100) { hdc_humidity = 100.0; } + if (hdc_humidity < 0) { hdc_humidity = 0.01; } + + ConvertHumidity(hdc_humidity); // Set global humidity + + hdc_valid = SENSOR_MAX_MISS; + + return true; +} + +/** + * Performs the detection of the HTC1080 sensor. + * + */ + +void HdcDetect(void) { + if (I2cActive(HDC1080_ADDR)) { +// AddLog_P2(LOG_LEVEL_DEBUG, PSTR("HdcDetect: Address = 0x%02X already in use."), HDC1080_ADDR); + + return; + } + + hdc_manufacturer_id = HdcReadManufacturerId(); + hdc_device_id = HdcReadDeviceId(); + + AddLog_P2(LOG_LEVEL_DEBUG, PSTR("HdcDetect: detected device with manufacturerId = 0x%04X and deviceId = 0x%04X"), hdc_manufacturer_id, hdc_device_id); + + if (hdc_device_id == HDC1080_DEV_ID) { + HdcInit(); + I2cSetActiveFound(HDC1080_ADDR, hdc_type_name); + } +} + +/** + * As the name suggests, this function is called every second + * for performing driver related logic. + * + */ +void HdcEverySecond(void) { + if (uptime &1) { // Every 2 seconds + if (!HdcTriggerRead()) { + AddLogMissed((char*) hdc_type_name, hdc_valid); + } + } +} + +/** + * Tasmota boilerplate for presenting the sensor data in the web UI, JSON for + * the MQTT messages, and so on. + * + */ +void HdcShow(bool json) { + if (hdc_valid) { + char temperature[33]; + + dtostrfd(hdc_temperature, Settings.flag2.temperature_resolution, temperature); + char humidity[33]; + dtostrfd(hdc_humidity, Settings.flag2.humidity_resolution, humidity); + + if (json) { + ResponseAppend_P(JSON_SNS_TEMPHUM, hdc_type_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, hdc_temperature); + KnxSensor(KNX_HUMIDITY, hdc_humidity); + } +#endif // USE_KNX +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_SNS_TEMP, hdc_type_name, temperature, TempUnit()); + WSContentSend_PD(HTTP_SNS_HUM, hdc_type_name, humidity); +#endif // USE_WEBSERVER + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xsns65(uint8_t function) +{ + if (!I2cEnabled(XI2C_45)) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR("Xsns65: I2C driver not enabled for this device.")); + + return false; + } + + bool result = false; + + if (FUNC_INIT == function) { + HdcDetect(); + } + else if (hdc_device_id) { + switch (function) { + case FUNC_EVERY_50_MSECOND: + if(is_reading && TimeReached(hdc_next_read)) { + if(!HdcRead()) { + AddLogMissed((char*) hdc_type_name, hdc_valid); + } + } + break; + case FUNC_EVERY_SECOND: + HdcEverySecond(); + break; + case FUNC_JSON_APPEND: + HdcShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_SENSOR: + HdcShow(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_HDC1080 +#endif // USE_I2C + diff --git a/tools/decode-status.py b/tools/decode-status.py index fe80630cc..25af64a97 100755 --- a/tools/decode-status.py +++ b/tools/decode-status.py @@ -198,7 +198,7 @@ a_features = [[ "USE_NRF24","USE_MIBLE","USE_HM10","USE_LE01MR", "USE_AHT1x","USE_WEMOS_MOTOR_V1","USE_DEVICE_GROUPS","USE_PWM_DIMMER" ],[ - "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","", + "USE_KEELOQ","USE_HRXL","USE_SONOFF_D1","USE_HDC1080", "","","","", "","","","", "","","","", @@ -239,7 +239,7 @@ else: obj = json.load(fp) def StartDecode(): - print ("\n*** decode-status.py v20200305 by Theo Arends and Jacek Ziolkowski ***") + print ("\n*** decode-status.py v20200314 by Theo Arends and Jacek Ziolkowski ***") # print("Decoding\n{}".format(obj))