/* xsns_97_hyt.ino - HYT I2C temperature and humidity sensor support for Tasmota Copyright (C) 2020 Thomas Schnittcher Copyright (C) 2022 Adjan Kretz, fix compatibility issues with current HYT 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_HYT /*********************************************************************************************\ * HYT221, HYT271, HYT371 and HYT939 Temperature and Humidity * https://www.ist-ag.com/en/products-services/humidity-modules-sensors * * I2C Address: 0x28 \*********************************************************************************************/ #define XSNS_97 97 #define XI2C_68 68 // See I2CDEVICES.md #define HYT_ADDR 0x28 // I2C address of HYT 221, 271, 371 etc. struct HYT { float humidity = NAN; float temperature = NAN; uint8_t bus; uint8_t valid = 0; uint8_t count = 0; char name[6] = "HYT"; } HYT; bool HYT_Read(void) { if (HYT.valid) { HYT.valid--; } TwoWire& myWire = I2cGetWire(HYT.bus); if (&myWire == nullptr) { return false; } // No valid I2c bus myWire.beginTransmission(HYT_ADDR); myWire.requestFrom(HYT_ADDR, 4); if (myWire.available() == 4) { uint8_t data1 = myWire.read(); uint8_t data2 = myWire.read(); uint8_t data3 = myWire.read(); uint8_t data4 = myWire.read(); myWire.endTransmission(); // Convert the data to 14-bits float humidity = ((((data1 & 0x3F) * 256) + data2) * 100.0) / 16383.0; int temp = ((data3 * 256) + (data4 & 0xFC)) / 4; float temperature = (temp / 16384.0) * 165.0 - 40.0; HYT.humidity = ConvertHumidity(humidity); HYT.temperature = ConvertTemp(temperature); } if (isnan(HYT.temperature) || isnan(HYT.humidity)) { return false; } HYT.valid = SENSOR_MAX_MISS; // HYT.valid = 1; return true; } /********************************************************************************************/ void HYT_Detect(void) { for (HYT.bus = 0; HYT.bus < 2; HYT.bus++) { if (!I2cSetDevice(HYT_ADDR, HYT.bus)) { continue; } if (HYT_Read()) { I2cSetActiveFound(HYT_ADDR, "HYT", HYT.bus); HYT.count = 1; break; } } } /********************************************************************************************/ void HYT_EverySecond(void) { if (!(TasmotaGlobal.uptime %4)) { // Every 4 seconds if (!HYT_Read()) { AddLogMissed(HYT.name, HYT.valid); } } } void HYT_Show(bool json) { if (HYT.valid) { TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), HYT.name, HYT.temperature, HYT.humidity); } } /*********************************************************************************************\ * Interface \*********************************************************************************************/ bool Xsns97(uint32_t function) { if (!I2cEnabled(XI2C_68)) { return false; } bool result = false; if (FUNC_INIT == function) { HYT_Detect(); } else if (HYT.count) { switch (function) { case FUNC_EVERY_SECOND: HYT_EverySecond(); break; case FUNC_JSON_APPEND: HYT_Show(1); break; #ifdef USE_WEBSERVER case FUNC_WEB_SENSOR: HYT_Show(0); break; #endif // USE_WEBSERVER } } return result; } #endif // USE_HYT #endif // USE_I2C