9 namespace mopeka_std_check {
11 static const char *
const TAG =
"mopeka_std_check";
12 static const uint16_t SERVICE_UUID = 0xADA0;
13 static const uint8_t MANUFACTURER_DATA_LENGTH = 23;
14 static const uint16_t MANUFACTURER_ID = 0x000D;
17 ESP_LOGCONFIG(TAG,
"Mopeka Std Check");
19 ESP_LOGCONFIG(TAG,
" Tank distance empty: %" PRIi32
"mm", this->
empty_mm_);
20 ESP_LOGCONFIG(TAG,
" Tank distance full: %" PRIi32
"mm", this->
full_mm_);
21 LOG_SENSOR(
" ",
"Level", this->
level_);
24 LOG_SENSOR(
" ",
"Reading Distance", this->
distance_);
39 ESP_LOGVV(TAG,
"parse_device(): MAC address %s found.", device.
address_str().c_str());
45 if (service_uuids.size() != 1) {
48 const auto &service_uuid = service_uuids[0];
56 if (manu_datas.size() != 1) {
57 ESP_LOGE(TAG,
"[%s] Unexpected manu_datas size (%d)", device.
address_str().c_str(), manu_datas.size());
61 const auto &manu_data = manu_datas[0];
65 if (manu_data.data.size() != MANUFACTURER_DATA_LENGTH) {
66 ESP_LOGE(TAG,
"[%s] Unexpected manu_data size (%d)", device.
address_str().c_str(), manu_data.data.size());
73 const u_int8_t hardware_id = mopeka_data->data_1 & 0xCF;
74 if (static_cast<SensorType>(hardware_id) !=
STANDARD && static_cast<SensorType>(hardware_id) !=
XL &&
75 static_cast<SensorType>(hardware_id) !=
ETRAILER) {
76 ESP_LOGE(TAG,
"[%s] Unsupported Sensor Type (0x%X)", device.
address_str().c_str(), hardware_id);
80 ESP_LOGVV(TAG,
"[%s] Sensor slow update rate: %d", device.
address_str().c_str(), mopeka_data->slow_update_rate);
81 ESP_LOGVV(TAG,
"[%s] Sensor sync pressed: %d", device.
address_str().c_str(), mopeka_data->sync_pressed);
82 for (u_int8_t i = 0; i < 3; i++) {
83 ESP_LOGVV(TAG,
"[%s] %u. Sensor data %u time %u.", device.
address_str().c_str(), (i * 4) + 1,
84 mopeka_data->val[i].value_0, mopeka_data->val[i].time_0);
85 ESP_LOGVV(TAG,
"[%s] %u. Sensor data %u time %u.", device.
address_str().c_str(), (i * 4) + 2,
86 mopeka_data->val[i].value_1, mopeka_data->val[i].time_1);
87 ESP_LOGVV(TAG,
"[%s] %u. Sensor data %u time %u.", device.
address_str().c_str(), (i * 4) + 3,
88 mopeka_data->val[i].value_2, mopeka_data->val[i].time_2);
89 ESP_LOGVV(TAG,
"[%s] %u. Sensor data %u time %u.", device.
address_str().c_str(), (i * 4) + 4,
90 mopeka_data->val[i].value_3, mopeka_data->val[i].time_3);
113 std::array<u_int8_t, 12> measurements_time = {};
114 std::array<u_int8_t, 12> measurements_value = {};
117 u_int8_t measurements_index = 0;
118 for (u_int8_t i = 0; i < 3; i++) {
119 measurements_time[measurements_index] = mopeka_data->val[i].time_0 + 1;
120 measurements_value[measurements_index] = mopeka_data->val[i].value_0;
121 measurements_index++;
122 measurements_time[measurements_index] = mopeka_data->val[i].time_1 + 1;
123 measurements_value[measurements_index] = mopeka_data->val[i].value_1;
124 measurements_index++;
125 measurements_time[measurements_index] = mopeka_data->val[i].time_2 + 1;
126 measurements_value[measurements_index] = mopeka_data->val[i].value_2;
127 measurements_index++;
128 measurements_time[measurements_index] = mopeka_data->val[i].time_3 + 1;
129 measurements_value[measurements_index] = mopeka_data->val[i].value_3;
130 measurements_index++;
135 u_int8_t number_of_usable_values = 0;
136 u_int16_t best_value = 0;
137 u_int16_t best_time = 0;
139 u_int16_t measurement_time = 0;
140 for (u_int8_t i = 0; i < 12; i++) {
142 measurement_time += measurements_time[i];
143 if (measurements_value[i] != 0) {
145 number_of_usable_values++;
146 if (measurements_value[i] > best_value) {
148 best_value = measurements_value[i];
149 best_time = measurement_time;
152 measurement_time = 0;
157 ESP_LOGV(TAG,
"[%s] Found %u values with best data %u time %u.", device.
address_str().c_str(),
158 number_of_usable_values, best_value, best_time);
160 if (number_of_usable_values < 1 || best_value < 2 || best_time < 2) {
162 ESP_LOGW(TAG,
"[%s] Poor read quality. Setting distance to 0.", device.
address_str().c_str());
166 if (this->
level_ !=
nullptr) {
171 ESP_LOGV(TAG,
"[%s] Speed of sound in current fluid %f m/s", device.
address_str().c_str(), lpg_speed_of_sound);
173 uint32_t distance_value = lpg_speed_of_sound * best_time / 100.0f;
181 if (this->
level_ !=
nullptr) {
182 uint8_t tank_level = 0;
183 if (distance_value >= this->
full_mm_) {
185 }
else if (distance_value > this->
empty_mm_) {
197 return 1040.71f - 4.87f * temperature - 137.5f * this->
propane_butane_mix_ - 0.0107f * temperature * temperature -
202 const float voltage = (float) ((message->
raw_voltage / 256.0f) * 2.0f + 1.5f);
203 ESP_LOGVV(TAG,
"Sensor battery voltage: %f V", voltage);
205 const float percent = (voltage - 2.2f) / 0.65f * 100.0f;
206 if (percent < 0.0f) {
209 if (percent > 100.0f) {
212 return (uint8_t) percent;
220 return (uint8_t) ((tmp - 25.0f) * 1.776964f);
std::string format_hex_pretty(const uint8_t *data, size_t length)
Format the byte array data of length len in pretty-printed, human-readable hex.
sensor::Sensor * temperature_
sensor::Sensor * distance_
bool parse_device(const esp32_ble_tracker::ESPBTDevice &device) override
Main parse function that gets called for all ble advertisements.
std::string address_str() const
const std::vector< ServiceData > & get_manufacturer_datas() const
uint8_t parse_temperature_(const mopeka_std_package *message)
const std::vector< ESPBTUUID > & get_service_uuids() const
sensor::Sensor * battery_level_
void dump_config() override
float get_lpg_speed_of_sound_(float temperature)
static ESPBTUUID from_uint16(uint16_t uuid)
void publish_state(float state)
Publish a new state to the front-end.
float propane_butane_mix_
uint8_t parse_battery_level_(const mopeka_std_package *message)
uint64_t address_uint64() const
Implementation of SPI Controller mode.