Skip to content

Commit

Permalink
Merge branch 'main' into release-please--branches--main--components--…
Browse files Browse the repository at this point in the history
…charger-module-firmware
  • Loading branch information
mikesmitty authored Sep 10, 2024
2 parents 1cd42e8 + 383ba0f commit 8be2b9e
Show file tree
Hide file tree
Showing 13 changed files with 786 additions and 8 deletions.
2 changes: 2 additions & 0 deletions .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
{
"esphome/components/lad": "0.0.1",
"esphome/components/pwrman_charger": "0.0.1",
"firmware/charger-module": "0.6.0",
"hardware/backplane": "0.7.6",
"hardware/charger-module": "0.12.1",
Expand Down
30 changes: 30 additions & 0 deletions esphome/components/lad/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import uart
from esphome.const import CONF_ID, CONF_MAX_CURRENT

CODEOWNERS = ["@mikesmitty"]
DEPENDENCIES = ["uart"]

CONF_LAD_ID = "lad_id"

lad_component_ns = cg.esphome_ns.namespace("lad_component")
LadComponent = lad_component_ns.class_("LadComponent", cg.Component, uart.UARTDevice)

LAD_SCHEMA = cv.Schema(
{
cv.GenerateID(CONF_LAD_ID): cv.use_id(LadComponent),
}
)

CONFIG_SCHEMA = (
cv.Schema({cv.GenerateID(): cv.declare_id(LadComponent)})
.extend(cv.COMPONENT_SCHEMA)
.extend(uart.UART_DEVICE_SCHEMA)
)


async def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
await cg.register_component(var, config)
await uart.register_uart_device(var, config)
177 changes: 177 additions & 0 deletions esphome/components/lad/binary_sensor/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import binary_sensor, uart
from esphome.const import (
CONF_ID,
DEVICE_CLASS_BATTERY,
DEVICE_CLASS_BATTERY_CHARGING,
ENTITY_CATEGORY_DIAGNOSTIC,
)
from .. import (
CONF_LAD_ID,
LAD_SCHEMA,
lad_component_ns,
)

CODEOWNERS = ["@mikesmitty"]
DEPENDENCIES = ["lad"]

CONF_AC_POWER_FAULT = "ac_power_fault"
CONF_BATTERY_CHARGED = "battery_charged"
CONF_BATTERY_CHARGING = "battery_charging"
CONF_BATTERY_IMBALANCE = "battery_imbalance"
CONF_BATTERY_POWER_FAULT = "battery_power_fault"
CONF_BATTERY_REVERSED = "battery_reversed"
CONF_BATTERY_SWITCH = "battery_switch"
CONF_BATTERY1_FAULT = "battery1_fault"
CONF_BATTERY2_FAULT = "battery2_fault"
CONF_BATTERY3_FAULT = "battery3_fault"
CONF_BATTERY4_FAULT = "battery4_fault"
CONF_FORCE_START = "force_start"
CONF_LINK_CONTROL_STATUS = "link_control_status"
CONF_LOW_BATTERY = "low_battery"
CONF_OUTPUT_OVERLOAD = "output_overload"
CONF_OVP_ACTIVE = "ovp_active"
CONF_STANDBY_POWER_ACTIVE = "standby_power_active"

ICON_BATTERY_ARROW_DOWN_OUTLINE = "mdi:battery-arrow-down-outline"
ICON_NUMERIC_5_BOX_MULTIPLE = "mdi:numeric-5-box-multiple"
ICON_POWER_SETTINGS = "mdi:power-settings"
ICON_USB_C_PORT = "mdi:usb-c-port"

LadBinarySensor = lad_component_ns.class_(
"LadBinarySensor", uart.UARTDevice, cg.PollingComponent
)

CONFIG_SCHEMA = LAD_SCHEMA.extend(
{
cv.GenerateID(): cv.declare_id(LadBinarySensor),
cv.Optional(CONF_AC_POWER_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_CHARGED): binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_BATTERY,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_CHARGING): binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_BATTERY_CHARGING,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_IMBALANCE): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_POWER_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_REVERSED): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_SWITCH): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY1_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY2_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY3_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY4_FAULT): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_FORCE_START): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_LINK_CONTROL_STATUS): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_LOW_BATTERY): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_OUTPUT_OVERLOAD): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_OVP_ACTIVE): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_STANDBY_POWER_ACTIVE): binary_sensor.binary_sensor_schema(
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
}
).extend(cv.polling_component_schema("60s"))


async def to_code(config):
paren = await cg.get_variable(config[CONF_LAD_ID])
var = cg.new_Pvariable(config[CONF_ID], paren)
await cg.register_component(var, config)

