Skip to content

Instantly share code, notes, and snippets.

@mateuszdrab
Last active September 15, 2024 05:25
Show Gist options
  • Save mateuszdrab/922c760582fce29d63608a1a405c541b to your computer and use it in GitHub Desktop.
Save mateuszdrab/922c760582fce29d63608a1a405c541b to your computer and use it in GitHub Desktop.
esp32:
board: esp32dev
# framework:
# type: arduino
logger:
level: DEBUG
esp32_ble_tracker:
binary_sensor:
- platform: ble_presence
mac_address: mac
name: "BLE Presence"
entity_category: "DIAGNOSTIC"
# - platform: template
# device_class: battery_charging
# name: "Charging"
ble_client:
- mac_address: mac
name: Renogy Battery
id: renogy_battery_bc
auto_connect: true
on_connect:
then:
- logger.log:
format: "BLE client connected to battery"
level: DEBUG
on_disconnect:
then:
- logger.log:
format: "BLE client disconnected from battery"
level: DEBUG
interval:
- interval: 30s
then:
- ble_client.ble_write:
characteristic_uuid: "FFD1"
service_uuid: "FFD0"
id: renogy_battery_bc
value: !lambda return {0x30, 0x03, 0x13, 0xB2, 0x00, 0x06, 0x65, 0x4A};
sensor:
- platform: template
name: "Current"
id: renogy_battery_current
device_class: current
unit_of_measurement: A
accuracy_decimals: 1
- platform: template
name: "Voltage"
id: renogy_battery_voltage
device_class: voltage
unit_of_measurement: V
accuracy_decimals: 1
- platform: template
name: "Present Capacity"
id: renogy_battery_present_capacity
unit_of_measurement: Ah
accuracy_decimals: 1
- platform: template
name: "Total Capacity"
id: renogy_battery_total_capacity
unit_of_measurement: Ah
accuracy_decimals: 1
- platform: template
name: "Charge Level"
id: renogy_battery_charge_level
icon: mdi:percent
unit_of_measurement: "%"
accuracy_decimals: 1
- platform: ble_client
ble_client_id: renogy_battery_bc
id: renogy_battery_sensor
internal: true
type: characteristic
service_uuid: FFF0
characteristic_uuid: FFF1
notify: true
update_interval: never
# on_notify:
# then:
# - lambda: |-
# ESP_LOGD("ble_client.notify", "x: %.2f", x);
lambda: |-
int receivedSize = x.size();
ESP_LOGD("ble_client_lambda", "Received bytes size: %d", receivedSize);
// Log each byte in the array
for (size_t i = 0; i < receivedSize; ++i) {
ESP_LOGD("main", "Byte %d: 0x%02X", i, x[i]);
}
if (receivedSize < 17) return NAN;
// Parse the function
uint8_t function;
std::memcpy(&function, &x[1], sizeof(function));
// function = ntohs(function); // Convert from network byte order to host byte order
ESP_LOGD("ble_client_lambda", "function: %d", function);
// Parse the current
int16_t current;
std::memcpy(&current, &x[3], sizeof(current));
current = ntohs(current); // Convert from network byte order to host byte order
ESP_LOGD("ble_client_lambda", "current: %d", current);
// Parse the voltage
uint16_t voltage;
std::memcpy(&voltage, &x[5], 2);
voltage = ntohs(voltage); // Convert from network byte order to host byte order
ESP_LOGD("ble_client_lambda", "voltage: %d", voltage);
// Parse the present capacity
uint32_t presentCapacity;
std::memcpy(&presentCapacity, &x[7], 4);
presentCapacity = ntohl(presentCapacity); // Convert from network byte order to host byte order
ESP_LOGD("ble_client_lambda", "presentCapacity: %d", presentCapacity);
// Parse the total capacity
uint32_t totalCapacity;
std::memcpy(&totalCapacity, &x[11], 4);
totalCapacity = ntohl(totalCapacity); // Convert from network byte order to host byte order
ESP_LOGD("ble_client_lambda", "totalCapacity: %d", totalCapacity);
// Convert the values to the appropriate units
float currentFloat = static_cast<float>(current) / 100.0f;
float voltageFloat = static_cast<float>(voltage) / 10.0f;
float presentCapacityFloat = static_cast<float>(presentCapacity) / 1000.0f;
float totalCapacityFloat = static_cast<float>(totalCapacity) / 1000.0f;
float chargeLevelFloat = (presentCapacityFloat / totalCapacityFloat) * 100.0f;
id(renogy_battery_current).publish_state(currentFloat);
id(renogy_battery_voltage).publish_state(voltageFloat);
id(renogy_battery_present_capacity).publish_state(presentCapacityFloat);
id(renogy_battery_total_capacity).publish_state(totalCapacityFloat);
id(renogy_battery_charge_level).publish_state(chargeLevelFloat);
ESP_LOGD("ble_client_lambda", "currentFloat: %.1f", currentFloat);
ESP_LOGD("ble_client_lambda", "voltageFloat: %.1f", voltageFloat);
ESP_LOGD("ble_client_lambda", "presentCapacityFloat: %.1f", presentCapacityFloat);
ESP_LOGD("ble_client_lambda", "totalCapacityFloat: %.1f", totalCapacityFloat);
ESP_LOGD("ble_client_lambda", "chargeLevelFloat: %.1f", chargeLevelFloat);
return 0.0; // this sensor isn't actually used other than to hook into raw value and publish to template sensors
@vaughancoke
Copy link

vaughancoke commented Sep 15, 2024

This is fantastic. Worked perfectly for me. I was wondering how hard would it be to adapt your code to handle 2 batteries and a Renogy BT-2 connected to a DCC50S? I'm sure I could duplicate the logic for a second battery but the DCC50S with the BT-2 has me a little stuck.

@riker65
Copy link

riker65 commented Sep 15, 2024

Hiplease check
https://github.com/mavenius/renogy-bt-esphome/issues/3#issuecomment-2336727157

This is a start working for rover I assume it should work for dcc50 as well, as a starting point

It is worth looking into Solarthing, especially the I'd scanner.

Once bt2 is plugged into the Rover or Dcc50 id is changing on dcc to 96 on rover to 17 in my case.

Maybe this helps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment