Thanks to this post I learned about an interesting ESP32 board with a compartment for a 18650 battery and this can be used as a backup power source in case of a power outage, and also monitor the battery charge level, know the remaining time until it is completely discharged and recharged. I took the ESP32 with battery here
Connection diagram for a divider with 220 kOhm resistors to reduce the voltage to 2.4 V with a fully charged battery at 4.175 V
I also made sensors that show not only the battery level, but also the remaining charging time to 100% and discharging to 0%.
I used a divider of two 220 kom resistors and lowered the voltage to 2.4 V to fall into the range from 150 to 2450. I took it from the table in the documentation esp32 on ADC voltage.
Next, I measured the voltage with a multimeter at full discharged and charged battery and used a filter, which obtained correct voltage readings with a small error of -/+ 0.05V. The fully measured battery had a voltage of 4.175V, and in the sensor the value was 2.151, this is a figure in parrots and I converted it to the real value thus 4.175/2.151 = 1.940957694095769 ~ 1.941
filters:
- multiply: 1.941
Working code. If you have your own thoughts on this matter, I will only be glad if you post your version of the code.
#####################################################################################
###################################### Variables ####################################
substitutions:
name: feeder-pettix-s36
#####################################################################################
################################# Basic configuration ###############################
esphome:
name: $name
friendly_name: Feeder Pettix S36
comment: Feeder Pettix S36
#####################################################################################
####################################### Platform ####################################
esp32:
board: esp32dev
framework:
type: arduino
#####################################################################################
################################ WiFi and access point ##############################
#Wi-Fi credentials for connecting the board to the home network
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: off
reboot_timeout: 5min
#If there is no connection with WiFi, then the access point will rise
ap:
ssid: ESP Feeder Pettix S36
password: !secret ap_esp_password
ap_timeout: 1 min
manual_ip:
static_ip: 192.168.4.1
gateway: 192.168.4.1
subnet: 255.255.255.0
#The mdns component forces the node to announce itself on the local network using the DNS Multicast Protocol (mDNS), by default for mDNS disabled: false
mdns:
disabled: false
#The captive portal component in ESPHome is a backup mechanism in case the connection to the configured Wi-Fi fails
captive_portal:
#Web server
web_server:
port: 80
#Logging
logger:
baud_rate: 0
#Enable Home Assistant API
api:
#Over-the-Air Update (OTA)
ota:
password: "esphome"
#####################################################################################
################################## Sensor ###########################################
sensor:
#ADC sensor for battery level sensor
- platform: adc
name: ADC
icon: mdi:flash
id: idADC
pin: GPIO32
attenuation: 11db
update_interval: 60s
accuracy_decimals: 3
internal: false #Hide - true \show - false
#Battery level sensor
- platform: copy
name: Battery Level
icon: mdi:battery
id: idBatteryLevel
source_id: idADC
unit_of_measurement: '%'
accuracy_decimals: 0
filters:
- calibrate_linear:
#The battery voltage should not be lower than 3V and higher than 4.2V. To get into the range 0-2500 you need to use a divider to reduce the voltage to 2.4V and specify attenuation: 11db
#A divider of resistors 220 and 220 kom is used
- 1.545 -> 0
- 2.151 -> 100
#Battery voltage sensor. The readings are reliable with an error
- platform: copy
name: "Battery Voltage"
icon: mdi:flash
id: idBatteryVoltage
source_id: idADC
accuracy_decimals: 3
filters:
- multiply: 1.941
#####################################################################################
##################################### Text sensor ###################################
text_sensor:
#IP
- platform: wifi_info
ip_address:
name: IP
icon: mdi:ip-network
#ESPHome Version
- platform: version
name: "ESPHome Version"
hide_timestamp: true
#Uptime
- platform: template
name: "Uptime"
icon: mdi:clock-start
id: idUptimeESP
entity_category: diagnostic
- platform: template
name: "Time"
icon: mdi:clock-digital
id: idTime
update_interval: 10s
lambda: |-
auto time_text = id(homeassistant_time).now().strftime("%H:%M:%S / %d-%m-%Y");
return { time_text };
#Remaining time until charging 100%
- name: "Charging time up to 100%"
id: idChargingTime
platform: template
update_interval: 10s
lambda: |-
auto time = id(homeassistant_time).now();
if (!time.is_valid())
{
return {};
}
auto diff = time.timestamp;
if (id(idBatteryLevel).state != 100)
{
auto result = ((diff / id(idBatteryLevel).state) * (100 - id(idBatteryLevel).state)) / 86400;
result = result < 0 ? 0 : result;
auto hours = static_cast<int>(result) / 3600;
auto minutes = (static_cast<int>(result) % 3600) / 60;
return to_string(hours) + "h " + to_string(minutes) + "m";
}
else
{
auto result = diff / 86400;
result = result < 0 ? 0 : result;
auto hours = static_cast<int>(result) / 3600;
auto minutes = (static_cast<int>(result) % 3600) / 60;
return to_string(hours) + "h " + to_string(minutes) + "m";
}
#Remaining time until discharge at 0%
- name: "Discharge time to 0%"
id: idDischargeTime
platform: template
update_interval: 10s
lambda: |-
auto time = id(homeassistant_time).now();
if (!time.is_valid())
{
return {};
}
auto diff = time.timestamp;
if (id(idBatteryLevel).state != 0)
{
auto result = ((diff / (100 - id(idBatteryLevel).state)) * id(idBatteryLevel).state) / 86400;
result = result < 0 ? 0 : result;
auto hours = static_cast<int>(result) / 3600;
auto minutes = (static_cast<int>(result) % 3600) / 60;
return to_string(hours) + "h " + to_string(minutes) + "m";
}
else
{
auto result = diff / 86400;
result = result < 0 ? 0 : result;
auto hours = static_cast<int>(result) / 3600;
auto minutes = (static_cast<int>(result) % 3600) / 60;
return to_string(hours) + "h " + to_string(minutes) + "m";
}
#####################################################################################
####################################### Button ######################################
button:
- platform: restart
name: "Restart"
icon: mdi:restart
#####################################################################################
######################################## Time #######################################
time:
- platform: homeassistant
id: homeassistant_time