13static const char *
const TAG =
"zwave_proxy";
16static constexpr size_t ZWAVE_MAX_LOG_BYTES = 168;
18static constexpr uint8_t ZWAVE_COMMAND_GET_NETWORK_IDS = 0x20;
20static constexpr uint8_t ZWAVE_COMMAND_TYPE_RESPONSE = 0x01;
21static constexpr uint8_t ZWAVE_MIN_GET_NETWORK_IDS_LENGTH = 9;
22static constexpr uint32_t HOME_ID_TIMEOUT_MS = 100;
24static uint8_t calculate_frame_checksum(
const uint8_t *data, uint8_t
length) {
29 for (uint8_t i = 1; i <
length - 1; i++) {
55 ESP_LOGV(TAG,
"Handled response during setup");
69 ESP_LOGW(TAG,
"Timeout reading Home ID during setup");
78 ESP_LOGV(TAG,
"Handled late response");
81 ESP_LOGW(TAG,
"Subscriber disconnected");
104 if (this->
buffer_[3] == ZWAVE_COMMAND_GET_NETWORK_IDS && this->
buffer_[2] == ZWAVE_COMMAND_TYPE_RESPONSE &&
112 ESP_LOGV(TAG,
"Sending to client: %s", YESNO(this->
api_connection_ !=
nullptr));
147 ESP_LOGE(TAG,
"Only one API subscription is allowed at a time");
151 ESP_LOGV(TAG,
"API connection is now subscribed");
156 ESP_LOGV(TAG,
"API connection is not subscribed");
163 ESP_LOGW(TAG,
"Unknown request type: %d",
type);
169 if (std::memcmp(this->
home_id_.data(), new_home_id, this->home_id_.size()) == 0) {
170 ESP_LOGV(TAG,
"Home ID unchanged");
173 std::memcpy(this->
home_id_.data(), new_home_id, this->home_id_.size());
182 ESP_LOGV(TAG,
"Skipping sending duplicate response: 0x%02X", data[0]);
185#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
197 if (conn !=
nullptr) {
211 uint8_t cmd[] = {0x01, 0x03, 0x00, command_id, 0x00};
212 cmd[4] = calculate_frame_checksum(cmd,
sizeof(cmd));
217 bool frame_completed =
false;
225 ESP_LOGW(TAG,
"Invalid LENGTH: %u",
byte);
229 ESP_LOGVV(TAG,
"Received LENGTH: %u",
byte);
237 ESP_LOGVV(TAG,
"Received TYPE: 0x%02X",
byte);
242 ESP_LOGVV(TAG,
"Received COMMAND ID: 0x%02X",
byte);
247 ESP_LOGVV(TAG,
"Received PAYLOAD: 0x%02X",
byte);
254 auto checksum = calculate_frame_checksum(this->
buffer_.data(), this->buffer_index_);
255 ESP_LOGVV(TAG,
"CHECKSUM Received: 0x%02X - Calculated: 0x%02X",
byte,
checksum);
257 ESP_LOGW(TAG,
"Bad checksum: expected 0x%02X, got 0x%02X",
checksum,
byte);
261#if ESPHOME_LOG_LEVEL >= ESPHOME_LOG_LEVEL_VERY_VERBOSE
265 frame_completed =
true;
274 frame_completed =
true;
281 ESP_LOGW(TAG,
"Bad parsing state; resetting");
285 return frame_completed;
293 ESP_LOGVV(TAG,
"Received START");
295 ESP_LOGD(TAG,
"Exited bootloader mode");
302 ESP_LOGVV(TAG,
"Received BL_MENU");
304 ESP_LOGD(TAG,
"Entered bootloader mode");
311 ESP_LOGVV(TAG,
"Received BL_BEGIN_UPLOAD");
314 ESP_LOGVV(TAG,
"Received ACK");
317 ESP_LOGW(TAG,
"Received NAK");
320 ESP_LOGW(TAG,
"Received CAN");
323 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
api::APIConnection * api_connection_
float get_setup_priority() const override
std::array< uint8_t, ZWAVE_HOME_ID_SIZE > home_id_
@ 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
bool api_is_connected()
Return whether the node has at least one client connected to the native API.
char * format_hex_pretty_to(char *buffer, size_t buffer_size, const uint8_t *data, size_t length, char separator)
Format byte array as uppercase hex to buffer (base implementation).
constexpr size_t format_hex_pretty_size(size_t byte_count)
Calculate buffer size needed for format_hex_pretty_to with separator: "XX:XX:...:XX\0".
Application App
Global storage of Application pointer - only one Application can exist.