#pragma once #include #include #include #include #include "esphome/components/pzem6l24/pzem6l24.h" namespace esphome::pzem6l24::testing { // The request PDU update() puts on the wire: read 64 input registers from 0x0000. static constexpr uint8_t READ_REQUEST_PDU[] = {0x04, 0x00, 0x00, 0x00, PZEM_REGISTER_COUNT}; // The request PDU reset_energy() puts on the wire for every phase. static constexpr auto RESET_REQUEST_PDU = build_reset_pdu(RESET_PHASE_ALL); // Builds the 128-byte register payload the meter returns, writing each quantity in the // little-endian byte order documented in pzem6l24.cpp's register map. class PayloadBuilder { public: PayloadBuilder &u8(size_t offset, uint8_t value) { this->data_[offset] = value; return *this; } PayloadBuilder &u16(size_t offset, uint16_t value) { this->data_[offset] = static_cast(value & 0xFF); this->data_[offset + 1] = static_cast(value >> 8); return *this; } PayloadBuilder &u32(size_t offset, uint32_t value) { this->u16(offset, static_cast(value & 0xFFFF)); this->u16(offset + 2, static_cast(value >> 16)); return *this; } PayloadBuilder &i32(size_t offset, int32_t value) { return this->u32(offset, static_cast(value)); } // Wraps the payload in a read-input-registers response PDU: function code, byte count, data. std::vector response_pdu() const { std::vector pdu{0x04, static_cast(PZEM_PAYLOAD_SIZE)}; pdu.insert(pdu.end(), this->data_.begin(), this->data_.end()); return pdu; } protected: std::array data_{}; }; } // namespace esphome::pzem6l24::testing