Add battery charging state and voltage (#1)

This commit is contained in:
Stefan Thoss
2023-12-22 21:22:26 -08:00
committed by GitHub
parent a477785a34
commit 469b50b607
5 changed files with 87 additions and 28 deletions

View File

@@ -1,6 +1,6 @@
# ESPHome AXP2101 Component
This custom component implements AXP2101 support for the M5Stack Core2 V1.1, building on top of https://github.com/martydingo/esphome-axp192. The Core2 uses an AXP192 while the Core2 V1.1 uses an AXP2101.
This custom component implements AXP2101 support for the M5Stack Core2 V1.1, building on top of https://github.com/martydingo/esphome-axp192 and https://github.com/lewisxhe/XPowersLib. The Core2 V1.1 uses an AXP2101 while the older Core2 uses an AXP192.
*This component does not offer full functionality yet, it only covers part of the AXP2101 features and is not fully tested.*
@@ -32,9 +32,12 @@ sensor:
i2c_id: bus_a
update_interval: 30s
brightness: 75%
battery_voltage:
name: "Battery Voltage"
battery_level:
name: "Battery Level"
id: battery_level
battery_charging:
name: "Battery Charging"
```
The display component required for the M5Stack Core2 V1.1 is as follows:

View File

@@ -1,6 +1,6 @@
#include "axp2101.h"
#include "esphome/core/log.h"
#include "esp_sleep.h"
#include "esphome/core/log.h"
#include <Esp.h>
#ifndef CONFIG_PMU_SDA
@@ -33,7 +33,7 @@ namespace axp2101 {
static const char *TAG = "axp2101.sensor";
void AXP2101Component::setup()
{
Serial.printf("getID:0x%x\n", PMU.getChipID());
ESP_LOGD(TAG, "getID:0x%x", PMU.getChipID());
// Set the minimum common working voltage of the PMU VBUS input,
// below this value will turn off the PMU
@@ -46,13 +46,13 @@ void AXP2101Component::setup()
// Get the VSYS shutdown voltage
uint16_t vol = PMU.getSysPowerDownVoltage();
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
ESP_LOGD(TAG, "-> getSysPowerDownVoltage:%u", vol);
// Set VSY off voltage as 2600mV , Adjustment range 2600mV ~ 3300mV
PMU.setSysPowerDownVoltage(2600);
vol = PMU.getSysPowerDownVoltage();
Serial.printf("-> getSysPowerDownVoltage:%u\n", vol);
ESP_LOGD(TAG, "-> getSysPowerDownVoltage:%u", vol);
// DC1 IMAX=2A
@@ -232,7 +232,7 @@ void AXP2101Component::setup()
// without the battery temperature detection function, otherwise it will cause abnormal charging
PMU.disableTSPinMeasure();
// PMU.enableTemperatureMeasure();
PMU.enableTemperatureMeasure();
// Enable internal ADC detection
PMU.enableBattDetection();
@@ -299,7 +299,9 @@ void AXP2101Component::setup()
void AXP2101Component::dump_config() {
ESP_LOGCONFIG(TAG, "AXP2101:");
LOG_I2C_DEVICE(this);
LOG_SENSOR(" ", "Battery Voltage", this->batteryvoltage_sensor_);
LOG_SENSOR(" ", "Battery Level", this->batterylevel_sensor_);
LOG_BINARY_SENSOR(" ", "Battery Charging", this->batterycharging_bsensor_);
}
float AXP2101Component::get_setup_priority() const { return setup_priority::DATA; }
@@ -308,6 +310,8 @@ void AXP2101Component::update() {
if (this->batterylevel_sensor_ != nullptr) {
float vbat = PMU.getBattVoltage();
ESP_LOGD(TAG, "Got Battery Voltage=%f", vbat);
this->batteryvoltage_sensor_->publish_state(vbat / 1000.);
// The battery percentage may be inaccurate at first use, the PMU will automatically
// learn the battery curve and will automatically calibrate the battery percentage
@@ -319,13 +323,20 @@ void AXP2101Component::update() {
batterylevel = 100.0 * ((vbat - 3.0) / (4.1 - 3.0));
}
ESP_LOGD(TAG, "Got Battery Level=%f (%f)", batterylevel, vbat);
ESP_LOGD(TAG, "Got Battery Level=%f", batterylevel);
if (batterylevel > 100.) {
batterylevel = 100;
}
this->batterylevel_sensor_->publish_state(batterylevel);
}
if (this->batterycharging_bsensor_ != nullptr) {
bool vcharging = PMU.isCharging();
ESP_LOGD(TAG, "Got Battery Charging=%s", vcharging ? "true" : "false");
this->batterycharging_bsensor_->publish_state(vcharging);
}
UpdateBrightness();
}

View File

@@ -1,9 +1,10 @@
#ifndef __AXP2101_H__
#define __AXP2101_H__
#include "esphome/core/component.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/components/binary_sensor/binary_sensor.h"
#include "esphome/components/i2c/i2c.h"
#include "esphome/components/sensor/sensor.h"
#include "esphome/core/component.h"
#define XPOWERS_CHIP_AXP2101
#include "XPowersLib.h"
@@ -31,7 +32,9 @@ enum AXP2101Model {
class AXP2101Component : public PollingComponent, public i2c::I2CDevice {
public:
void set_batteryvoltage_sensor(sensor::Sensor *batteryvoltage_sensor) { batteryvoltage_sensor_ = batteryvoltage_sensor; }
void set_batterylevel_sensor(sensor::Sensor *batterylevel_sensor) { batterylevel_sensor_ = batterylevel_sensor; }
void set_batterycharging_bsensor(binary_sensor::BinarySensor *batterycharging_bsensor) { batterycharging_bsensor_ = batterycharging_bsensor; }
void set_brightness(float brightness) { brightness_ = brightness; }
void set_model(AXP2101Model model) { this->model_ = model; }
@@ -46,7 +49,9 @@ private:
static std::string GetStartupReason();
protected:
sensor::Sensor *batteryvoltage_sensor_;
sensor::Sensor *batterylevel_sensor_;
binary_sensor::BinarySensor *batterycharging_bsensor_;
float brightness_{1.0f};
float curr_brightness_{-1.0f};
AXP2101Model model_;

View File

@@ -1,13 +1,25 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import CONF_ID,\
CONF_BATTERY_LEVEL, CONF_BRIGHTNESS, UNIT_PERCENT, ICON_BATTERY, CONF_MODEL
from esphome.components import binary_sensor, i2c, sensor
from esphome.const import (
CONF_BATTERY_LEVEL,
CONF_BATTERY_VOLTAGE,
CONF_BRIGHTNESS,
CONF_ID,
CONF_MODEL,
DEVICE_CLASS_BATTERY_CHARGING,
DEVICE_CLASS_VOLTAGE,
ENTITY_CATEGORY_DIAGNOSTIC,
ICON_BATTERY,
UNIT_PERCENT,
)
DEPENDENCIES = ['i2c']
DEPENDENCIES = ["i2c"]
axp2101_ns = cg.esphome_ns.namespace('axp2101')
AXP2101Component = axp2101_ns.class_('AXP2101Component', cg.PollingComponent, i2c.I2CDevice)
axp2101_ns = cg.esphome_ns.namespace("axp2101")
AXP2101Component = axp2101_ns.class_(
"AXP2101Component", cg.PollingComponent, i2c.I2CDevice
)
AXP2101Model = axp2101_ns.enum("AXP2101Model")
MODELS = {
@@ -16,17 +28,32 @@ MODELS = {
AXP2101_MODEL = cv.enum(MODELS, upper=True, space="_")
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(AXP2101Component),
cv.Required(CONF_MODEL): AXP2101_MODEL,
cv.Optional(CONF_BATTERY_LEVEL):
sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
accuracy_decimals=1,
icon=ICON_BATTERY,
),
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x77))
CONF_BATTERY_CHARGING = "battery_charging"
CONFIG_SCHEMA = (
cv.Schema(
{
cv.GenerateID(): cv.declare_id(AXP2101Component),
cv.Required(CONF_MODEL): AXP2101_MODEL,
cv.Optional(CONF_BATTERY_VOLTAGE): sensor.sensor_schema(
device_class=DEVICE_CLASS_VOLTAGE,
accuracy_decimals=3,
entity_category=ENTITY_CATEGORY_DIAGNOSTIC,
),
cv.Optional(CONF_BATTERY_LEVEL): sensor.sensor_schema(
unit_of_measurement=UNIT_PERCENT,
accuracy_decimals=0,
icon=ICON_BATTERY,
),
cv.Optional(CONF_BATTERY_CHARGING): binary_sensor.binary_sensor_schema(
device_class=DEVICE_CLASS_BATTERY_CHARGING,
),
cv.Optional(CONF_BRIGHTNESS, default=1.0): cv.percentage,
}
)
.extend(cv.polling_component_schema("60s"))
.extend(i2c.i2c_device_schema(0x77))
)
def to_code(config):
@@ -38,11 +65,21 @@ def to_code(config):
cg.add(var.set_model(config[CONF_MODEL]))
if CONF_BATTERY_VOLTAGE in config:
conf = config[CONF_BATTERY_VOLTAGE]
sens = yield sensor.new_sensor(conf)
cg.add(var.set_batteryvoltage_sensor(sens))
if CONF_BATTERY_LEVEL in config:
conf = config[CONF_BATTERY_LEVEL]
sens = yield sensor.new_sensor(conf)
cg.add(var.set_batterylevel_sensor(sens))
if CONF_BATTERY_CHARGING in config:
conf = config[CONF_BATTERY_CHARGING]
sens = yield binary_sensor.new_binary_sensor(conf)
cg.add(var.set_batterycharging_bsensor(sens))
if CONF_BRIGHTNESS in config:
conf = config[CONF_BRIGHTNESS]
cg.add(var.set_brightness(conf))

View File

@@ -54,9 +54,12 @@ sensor:
i2c_id: bus_a
update_interval: 30s
brightness: 75%
battery_voltage:
name: "Battery Voltage"
battery_level:
name: "Battery Level"
id: battery_level
battery_charging:
name: "Battery Charging"
- platform: mpu6886
address: 0x68