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