Add "off reason" (OR) text sensor (Closes: #57)

This commit is contained in:
Sebastian Muszynski 2022-06-15 20:18:52 +02:00
parent 3c89419e36
commit 23ccb75c13
9 changed files with 140 additions and 2 deletions

View File

@ -176,6 +176,8 @@ jobs:
esphome -s external_components_source components config phoenix-inverter-esp8266-example.yaml
- run: |
esphome -s external_components_source components config debug-esp8266-example.yaml
- run: |
esphome -s external_components_source components config debug-esp32-example.yaml
- run: |
esphome -s external_components_source components config tests/emulator-all-keys.yaml
esphome -s external_components_source components config tests/fake-bmv600.yaml
@ -232,3 +234,5 @@ jobs:
esphome -s external_components_source components compile phoenix-charger-esp8266-example.yaml
- run: |
esphome -s external_components_source components compile phoenix-inverter-esp8266-example.yaml
- run: |
esphome -s external_components_source components compile debug-esp32-example.yaml

View File

@ -82,6 +82,7 @@ CONF_MAX_AUXILIARY_BATTERY_VOLTAGE = "max_auxiliary_battery_voltage"
CONF_AMOUNT_OF_DISCHARGED_ENERGY = "amount_of_discharged_energy"
CONF_AMOUNT_OF_CHARGED_ENERGY = "amount_of_charged_energy"
CONF_DC_MONITOR_MODE_ID = "dc_monitor_mode_id"
CONF_OFF_REASON_BITMASK = "off_reason_bitmask"
UNIT_AMPERE_HOURS = "Ah"
@ -137,6 +138,7 @@ SENSORS = [
CONF_AMOUNT_OF_DISCHARGED_ENERGY,
CONF_AMOUNT_OF_CHARGED_ENERGY,
CONF_DC_MONITOR_MODE_ID,
CONF_OFF_REASON_BITMASK,
]
@ -446,6 +448,12 @@ CONFIG_SCHEMA = cv.Schema(
accuracy_decimals=0,
device_class=DEVICE_CLASS_EMPTY,
),
cv.Optional(CONF_OFF_REASON_BITMASK): sensor.sensor_schema(
unit_of_measurement=UNIT_EMPTY,
icon=ICON_EMPTY,
accuracy_decimals=0,
device_class=DEVICE_CLASS_EMPTY,
),
}
)

View File

@ -23,6 +23,7 @@ CONF_ALARM_CONDITION_ACTIVE = "alarm_condition_active"
CONF_ALARM_REASON = "alarm_reason"
CONF_MODEL_DESCRIPTION = "model_description"
CONF_DC_MONITOR_MODE = "dc_monitor_mode"
CONF_OFF_REASON = "off_reason"
TEXT_SENSORS = [
CONF_CHARGING_MODE,
@ -39,6 +40,7 @@ TEXT_SENSORS = [
CONF_ALARM_REASON,
CONF_MODEL_DESCRIPTION,
CONF_DC_MONITOR_MODE,
CONF_OFF_REASON,
]
@ -84,6 +86,9 @@ CONFIG_SCHEMA = cv.Schema(
cv.Optional(CONF_DC_MONITOR_MODE): text_sensor.TEXT_SENSOR_SCHEMA.extend(
{cv.GenerateID(): cv.declare_id(text_sensor.TextSensor)}
),
cv.Optional(CONF_OFF_REASON): text_sensor.TEXT_SENSOR_SCHEMA.extend(
{cv.GenerateID(): cv.declare_id(text_sensor.TextSensor)}
),
}
)

View File

