-
-
Save noone2k/2ddea4c9bf116aaaefb8626b064d9a41 to your computer and use it in GitHub Desktop.
esphome: | |
name: bc2500-ble-idf | |
friendly_name: bc2500-ble-idf | |
esp32: | |
board: az-delivery-devkit-v4 | |
framework: | |
type: esp-idf | |
sdkconfig_options: | |
CONFIG_FREERTOS_UNICORE: y | |
advanced: | |
ignore_efuse_mac_crc: true | |
# Enable logging | |
logger: | |
# level: INFO | |
# level: DEBUG | |
# baud_rate: 0 | |
ota: | |
password: !secret ota_password | |
wifi: | |
ssid: !secret wifi_ssid | |
password: !secret wifi_password | |
reboot_timeout: 0s | |
fast_connect: True | |
# Enable fallback hotspot (captive portal) in case wifi connection fails | |
ap: | |
ssid: "Bc2500-Ble Fallback Hotspot" | |
web_server: | |
port: 80 | |
local: true | |
js_include: "./v2/www.js" | |
js_url: "" | |
version: 2 | |
captive_portal: | |
mqtt: | |
id: mqtt_client | |
broker: !secret mqtt_broker | |
port: !secret mqtt_port | |
discovery: False | |
reboot_timeout: 0s | |
topic_prefix: b2500 | |
log_topic: b2500/debug | |
time: | |
- platform: sntp | |
id: sntp_time | |
on_time: | |
# Every 10 seconds | |
- seconds: /10 | |
then: | |
- script.execute: ble_process | |
- script.wait: ble_process | |
#- script.execute: power_zero | |
#- button.press: query_info3 | |
globals: | |
- id: ble_1_connected | |
type: bool | |
initial_value: '0' | |
- id: ble_1_initialized | |
type: bool | |
initial_value: '0' | |
- id: ble_2_connected | |
type: bool | |
initial_value: '0' | |
- id: ble_2_initialized | |
type: bool | |
initial_value: '0' | |
- id: cmd30_xor_last_1 | |
type: int | |
initial_value: '0' | |
- id: cmd30_xor_last_2 | |
type: int | |
initial_value: '0' | |
- id: internal_console_dbg | |
type: bool | |
initial_value: '0' | |
- id: internal_console_hexdump | |
type: bool | |
initial_value: '1' | |
esp32_ble_tracker: | |
ble_client: | |
- mac_address: !secret hm2500_1_mac | |
id: bc2500_1 | |
on_connect: | |
then: | |
- globals.set: | |
id: ble_1_connected | |
value: '1' | |
- binary_sensor.template.publish: | |
id: bool_ble_ok_1 | |
state: ON | |
- script.execute: | |
id: ble_set_time | |
ble_device_nr: 1 | |
- script.wait: ble_set_time | |
- script.execute: | |
id: ble_set_time | |
ble_device_nr: 1 | |
- script.wait: ble_set_time | |
on_disconnect: | |
then: | |
- binary_sensor.template.publish: | |
id: bool_ble_ok_1 | |
state: OFF | |
- globals.set: | |
id: ble_1_connected | |
value: '0' | |
- globals.set: | |
id: ble_1_initialized | |
value: '0' | |
- mac_address: !secret hm2500_2_mac | |
id: bc2500_2 | |
on_connect: | |
then: | |
- globals.set: | |
id: ble_2_connected | |
value: '1' | |
- binary_sensor.template.publish: | |
id: bool_ble_ok_2 | |
state: ON | |
- script.execute: | |
id: ble_set_time | |
ble_device_nr: 2 | |
- script.wait: ble_set_time | |
- script.execute: | |
id: ble_set_time | |
ble_device_nr: 2 | |
- script.wait: ble_set_time | |
on_disconnect: | |
then: | |
- binary_sensor.template.publish: | |
id: bool_ble_ok_2 | |
state: OFF | |
- globals.set: | |
id: ble_2_connected | |
value: '0' | |
- globals.set: | |
id: ble_2_initialized | |
value: '0' | |
button: | |
- platform: restart | |
id: controller_restart | |
name: "Restart Controller" | |
number: | |
- platform: template | |
name: "D1-52: Entladeschwelle" | |
id: sensor_discharge_treshold_1 | |
state_topic: b2500/1/battery/discharge_treshold | |
command_topic: b2500/1/battery/discharge_treshold/set | |
optimistic: True | |
min_value: 1 | |
max_value: 500 | |
step: 1 | |
restore_value: True | |
on_value: | |
- script.execute: | |
id: ble_set_discharge_treshold | |
ble_device_nr: 1 | |
discharge: !lambda return x; | |
- platform: template | |
name: "D1-53: DOD" | |
state_topic: b2500/1/battery/dod | |
command_topic: b2500/1/battery/dod/set | |
id: sensor_dod_1 | |
optimistic: True | |
min_value: 10 | |
max_value: 100 | |
step: 1 | |
restore_value: True | |
on_value: | |
- script.execute: | |
id: ble_set_dod | |
ble_device_nr: 1 | |
dod: !lambda return x; | |
- platform: template | |
name: "D2-52: Entladeschwelle" | |
id: sensor_discharge_treshold_2 | |
state_topic: b2500/2/battery/discharge_treshold | |
command_topic: b2500/2/battery/discharge_treshold/set | |
optimistic: True | |
min_value: 1 | |
max_value: 500 | |
step: 1 | |
restore_value: True | |
on_value: | |
- script.execute: | |
id: ble_set_discharge_treshold | |
ble_device_nr: 2 | |
discharge: !lambda return x; | |
- platform: template | |
name: "D2-53: DOD" | |
state_topic: b2500/2/battery/dod | |
command_topic: b2500/2/battery/dod/set | |
id: sensor_dod_2 | |
optimistic: True | |
min_value: 10 | |
max_value: 100 | |
step: 1 | |
restore_value: True | |
on_value: | |
- script.execute: | |
id: ble_set_dod | |
ble_device_nr: 2 | |
dod: !lambda return x; | |
### power zero | |
- platform: template | |
name: "MQTT: opendtu set limit" | |
id: mqtt_opendtu_limit | |
internal: False | |
state_topic: !secret mqtt_opendtu_limit_cmd | |
command_topic: !secret mqtt_opendtu_limit_state | |
optimistic: True | |
min_value: 1 | |
max_value: 75 | |
step: 1 | |
restore_value: True | |
- platform: template | |
name: "MQTT: opendtu set limit max" | |
id: mqtt_opendtu_limit_max | |
internal: False | |
optimistic: True | |
min_value: 1 | |
max_value: 75 | |
step: 1 | |
restore_value: True | |
switch: | |
- platform: template | |
id: switch_powerout_1_1 | |
name: "D1-01: Power Out 1" | |
state_topic: b2500/1/power1/enabled | |
command_topic: b2500/1/power1/enabled/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- switch.turn_on: switch_powerout_1_1 | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 1 | |
on_turn_off: | |
then: | |
- switch.turn_off: switch_powerout_1_1 | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 1 | |
- platform: template | |
id: switch_powerout_1_2 | |
name: "D1-02: Power Out 2" | |
state_topic: b2500/1/power2/enabled | |
command_topic: b2500/1/power2/enabled/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- switch.turn_on: switch_powerout_1_2 | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 1 | |
on_turn_off: | |
then: | |
- switch.turn_off: switch_powerout_1_2 | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 1 | |
- platform: template | |
id: switch_powerout_2_1 | |
name: "D2-01: Power Out 1" | |
state_topic: b2500/2/power1/enabled | |
command_topic: b2500/2/power1/enabled/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 2 | |
on_turn_off: | |
then: | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 2 | |
- platform: template | |
id: switch_powerout_2_2 | |
name: "D2-02: Power Out 2" | |
state_topic: b2500/2/power2/enabled | |
command_topic: b2500/2/power2/enabled/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 2 | |
on_turn_off: | |
then: | |
- script.execute: | |
id: ble_powerout | |
ble_device_nr: 2 | |
- platform: template | |
id: switch_pv2_passthrough_1 | |
name: "D1-03: PV2 Passtrough" | |
state_topic: b2500/1/pv2/passtrough | |
command_topic: b2500/1/pv2/passtrough/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- script.execute: | |
id: ble_passthrough | |
ble_device_nr: 1 | |
switch_cmd: 0 | |
on_turn_off: | |
then: | |
- script.execute: | |
id: ble_passthrough | |
ble_device_nr: 1 | |
switch_cmd: 1 | |
- platform: template | |
id: switch_pv2_passthrough_2 | |
name: "D2-03: PV2 Passtrough" | |
state_topic: b2500/2/pv2/passtrough | |
command_topic: b2500/2/pv2/passtrough/set | |
optimistic: True | |
assumed_state: True | |
on_turn_on: | |
then: | |
- script.execute: | |
id: ble_passthrough | |
ble_device_nr: 2 | |
switch_cmd: 0 | |
on_turn_off: | |
then: | |
- script.execute: | |
id: ble_passthrough | |
ble_device_nr: 2 | |
switch_cmd: 1 | |
- platform: template | |
id: switch_debug_hexdump | |
name: "INTERNAL:DEBUG HEXDUMP" | |
optimistic: True | |
#assumed_state: True | |
- platform: template | |
id: switch_opendtu_limit | |
name: "MQTT: opendtu - zero power" | |
optimistic: True | |
#assumed_state: True | |
text: | |
- platform: template | |
name: "A1-t01 - Device Type" | |
id: txt_A01_1 | |
state_topic: b2500/1/device/type | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A1-t02 - Device ID" | |
state_topic: b2500/1/device/id | |
id: txt_A02_1 | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A1-t03 - MAC" | |
id: txt_A03_1 | |
state_topic: b2500/1/device/ble_mac | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A1-t04 - SSID" | |
id: txt_A11_1 | |
state_topic: b2500/1/device/wifi_ssid | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A2-t01 - Device Type" | |
id: txt_A01_2 | |
state_topic: b2500/2/device/type | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A2-t02 - Device ID" | |
id: txt_A02_2 | |
state_topic: b2500/2/device/id | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A2-t03 - MAC" | |
id: txt_A03_2 | |
optimistic: true | |
state_topic: b2500/2/device/ble_mac | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A2-t04 - SSID" | |
id: txt_A11_2 | |
state_topic: b2500/2/device/wifi_ssid | |
optimistic: true | |
max_length: 30 | |
mode: text | |
- platform: template | |
name: "A1-t56: Szene" | |
id: txt_scene_1 | |
state_topic: b2500/1/device/scene | |
optimistic: true | |
max_length: 32 | |
mode: text | |
- platform: template | |
name: "A1-t57: Region" | |
id: txt_region_1 | |
state_topic: b2500/1/device/region | |
optimistic: true | |
max_length: 8 | |
mode: text | |
- platform: template | |
name: "A2-t56: Szene" | |
id: txt_scene_2 | |
state_topic: b2500/2/device/scene | |
optimistic: true | |
max_length: 32 | |
mode: text | |
- platform: template | |
name: "A2-t57: Region" | |
id: txt_region_2 | |
state_topic: b2500/2/device/region | |
optimistic: true | |
max_length: 8 | |
mode: text | |
binary_sensor: | |
- platform: template | |
name: "D1-i01: PV 1 - Aktiv" | |
id: bool_pv_active_1_1 | |
state_topic: b2500/1/pv1/active | |
- platform: template | |
name: "D1-i11: PV 2 - Aktiv" | |
id: bool_pv_active_1_2 | |
state_topic: b2500/1/pv2/active | |
- platform: template | |
name: "D1-i02: PV 1 - Transparent" | |
id: bool_pv_transparent_1_1 | |
state_topic: b2500/1/pv1/transparent | |
- platform: template | |
name: "D1-i11: PV 2 - Transparent" | |
id: bool_pv_transparent_1_2 | |
state_topic: b2500/1/pv2/transparent | |
- platform: template | |
name: "D1-i54: Wifi Connected (?)" | |
id: bool_wifi_ok_1 | |
state_topic: b2500/1/device/wifi_ok | |
- platform: template | |
name: "D1-i55: MQTT1 Connected" | |
id: bool_mqtt1_ok_1 | |
state_topic: b2500/1/device/mqtt_ok | |
- platform: template | |
name: "D1-i58: BLE Connected" | |
id: bool_ble_ok_1 | |
state_topic: b2500/1/device/ble_ok | |
- platform: template | |
name: "D1-i21: Ausgang 1 - Aktiv" | |
id: bool_power_active_1_1 | |
state_topic: b2500/1/power1/active | |
- platform: template | |
name: "D1-i31: Ausgang 2 - Aktiv" | |
id: bool_power_active_1_2 | |
state_topic: b2500/1/power2/active | |
- platform: template | |
name: "D1-i40: Erweiterung 1 - angeschlossen" | |
id: bool_extern_connected_1_1 | |
state_topic: b2500/1/extern1/connected | |
- platform: template | |
name: "D1-i41: Erweiterung 2 - angeschlossen" | |
id: bool_extern_connected_1_2 | |
state_topic: b2500/1/extern2/connected | |
- platform: template | |
name: "D2-i01: PV 1 - Aktiv" | |
id: bool_pv_active_2_1 | |
state_topic: b2500/2/pv1/active | |
- platform: template | |
name: "D2-i11: PV 2 - Aktiv" | |
id: bool_pv_active_2_2 | |
state_topic: b2500/2/pv2/active | |
- platform: template | |
name: "D2-i02: PV 1 - Transparent" | |
id: bool_pv_transparent_2_1 | |
state_topic: b2500/2/pv1/transparent | |
- platform: template | |
name: "D2-i12: PV 2 - Transparent" | |
id: bool_pv_transparent_2_2 | |
state_topic: b2500/2/pv2/transparent | |
- platform: template | |
name: "D2-i54: Wifi Connected (?)" | |
id: bool_wifi_ok_2 | |
state_topic: b2500/2/device/wifi_ok | |
- platform: template | |
name: "D2-i55: MQTT1 Connected" | |
id: bool_mqtt1_ok_2 | |
state_topic: b2500/2/device/mqtt_ok | |
- platform: template | |
name: "D2-i58: BLE Connected" | |
id: bool_ble_ok_2 | |
state_topic: b2500/2/device/ble_ok | |
- platform: template | |
name: "D2-i21: Ausgang 1 - Aktiv" | |
id: bool_power_active_2_1 | |
state_topic: b2500/2/power1/active | |
- platform: template | |
name: "D2-i31: Ausgang 2 - Aktiv" | |
id: bool_power_active_2_2 | |
state_topic: b2500/2/power2/active | |
- platform: template | |
name: "D2-i40: Erweiterung 1 - angeschlossen" | |
id: bool_extern_connected_2_1 | |
state_topic: b2500/2/extern1/connected | |
- platform: template | |
name: "D2-i41: Erweiterung 2 - angeschlossen" | |
id: bool_extern_connected_2_2 | |
state_topic: b2500/2/extern2/connected | |
sensor: | |
- platform: template | |
name: "D1-i05: PV 1 - Leistung" | |
id: sensor_pv_power_in_1_1 | |
state_topic: b2500/1/pv1/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D1-i15: PV 2 - Leistung" | |
id: sensor_pv_power_in_1_2 | |
state_topic: b2500/1/pv2/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D1-i50: Füllstand der Batterie in Prozent" | |
id: sensor_bat_remain_1 | |
state_topic: b2500/1/battery/remaining_percent | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D1-i51: Füllstand der Batterie in Wh" | |
id: sensor_bat_capacity_1 | |
state_topic: b2500/1/battery/remaining_capacity | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D1-i25: Ausgang 1 - Leistung" | |
id: sensor_power_out_1_1 | |
state_topic: b2500/1/power1/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D1-i35: Ausgang 2 - Leistung" | |
id: sensor_power_out_1_2 | |
state_topic: b2500/1/power2/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "A1-t59: Geräte Version" | |
id: sensor_device_version_1 | |
state_topic: b2500/1/device/fw_version | |
accuracy_decimals: 2 | |
- platform: template | |
name: "D2-i05: PV 1 - Leistung" | |
id: sensor_pv_power_in_2_1 | |
state_topic: b2500/2/pv1/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D2-i15: PV 2 - Leistung" | |
id: sensor_pv_power_in_2_2 | |
state_topic: b2500/2/pv2/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D2-i50: Füllstand der Batterie in Prozent" | |
id: sensor_bat_remain_2 | |
state_topic: b2500/2/battery/remaining_percent | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D2-i51: Füllstand der Batterie in Wh" | |
id: sensor_bat_capacity_2 | |
state_topic: b2500/2/battery/remaining_capacity | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D2-i25: Ausgang 1 - Leistung " | |
id: sensor_power_out_2_1 | |
state_topic: b2500/2/power1/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "D2-i35: Ausgang 2 - Leistung " | |
id: sensor_power_out_2_2 | |
state_topic: b2500/2/power2/power | |
accuracy_decimals: 0 | |
- platform: template | |
name: "A2-t59: Geräte Version" | |
id: sensor_device_version_2 | |
state_topic: b2500/2/device/fw_version | |
accuracy_decimals: 2 | |
- platform: ble_client | |
ble_client_id: bc2500_1 | |
internal: True | |
type: characteristic | |
name: "infoX2a" | |
id: infoX2a | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff02' | |
notify: True | |
lambda: |- | |
std::vector<char> tData; | |
for (auto b : x) { tData.push_back(b); } | |
id(ble_notify_parse).execute(1,tData); | |
return (float)x[0]; | |
- platform: ble_client | |
ble_client_id: bc2500_2 | |
internal: True | |
type: characteristic | |
name: "infoX2b" | |
id: infoX2b | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff02' | |
notify: True | |
lambda: |- | |
std::vector<char> tData; | |
for (auto b : x) { tData.push_back(b); } | |
id(ble_notify_parse).execute(2,tData); | |
return (float)x[0]; | |
### power zero - mqtt grid power sensor ( any who publish the grid power to mqtt - defined in secrets,yaml ) | |
- platform: mqtt_subscribe | |
name: "MQTT: Grid Power" | |
id: mqtt_grid_power | |
topic: !secret mqtt_grid_power | |
on_value: | |
then: | |
- script.execute: power_zero | |
###test | |
- platform: ble_client | |
ble_client_id: bc2500_1 | |
internal: True | |
type: characteristic | |
name: "infoX6a" | |
id: infoX6a | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff06' | |
notify: True | |
lambda: |- | |
std::vector<char> tData; | |
for (auto b : x) { tData.push_back(b); } | |
id(ble_notify_parse_test).execute(1,tData); | |
return (float)x[0]; | |
- platform: ble_client | |
ble_client_id: bc2500_2 | |
internal: True | |
type: characteristic | |
name: "infoX6b" | |
id: infoX6b | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff06' | |
notify: True | |
lambda: |- | |
std::vector<char> tData; | |
for (auto b : x) { tData.push_back(b); } | |
id(ble_notify_parse_test).execute(1,tData); | |
return (float)x[0]; | |
script: | |
# ble communication | |
# | |
# action ( 00f1 ) | |
# | |
# head = 0x73 | |
# length = len(paket) | |
# cntl = 0x23 | |
# cmd = 0x02 set Region 1Byte (0x00 = EU / 0x01 = China / 0x02 = Non-EU) | |
# = 0x03 runtimeInfo 1Byte (0x01) | |
# = 0x04 DeviceInfo 1Byte (0x01) | |
# = 0x0B DOD 1Byte (0-100) | |
# = 0x0C Entladeschwelle 2Byte (0-500) | |
# = 0x0D PV2-Passtrough 1Byte (0x00 on / 0x01 off) | |
# = 0x0E PowerOut 1Byte (0x00 1-2 off / 0x01 1 on / 0x02 2 on / 0x03 1-2 on) | |
# | |
# = 0x05 Wifi-Config xByte ( ssid<.,.>pwd ) | |
# = 0x08 Wifi-State 1Byte (0x01) ???? | |
# | |
# q&d c&p - more details will be added, maybe ... | |
# = 0x14 set AWS MQTT xByte ( url<.,.>Port ) .... | |
# = 0x60 set MQTT Certs xByte ( 0x00 = client.key / 0x01 = client.crt / 0x02 = ca.crt + cert len ) | |
# = 0x61 trans MQTT Certs xByte ( jeweils 128bytes des certs ) | |
# = 0x62 end MQTT Certs xByte ( ) | |
# | |
# testing / notes | |
# = 0x01 Debug ?!?! 1Byte (0x00 = off / 0x01 = on) - enables QBLEGATTSNOTIFY notify 1 / 81 ( entspricht ~ runtimeinfo ) | |
# = 0x06 | |
# = 0x07 | |
# = 0x09 | |
# = 0x0A | |
# = 0x0E HW-RESET ????? / send before head 0XAA ( deactivate output ??? ) | |
# = 0x0F new in fw 131 1Byte ( 0x01 ) | |
# | |
# = 0x30 found in logs ... unknown parm 0x01 ???? answers since fw 131 | |
# = 0x14 maybe not for mqtt ... set localtime ??? for auth/certs/challenge requests ????? ( query/set wifi depends ????) | |
# | |
# data = xx xx xx xx xx xx .... / depends on cmd | |
# crc = xor len(paket) - 1 | |
# | |
# | |
# responses ( ff02 ): | |
# | |
# head = 0x73 | |
# length = len(paket) | |
# cntl = 0x23 | |
# cmd = cmd | |
# data = xx xx xx xx xx .... | |
# | |
# | |
# | |
################ maybe direct for arm | |
# send ( ff01 ) | |
# | |
# head1 = 0xAA | |
# head2(?) = 0x55 ( not length ?!?!? ) | |
# cmd = 1x / 2x / 3x ( flash - 30 "open"/ 31 - write / 32 "close" ) / 5x | |
# data = xx xx xx xx xx .... | |
# crc = xor len(paket) -1 | |
# | |
################ maybe direct for bms | |
# send/receive ( ff06 ) | |
# | |
# head = 0xAA | |
# len = 0x05/0x03 | |
# data = xx xx xxx ( xx xx ) | |
# crc = x1 + x2 + ... + xn | |
# | |
# | |
# | |
# -> aa 05 01 00 01 01 00 08 | |
# <- aa 01 00 01 | |
# | |
# -> aa 05 01 00 01 00 00 07 | |
# <- aa 01 00 01 | |
# | |
- id: ble_command_simple | |
parameters: | |
ble_device_nr: int | |
ble_cmd: int | |
ble_cmd_parm: int | |
then: | |
- logger.log: | |
format: "ble command parse: %i [%i] %i" | |
args: [ 'ble_device_nr','ble_cmd','ble_cmd_parm' ] | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 1);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_1 | |
#service_uuid: 'ff00' | |
#characteristic_uuid: 'ff01' | |
service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
characteristic_uuid: 0000ff01-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat1{ 0x73,0x06,0x23,(unsigned char)ble_cmd}; | |
if (ble_cmd == 0x0C) { | |
rdat1.push_back((uint8_t)((ble_cmd_parm >> 0) & 0xFF)); | |
rdat1.push_back((uint8_t)((ble_cmd_parm >> 8) & 0xFF)); | |
} else { | |
rdat1.push_back((unsigned char)ble_cmd_parm); | |
} | |
int rlen = rdat1.size(); | |
rdat1.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat1[i]; | |
} | |
rdat1.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat1) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat1; | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 2);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_2 | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff01' | |
value: !lambda |- | |
std::vector<unsigned char> rdat2{ 0x73,0x06,0x23,(unsigned char)ble_cmd}; | |
if (ble_cmd == 0x0C) { | |
rdat2.push_back((uint8_t)((ble_cmd_parm >> 0) & 0xFF)); | |
rdat2.push_back((uint8_t)((ble_cmd_parm >> 8) & 0xFF)); | |
} else { | |
rdat2.push_back((unsigned char)ble_cmd_parm); | |
} | |
int rlen = rdat2.size(); | |
rdat2.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat2[i]; | |
} | |
rdat2.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat2) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat2; | |
- id: ble_command_string | |
parameters: | |
ble_device_nr: int | |
ble_cmd: int | |
ble_cmd_parm: string | |
then: | |
- logger.log: | |
format: "ble command parse: %i [%i]" | |
args: [ 'ble_device_nr','ble_cmd'] | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 1);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_1 | |
#service_uuid: 'ff00' | |
#characteristic_uuid: 'ff01' | |
service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
characteristic_uuid: 0000ff01-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat1{ 0x73,0x06,0x23,(unsigned char)ble_cmd}; | |
for (auto b : ble_cmd_parm) { | |
rdat1.push_back((unsigned char)b); | |
} | |
int rlen = rdat1.size(); | |
rdat1.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat1[i]; | |
} | |
rdat1.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat1) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat1; | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 2);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_2 | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff01' | |
#service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
#characteristic_uuid: 0000ff01-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat2{ 0x73,0x06,0x23,(unsigned char)ble_cmd}; | |
for (auto b : ble_cmd_parm) { | |
rdat2.push_back((unsigned char)b); | |
} | |
int rlen = rdat2.size(); | |
rdat2.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat2[i]; | |
} | |
rdat2.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat2) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat2; | |
- id: ble_set_time | |
parameters: | |
ble_device_nr: int | |
then: | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 1);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_1 | |
#service_uuid: 'ff00' | |
#characteristic_uuid: 'ff01' | |
service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
characteristic_uuid: 0000ff01-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat1{ 0x73,0x0d,0x23,0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00 }; | |
auto time = id(sntp_time).now(); | |
rdat1.at(4) = time.year - 1900; | |
rdat1.at(5) = time.month; | |
rdat1.at(6) = time.day_of_month; | |
rdat1.at(7) = time.hour; | |
rdat1.at(8) = time.minute; | |
rdat1.at(9) = time.second + 1; | |
int rlen = rdat1.size(); | |
rdat1.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat1[i]; | |
} | |
rdat1.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat1) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat1; | |
- globals.set: | |
id: ble_1_initialized | |
value: '1' | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 2);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_2 | |
service_uuid: 'ff00' | |
characteristic_uuid: 'ff01' | |
#service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
#characteristic_uuid: 0000ff01-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat2{ 0x73,0x0d,0x23,0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00 }; | |
auto time = id(sntp_time).now(); | |
rdat2.at(4) = time.year - 1900; | |
rdat2.at(5) = time.month; | |
rdat2.at(6) = time.day_of_month; | |
rdat2.at(7) = time.hour; | |
rdat2.at(8) = time.minute; | |
rdat2.at(9) = time.second + 1; | |
int rlen = rdat2.size(); | |
rdat2.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat2[i]; | |
} | |
rdat2.push_back(rxor); | |
if (id(internal_console_dbg)) { | |
for (auto b : rdat2) { | |
ESP_LOGD("COMMAND", "%x - %i - %c", b,b,b); | |
} | |
} | |
return rdat2; | |
- globals.set: | |
id: ble_2_initialized | |
value: '1' | |
- id: ble_command_raw_06 | |
parameters: | |
ble_device_nr: int | |
ble_cmd_parm: char[] | |
then: | |
- logger.log: | |
format: "ble command parse (raw): %i" | |
args: [ 'ble_device_nr'] | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 1);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_1 | |
#service_uuid: 'ff00' | |
#characteristic_uuid: 'ff06' | |
service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
characteristic_uuid: 0000ff06-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat1; | |
for (auto b : ble_cmd_parm) { | |
rdat1.push_back((unsigned char)b); | |
} | |
/* | |
int rlen = rdat1.size(); | |
rdat1.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat1[i]; | |
} | |
rdat1.push_back(rxor); | |
*/ | |
//if (id(internal_console_dbg)) { | |
for (auto b : rdat1) { | |
ESP_LOGD("COMMAND raw", "%x - %i - %c", b,b,b); | |
} | |
//} | |
return rdat1; | |
- if: | |
condition: | |
lambda: 'return (ble_device_nr == 2);' | |
then: | |
- ble_client.ble_write: | |
id: bc2500_2 | |
#service_uuid: 'ff00' | |
#characteristic_uuid: 'ff06' | |
service_uuid: 0000ff00-0000-1000-8000-00805f9b34fb | |
characteristic_uuid: 0000ff06-0000-1000-8000-00805f9b34fb | |
value: !lambda |- | |
std::vector<unsigned char> rdat2; | |
for (auto b : ble_cmd_parm) { | |
rdat2.push_back((unsigned char)b); | |
} | |
/* | |
int rlen = rdat2.size(); | |
rdat2.at(1) = rlen+1; | |
int rxor = 0; | |
for (int i=0;i<rlen;i++) { | |
rxor = rxor ^ rdat2[i]; | |
} | |
rdat2.push_back(rxor); | |
*/ | |
//if (id(internal_console_dbg)) { | |
for (auto b : rdat2) { | |
ESP_LOGD("COMMAND raw", "%x - %i - %c", b,b,b); | |
} | |
//} | |
return rdat2; | |
- id: ble_process | |
then: | |
- if: | |
condition: | |
- lambda: 'return (id(ble_1_connected) && id(ble_1_initialized));' | |
then: | |
- script.execute: | |
id: ble_runtime_query | |
ble_device_nr: 1 | |
- script.wait: ble_runtime_query | |
### query cmd30 if firmware > 1.30 | |
- if: | |
condition: | |
- lambda: 'return (id(sensor_device_version_1).state * 100 > 130);' | |
then: | |
- script.execute: | |
id: ble_runtime_query30 | |
ble_device_nr: 1 | |
- script.wait: ble_runtime_query30 | |
- script.execute: | |
id: ble_runtime_query0F | |
ble_device_nr: 1 | |
- script.wait: ble_runtime_query0F | |
### query deviceinfo if empty | |
- if: | |
condition: | |
- lambda: 'return (id(txt_A03_1).state == "");' | |
then: | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: 1 | |
ble_cmd: 0x04 | |
ble_cmd_parm: 0x01 | |
- script.wait: ble_command_simple | |
- if: | |
condition: | |
- lambda: 'return (id(ble_2_connected) && id(ble_2_initialized));' | |
then: | |
- script.execute: | |
id: ble_runtime_query | |
ble_device_nr: 2 | |
- script.wait: ble_runtime_query | |
### query cmd30 if firmware > 1.30 | |
- if: | |
condition: | |
- lambda: 'return (id(sensor_device_version_2).state * 100 > 130);' | |
then: | |
- script.execute: | |
id: ble_runtime_query30 | |
ble_device_nr: 2 | |
- script.wait: ble_runtime_query30 | |
- script.execute: | |
id: ble_runtime_query0F | |
ble_device_nr: 2 | |
- script.wait: ble_runtime_query0F | |
### query deviceinfo if empty | |
- if: | |
condition: | |
- lambda: 'return (id(txt_A03_2).state == "");' | |
then: | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: 2 | |
ble_cmd: 0x04 | |
ble_cmd_parm: 0x01 | |
- script.wait: ble_command_simple | |
- id: ble_runtime_query | |
parameters: | |
ble_device_nr: int | |
then: | |
- logger.log: | |
format: "runtime query: %i" | |
args: [ 'ble_device_nr' ] | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x03 | |
ble_cmd_parm: 0x01 | |
- script.wait: ble_command_simple | |
- id: ble_runtime_query30 | |
parameters: | |
ble_device_nr: int | |
then: | |
- logger.log: | |
format: "runtime query 30: %i" | |
args: [ 'ble_device_nr' ] | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x30 | |
ble_cmd_parm: 0x01 | |
- script.wait: ble_command_simple | |
- id: ble_runtime_query0F | |
parameters: | |
ble_device_nr: int | |
then: | |
- logger.log: | |
format: "runtime query 0F: %i" | |
args: [ 'ble_device_nr' ] | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x0F | |
ble_cmd_parm: 0x01 | |
- script.wait: ble_command_simple | |
- id: ble_powerout | |
parameters: | |
ble_device_nr: int | |
then: | |
- lambda: |- | |
int ble_cmd_t = 0x00; | |
if ( ble_device_nr == 1 ) { | |
if ( ! id(switch_powerout_1_1).state && ! id(switch_powerout_1_2).state ) { ble_cmd_t = 0x00; } | |
if ( id(switch_powerout_1_1).state && ! id(switch_powerout_1_2).state ) { ble_cmd_t = 0x01; } | |
if ( ! id(switch_powerout_1_1).state && id(switch_powerout_1_2).state ) { ble_cmd_t = 0x02; } | |
if ( id(switch_powerout_1_1).state && id(switch_powerout_1_2).state ) { ble_cmd_t = 0x03; } | |
} | |
if ( ble_device_nr == 2 ) { | |
if ( ! id(switch_powerout_2_1).state && ! id(switch_powerout_2_2).state ) { ble_cmd_t = 0x00; } | |
if ( id(switch_powerout_2_1).state && ! id(switch_powerout_2_2).state ) { ble_cmd_t = 0x01; } | |
if ( ! id(switch_powerout_2_1).state && id(switch_powerout_2_2).state ) { ble_cmd_t = 0x02; } | |
if ( id(switch_powerout_2_1).state && id(switch_powerout_2_2).state ) { ble_cmd_t = 0x03; } | |
} | |
id(ble_command_simple).execute(ble_device_nr,0x0E,ble_cmd_t); | |
if (ble_cmd_t == 0x00) { ESP_LOGD("set_power_out", "Device %i - %s", ble_device_nr,"1 OFF / 2 OFF"); } | |
if (ble_cmd_t == 0x01) { ESP_LOGD("set_power_out", "Device %i - %s", ble_device_nr,"1 ON / 2 OFF"); } | |
if (ble_cmd_t == 0x02) { ESP_LOGD("set_power_out", "Device %i - %s", ble_device_nr,"1 OFF / 2 ON"); } | |
if (ble_cmd_t == 0x03) { ESP_LOGD("set_power_out", "Device %i - %s", ble_device_nr,"1 ON / 2 ON"); } | |
- id: ble_passthrough | |
parameters: | |
ble_device_nr: int | |
switch_cmd: bool | |
then: | |
- logger.log: | |
format: "PV2 Passthrough %i : %i" | |
args: [ble_device_nr,switch_cmd] | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x0D | |
ble_cmd_parm: !lambda return switch_cmd; | |
- id: ble_set_dod | |
parameters: | |
ble_device_nr: int | |
dod: int | |
then: | |
- logger.log: | |
format: "set DOD: %i" | |
args: [ 'dod' ] | |
- if: | |
condition: | |
lambda: 'return ( dod <= 100 && dod >= 10);' | |
then: | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x0B | |
ble_cmd_parm: !lambda return dod; | |
- id: ble_set_discharge_treshold | |
parameters: | |
ble_device_nr: int | |
discharge: int | |
then: | |
- logger.log: | |
format: "set discharge level: %i" | |
args: [ 'discharge' ] | |
- if: | |
condition: | |
lambda: 'return ( discharge <= 500 && discharge >= 1);' | |
then: | |
- script.execute: | |
id: ble_command_simple | |
ble_device_nr: !lambda return ble_device_nr; | |
ble_cmd: 0x0C | |
ble_cmd_parm: !lambda return discharge; | |
- id: ble_notify_parse_test | |
parameters: | |
ble_device_nr: int | |
x: char[] | |
then: | |
- logger.log: | |
format: "runtime parse: %i" | |
args: [ 'ble_device_nr' ] | |
- lambda: |- | |
//if (id(internal_console_dbg)) { | |
ESP_LOGD("parse test", "x[3] = %i", x[3]); | |
for (auto b : x) { | |
ESP_LOGD("data test", "%.2x \t %i \t %c", b,b,b); | |
} | |
//} | |
- id: ble_notify_parse | |
parameters: | |
ble_device_nr: int | |
x: char[] | |
then: | |
- logger.log: | |
format: "runtime parse: %i" | |
args: [ 'ble_device_nr' ] | |
- lambda: |- | |
ESP_LOGD("notify_parse", "Device: %i", ble_device_nr); | |
if (id(internal_console_dbg)) { | |
ESP_LOGD("parse", "x[3] = %i", x[3]); | |
for (auto b : x) { | |
ESP_LOGD("data", "%.2x \t %i \t %c", b,b,b); | |
} | |
} | |
if (id(switch_debug_hexdump).state == true) { | |
ESP_LOG_BUFFER_HEXDUMP("hexdump", &x[0], x.size(), ESP_LOG_ERROR); | |
} | |
if ((std::count (x.begin(), x.end(), '_') == 16) || (std::count (x.begin(), x.begin() + 10, '_') == 3)) | |
{ | |
ESP_LOGD("main", "Data: cmd 0x0F"); | |
int pos = 0; | |
int soc = 0; | |
int t1 = 0; | |
int t2 = 0; | |
float cv = 0.0; | |
float cmin = std::numeric_limits<float>::max(); | |
float cmax = std::numeric_limits<float>::min(); | |
float ct = 0.0; | |
int found = -1; | |
char delimiter = '_'; | |
std::string xstr; | |
std::vector<float> cellV; | |
xstr.assign(x.begin(), x.end()); // copy values from vector into string xstr, deep copy | |
xstr = xstr + delimiter; // append delimiter to xstr | |
found = xstr.find(delimiter); // search for position of the first delimiter | |
while (found != -1) // loop until no more delimiter found | |
{ | |
if(pos == 0) soc = atoi( xstr.substr(0, found).c_str()); // pos 0 don't care | |
if(pos == 1) t1 = atoi( xstr.substr(0, found).c_str()); // pos 1 get int value of temperature sensor 1 | |
if(pos == 2) t2 = atoi( xstr.substr(0, found).c_str()); // pos 2 get int value of temperature sensor 2 | |
if((pos >= 3) && (pos <= 16)) // pos 3-16 parse pos for the 14 cell voltages | |
{ | |
ct = atof( xstr.substr(0, found).c_str()); // get float value of pos x | |
cellV.push_back(ct); | |
//ESP_LOGD("cell voltage", ct.c_str()); | |
cv += ct; // add actual value to var cv | |
if(ct > cmax) cmax = ct; // check for higher value as stored in cmax | |
if(ct < cmin) cmin = ct; // check for lower value as stored in cmin | |
} | |
xstr.erase(xstr.begin(), xstr.begin() + found + 1); // remove parsed string part | |
found = xstr.find(delimiter); // find next delimiter | |
pos++; // increment pos | |
} | |
/* calculate SoC from cell voltages | |
cell empty = 3.0 Volt = 0% SoC | |
cell full = 3.5 Volt = 100% SoC | |
*/ | |
// float soccalc = (cv/14000 - 3.0) * 200; | |
float lowlimit = 3.0; // low voltage limit | |
float highlimit = 3.5; // high voltage limit | |
float soccalc = 100*((cv/14000) | |
- highlimit)/(highlimit - lowlimit) + 100; // equation of line with two points (0,lowlimit) (100,highlimit) | |
ESP_LOGD("cellVoltage","soc: %i, temp1: %i, temp2: %i",soc,t1,t2); | |
ESP_LOGD("cellVoltage","cell01: %.f, cell 02: %.f, cell 03: %.f, cell 04: %.f", cellV[0], cellV[1], cellV[2], cellV[3]); | |
ESP_LOGD("cellVoltage","cell05: %.f, cell 06: %.f, cell 07: %.f, cell 08: %.f", cellV[4], cellV[5], cellV[6], cellV[7]); | |
ESP_LOGD("cellVoltage","cell09: %.f, cell 10: %.f, cell 11: %.f, cell 12: %.f", cellV[8], cellV[9], cellV[10], cellV[11]); | |
ESP_LOGD("cellVoltage","cell13: %.f, cell 14: %.f", cellV[12], cellV[13]); | |
char mtopic[48]; | |
for (int i=0; i<14; i++) { | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/%02d/voltage",ble_device_nr,i+1); | |
//ESP_LOGD("cellVoltageX","%s : %f", mtopic, cellV[i]); | |
id(mqtt_client).publish(mtopic,to_string(cellV[i]/1000)); | |
} | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/voltage",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(cv/1000)); | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/cmin",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(cmin/1000)); | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/cmax",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(cmax/1000)); | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/cavg",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(cv/14000)); | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/cdiff",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string((cmax-cmin)/1000)); | |
snprintf(mtopic, 48,"b2500/%i/battery/cells/sum/soccalc",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(soccalc)); | |
snprintf(mtopic, 48,"b2500/%i/battery/temp1",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(t1)); | |
snprintf(mtopic, 48,"b2500/%i/battery/temp2",ble_device_nr); | |
id(mqtt_client).publish(mtopic,to_string(t2)); | |
/* | |
id(bcsoc).publish_state(soc); // SOC from device (%) | |
id(bcsoccalc).publish_state(soccalc); // SOC calculated from cell voltages (%) | |
id(bctemp1).publish_state(t1); // Temperature 1 (°C) | |
id(bctemp2).publish_state(t2); // Temperature 2 (°C) | |
id(bccvsum).publish_state(cv/1000); // sum of cellvoltages = battery Voltage(V) | |
id(bccvmin).publish_state(cmin/1000); // lowest cellvoltage (V) | |
id(bccvmax).publish_state(cmax/1000); // highest cellvoltage (V) | |
id(bccvdiff).publish_state((cmax-cmin)/1000); | |
id(bccvavg).publish_state(cv/14000); // avarage cellvoltage (V) | |
*/ | |
} | |
else if (x[3] == 0x03) { | |
ESP_LOGD("main", "Data: runtimeInfo "); | |
//sensor | |
// pv_level 1 und 2 | |
/* | |
[6][7] PV-Eingangsleistung 1 (2Byte) | |
[8][9] PV-Eingangsleistung 2 (2Byte) | |
x[Y] | x[Z] << 8; | |
*/ | |
int pvPower1 = x[6] | x[7] << 8; | |
int pvPower2 = x[8] | x[9] << 8; | |
if (ble_device_nr==1) { id(sensor_pv_power_in_1_1).publish_state(pvPower1); id(sensor_pv_power_in_1_2).publish_state(pvPower2); } | |
if (ble_device_nr==2) { id(sensor_pv_power_in_2_1).publish_state(pvPower1); id(sensor_pv_power_in_2_2).publish_state(pvPower2); } | |
// Batterie Stand in % | |
/* | |
[10][11] Verbleibende Batteriekapazität in Prozent (2Byte) | |
x[Y] | x[Z] << 8; | |
*/ | |
int batRemain = x[10] | x[11] << 8 ; | |
if (ble_device_nr==1) { id(sensor_bat_remain_1).publish_state(batRemain / 10); } | |
if (ble_device_nr==2) { id(sensor_bat_remain_2).publish_state(batRemain / 10); } | |
// Entladen bei weniger als ??? Watt PV Eingang | |
/* | |
[19][20] Entladeschwelle(2Byte) | |
x[Y] | x[Z] << 8; | |
*/ | |
int disCharge = x[19] | x[20] << 8; | |
if (ble_device_nr==1) { id(sensor_discharge_treshold_1).publish_state(disCharge); } | |
if (ble_device_nr==2) { id(sensor_discharge_treshold_2).publish_state(disCharge); } | |
// Füllstand des Akkus in Wh | |
/* | |
[22][23] Gesamtkapazität der Batterie (1Byte) | |
x[Y] | x[Z] << 8; | |
*/ | |
int batCapacity = x[22] | x[23] << 8; | |
if (ble_device_nr==1) { id(sensor_bat_capacity_1).publish_state(batCapacity); } | |
if (ble_device_nr==2) { id(sensor_bat_capacity_2).publish_state(batCapacity); } | |
// Ausgangsleistung in Watt | |
/* | |
[24][25] Ausgangsleistung 1(1Byte) | |
[26][27] Ausgangsleistung 2(1Byte) | |
x[Y] | x[Z] << 8; | |
*/ | |
int powerOut1 = x[24] | x[25] << 8; | |
int powerOut2 = x[26] | x[27] << 8; | |
if (ble_device_nr==1) { id(sensor_power_out_1_1).publish_state(powerOut1); id(sensor_power_out_1_2).publish_state(powerOut2); } | |
if (ble_device_nr==2) { id(sensor_power_out_2_1).publish_state(powerOut1); id(sensor_power_out_2_2).publish_state(powerOut2); } | |
// Geräte Version ( Firmware ? ) | |
/* | |
[12] B2500 Geräteversion (1Byte) | |
0-255 ( ~ anzeige als /100 ) | |
*/ | |
float dev_version = x[12]; | |
if (ble_device_nr==1) { id(sensor_device_version_1).publish_state(dev_version / 100); } | |
if (ble_device_nr==2) { id(sensor_device_version_2).publish_state(dev_version / 100); } | |
// | |
/* | |
[18] Dod (1Byte) | |
0-100 Prozentualer Anteil der Entladeleistung an der Nennleistung | |
*/ | |
int dod_level = x[18]; | |
if (ble_device_nr==1) { id(sensor_dod_1).publish_state(dod_level); } | |
if (ble_device_nr==2) { id(sensor_dod_2).publish_state(dod_level); } | |
// binary sensor / bool | |
// pv 1 und 2 in | |
/* | |
[x4] PV IN 1 Zustand (1Byte) | |
[x5] PV IN 2 Zustand (1Byte) | |
0x00 (off) | |
0x01 (Aufladung) | |
0x02 (transparent für Wechselrichter) | |
*/ | |
if (ble_device_nr==1) { | |
if( x[4] == 0x00 ) { id(bool_pv_active_1_1).publish_state(false);id(bool_pv_transparent_1_1).publish_state(false); } | |
if( x[4] == 0x01 ) { id(bool_pv_active_1_1).publish_state(true); id(bool_pv_transparent_1_1).publish_state(false); } | |
if( x[4] == 0x02 ) { id(bool_pv_active_1_1).publish_state(true); id(bool_pv_transparent_1_1).publish_state(true); } | |
if( x[5] == 0x00 ) { id(bool_pv_active_1_2).publish_state(false);id(bool_pv_transparent_1_2).publish_state(false); } | |
if( x[5] == 0x01 ) { id(bool_pv_active_1_2).publish_state(true); id(bool_pv_transparent_1_2).publish_state(false); } | |
if( x[5] == 0x02 ) { id(bool_pv_active_1_2).publish_state(true); id(bool_pv_transparent_1_2).publish_state(true); } | |
} | |
if (ble_device_nr==2) { | |
if( x[4] == 0x00 ) { id(bool_pv_active_2_1).publish_state(false);id(bool_pv_transparent_2_1).publish_state(false); } | |
if( x[4] == 0x01 ) { id(bool_pv_active_2_1).publish_state(true); id(bool_pv_transparent_2_1).publish_state(false); } | |
if( x[4] == 0x02 ) { id(bool_pv_active_2_1).publish_state(true); id(bool_pv_transparent_2_1).publish_state(true); } | |
if( x[5] == 0x00 ) { id(bool_pv_active_2_2).publish_state(false);id(bool_pv_transparent_2_2).publish_state(false); } | |
if( x[5] == 0x01 ) { id(bool_pv_active_2_2).publish_state(true); id(bool_pv_transparent_2_2).publish_state(false); } | |
if( x[5] == 0x02 ) { id(bool_pv_active_2_2).publish_state(true); id(bool_pv_transparent_2_2).publish_state(true); } | |
} | |
// pv 2 durchleiten | |
/* | |
[13] Einstellung des Ladevorgangs (1Byte) | |
0x00 (PV1 Aufladung PV2 Durchleitung) | |
0x01 (Volles Laden und Entladen) | |
*/ | |
if (ble_device_nr==1) { | |
if( x[13] == 0x00 ) { id(switch_pv2_passthrough_1).turn_on(); } | |
if( x[13] == 0x01 ) { id(switch_pv2_passthrough_1).turn_off(); } | |
} | |
if (ble_device_nr==2) { | |
if( x[13] == 0x00 ) { id(switch_pv2_passthrough_2).turn_on(); } | |
if( x[13] == 0x01 ) { id(switch_pv2_passthrough_2).turn_off(); } | |
} | |
// RESERVED ( wifi / mqtt ) | |
/* | |
[15] Reserve(1Byte) | |
0x00 wifi funktioniert nicht | |
0x01 wifi ok, mqtt nicht verbunden | |
0x02 wifi ok, mqtt connect ok | |
??? 0x03 wifi ok, mqtt1 connect ok, mqtt2 connect ok | |
maybe wifi / mqtt | |
00 = false / false | |
01 = true / false | |
02 = false / true | |
03 = true / true | |
------- | |
first part means not wifi connected ?!?!? | |
00 = ??? / mqtt not connected | |
01 = ??? / mqtt not connected | |
02 = ??? / mqtt connected | |
03 = ??? / mqtt connected | |
*/ | |
// wifi and mqtt, 03 maybe webserver | |
if (ble_device_nr==1) { | |
if( x[15] == 0x00 ) { id(bool_wifi_ok_1).publish_state(false); id(bool_mqtt1_ok_1).publish_state(false); } | |
if( x[15] == 0x01 ) { id(bool_wifi_ok_1).publish_state(true); id(bool_mqtt1_ok_1).publish_state(false);} | |
if( x[15] == 0x02 ) { id(bool_wifi_ok_1).publish_state(false); id(bool_mqtt1_ok_1).publish_state(true); } | |
if( x[15] == 0x03 ) { id(bool_wifi_ok_1).publish_state(true); id(bool_mqtt1_ok_1).publish_state(true); } | |
} | |
if (ble_device_nr==2) { | |
if( x[15] == 0x00 ) { id(bool_wifi_ok_2).publish_state(false); id(bool_mqtt1_ok_2).publish_state(false); } | |
if( x[15] == 0x01 ) { id(bool_wifi_ok_2).publish_state(true); id(bool_mqtt1_ok_2).publish_state(false); } | |
if( x[15] == 0x02 ) { id(bool_wifi_ok_2).publish_state(false); id(bool_mqtt1_ok_2).publish_state(true); } | |
if( x[15] == 0x03 ) { id(bool_wifi_ok_2).publish_state(true); id(bool_mqtt1_ok_2).publish_state(true); } | |
} | |
// power 1 und 2 enabled/disabled | |
/* | |
[14] Entlade-Modus / Enabled (1Byte) | |
0x00 OUT1&OUT2 Sperren | |
0x01 nur OUT1 Freigabe | |
0x02 nur OUT2 Freigabe | |
0x03 OUT1&OUT2 Freigabe | |
*/ | |
if (ble_device_nr==1) { | |
if( x[14] == 0x00 ) { id(switch_powerout_1_1).turn_off(); id(switch_powerout_1_2).turn_off();} | |
if( x[14] == 0x01 ) { id(switch_powerout_1_1).turn_on(); id(switch_powerout_1_2).turn_off();} | |
if( x[14] == 0x02 ) { id(switch_powerout_1_1).turn_off(); id(switch_powerout_1_2).turn_on(); } | |
if( x[14] == 0x03 ) { id(switch_powerout_1_1).turn_on(); id(switch_powerout_1_2).turn_on(); } | |
} | |
if (ble_device_nr==2) { | |
if( x[14] == 0x00 ) { id(switch_powerout_2_1).turn_off(); id(switch_powerout_2_2).turn_off();} | |
if( x[14] == 0x01 ) { id(switch_powerout_2_1).turn_on(); id(switch_powerout_2_2).turn_off();} | |
if( x[14] == 0x02 ) { id(switch_powerout_2_1).turn_off(); id(switch_powerout_2_2).turn_on(); } | |
if( x[14] == 0x03 ) { id(switch_powerout_2_1).turn_on(); id(switch_powerout_2_2).turn_on(); } | |
} | |
// power 1 und 2 active | |
/* | |
[16] Ausgang Port 1 Status (1Byte) | |
[17] Ausgang Port 2 Status (1Byte) | |
0x00(Aus) | |
0x01(Entladung) | |
*/ | |
if (ble_device_nr==1) { | |
if( x[16] == 0x00 ) { id(bool_power_active_1_1).publish_state(false);} | |
if( x[16] == 0x01 ) { id(bool_power_active_1_1).publish_state(true); } | |
if( x[17] == 0x00 ) { id(bool_power_active_1_2).publish_state(false);} | |
if( x[17] == 0x01 ) { id(bool_power_active_1_2).publish_state(true); } | |
} | |
if (ble_device_nr==2) { | |
if( x[16] == 0x00 ) { id(bool_power_active_2_1).publish_state(false);} | |
if( x[16] == 0x01 ) { id(bool_power_active_2_1).publish_state(true); } | |
if( x[17] == 0x00 ) { id(bool_power_active_2_2).publish_state(false);} | |
if( x[17] == 0x01 ) { id(bool_power_active_2_2).publish_state(true); } | |
} | |
// zusatzakku 1 und 2 | |
/* | |
[28] Ist Netzgerät 1 angeschlossen (1Byte) | |
[29] Ist Netzgerät 2 angeschlossen (1Byte) | |
0x00(Kein Akkupack angeschlossen) | |
0x01(Verbinden Sie das Netzteil) | |
*/ | |
if (ble_device_nr==1) { | |
if( x[28] == 0x00 ) { id(bool_extern_connected_1_1).publish_state(false);} | |
if( x[28] == 0x01 ) { id(bool_extern_connected_1_1).publish_state(true); } | |
if( x[29] == 0x00 ) { id(bool_extern_connected_1_2).publish_state(false);} | |
if( x[29] == 0x01 ) { id(bool_extern_connected_1_2).publish_state(true); } | |
} | |
if (ble_device_nr==2) { | |
if( x[28] == 0x00 ) { id(bool_extern_connected_2_1).publish_state(false);} | |
if( x[28] == 0x01 ) { id(bool_extern_connected_2_1).publish_state(true); } | |
if( x[29] == 0x00 ) { id(bool_extern_connected_2_2).publish_state(false);} | |
if( x[29] == 0x01 ) { id(bool_extern_connected_2_2).publish_state(true); } | |
} | |
if (ble_device_nr==1) { | |
auto call_21 = id(txt_scene_1).make_call(); | |
if( x[21] == 0x00 ) { call_21.set_value("Tag"); } | |
if( x[21] == 0x01 ) { call_21.set_value("Nacht"); } | |
if( x[21] == 0x02 ) { call_21.set_value("Morgens/Abends"); } | |
call_21.perform(); | |
} | |
if (ble_device_nr==2) { | |
auto call_21 = id(txt_scene_2).make_call(); | |
if( x[21] == 0x00 ) { call_21.set_value("Tag"); } | |
if( x[21] == 0x01 ) { call_21.set_value("Nacht"); } | |
if( x[21] == 0x02 ) { call_21.set_value("Morgens/Abends"); } | |
call_21.perform(); | |
} | |
if (ble_device_nr==1) { | |
auto call_30 = id(txt_region_1).make_call(); | |
if( x[30] == 0x00 ) { call_30.set_value("EU"); } | |
if( x[30] == 0x01 ) { call_30.set_value("China"); } | |
if( x[30] == 0x02 ) { call_30.set_value("non-EU"); } | |
call_30.perform(); | |
} | |
if (ble_device_nr==2) { | |
auto call_30 = id(txt_region_2).make_call(); | |
if( x[30] == 0x00 ) { call_30.set_value("EU"); } | |
if( x[30] == 0x01 ) { call_30.set_value("China"); } | |
if( x[30] == 0x02 ) { call_30.set_value("non-EU"); } | |
call_30.perform(); | |
} | |
} | |
else if (x[3] == 0x04) { | |
ESP_LOGD("main", "Data: deviceInfo "); | |
//for (auto b : x) { | |
// ESP_LOGD("data", "%i", b); | |
//} | |
// 's<#?type=<5>,id=<24>,mac=<12>t' | |
// ESP_LOGD("data", "%s", vType); | |
int data_len = x.size(); | |
unsigned char vType[8]; | |
for (int i=9;i<14;i++) { | |
vType[i-9] = x[i]; | |
} | |
vType[5] = 0x00; | |
unsigned char vID[32]; | |
for (int i=18;i<42;i++) { | |
vID[i-18] = x[i]; | |
} | |
vID[24]=0x00; | |
unsigned char vMac[16]; | |
for (int i=47;i<59;i++) { | |
vMac[i-47] = x[i]; | |
} | |
vMac[12] = 0x00; | |
ESP_LOGD("deviceInfo", "%i: %s [%s] %s", data_len,vType,vMac,vID); | |
std::string sType(reinterpret_cast<char*>(vType)); | |
std::string sID(reinterpret_cast<char*>(vID)); | |
std::string sMac(reinterpret_cast<char*>(vMac)); | |
if (ble_device_nr==1) { id(txt_A01_1).publish_state(sType); id(txt_A02_1).publish_state(sID); id(txt_A03_1).publish_state(sMac); } | |
if (ble_device_nr==2) { id(txt_A01_2).publish_state(sType); id(txt_A02_2).publish_state(sID); id(txt_A03_2).publish_state(sMac); } | |
} | |
// get wifi info - "admin mode" only | |
else if (x[3] == 0x08) { | |
ESP_LOGD("main", "Data: wifiInfo "); | |
int data_len = x.size(); | |
unsigned char vSSID[32]; | |
for (int i=4;i<data_len-1;i++) { | |
vSSID[i-4] = x[i]; | |
} | |
vSSID[data_len-5] = 0x00; | |
ESP_LOGD("deviceInfo", "%i: %s", data_len,vSSID); | |
std::string sSSID(reinterpret_cast<char*>(vSSID)); | |
if (ble_device_nr==1) { id(txt_A11_1).publish_state(sSSID); } | |
if (ble_device_nr==2) { id(txt_A11_2).publish_state(sSSID); } | |
for (auto b : x) { | |
ESP_LOGD("data", "%x \t %i \t %x", b,b,b); | |
} | |
} | |
else if (x[3] == 0x30) { | |
ESP_LOGD("main", "Data: cmd 0x30 "); | |
int data_len = x.size(); | |
int data_pos = 0; | |
int rxor = 0; | |
for (int i=0;i<data_len;i++) { | |
rxor = rxor ^ x[i]; | |
} | |
/* | |
//if( rxor != id(cmd30_xor_last_1) ) { | |
ESP_LOGD("data 30 - raw" , "Device %i",ble_device_nr); | |
ESP_LOGD("data 30 - raw" , "0x%.2x 0x%.2x 0x%.2x 0x%.2x", x[0], x[1], x[2], x[3]); | |
for(int i=4;i<data_len-1;i++) { | |
ESP_LOGD("data 30 - raw" , "0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x 0x%.2x", x[i], x[i+1], x[i+2], x[i+3], x[i+4],x[i+5],x[i+6],x[i+7],x[i+8]); | |
i += 8; | |
} | |
//ESP_LOGD("data 30 - raw" , " "); | |
id(cmd30_xor_last_1) = rxor; | |
//} | |
*/ | |
} | |
/* | |
else if (x[3] == 0x30) { | |
ESP_LOGD("main", "Data: cmd 0x30"); | |
int data_len = x.size(); | |
for(int i=0;i<data_len;i++) { | |
int d1 = x[i]; | |
ESP_LOGD("data 30" , "%x \t %i \t %c" , d1, d1, char(d1)); | |
} | |
} | |
*/ | |
// debug ??? | |
else if (x[3] == 0x01) { | |
ESP_LOGD("main", "Data: cmd 0x01"); | |
int data_len = x.size(); | |
for(int i=0;i<data_len;i++) { | |
int d1 = x[i]; | |
ESP_LOGD("data 01" , "%x \t %i \t %c" , d1, d1, char(d1)); | |
} | |
} | |
else if (x[3] == 0x81) { | |
ESP_LOGD("main", "Data: cmd 0x81"); | |
int data_len = x.size(); | |
for(int i=0;i<data_len;i++) { | |
int d1 = x[i]; | |
ESP_LOGD("data 81" , "%x \t %i \t %c" , d1, d1, char(d1)); | |
} | |
} | |
else { | |
/*int data_len = x.size(); | |
for(int i=0;i<data_len;i++) { | |
int d1 = x[i]; | |
ESP_LOGD("unknown" , "%x \t %i \t %c" , d1, d1, char(d1)); | |
} | |
*/ | |
ESP_LOG_BUFFER_HEXDUMP("hexdump", &x[0], x.size(), ESP_LOG_ERROR); | |
} | |
- id: power_zero | |
then: | |
### Nulleinspeisung - Powerzero by neromatrix | |
### - mqtt only adaption by noone2k | |
### first attempt, use at your own risk ! | |
### Ver. 0.01m | |
- lambda: |- | |
if(id(switch_opendtu_limit).state) | |
{ | |
int ptu_min_value = 5; | |
int ptu_max_value = id(mqtt_opendtu_limit_max).state; // 50; // <- nax rel value -> id(npw2500_zeropower_max_powerlimit_rel).state; | |
int ptu_limit = 0; | |
int ptu_max_power = 900; // max:2 (x:4*2 for 4port using 2port) | |
int grid_to_ptu_ratio = ptu_max_power/100; | |
int grid_min_value = 20; | |
static int ptu_old_limit = 0; | |
/* | |
<- actual power mqtt -> prev. int(id(npw2500_grid_power).state); | |
keep over grid_min_value | |
*/ | |
int grid_value = int(id(mqtt_grid_power).state) - grid_min_value;; | |
ptu_limit = grid_value / grid_to_ptu_ratio + ptu_old_limit; | |
if(ptu_limit > ptu_max_value) ptu_limit = ptu_max_value; | |
if(ptu_limit < ptu_min_value) ptu_limit = ptu_min_value; | |
// change only if diff more than +/-1% | |
if ( ptu_limit - ptu_old_limit > 1 || ptu_old_limit - ptu_limit > 1 ) { | |
ESP_LOGD("npw2500","PowerZero PTU old limit %d, PTU new limit %d, Grid value %d " ,ptu_old_limit, ptu_limit, grid_value); | |
ptu_old_limit = ptu_limit; | |
//char mtopic[64]; | |
//snprintf(mtopic, 64,"openDTU/XXXXXXXXXXX/cmd/limit_persistent_relative"); | |
//id(mqtt_client).publish(mtopic,to_string(ptu_limit)); | |
id(mqtt_opendtu_limit).publish_state(ptu_limit); | |
} | |
} |
wie es der zufall so will, wurde gerade einer geliefert ...
mir ging es auf den senkel, das eine v1 immer wieder voll war und in den passthrough ging.
hab dann immer den überschuss mit nem ladegerät in einen anderen akku geladen ( höhere verluste durch doppelte umwandlung ).
stand vor der wahl den rd6024 umzubauen, das das automatisch geht oder ne erweiterung.
bin erstmal mit der erweiterung gegangen, die dürfte den passthrough etwas verzögern ....
hab ihn aber noch nicht angeschlossen ...
die fragen dazu habe ich auch, und wird sich zeigen ;)
Na dann bestell ich mal - mal gucken ob Du uns bis dahin was gezaubert hast. Gibt eigentlich einen "donatebutton" irgendwo? ;)
ich kann dazu (noch) keine aussagen machen.
und damit auch keine empfehlung geben ( was ich nicht kenne,kann ich nicht empfehlen 😁 )...
will dich aber nicht davon abhalten ... würde es gröbere probleme geben,
hätte man wahrscheinlich schon in den foren was dazu gelesen.
habs mir nur bestellt, weil ich das gebrauchen kann .... ob es was taugt, weiss ich noch nicht ...
Ich erhoffe mir ja, dass der Speicher das erkannt und das Ganze als "einen" sieht. Aber mal sehen, kannst ja gern mal berichten.
ja, das teil wird als ein gerät erkannt .. ist ja auch richtig ...
auch die rest prozente und kapazität sind eine einheit ..
damit die stimmen, müssen dann aber wahrscheinlich beide ordentlich kalibiert sein.
was mir fehlt die ist abfrage der zellen und temperatur ... ggf. mal ein bisserl tiefer bohren, ob das möglich ist,
aber bei einem kurzen blick , sieht es nicht so aus ... das wird alles intern gehandelt ...
auch über die mechanismen, wie die lastverteilung ist oder wie geladen/entladen wird,
da muss ich mal direkt bei schuss nachfragen.
das kann man nicht so ohne weiteres direkt aus den übermittelten ( oder der fehlenden) daten ablesen.
im idealfall gleichen sich beide an bzw. aus ... und man kann weiterhin sich auf die zell-infos der hauptbatterie verlassen.
//edit
bin mal gespannt, wie sich die werte zeigen, wenn die hauptbatterie voll ist und der speicher hoffentlich nachzieht.
hatte die erweiterung angeschlossen, als die hauptbatterie voll war und anschließend ging die die restkapatizät von 100% auf 81%.
mal hoffen, das die sonne heute mitspielt ...
Schade, dass man den Erweiterungsspeicher nicht auslesen kann. Ich könnte mir vorstellen, dass der Speicher vorgeladen bei Dir ankommt. Das würde erklären, warum der Speicher nicht auf unter 60% fällt. Schuss muss ja davon ausgehen, dass so ein Speicher auch gerne mal 6 Monte in einem Regal steht - da darf sich das Teil nicht Tiefenentladen. (Das ist natürlich nur eine Annahme)
ja, die speicher kommen alle vorgeladen ...
momentan spielt mal wieder das wetter nicht so richtig mit, um alles gründlich zu testen.
und die erweiterung könnte m.h. von rs485 direkt mit dem bms ( sinowealth ) kommunizieren.
es besteht also noch ne (sehr) kleine chance das man an die daten kommt, ohne sich an den bus zu hängen,
mit bestimmten ble befehlen, die für das bms gedacht sind. die hatte ich schon wieder total vergessen.
mal bei zeiten ne kleine testreihe durch gehen bzw. mal den code daraufhin untersuchen.
der standardbefehl für die cellinfos ( cmd0f ) ist fest auf die speicherbereiche der internen zellen kodiert.
da bräuchte es nen fimware-update, damit das direkt klappt.
// edit
auch sieht es so aus, als wenn erst die hauptbatterie und dann die zusatzbatterie geladen wird ( v1 mit firmware 1.39 ).
der strom scheint auch über die zellen der hauptbatterie zu gehen, da die ausgelesenen werte, über die einer ruhenden zelle gehen.
müsste u.a. deswegen auch den bms-fix dazu etwas anpassen ... sonst schaltet die hauptbatterie den output aus, wenn die voll ist, aber das externe powerpack gerade mal anfängt.
aber das ist alles momentan zu früh um irgendwas definitives zu sagen.
@noone2k
Die Lade-Reihenfolge kann ich bestätigen: Erst Haupt-Batterie, dann Erweiterung.
Beim Entladen ist dann erst die Erweiterung dran, dann die Haupt-Batterie.
Also wird der Zusatzspeicher im Script (noch) nicht erkannt ?
Ahhh, aber die Kapazität erkennt es also schon. Das reicht mir aus 👍
Und es zeigt ja auch an das da eine Erweiterung dran hängt.
Muß wohl doch nochmal einkaufen gehen 😇 Wo bekommt man den denn günstig her, will nicht unbedingt nen Haufen Versand zahlen.
ich mach ungern für jmd, werbung, aber habs bei enercab bestellt.
bisher nur gute erfahrung bei denen ... ob günstig k.a. ( um die 650 - inkl versand ) ...
und die kümmern sich um den rückversand, sollte da mal was sein ( bisher musste ich das noch nicht anspruch nehmen )
//edit
und man muss dazu sagen, so eine erweiterung lohnt sich nur bei genug einstrahlung ( zeitlich im jahr halt eingeschränkt )
und wenn einem der passthrough stört und wirklich das letzte fitzelchen geerntete sonne auch selbst nutzen möchte.
wenn es einem rein um die rentabilität geht, müsste man mal kalkulieren, aber das ist nicht mein hauptaugenmerk.
das hametech system, sollte aber zu den günstigsten baukasten systemen gehören, wenn man auf diy steht.
ein bisserl mehr auslesbare infos zu den erweiterungsbatterien wäre aber schon schön ... mal gucken ...
muss nochmal kurz dazu sagen, die werte die in dem screenshot zu sehen sind, stammern (fast) alle nur von der hauptbatterie ...
abweichend davon ( müsste mal an die beschriftungen ran, aber die sind ja nur für mich :D )
remaining = gemeldete rest prozent ( gilt für beide basis+powerpack verbund ) - auch als SoC bekannt ;)
rest kwh = gemeldete rest kwh ( gilt für beide basis+powerpack im verbund)
und die SoC angabe ist halt eine berechnete der hauptbatterie ...
aber diese berechnung wollte ich ggf. sowieso rausnehmen, die müsste jeder für sich selbst individuell festlegen ... ( k.a. ob das im git überhaupt drinne ist )
es gibt noch den SoC der basis einzeln, den exportiere ich aber glaube nicht per mqtt ...
der ist aber sowieso immer 100%, solange nur von dem powerpack gezogen wird.
müsste den vllt. nochmal gesondert exportieren ...
die stimmen halt nur, wenn die kiste ordentlich kalibriert ist und beim zusatzspeicher k.a. wie und ob da was kalibriert wurde/wird.
aber beim kompletten aufladen, hing der auch ne weile bei 99% ... also wird das system dort ähnlich arbeiten, wie bei der basis.
da bei mir die ble verbindung beim v2 ( fw 214 ) relativ instabil ist, habe ich gestern mal schnell was zusammengetackert,
um in openhab direkt die lokale mqtt-steuerung zu testen.
einfach um zu sehen, ob diese stabiler ist, wenn man auf ble verzichtet.
möchte dazu noch sagen, die v1 mit der fw 1.39 ist richtig stabil, keine verbindungsabbrüche etc.
musste nur 1 oder 2 mal innerhalb eines monats die kiste ( nur eine von den 2 ), manuell neu starten.
eine kiste muss ich noch einrichten, da werde ich ggf. auch mal paar screenshots machen und was im wiki dazu posten,
inkl. script.
momentan nutze ich dazu nur zwei rules, eines zum senden des abfragebefehls und eines zum lesen/parsen der werte.
das ganze ist erstmal nur zum auslesen der werte.
per mqtt kann man leider keine zellinfos auslesen, so das einige fixes oder überwachnngen nicht möglich sind,
die die ble lösung bietet.
die gelieferten werte sollten aber bereits ausreichen, um sich einen überblick zu verschaffen und ein einfaches controlling ermöglichen.
btw. falls man die sternchen auf dem screenshot sieht 😁 : das sind keine ausgelesenen, sondern errechnete oder manuell eingetragenen, werte.
//edit ich mache erstmal ein update meines smarthome servers damit alles auf dem aktuellen stand ist und hoffe, das alles gut geht 😁
erfahrungsgemäßg kommt da immer was dazwischen was etwas nacharbeit verlangt 😁
Mal ne andere Frage, es gibt ja jetzt den Erweiterungsspeicher - hat den schon jemand in Betrieb? Es kling schon verlockend aus den 2240Wh -> 4480Wh zu machen.
@noone2k liest Du die Erweiterung bzw. die Kapazität mit aus?