diff --git a/README.md b/README.md index 70c93c3..21f264d 100644 --- a/README.md +++ b/README.md @@ -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: diff --git a/components/axp2101/axp2101.cpp b/components/axp2101/axp2101.cpp index 3252cdc..f310dec 100644 --- a/components/axp2101/axp2101.cpp +++ b/components/axp2101/axp2101.cpp @@ -1,6 +1,6 @@ #include "axp2101.h" -#include "esphome/core/log.h" #include "esp_sleep.h" +#include "esphome/core/log.h" #include #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(); } diff --git a/components/axp2101/axp2101.h b/components/axp2101/axp2101.h index f68deb0..47085cf 100644 --- a/components/axp2101/axp2101.h +++ b/components/axp2101/axp2101.h @@ -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_; diff --git a/components/axp2101/sensor.py b/components/axp2101/sensor.py index 190f70e..0d3b47a 100644 --- a/components/axp2101/sensor.py +++ b/components/axp2101/sensor.py @@ -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)) diff --git a/sample-config/m5core2.yaml b/sample-config/m5core2.yaml index ff16ff2..e87804e 100644 --- a/sample-config/m5core2.yaml +++ b/sample-config/m5core2.yaml @@ -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