diff --git a/components/philips_coffee_machine/number/beverage_setting.cpp b/components/philips_coffee_machine/number/beverage_setting.cpp index ceb69eb..c030679 100644 --- a/components/philips_coffee_machine/number/beverage_setting.cpp +++ b/components/philips_coffee_machine/number/beverage_setting.cpp @@ -23,11 +23,8 @@ namespace esphome target_amount_ = (std::isnan(value) || std::isnan(state)) ? -1 : value; } - void BeverageSetting::update_status(uint8_t *data, size_t len) + void BeverageSetting::update_status(uint8_t *data) { - // reject invalid messages - if (len < 19 && data[0] != message_header[0] && data[1] != message_header[1]) - return; if (!status_sensor_->has_state()) return; diff --git a/components/philips_coffee_machine/number/beverage_setting.h b/components/philips_coffee_machine/number/beverage_setting.h index df0a980..5bbaf9e 100644 --- a/components/philips_coffee_machine/number/beverage_setting.h +++ b/components/philips_coffee_machine/number/beverage_setting.h @@ -110,10 +110,9 @@ namespace esphome /** * @brief Updates the sensor value based on the incoming messages. - * @param data incoming data from the motherboard - * @param len length of the incoming data + * @param data incoming data from the motherboard (19 bytes) */ - void update_status(uint8_t *data, size_t len); + void update_status(uint8_t *data); private: /// @brief Setting type to which this component applies diff --git a/components/philips_coffee_machine/philips_coffee_machine.cpp b/components/philips_coffee_machine/philips_coffee_machine.cpp index 65599e8..37edad2 100644 --- a/components/philips_coffee_machine/philips_coffee_machine.cpp +++ b/components/philips_coffee_machine/philips_coffee_machine.cpp @@ -1,7 +1,8 @@ #include "esphome/core/log.h" #include "philips_coffee_machine.h" -#define BUFFER_SIZE 32 +#define MAINBOARD_BUFFER_SIZE 19 +#define DISPLAY_BUFFER_SIZE 12 namespace esphome { @@ -19,13 +20,14 @@ namespace esphome void PhilipsCoffeeMachine::loop() { - uint8_t buffer[BUFFER_SIZE]; + uint8_t display_buffer[DISPLAY_BUFFER_SIZE]; + uint8_t mainboard_buffer[MAINBOARD_BUFFER_SIZE]; // Pipe display to mainboard if (display_uart_.available()) { - uint8_t size = std::min(display_uart_.available(), BUFFER_SIZE); - display_uart_.read_array(buffer, size); + uint8_t size = std::min(display_uart_.available(), DISPLAY_BUFFER_SIZE); + display_uart_.read_array(display_buffer, size); // Check if a action button is currently performing a long press bool long_pressing = false; @@ -42,43 +44,58 @@ namespace esphome // Drop messages if button long-press is currently injecting messages if (!long_pressing) - mainboard_uart_.write_array(buffer, size); + mainboard_uart_.write_array(display_buffer, size); last_message_from_display_time_ = millis(); } - // Read until start index + // Read and forward until valid start bytes have been received while (mainboard_uart_.available()) { - uint8_t buffer = mainboard_uart_.peek(); - if (buffer == message_header[0]) - break; - display_uart_.write(mainboard_uart_.read()); + mainboard_buffer[0] = mainboard_uart_.read(); + display_uart_.write(mainboard_buffer[0]); + if (mainboard_buffer[0] == message_header[0]) + { + mainboard_buffer[1] = mainboard_uart_.read(); + display_uart_.write(mainboard_buffer[1]); + if (mainboard_buffer[1] == message_header[1]) + { + break; + } + } } // Pipe to display if (mainboard_uart_.available()) { - uint8_t size = std::min(mainboard_uart_.available(), BUFFER_SIZE); - mainboard_uart_.read_array(buffer, size); + uint8_t size = std::min(mainboard_uart_.available(), MAINBOARD_BUFFER_SIZE - 2); + mainboard_uart_.read_array(mainboard_buffer + 2, size); - display_uart_.write_array(buffer, size); + display_uart_.write_array(mainboard_buffer + 2, size); - // Only process messages starting with start bytes - if (size > 1 && buffer[0] == message_header[0] && buffer[1] == message_header[1]) + if (size >= MAINBOARD_BUFFER_SIZE - 2) { - last_message_from_mainboard_time_ = millis(); - + // Only process messages starting with start bytes + // Only process duplicate messages (crude checksum alternative) + // TODO: figure out how the checksum is calculated and only parse valid messages + if (mainboard_buffer[0] == message_header[0] && + mainboard_buffer[1] == message_header[1] && + std::equal(mainboard_buffer + 17, mainboard_buffer + 19, std::begin(last_mainboard_message_checksum_))) + { + last_message_from_mainboard_time_ = millis(); #ifdef USE_TEXT_SENSOR - // Update status sensors - for (philips_status_sensor::StatusSensor *status_sensor : status_sensors_) - status_sensor->update_status(buffer, size); + // Update status sensors + for (philips_status_sensor::StatusSensor *status_sensor : status_sensors_) + status_sensor->update_status(mainboard_buffer); #ifdef USE_NUMBER - // Update beverage settings - for (philips_beverage_setting::BeverageSetting *beverage_setting : beverage_settings_) - beverage_setting->update_status(buffer, size); + // Update beverage settings + for (philips_beverage_setting::BeverageSetting *beverage_setting : beverage_settings_) + beverage_setting->update_status(mainboard_buffer); #endif #endif + } + // retain last checksum for comparison with next checksum + std::copy_n(mainboard_buffer + 17, 2, last_mainboard_message_checksum_); } } diff --git a/components/philips_coffee_machine/philips_coffee_machine.h b/components/philips_coffee_machine/philips_coffee_machine.h index 4ce2365..dd085f1 100644 --- a/components/philips_coffee_machine/philips_coffee_machine.h +++ b/components/philips_coffee_machine/philips_coffee_machine.h @@ -148,6 +148,9 @@ namespace esphome uint32_t last_message_from_mainboard_time_ = 0; uint32_t last_message_from_display_time_ = 0; + /// @brief the last received mainboard message checksum; new messages are compared to this as a kind of pseudo-checksum + uint8_t last_mainboard_message_checksum_[2] = {0x00}; + /// @brief reference to uart connected to the display unit uart::UARTDevice display_uart_; diff --git a/components/philips_coffee_machine/text_sensor/status_sensor.cpp b/components/philips_coffee_machine/text_sensor/status_sensor.cpp index daae769..93f3ef4 100644 --- a/components/philips_coffee_machine/text_sensor/status_sensor.cpp +++ b/components/philips_coffee_machine/text_sensor/status_sensor.cpp @@ -18,13 +18,8 @@ namespace esphome ESP_LOGCONFIG(TAG, "Philips Status Text Sensor"); } - void StatusSensor::update_status(uint8_t *data, size_t len) + void StatusSensor::update_status(uint8_t *data) { - // reject invalid messages - if (len < 19 && data[0] != message_header[0] && data[1] != message_header[1]) - return; - - // TODO: figure out how the checksum is calculated and only parse valid messages // Check if the play/pause button is on/off/blinking if ((data[16] == led_on) != play_pause_led_) diff --git a/components/philips_coffee_machine/text_sensor/status_sensor.h b/components/philips_coffee_machine/text_sensor/status_sensor.h index 5857caf..71f251a 100644 --- a/components/philips_coffee_machine/text_sensor/status_sensor.h +++ b/components/philips_coffee_machine/text_sensor/status_sensor.h @@ -28,8 +28,9 @@ namespace esphome /** * @brief Updates the status of this sensor based on the messages sent by the mainboard + * @param data incoming data from the motherboard (19 bytes) */ - void update_status(uint8_t *data, size_t len); + void update_status(uint8_t *data); /** * @brief Sets the status to Off