@ -1,12 +1,33 @@
#include "victron.h"
#include "esphome/core/log.h"
#include <algorithm> // std::min
#include "esphome/core/helpers.h"
namespace esphome {
namespace victron {
static const char *const TAG = "victron";
static const uint8_t OFF_REASONS_SIZE = 16;
static const char *const OFF_REASONS[OFF_REASONS_SIZE] = {
"No input power", // 0000 0000 0000 0001
"Switched off (power switch)", // 0000 0000 0000 0010
"Switched off (device mode register)", // 0000 0000 0000 0100
"Remote input", // 0000 0000 0000 1000
"Protection active", // 0000 0000 0001 0000
"Paygo", // 0000 0000 0010 0000
"BMS", // 0000 0000 0100 0000
"Engine shutdown detection", // 0000 0000 1000 0000
"Analysing input voltage", // 0000 0001 0000 0000
"Unknown: Bit 10", // 0000 0010 0000 0000
"Unknown: Bit 11", // 0000 0100 0000 0000
"Unknown: Bit 12", // 0000 1000 0000 0000
"Unknown: Bit 13", // 0001 0000 0000 0000
"Unknown: Bit 14", // 0010 0000 0000 0000
"Unknown: Bit 15", // 0100 0000 0000 0000
"Unknown: Bit 16", // 1000 0000 0000 0000
};
void VictronComponent::dump_config() { // NOLINT(google-readability-function-size,readability-function-size)
ESP_LOGCONFIG(TAG, "Victron:");
LOG_BINARY_SENSOR(" ", "Load state", load_state_binary_sensor_);
@ -33,6 +54,7 @@ void VictronComponent::dump_config() { // NOLINT(google-readability-function-si
LOG_SENSOR(" ", "Warning Code", warning_code_sensor_);
LOG_SENSOR(" ", "Tracking Mode ID", tracking_mode_id_sensor_);
LOG_SENSOR(" ", "Device Mode ID", device_mode_id_sensor_);
LOG_SENSOR(" ", "Off Reason Bitmask", off_reason_bitmask_sensor_);
LOG_TEXT_SENSOR(" ", "Charging Mode", charging_mode_text_sensor_);
LOG_TEXT_SENSOR(" ", "Error Text", error_text_sensor_);
LOG_TEXT_SENSOR(" ", "Warning Text", warning_text_sensor_);
@ -41,6 +63,7 @@ void VictronComponent::dump_config() { // NOLINT(google-readability-function-si
LOG_TEXT_SENSOR(" ", "Firmware Version", firmware_version_text_sensor_);
LOG_TEXT_SENSOR(" ", "Firmware Version 24bit", firmware_version_24bit_text_sensor_);
LOG_TEXT_SENSOR(" ", "Device Type", device_type_text_sensor_);
LOG_TEXT_SENSOR(" ", "Off Reason", off_reason_text_sensor_);
LOG_SENSOR(" ", "Battery Temperature ", battery_temperature_sensor_);
LOG_SENSOR(" ", "Instantaneous Power", instantaneous_power_sensor_);
@ -592,6 +615,26 @@ static const std::string device_type_text(int value) {
}
}
static const std::string off_reason_text(uint32_t mask) {
bool first = true;
std::string value_list = "";
if (mask) {
for (uint8_t i = 0; i < OFF_REASONS_SIZE; i++) {
if (mask & (1 << i)) {
if (first) {
first = false;
} else {
value_list.append(";");
}
value_list.append(OFF_REASONS[i]);
}
}
}
return value_list;
}
void VictronComponent::handle_value_() {
int value;
@ -718,7 +761,14 @@ void VictronComponent::handle_value_() {
return;
}
// @TODO: "OR" Off reason
if (label_ == "OR") {
auto off_reason_bitmask = parse_hex<uint32_t>(value_.substr(2, value_.size() - 2));
if (off_reason_bitmask) {
this->publish_state_(off_reason_bitmask_sensor_, *off_reason_bitmask);
this->publish_state_(off_reason_text_sensor_, off_reason_text(*off_reason_bitmask));
}
return;
}
if (label_ == "H1") {
// mAh -> Ah

View File

@ -183,6 +183,9 @@ class VictronComponent : public uart::UARTDevice, public Component {
void set_amount_of_charged_energy_sensor(sensor::Sensor *amount_of_charged_energy_sensor) {
amount_of_charged_energy_sensor_ = amount_of_charged_energy_sensor;
}
void set_off_reason_bitmask_sensor(sensor::Sensor *off_reason_bitmask_sensor) {
off_reason_bitmask_sensor_ = off_reason_bitmask_sensor;
}
void set_alarm_condition_active_text_sensor(text_sensor::TextSensor *alarm_condition_active_text_sensor) {
alarm_condition_active_text_sensor_ = alarm_condition_active_text_sensor;
@ -193,6 +196,9 @@ class VictronComponent : public uart::UARTDevice, public Component {
void set_model_description_text_sensor(text_sensor::TextSensor *model_description_text_sensor) {
model_description_text_sensor_ = model_description_text_sensor;
}
void set_off_reason_text_sensor(text_sensor::TextSensor *off_reason_text_sensor) {
off_reason_text_sensor_ = off_reason_text_sensor;
}
void dump_config() override;
void loop() override;
@ -237,6 +243,7 @@ class VictronComponent : public uart::UARTDevice, public Component {
sensor::Sensor *tracking_mode_id_sensor_{nullptr};
sensor::Sensor *device_mode_id_sensor_{nullptr};
sensor::Sensor *dc_monitor_mode_id_sensor_{nullptr};
sensor::Sensor *off_reason_bitmask_sensor_{nullptr};
text_sensor::TextSensor *charging_mode_text_sensor_{nullptr};
text_sensor::TextSensor *error_text_sensor_{nullptr};
text_sensor::TextSensor *warning_text_sensor_{nullptr};
@ -247,6 +254,7 @@ class VictronComponent : public uart::UARTDevice, public Component {
text_sensor::TextSensor *device_type_text_sensor_{nullptr};
text_sensor::TextSensor *serial_number_text_sensor_{nullptr};
text_sensor::TextSensor *dc_monitor_mode_text_sensor_{nullptr};
text_sensor::TextSensor *off_reason_text_sensor_{nullptr};
sensor::Sensor *battery_temperature_sensor_{nullptr};
sensor::Sensor *instantaneous_power_sensor_{nullptr};

56
debug-esp32-example.yaml Normal file
View File

@ -0,0 +1,56 @@
substitutions:
name: victron-debug
external_components_source: github://KinDR007/VictronMPPT-ESPHOME@main
tx_pin: GPIO16
rx_pin: GPIO17
esphome:
name: ${name}
esp32:
board: wemos_d1_mini32
framework:
type: esp-idf
version: latest
external_components:
- source: ${external_components_source}
refresh: 0s
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ota:
api:
logger:
uart:
id: uart0
baud_rate: 19200
tx_pin: ${tx_pin}
rx_pin: ${rx_pin}
debug:
direction: BOTH
dummy_receiver: true
after:
delimiter: "\n"
sequence:
- lambda: UARTDebug::log_string(direction, bytes);
victron:
uart_id: uart0
id: victron0
throttle: 10s
text_sensor:
- platform: victron
victron_id: victron0
model_description:
name: "${name} model description"
firmware_version:
name: "${name} firmware version"
device_type:
name: "${name} device type"
serial_number:
name: "${name} serial number"

View File

@ -59,6 +59,8 @@ sensor:
name: "${name} ac out apparent power"
warning_code:
name: "${name} warning code"
off_reason_bitmask:
name: "${name} off reason bitmask"
text_sensor:
- platform: victron
@ -78,6 +80,8 @@ text_sensor:
name: "${name} device mode"
warning:
name: "${name} warning"
off_reason:
name: "${name} off reason"
binary_sensor:
- platform: victron

3
test-esp32.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
esphome -s external_components_source components ${1:-run} debug-esp32-example.yaml

View File

@ -71,7 +71,7 @@ interval:
- uart.write: "LOAD\tON\r\n"
- uart.write: "MODE\t2\r\n"
- uart.write: "MPPT\t2\r\n"
- uart.write: "OR\t0x00000000\r\n"
- uart.write: "OR\t0x00000003\r\n"
- uart.write: "P\t130\r\n"
- uart.write: "PID\t0x204\r\n"
- uart.write: "PPV\t130\r\n"