From 1b398e1d078425993513061115b4bb04c2579251 Mon Sep 17 00:00:00 2001 From: Sebastian Muszynski Date: Sat, 26 Feb 2022 23:10:05 +0100 Subject: [PATCH] Add BMS controls (#44) --- .gitignore | 2 +- components/jk_bms/jk_bms.cpp | 3 ++ components/jk_bms/jk_bms.h | 2 ++ components/jk_bms/switch/jk_switch.cpp | 5 +--- components/jk_bms/switch/jk_switch.h | 4 +-- components/jk_modbus/jk_modbus.cpp | 40 +++++++++++++++++--------- components/jk_modbus/jk_modbus.h | 6 ++-- test.sh | 3 ++ 8 files changed, 41 insertions(+), 24 deletions(-) create mode 100755 test.sh diff --git a/.gitignore b/.gitignore index dd71e158..862848c0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .idea/ -secret.yaml +secrets.yaml .esphome/ **/.pioenvs/ **/.piolibdeps/ diff --git a/components/jk_bms/jk_bms.cpp b/components/jk_bms/jk_bms.cpp index 0d5bf015..74cff6f6 100644 --- a/components/jk_bms/jk_bms.cpp +++ b/components/jk_bms/jk_bms.cpp @@ -9,6 +9,7 @@ static const char *const TAG = "jk_bms"; static const uint8_t FUNCTION_READ_ALL = 0x06; static const uint8_t ADDRESS_READ_ALL = 0x00; +static const uint8_t WRITE_REGISTER = 0x02; static const uint8_t ERRORS_SIZE = 14; static const char *const ERRORS[ERRORS_SIZE] = { @@ -346,6 +347,8 @@ void JkBms::on_status_data_(const std::vector &data) { // 00 00 00 00 68 00 00 54 D1: End of frame } +void JkBms::write_register(uint8_t address, uint8_t value) { this->send(WRITE_REGISTER, address, value); } + void JkBms::update() { this->read_registers(FUNCTION_READ_ALL, ADDRESS_READ_ALL); diff --git a/components/jk_bms/jk_bms.h b/components/jk_bms/jk_bms.h index deccfd23..39e7824c 100644 --- a/components/jk_bms/jk_bms.h +++ b/components/jk_bms/jk_bms.h @@ -206,6 +206,8 @@ class JkBms : public PollingComponent, public jk_modbus::JkModbusDevice { void update() override; + void write_register(uint8_t address, uint8_t value); + protected: sensor::Sensor *min_cell_voltage_sensor_; sensor::Sensor *max_cell_voltage_sensor_; diff --git a/components/jk_bms/switch/jk_switch.cpp b/components/jk_bms/switch/jk_switch.cpp index 80d8c01f..117a010e 100644 --- a/components/jk_bms/switch/jk_switch.cpp +++ b/components/jk_bms/switch/jk_switch.cpp @@ -8,10 +8,7 @@ namespace jk_bms { static const char *const TAG = "jk_bms.switch"; void JkSwitch::dump_config() { LOG_SWITCH("", "JkBms Switch", this); } -void JkSwitch::write_state(bool state) { - // @FIXME - // this->parent_->write_register(this->holding_register_, (uint16_t) state); -} +void JkSwitch::write_state(bool state) { this->parent_->write_register(this->holding_register_, (uint8_t) state); } } // namespace jk_bms } // namespace esphome diff --git a/components/jk_bms/switch/jk_switch.h b/components/jk_bms/switch/jk_switch.h index 0d505224..eaf4c9a6 100644 --- a/components/jk_bms/switch/jk_switch.h +++ b/components/jk_bms/switch/jk_switch.h @@ -11,7 +11,7 @@ class JkBms; class JkSwitch : public switch_::Switch, public Component { public: void set_parent(JkBms *parent) { this->parent_ = parent; }; - void set_holding_register(uint16_t holding_register) { this->holding_register_ = holding_register; }; + void set_holding_register(uint8_t holding_register) { this->holding_register_ = holding_register; }; void dump_config() override; void loop() override {} float get_setup_priority() const override { return setup_priority::DATA; } @@ -19,7 +19,7 @@ class JkSwitch : public switch_::Switch, public Component { protected: void write_state(bool state) override; JkBms *parent_; - uint16_t holding_register_; + uint8_t holding_register_; }; } // namespace jk_bms diff --git a/components/jk_modbus/jk_modbus.cpp b/components/jk_modbus/jk_modbus.cpp index adc43006..4e328659 100644 --- a/components/jk_modbus/jk_modbus.cpp +++ b/components/jk_modbus/jk_modbus.cpp @@ -91,19 +91,33 @@ float JkModbus::get_setup_priority() const { // After UART bus return setup_priority::BUS - 1.0f; } -void JkModbus::send(uint8_t address, uint8_t function, uint16_t start_address, uint16_t register_count) { - uint8_t frame[8]; - frame[0] = address; - frame[1] = function; - frame[2] = start_address >> 8; - frame[3] = start_address >> 0; - frame[4] = register_count >> 8; - frame[5] = register_count >> 0; - auto crc = chksum(frame, 6); - frame[6] = crc >> 8; - frame[7] = crc >> 0; - - this->write_array(frame, 8); +void JkModbus::send(uint8_t function, uint8_t address, uint8_t value) { + uint8_t frame[22]; + frame[0] = 0x4E; // start sequence + frame[1] = 0x57; // start sequence + frame[2] = 0x00; // data length lb + frame[3] = 0x14; // data length hb + frame[4] = 0x00; // bms terminal number + frame[5] = 0x00; // bms terminal number + frame[6] = 0x00; // bms terminal number + frame[7] = 0x00; // bms terminal number + frame[8] = function; // command word: 0x01 (activation), 0x02 (write), 0x03 (read), 0x05 (password), 0x06 (read all) + frame[9] = 0x02; // frame source: 0x00 (bms), 0x01 (bluetooth), 0x02 (gps), 0x03 (computer) + frame[10] = 0x02; // frame type: 0x00 (read data), 0x01 (reply frame), 0x02 (BMS active upload) + frame[11] = address; // register: 0x00 (read all registers), 0x8E...0xBF (holding registers) + frame[12] = value; // data + frame[13] = 0x00; // record number + frame[14] = 0x00; // record number + frame[15] = 0x00; // record number + frame[16] = 0x00; // record number + frame[17] = 0x68; // end sequence + auto crc = chksum(frame, 17); + frame[18] = 0x00; // crc unused + frame[19] = 0x00; // crc unused + frame[20] = crc >> 8; + frame[21] = crc >> 0; + + this->write_array(frame, 22); this->flush(); } diff --git a/components/jk_modbus/jk_modbus.h b/components/jk_modbus/jk_modbus.h index 9d82f6a3..96ee5f6d 100644 --- a/components/jk_modbus/jk_modbus.h +++ b/components/jk_modbus/jk_modbus.h @@ -20,7 +20,7 @@ class JkModbus : public uart::UARTDevice, public Component { float get_setup_priority() const override; - void send(uint8_t address, uint8_t function, uint16_t start_address, uint16_t register_count); + void send(uint8_t function, uint8_t address, uint8_t value); void read_registers(uint8_t function, uint8_t address); protected: @@ -37,9 +37,7 @@ class JkModbusDevice { void set_address(uint8_t address) { address_ = address; } virtual void on_jk_modbus_data(const uint8_t &function, const std::vector &data) = 0; - void send(uint8_t function, uint16_t start_address, uint16_t register_count) { - this->parent_->send(this->address_, function, start_address, register_count); - } + void send(int8_t function, uint8_t address, uint8_t value) { this->parent_->send(function, address, value); } void read_registers(uint8_t function, uint8_t address) { this->parent_->read_registers(function, address); } protected: diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..1a02875e --- /dev/null +++ b/test.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +esphome -s external_components_source components ${1:-run} esp32-example-faker.yaml