ESPHome 2026.5.1
Loading...
Searching...
No Matches
zyaura.cpp
Go to the documentation of this file.
1#include "zyaura.h"
2#include "esphome/core/log.h"
3
4namespace esphome::zyaura {
5
6static const char *const TAG = "zyaura";
7
8bool IRAM_ATTR ZaDataProcessor::decode(uint32_t ms, bool data) {
9 // check if a new message has started, based on time since previous bit
10 if ((ms - this->prev_ms_) > ZA_MAX_MS) {
11 this->num_bits_ = 0;
12 }
13 this->prev_ms_ = ms;
14
15 // number of bits received is basically the "state"
16 if (this->num_bits_ < ZA_FRAME_SIZE) {
17 // store it while it fits
18 int idx = this->num_bits_ / 8;
19 this->buffer_[idx] = (this->buffer_[idx] << 1) | (data ? 1 : 0);
20 this->num_bits_++;
21
22 // are we done yet?
23 if (this->num_bits_ == ZA_FRAME_SIZE) {
24 // validate checksum
25 uint8_t checksum = this->buffer_[ZA_BYTE_TYPE] + this->buffer_[ZA_BYTE_HIGH] + this->buffer_[ZA_BYTE_LOW];
26 if (checksum != this->buffer_[ZA_BYTE_SUM] || this->buffer_[ZA_BYTE_END] != ZA_MSG_DELIMETER) {
27 return false;
28 }
29
30 this->message->type = (ZaDataType) this->buffer_[ZA_BYTE_TYPE];
31 this->message->value = this->buffer_[ZA_BYTE_HIGH] << 8 | this->buffer_[ZA_BYTE_LOW];
32 return true;
33 }
34 }
35
36 return false;
37}
38
40 pin_clock->setup();
41 pin_data->setup();
42 this->pin_clock_ = pin_clock->to_isr();
43 this->pin_data_ = pin_data->to_isr();
45}
46
48 uint32_t now = millis();
49 bool data_bit = arg->pin_data_.digital_read();
50
51 if (arg->processor_.decode(now, data_bit)) {
52 arg->set_data_(arg->processor_.message);
53 }
54}
55
57 switch (message->type) {
58 case HUMIDITY:
59 this->humidity = message->value;
60 break;
61 case TEMPERATURE:
62 this->temperature = message->value;
63 break;
64 case CO2:
65 this->co2 = message->value;
66 break;
67 }
68}
69
70bool ZyAuraSensor::publish_state_(ZaDataType data_type, sensor::Sensor *sensor, uint16_t *data_value) {
71 // Sensor wasn't added to configuration
72 if (sensor == nullptr) {
73 return true;
74 }
75
76 float value = NAN;
77 switch (data_type) {
78 case HUMIDITY:
79 value = (*data_value > 10000) ? NAN : (*data_value / 100.0f);
80 break;
81 case TEMPERATURE:
82 value = (*data_value > 5970) ? NAN : (*data_value / 16.0f - 273.15f);
83 break;
84 case CO2:
85 value = (*data_value > 10000) ? NAN : *data_value;
86 break;
87 }
88
89 sensor->publish_state(value);
90
91 // Sensor reported wrong value
92 if (std::isnan(value)) {
93 ESP_LOGW(TAG, "Sensor reported invalid data. Is the update interval too small?");
94 this->status_set_warning();
95 return false;
96 }
97
98 *data_value = -1;
99 return true;
100}
101
103 ESP_LOGCONFIG(TAG, "ZyAuraSensor:");
104 LOG_PIN(" Pin Clock: ", this->pin_clock_);
105 LOG_PIN(" Pin Data: ", this->pin_data_);
106 LOG_UPDATE_INTERVAL(this);
107
108 LOG_SENSOR(" ", "CO2", this->co2_sensor_);
109 LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
110 LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
111}
112
114 bool co2_result = this->publish_state_(CO2, this->co2_sensor_, &this->store_.co2);
115 bool temperature_result = this->publish_state_(TEMPERATURE, this->temperature_sensor_, &this->store_.temperature);
116 bool humidity_result = this->publish_state_(HUMIDITY, this->humidity_sensor_, &this->store_.humidity);
117
118 if (co2_result && temperature_result && humidity_result) {
119 this->status_clear_warning();
120 }
121}
122
123} // namespace esphome::zyaura
uint8_t checksum
Definition bl0906.h:3
void status_clear_warning()
Definition component.h:306
virtual void setup()=0
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition gpio.h:107
virtual ISRInternalGPIOPin to_isr() const =0
Base-class for all sensors.
Definition sensor.h:47
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:68
uint8_t buffer_[ZA_MSG_LEN]
Definition zyaura.h:37
bool decode(uint32_t ms, bool data)
Definition zyaura.cpp:8
void set_data_(ZaMessage *message)
Definition zyaura.cpp:56
ZaDataProcessor processor_
Definition zyaura.h:54
ISRInternalGPIOPin pin_data_
Definition zyaura.h:53
void setup(InternalGPIOPin *pin_clock, InternalGPIOPin *pin_data)
Definition zyaura.cpp:39
static void interrupt(ZaSensorStore *arg)
Definition zyaura.cpp:47
ISRInternalGPIOPin pin_clock_
Definition zyaura.h:52
sensor::Sensor * temperature_sensor_
Definition zyaura.h:77
InternalGPIOPin * pin_clock_
Definition zyaura.h:74
sensor::Sensor * humidity_sensor_
Definition zyaura.h:78
InternalGPIOPin * pin_data_
Definition zyaura.h:75
void dump_config() override
Definition zyaura.cpp:102
bool publish_state_(ZaDataType data_type, sensor::Sensor *sensor, uint16_t *data_value)
Definition zyaura.cpp:70
sensor::Sensor * co2_sensor_
Definition zyaura.h:76
const char * message
Definition component.cpp:35
@ INTERRUPT_FALLING_EDGE
Definition gpio.h:51
uint32_t IRAM_ATTR HOT millis()
Definition hal.cpp:28
static void uint32_t