if ac_power_fault_config := config.get(CONF_AC_POWER_FAULT):
sens = await binary_sensor.new_binary_sensor(ac_power_fault_config)
cg.add(var.set_ac_power_fault_binary_sensor(sens))

if battery_charged_config := config.get(CONF_BATTERY_CHARGED):
sens = await binary_sensor.new_binary_sensor(battery_charged_config)
cg.add(var.set_battery_charged_binary_sensor(sens))

if battery_charging_config := config.get(CONF_BATTERY_CHARGING):
sens = await binary_sensor.new_binary_sensor(battery_charging_config)
cg.add(var.set_battery_charging_binary_sensor(sens))

if battery_imbalance_config := config.get(CONF_BATTERY_IMBALANCE):
sens = await binary_sensor.new_binary_sensor(battery_imbalance_config)
cg.add(var.set_battery_imbalance_binary_sensor(sens))

if battery_power_fault_config := config.get(CONF_BATTERY_POWER_FAULT):
sens = await binary_sensor.new_binary_sensor(battery_power_fault_config)
cg.add(var.set_battery_power_fault_binary_sensor(sens))

if battery_reversed_config := config.get(CONF_BATTERY_REVERSED):
sens = await binary_sensor.new_binary_sensor(battery_reversed_config)
cg.add(var.set_battery_reversed_binary_sensor(sens))

if battery_switch_config := config.get(CONF_BATTERY_SWITCH):
sens = await binary_sensor.new_binary_sensor(battery_switch_config)
cg.add(var.set_battery_switch_binary_sensor(sens))

if battery1_fault_config := config.get(CONF_BATTERY1_FAULT):
sens = await binary_sensor.new_binary_sensor(battery1_fault_config)
cg.add(var.set_battery1_fault_binary_sensor(sens))

if battery2_fault_config := config.get(CONF_BATTERY2_FAULT):
sens = await binary_sensor.new_binary_sensor(battery2_fault_config)
cg.add(var.set_battery2_fault_binary_sensor(sens))

if battery3_fault_config := config.get(CONF_BATTERY3_FAULT):
sens = await binary_sensor.new_binary_sensor(battery3_fault_config)
cg.add(var.set_battery3_fault_binary_sensor(sens))

if battery4_fault_config := config.get(CONF_BATTERY4_FAULT):
sens = await binary_sensor.new_binary_sensor(battery4_fault_config)
cg.add(var.set_battery4_fault_binary_sensor(sens))

if force_start_config := config.get(CONF_FORCE_START):
sens = await binary_sensor.new_binary_sensor(force_start_config)
cg.add(var.set_force_start_binary_sensor(sens))

if link_control_status_config := config.get(CONF_LINK_CONTROL_STATUS):
sens = await binary_sensor.new_binary_sensor(link_control_status_config)
cg.add(var.set_link_control_status_binary_sensor(sens))

if low_battery_config := config.get(CONF_LOW_BATTERY):
sens = await binary_sensor.new_binary_sensor(low_battery_config)
cg.add(var.set_low_battery_binary_sensor(sens))

if output_overload_config := config.get(CONF_OUTPUT_OVERLOAD):
sens = await binary_sensor.new_binary_sensor(output_overload_config)
cg.add(var.set_output_overload_binary_sensor(sens))

if ovp_active_config := config.get(CONF_OVP_ACTIVE):
sens = await binary_sensor.new_binary_sensor(ovp_active_config)
cg.add(var.set_ovp_active_binary_sensor(sens))

if standby_power_active_config := config.get(CONF_STANDBY_POWER_ACTIVE):
sens = await binary_sensor.new_binary_sensor(standby_power_active_config)
cg.add(var.set_standby_power_active_binary_sensor(sens))
106 changes: 106 additions & 0 deletions esphome/components/lad/binary_sensor/lad_binary_sensor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#include "lad_binary_sensor.h"

#include "esphome/components/binary_sensor/binary_sensor.h"
#include "esphome/core/component.h"
#include "esphome/core/log.h"

