ESPHome  2024.4.1
zyaura.cpp
Go to the documentation of this file.
1 #include "zyaura.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace zyaura {
6 
7 static const char *const TAG = "zyaura";
8 
9 bool 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 
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 
71 bool 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
void set_data_(ZaMessage *message)
Definition: zyaura.cpp:57
void update() override
Definition: zyaura.cpp:114
virtual void setup()=0
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:25
static void interrupt(ZaSensorStore *arg)
Definition: zyaura.cpp:48
void setup(InternalGPIOPin *pin_clock, InternalGPIOPin *pin_data)
Definition: zyaura.cpp:40
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
ISRInternalGPIOPin pin_data_
Definition: zyaura.h:54
uint16_t temperature
Definition: sun_gtil2.cpp:26
uint8_t checksum
Definition: bl0939.h:35
ZaDataProcessor processor_
Definition: zyaura.h:55
bool publish_state_(ZaDataType data_type, sensor::Sensor *sensor, uint16_t *data_value)
Definition: zyaura.cpp:71
void dump_config() override
Definition: zyaura.cpp:103
virtual ISRInternalGPIOPin to_isr() const =0
uint8_t buffer_[ZA_MSG_LEN]
Definition: zyaura.h:38
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
Base-class for all sensors.
Definition: sensor.h:57
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
Definition: gpio.h:81
bool decode(uint32_t ms, bool data)
Definition: zyaura.cpp:9