diff --git a/tasmota/xsns_91_vindriktning.ino b/tasmota/xsns_91_vindriktning.ino index 640eeede9..07bb58a89 100644 --- a/tasmota/xsns_91_vindriktning.ino +++ b/tasmota/xsns_91_vindriktning.ino @@ -19,25 +19,28 @@ #ifdef USE_VINDRIKTNING /*********************************************************************************************\ - * IKEA VINDRIKTNING particle concentration sensor + * IKEA VINDRIKTNING PM2.5 particle concentration sensor + * + * This sensor uses a subset of the PM1006K LED particle sensor + * To use Tasmota the user needs to add an ESP8266 or ESP32 \*********************************************************************************************/ -#define XSNS_91 91 +#define XSNS_91 91 + +//#define XSNS_91_XTRA_INFO // Display unverified data for PM1.0 and PM10 #include -#ifndef MIN_INTERVAL_PERIOD -#define MIN_INTERVAL_PERIOD 60 // minimum interval period in seconds required for passive mode -#endif - #define VINDRIKTNING_DATASET_SIZE 20 TasmotaSerial *VindriktningSerial; struct VINDRIKTNING { uint16_t pm2_5 = 0; +#ifdef XSNS_91_XTRA_INFO uint16_t pm1_0 = 0; uint16_t pm10 = 0; +#endif // XSNS_91_XTRA_INFO uint8_t type = 1; uint8_t valid = 0; bool discovery_triggered = false; @@ -48,26 +51,16 @@ bool VindriktningReadData(void) { return false; } - int serial_in_byte_counter = 0; uint8_t buffer[VINDRIKTNING_DATASET_SIZE]; - uint8_t crc = 0; - - while (VindriktningSerial->available()) { - uint8_t serial_in_byte = VindriktningSerial->read(); - if (serial_in_byte_counter <= VINDRIKTNING_DATASET_SIZE -1) { - buffer[serial_in_byte_counter++] = serial_in_byte; - crc += serial_in_byte; - } - } + VindriktningSerial->readBytes(buffer, VINDRIKTNING_DATASET_SIZE); VindriktningSerial->flush(); // Make room for another burst AddLogBuffer(LOG_LEVEL_DEBUG_MORE, buffer, VINDRIKTNING_DATASET_SIZE); - if (serial_in_byte_counter < VINDRIKTNING_DATASET_SIZE) { - AddLog(LOG_LEVEL_DEBUG, PSTR("VDN: Not enough data (%d < 20)"), serial_in_byte_counter); - return false; + uint8_t crc = 0; + for (uint32_t i = 0; i < VINDRIKTNING_DATASET_SIZE; i++) { + crc += buffer[i]; } - if (crc != 0) { AddLog(LOG_LEVEL_DEBUG, PSTR("VDN: " D_CHECKSUM_FAILURE)); return false; @@ -75,10 +68,12 @@ bool VindriktningReadData(void) { // sample data: // 16 11 0b 00 00 00 0c 00 00 03 cb 00 00 00 0c 01 00 00 00 e7 - // |pm2_5| |pm1_0| |pm10 | | CRC | + // |pm2_5| |pm1_0| |pm10 | | CRC | Vindriktning.pm2_5 = (buffer[5] << 8) | buffer[6]; +#ifdef XSNS_91_XTRA_INFO Vindriktning.pm1_0 = (buffer[9] << 8) | buffer[10]; Vindriktning.pm10 = (buffer[13] << 8) | buffer[14]; +#endif // XSNS_91_XTRA_INFO if (!Vindriktning.discovery_triggered) { TasmotaGlobal.discovery_counter = 1; // force TasDiscovery() @@ -91,7 +86,7 @@ bool VindriktningReadData(void) { void VindriktningSecond(void) { // Every second if (VindriktningReadData()) { - Vindriktning.valid = MIN_INTERVAL_PERIOD; + Vindriktning.valid = 60; } else { if (Vindriktning.valid) { Vindriktning.valid--; @@ -112,6 +107,8 @@ void VindriktningInit(void) { } } +#ifdef XSNS_91_XTRA_INFO + #ifdef USE_WEBSERVER const char HTTP_VINDRIKTNING_SNS[] PROGMEM = "{s}VINDRIKTNING " D_ENVIRONMENTAL_CONCENTRATION " 1.0 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}" @@ -122,8 +119,7 @@ const char HTTP_VINDRIKTNING_SNS[] PROGMEM = void VindriktningShow(bool json) { if (Vindriktning.valid) { if (json) { - ResponseAppend_P(PSTR(",\"VINDRIKTNING\":{\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"), - Vindriktning.pm1_0, Vindriktning.pm2_5, Vindriktning.pm10); + ResponseAppend_P(PSTR(",\"VINDRIKTNING\":{\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"), Vindriktning.pm1_0, Vindriktning.pm2_5, Vindriktning.pm10); #ifdef USE_DOMOTICZ if (0 == TasmotaGlobal.tele_period) { DomoticzSensor(DZ_COUNT, Vindriktning.pm1_0); // PM1.0 @@ -139,6 +135,32 @@ void VindriktningShow(bool json) { } } +#else // No XSNS_91_XTRA_INFO + +#ifdef USE_WEBSERVER +const char HTTP_VINDRIKTNING_SNS[] PROGMEM = + "{s}VINDRIKTNING " D_ENVIRONMENTAL_CONCENTRATION " 2.5 " D_UNIT_MICROMETER "{m}%d " D_UNIT_MICROGRAM_PER_CUBIC_METER "{e}"; +#endif // USE_WEBSERVER + +void VindriktningShow(bool json) { + if (Vindriktning.valid) { + if (json) { + ResponseAppend_P(PSTR(",\"VINDRIKTNING\":{\"PM2.5\":%d}"), Vindriktning.pm2_5); +#ifdef USE_DOMOTICZ + if (0 == TasmotaGlobal.tele_period) { + DomoticzSensor(DZ_VOLTAGE, Vindriktning.pm2_5); // PM2.5 + } +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { + WSContentSend_PD(HTTP_VINDRIKTNING_SNS, Vindriktning.pm2_5); +#endif // USE_WEBSERVER + } + } +} + +#endif // XSNS_91_XTRA_INFO + /*********************************************************************************************\ * Interface \*********************************************************************************************/