#pragma once #include "esphome/core/component.h" #include "esphome/core/defines.h" #include "esphome/core/log.h" #include "esphome/components/uart/uart.h" #ifdef USE_SENSOR #include "esphome/components/sensor/sensor.h" #endif #ifdef USE_BINARY_SENSOR #include "esphome/components/binary_sensor/binary_sensor.h" #endif #ifdef USE_TEXT_SENSOR #include "esphome/components/text_sensor/text_sensor.h" #endif #ifdef USE_NUMBER #include "esphome/components/number/number.h" #endif #ifdef USE_SELECT #include "esphome/components/select/select.h" #endif #ifdef USE_SWITCH #include "esphome/components/switch/switch.h" #endif #include "decode.h" #include "commands.h" #include "helpers.h" #include #include #include namespace esphome { namespace panasonic_heatpump { enum LoopState { READ_RESPONSE, CHECK_RESPONSE, SET_NUMBER_TRAITS, PUBLISH_SENSOR, PUBLISH_BINARY_SENSOR, PUBLISH_TEXT_SENSOR, PUBLISH_NUMBER, PUBLISH_SELECT, PUBLISH_SWITCH, SEND_REQUEST, READ_REQUEST, RESTART_LOOP }; enum RequestType { INITIAL, POLLING, COMMAND, NONE }; class PanasonicHeatpumpComponent : public PollingComponent, public uart::UARTDevice { public: // ToDo: Add template for custom sensor classes similar to SUB_SENSOR (see Pipsolar) #ifdef USE_SENSOR SUB_SENSOR(top1); SUB_SENSOR(top5); SUB_SENSOR(top6); SUB_SENSOR(top7); SUB_SENSOR(top8); SUB_SENSOR(top9); SUB_SENSOR(top10); SUB_SENSOR(top11); SUB_SENSOR(top12); SUB_SENSOR(top14); SUB_SENSOR(top15); SUB_SENSOR(top16); SUB_SENSOR(top21); SUB_SENSOR(top22); SUB_SENSOR(top23); SUB_SENSOR(top24); SUB_SENSOR(top25); SUB_SENSOR(top27); SUB_SENSOR(top28); SUB_SENSOR(top29); SUB_SENSOR(top30); SUB_SENSOR(top31); SUB_SENSOR(top32); SUB_SENSOR(top33); SUB_SENSOR(top34); SUB_SENSOR(top35); SUB_SENSOR(top36); SUB_SENSOR(top37); SUB_SENSOR(top38); SUB_SENSOR(top39); SUB_SENSOR(top40); SUB_SENSOR(top41); SUB_SENSOR(top42); SUB_SENSOR(top43); SUB_SENSOR(top45); SUB_SENSOR(top46); SUB_SENSOR(top47); SUB_SENSOR(top48); SUB_SENSOR(top49); SUB_SENSOR(top50); SUB_SENSOR(top51); SUB_SENSOR(top52); SUB_SENSOR(top53); SUB_SENSOR(top54); SUB_SENSOR(top55); SUB_SENSOR(top56); SUB_SENSOR(top57); SUB_SENSOR(top62); SUB_SENSOR(top63); SUB_SENSOR(top64); SUB_SENSOR(top65); SUB_SENSOR(top66); SUB_SENSOR(top67); SUB_SENSOR(top70); SUB_SENSOR(top71); SUB_SENSOR(top72); SUB_SENSOR(top73); SUB_SENSOR(top74); SUB_SENSOR(top75); SUB_SENSOR(top77); SUB_SENSOR(top78); SUB_SENSOR(top79); SUB_SENSOR(top80); SUB_SENSOR(top82); SUB_SENSOR(top83); SUB_SENSOR(top84); SUB_SENSOR(top85); SUB_SENSOR(top86); SUB_SENSOR(top87); SUB_SENSOR(top88); SUB_SENSOR(top89); SUB_SENSOR(top90); SUB_SENSOR(top91); SUB_SENSOR(top93); SUB_SENSOR(top95); SUB_SENSOR(top96); SUB_SENSOR(top97); SUB_SENSOR(top98); SUB_SENSOR(top102); SUB_SENSOR(top103); SUB_SENSOR(top104); SUB_SENSOR(top105); SUB_SENSOR(top113); SUB_SENSOR(top115); SUB_SENSOR(top116); SUB_SENSOR(top117); SUB_SENSOR(top118); SUB_SENSOR(top127); SUB_SENSOR(top128); SUB_SENSOR(top131); SUB_SENSOR(top134); SUB_SENSOR(top135); SUB_SENSOR(top136); SUB_SENSOR(top137); SUB_SENSOR(top138); #endif #ifdef USE_BINARY_SENSOR SUB_BINARY_SENSOR(top0); SUB_BINARY_SENSOR(top2); SUB_BINARY_SENSOR(top3); SUB_BINARY_SENSOR(top13); SUB_BINARY_SENSOR(top26); SUB_BINARY_SENSOR(top60); SUB_BINARY_SENSOR(top61); SUB_BINARY_SENSOR(top68); SUB_BINARY_SENSOR(top69); SUB_BINARY_SENSOR(top99); SUB_BINARY_SENSOR(top100); SUB_BINARY_SENSOR(top108); SUB_BINARY_SENSOR(top109); SUB_BINARY_SENSOR(top110); SUB_BINARY_SENSOR(top119); SUB_BINARY_SENSOR(top120); SUB_BINARY_SENSOR(top121); SUB_BINARY_SENSOR(top122); SUB_BINARY_SENSOR(top123); SUB_BINARY_SENSOR(top124); SUB_BINARY_SENSOR(top129); SUB_BINARY_SENSOR(top132); SUB_BINARY_SENSOR(top133); #endif #ifdef USE_TEXT_SENSOR SUB_TEXT_SENSOR(top4); SUB_TEXT_SENSOR(top17); SUB_TEXT_SENSOR(top18); SUB_TEXT_SENSOR(top19); SUB_TEXT_SENSOR(top20); SUB_TEXT_SENSOR(top44); SUB_TEXT_SENSOR(top58); SUB_TEXT_SENSOR(top59); SUB_TEXT_SENSOR(top76); SUB_TEXT_SENSOR(top81); SUB_TEXT_SENSOR(top92); SUB_TEXT_SENSOR(top94); SUB_TEXT_SENSOR(top101); SUB_TEXT_SENSOR(top106); SUB_TEXT_SENSOR(top107); SUB_TEXT_SENSOR(top111); SUB_TEXT_SENSOR(top112); SUB_TEXT_SENSOR(top114); SUB_TEXT_SENSOR(top125); SUB_TEXT_SENSOR(top126); SUB_TEXT_SENSOR(top130); #endif #ifdef USE_NUMBER SUB_NUMBER(set5); SUB_NUMBER(set6); SUB_NUMBER(set7); SUB_NUMBER(set8); SUB_NUMBER(set11); SUB_NUMBER(set15); SUB_NUMBER(set16_1); SUB_NUMBER(set16_2); SUB_NUMBER(set16_3); SUB_NUMBER(set16_4); SUB_NUMBER(set16_5); SUB_NUMBER(set16_6); SUB_NUMBER(set16_7); SUB_NUMBER(set16_8); SUB_NUMBER(set16_9); SUB_NUMBER(set16_10); SUB_NUMBER(set16_11); SUB_NUMBER(set16_12); SUB_NUMBER(set16_13); SUB_NUMBER(set16_14); SUB_NUMBER(set16_15); SUB_NUMBER(set16_16); SUB_NUMBER(set18); SUB_NUMBER(set19); SUB_NUMBER(set20); SUB_NUMBER(set21); SUB_NUMBER(set22); SUB_NUMBER(set23); SUB_NUMBER(set27); SUB_NUMBER(set29); SUB_NUMBER(set36); SUB_NUMBER(set37); SUB_NUMBER(set38); void control_number(number::Number* object, float value); #endif #ifdef USE_SELECT SUB_SELECT(set2); SUB_SELECT(set3); SUB_SELECT(set4); SUB_SELECT(set9); SUB_SELECT(set17); SUB_SELECT(set26); SUB_SELECT(set35); void control_select(select::Select* object, size_t value); #endif #ifdef USE_SWITCH SUB_SWITCH(set1); SUB_SWITCH(set10); SUB_SWITCH(set12); SUB_SWITCH(set13); SUB_SWITCH(set14); SUB_SWITCH(set24); SUB_SWITCH(set25); SUB_SWITCH(set28); SUB_SWITCH(set30); SUB_SWITCH(set31); SUB_SWITCH(set32); SUB_SWITCH(set33); SUB_SWITCH(set34); void control_switch(switch_::Switch* object, bool state); #endif PanasonicHeatpumpComponent() = default; // base class functions float get_setup_priority() const override { return setup_priority::DATA; } void dump_config() override; void setup() override; void update() override; void loop() override; // option functions void set_uart_client(uart::UARTComponent* uart) { this->uart_client_ = uart; } void set_log_uart_msg(bool enable) { this->log_uart_msg_ = enable; } // uart message variables to use in lambda functions int getResponseByte(const int index); protected: // options variables uart::UARTComponent* uart_client_ { nullptr }; bool log_uart_msg_ { false }; // uart message variables std::vector heatpump_message_; std::vector response_message_; std::vector request_message_; std::vector command_message_; uint8_t payload_length_; uint8_t byte_; uint8_t current_response_count_ { 0 }; uint8_t last_response_count_ { 0 }; bool response_receiving_ { false }; bool request_receiving_ { false }; RequestType next_request_ { RequestType::INITIAL }; LoopState loop_state_ { LoopState::RESTART_LOOP }; uint16_t trait_update_counter_ { 0 }; // uart message functions void read_response(); void send_request(RequestType requestType); void read_request(); bool check_response(const std::vector& data); void set_command_byte(const uint8_t value, const uint8_t index); void set_command_bytes(const std::vector>& data); // sensor and control publish functions void set_number_traits(const std::vector& data); void publish_sensor(const std::vector& data); void publish_binary_sensor(const std::vector& data); void publish_text_sensor(const std::vector& data); void publish_number(const std::vector& data); void publish_select(const std::vector& data); void publish_switch(const std::vector& data); }; } // namespace panasonic_heatpump } // namespace esphome