11static const char *
const TAG =
"zwave_proxy";
13static constexpr uint8_t ZWAVE_COMMAND_GET_NETWORK_IDS = 0x20;
15static constexpr uint8_t ZWAVE_COMMAND_TYPE_RESPONSE = 0x01;
16static constexpr uint8_t ZWAVE_MIN_GET_NETWORK_IDS_LENGTH = 9;
17static constexpr uint32_t HOME_ID_TIMEOUT_MS = 100;
19static uint8_t calculate_frame_checksum(
const uint8_t *data, uint8_t
length) {
24 for (uint8_t i = 1; i <
length - 1; i++) {
50 ESP_LOGV(TAG,
"Handled response during setup");
64 ESP_LOGW(TAG,
"Timeout reading Home ID during setup");
73 ESP_LOGV(TAG,
"Handled late response");
76 ESP_LOGW(TAG,
"Subscriber disconnected");
99 if (this->
buffer_[3] == ZWAVE_COMMAND_GET_NETWORK_IDS && this->
buffer_[2] == ZWAVE_COMMAND_TYPE_RESPONSE &&
107 ESP_LOGV(TAG,
"Sending to client: %s", YESNO(this->
api_connection_ !=
nullptr));
141 ESP_LOGE(TAG,
"Only one API subscription is allowed at a time");
145 ESP_LOGV(TAG,
"API connection is now subscribed");
149 ESP_LOGV(TAG,
"API connection is not subscribed");
155 ESP_LOGW(TAG,
"Unknown request type: %d",
type);
161 if (std::memcmp(this->
home_id_.data(), new_home_id, this->home_id_.size()) == 0) {
162 ESP_LOGV(TAG,
"Home ID unchanged");
165 std::memcpy(this->
home_id_.data(), new_home_id, this->home_id_.size());
173 ESP_LOGV(TAG,
"Skipping sending duplicate response: 0x%02X", data[0]);
185 if (conn !=
nullptr) {
199 uint8_t cmd[] = {0x01, 0x03, 0x00, command_id, 0x00};
200 cmd[4] = calculate_frame_checksum(cmd,
sizeof(cmd));
205 bool frame_completed =
false;
213 ESP_LOGW(TAG,
"Invalid LENGTH: %u",
byte);
217 ESP_LOGVV(TAG,
"Received LENGTH: %u",
byte);
225 ESP_LOGVV(TAG,
"Received TYPE: 0x%02X",
byte);
230 ESP_LOGVV(TAG,
"Received COMMAND ID: 0x%02X",
byte);
235 ESP_LOGVV(TAG,
"Received PAYLOAD: 0x%02X",
byte);
242 auto checksum = calculate_frame_checksum(this->
buffer_.data(), this->buffer_index_);
243 ESP_LOGVV(TAG,
"CHECKSUM Received: 0x%02X - Calculated: 0x%02X",
byte,
checksum);
245 ESP_LOGW(TAG,
"Bad checksum: expected 0x%02X, got 0x%02X",
checksum,
byte);
250 frame_completed =
true;
259 frame_completed =
true;
266 ESP_LOGW(TAG,
"Bad parsing state; resetting");
270 return frame_completed;
278 ESP_LOGVV(TAG,
"Received START");
280 ESP_LOGD(TAG,
"Exited bootloader mode");
287 ESP_LOGVV(TAG,
"Received BL_MENU");
289 ESP_LOGD(TAG,
"Entered bootloader mode");
296 ESP_LOGVV(TAG,
"Received BL_BEGIN_UPLOAD");
299 ESP_LOGVV(TAG,
"Received ACK");
302 ESP_LOGW(TAG,
"Received NAK");
305 ESP_LOGW(TAG,
"Received CAN");
308 ESP_LOGW(TAG,
"Unrecognized START: 0x%02X",
byte);
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void status_set_warning(const char *message=nullptr)
void status_clear_warning()
bool is_connection_setup() override
bool send_message(const ProtoMessage &msg, uint8_t message_type)
void on_zwave_proxy_request(const esphome::api::ProtoMessage &msg)
static constexpr uint8_t MESSAGE_TYPE
static constexpr uint8_t MESSAGE_TYPE
enums::ZWaveProxyRequestType type
bool read_byte(uint8_t *data)
void write_byte(uint8_t data)
void write_array(const uint8_t *data, size_t len)
void zwave_proxy_request(api::APIConnection *api_connection, api::enums::ZWaveProxyRequestType type)
api::ZWaveProxyFrame outgoing_proto_msg_
void send_frame(const uint8_t *data, size_t length)
bool parse_byte_(uint8_t byte)
void parse_start_(uint8_t byte)
void send_homeid_changed_msg_(api::APIConnection *conn=nullptr)
void send_simple_command_(uint8_t command_id)
bool set_home_id(const uint8_t *new_home_id)
void api_connection_authenticated(api::APIConnection *conn)
bool can_proceed() override
ZWaveParsingState parsing_state_
std::array< uint8_t, MAX_ZWAVE_FRAME_SIZE > buffer_
void dump_config() override
std::array< uint8_t, 4 > home_id_
api::APIConnection * api_connection_
float get_setup_priority() const override
@ ZWAVE_PROXY_REQUEST_TYPE_SUBSCRIBE
@ ZWAVE_PROXY_REQUEST_TYPE_UNSUBSCRIBE
@ ZWAVE_PROXY_REQUEST_TYPE_HOME_ID_CHANGE
APIServer * global_api_server
const float BEFORE_CONNECTION
For components that should be initialized after WiFi and before API is connected.
@ ZWAVE_FRAME_TYPE_BL_MENU
@ ZWAVE_FRAME_TYPE_BL_BEGIN_UPLOAD
@ ZWAVE_PARSING_STATE_WAIT_COMMAND_ID
@ ZWAVE_PARSING_STATE_WAIT_LENGTH
@ ZWAVE_PARSING_STATE_WAIT_CHECKSUM
@ ZWAVE_PARSING_STATE_WAIT_PAYLOAD
@ ZWAVE_PARSING_STATE_SEND_ACK
@ ZWAVE_PARSING_STATE_SEND_NAK
@ ZWAVE_PARSING_STATE_READ_BL_MENU
@ ZWAVE_PARSING_STATE_WAIT_TYPE
@ ZWAVE_PARSING_STATE_SEND_CAN
@ ZWAVE_PARSING_STATE_WAIT_START
ZWaveProxy * global_zwave_proxy
Providing packet encoding functions for exchanging data with a remote host.
bool api_is_connected()
Return whether the node has at least one client connected to the native API.
std::string format_hex_pretty(const uint8_t *data, size_t length, char separator, bool show_length)
Format a byte array in pretty-printed, human-readable hex format.
Application App
Global storage of Application pointer - only one Application can exist.