namespace esphome {
namespace lad_component {

static const char *TAG = "lad.binary_sensor";

float LadBinarySensor::get_setup_priority() const { return setup_priority::DATA; }

void LadBinarySensor::setup() { ESP_LOGCONFIG(TAG, "Setting up LadBinarySensor..."); }

void LadBinarySensor::update() {
// Response is 5 bytes plus the length of the data
// R/W | LEN | CMD 2 bytes | DATA | CRC
uint8_t data[9] = {0};

if (!this->parent_->read_register_(this->lad_status_, data, 9)) {
ESP_LOGE(TAG, "Failed to read LAD status register");
}

uint8_t battery_switch_status = data[5];
uint8_t status_high = data[6];
uint8_t status_low = data[7];

if (this->ac_power_fault_binary_sensor_ != nullptr) {
// AC power fault status is 0 when AC power is faulting
this->ac_power_fault_binary_sensor_->publish_state(CHECK_BIT(status_low, 0) == 0);
}
if (this->battery_charged_binary_sensor_ != nullptr) {
this->battery_charged_binary_sensor_->publish_state(CHECK_BIT(status_high, 4));
}
if (this->battery_charging_binary_sensor_ != nullptr) {
this->battery_charging_binary_sensor_->publish_state(CHECK_BIT(status_high, 5));
}
if (this->battery_imbalance_binary_sensor_ != nullptr) {
this->battery_imbalance_binary_sensor_->publish_state(CHECK_BIT(status_low, 7));
}
if (this->battery_power_fault_binary_sensor_ != nullptr) {
this->battery_power_fault_binary_sensor_->publish_state(CHECK_BIT(status_low, 1));
}
if (this->battery_reversed_binary_sensor_ != nullptr) {
this->battery_reversed_binary_sensor_->publish_state(CHECK_BIT(status_high, 6));
}
if (this->battery_switch_binary_sensor_ != nullptr) {
// Battery switch status is 0 when the battery is online
this->battery_switch_binary_sensor_->publish_state(battery_switch_status == 0);
}
if (this->battery1_fault_binary_sensor_ != nullptr) {
this->battery1_fault_binary_sensor_->publish_state(CHECK_BIT(status_high, 0));
}
if (this->battery2_fault_binary_sensor_ != nullptr) {
this->battery2_fault_binary_sensor_->publish_state(CHECK_BIT(status_high, 1));
}
if (this->battery3_fault_binary_sensor_ != nullptr) {
this->battery3_fault_binary_sensor_->publish_state(CHECK_BIT(status_high, 2));
}
if (this->battery4_fault_binary_sensor_ != nullptr) {
this->battery4_fault_binary_sensor_->publish_state(CHECK_BIT(status_high, 3));
}
if (this->force_start_binary_sensor_ != nullptr) {
this->force_start_binary_sensor_->publish_state(CHECK_BIT(status_high, 7));
}
if (this->link_control_status_binary_sensor_ != nullptr) {
this->link_control_status_binary_sensor_->publish_state(CHECK_BIT(status_low, 5));
}
if (this->low_battery_binary_sensor_ != nullptr) {
this->low_battery_binary_sensor_->publish_state(CHECK_BIT(status_low, 3));
}
if (this->output_overload_binary_sensor_ != nullptr) {
this->output_overload_binary_sensor_->publish_state(CHECK_BIT(status_low, 2));
}
if (this->ovp_active_binary_sensor_ != nullptr) {
this->ovp_active_binary_sensor_->publish_state(CHECK_BIT(status_low, 6));
}
if (this->standby_power_active_binary_sensor_ != nullptr) {
this->standby_power_active_binary_sensor_->publish_state(CHECK_BIT(status_low, 4));
}
}

void LadBinarySensor::dump_config() {
ESP_LOGCONFIG(TAG, "LAD Sensor:");
LOG_BINARY_SENSOR(" ", "ACPowerFaultBinarySensor", this->ac_power_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatteryChargedBinarySensor", this->battery_charged_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatteryChargingBinarySensor", this->battery_charging_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatteryImbalanceBinarySensor", this->battery_imbalance_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatteryPowerFaultBinarySensor", this->battery_power_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatteryReversedBinarySensor", this->battery_reversed_binary_sensor_);
LOG_BINARY_SENSOR(" ", "BatterySwitchBinarySensor", this->battery_switch_binary_sensor_);
LOG_BINARY_SENSOR(" ", "Battery1FaultBinarySensor", this->battery1_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "Battery2FaultBinarySensor", this->battery2_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "Battery3FaultBinarySensor", this->battery3_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "Battery4FaultBinarySensor", this->battery4_fault_binary_sensor_);
LOG_BINARY_SENSOR(" ", "ForceStartBinarySensor", this->force_start_binary_sensor_);
LOG_BINARY_SENSOR(" ", "LinkControlStatusBinarySensor", this->link_control_status_binary_sensor_);
LOG_BINARY_SENSOR(" ", "LowBatteryBinarySensor", this->low_battery_binary_sensor_);
LOG_BINARY_SENSOR(" ", "OutputOverloadBinarySensor", this->output_overload_binary_sensor_);
LOG_BINARY_SENSOR(" ", "OvpActiveBinarySensor", this->ovp_active_binary_sensor_);
LOG_BINARY_SENSOR(" ", "StandbyPowerActiveBinarySensor", this->standby_power_active_binary_sensor_);
}

} // namespace lad_component
} // namespace esphome
Loading

0 comments on commit 8be2b9e

Please sign in to comment.