-
-
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); | |
} | |
} |
meine batterie hat jetzt gerade mal 40 ladezyklen durch und fällt jede nacht von 13% auf 0%. ist jetzt schon bei mir die batterie kaputt oder woran kann das liegen?
wie war der wert vmin zu dem zeitpunkt ?
du kannst mit den scripten die cellspannungen auslesen ... wenn eine zelle auf ~ 2.85V rutscht , schaltet das bms ab ...
ich gehe davon aus, das deine kiste nicht ordentlich kalibriert ist, dann kann auch die einstellungen dod nicht funktionieren
bzw. wenn der soc sagt 13% springt der auf 0%, wenn 2.85V erreicht wurde und das bms abschaltet.
da fällt mir ein, in den scripten ist eine funktion die die ausgänge deaktiviert, wenn eine zelle 3.1V erreicht,
gerade weil die dod-funktion nicht funktioniert, wenn der soc, wegen falscher kalibrierung, falsch übermittelt wird.
das soll die kiste vor einer tiefentladung und die zellen vor schneller alterung schützen ...
Gab gerade bei mir ein App Update.Sehe jetzt so keine Unterschiede ausser der Schrift.
Was aber neu ist: Man kann jetzt den angeschlossenen Wechselrichter aussuchen.
Warum, keine Ahnung ! 😉
Offizieller ChangeLog:
- Optimize Mqtt and Ble connect!
- Compatible with pad phone
- Add some new feature.
- Add pull to refresh for update data.
- Fix some bugs.
Hallo zusammen.
Mal eine "vielleicht" blöde Frage.
Ich habe den Marstek B2500 mit einer V212 Firmware. Dieser hat mir der Support für das MQTT freigeschaltet.
Wo finde ich bitte in der APP die Einstellungen um MQTT zu konfigurieren?
Ein MQTT Server läuft bei lokal im Netz.
Geht MQTT über WLAN und/oder nur über Bluetooth?
Danke für eure Antworten.
Hallo,
mich habe nun meinen zweiten Accu erhalten und habe diesen auch erfolgreich angebunden. Nun würde ich gerne auch das Template switch.b2500_v2_ble_idf_d1_01_3_timer3 und switch.b2500_v2_ble_idf_d2_01_3_timer3 aktivieren. Leider erscheint nur switch.b2500_v2_ble_idf_d1_01_3_timer3 bei mir in Homeassistant. Der Accu 1 ist auf Mac3 und Accu2 auf Mac4 was muss ich hier noch beachten ?
die v2 version des scriptes ist noch nicht für 2 akkus fertiggestellt,
da ich momentan selbst nur einen davon hier habe.
werde mal gucken,ob ich das in nächster zeit irgendwie hinbekomme.
habe mir gerade nen zusatzakku bestellt da momentan einer der akkus ständig bereits sehr früh, in den passthrough geht, weil voll.
und werde erstmal da gucken ( wenn er dann geliefert wurde ), was damit ist.
nen zusatzakku scheint zumindestens im sommer sinn zu machen ...
der verschwendete strom tut irgendwie weh 😁
@azazul1980 Du kannst dir hierüber eine Config für bis zu 3 Akkus generieren: https://tomquist.github.io/esphome-b2500/
@tomquist ich habe mir dein Converter angeschaut. Generell coole Sache aber die Namensgebung ist dann komplett hinüber. Dann müsste ich all meine Automatitionen abändern in Homeassistant und das sind einigen😔.
@noone2k wäre cool wenn irgend wann ein zweiter Accu mit dieser Funktion reinkommen würde.
habe mir auch mal die aktuelle version angeschaut. 👍
den online generator kann ich wirklich jedem empfehlen, der neu einsteigt
oder mit einem esp32 verschiedene HW versionen parallel nutzen möchte.
wenn man das in EINEM fertigen yaml umsetzen möchte, müsste man mit vielen verschachtelungen arbeiten.
durch das templating kommt dabei ein sauberer und strukturierter code bei raus,
mit genau dem, was man nutzen möchte und weniger overhead ( bspw. wenn man nur einen akku nutzen möchte ).
Leider bekommt man diesen ESP:
APKLVSR ESP32 USB C NodeMCU Entwicklung Board ESP-WROOM-32 CP2102 2.4 GHz WLAN WiFi Bluetooth Internet Development Board für Arduino
Mit dem online generator nicht zum laufen, woran es liegt weiß keiner.
Leider bekommt man diesen ESP:
APKLVSR ESP32 USB C NodeMCU Entwicklung Board ESP-WROOM-32 CP2102 2.4 GHz WLAN WiFi Bluetooth Internet Development Board für ArduinoMit dem online generator nicht zum laufen, woran es liegt weiß keiner.
Ich habe den Gleichen mit CH340 und der funktioniert einwandfrei. Der Unterschied ist doch nur der USB to serial chip...
bin kein profi: es liegt irgendwie am config output_power. das meinte auf jedenfall der ersteller vom tool [tomquist]. kannst du mir sagen wie deine config aussieht?
also welches board du genommen hast usw?
ja danke, aber keine chance. er verbindet sich nur einmal ganz kurz zu mein mqtt server und dann wird er als offline angezeigt.
also ich habe jede ermöglich variante probiert aber ich bekomme es nicht am laufen mit dem Generator, ich habe auch verschiedene ESP32 probiert. Sie verbinden sich einmal ganz kurz zu meinen MQTT server und erstellen auch objekte im IOBroker aber er wird dann sofort als Offline angezeigt. hier meine Config:
{
"name": "b2500-v2",
"friendly_name": "b2500-v2",
"mqtt": {
"topic": "b2500v2",
"broker": "192.168.178.44",
"port": "1324",
"username": "denjo",
"password": "***",
"discovery": false
},
"wifi": {
"ssid": "FRITZ!Box Denjo",
"password": "***"
},
"board": "esp32dev",
"enable_auto_restart": true,
"auto_restart": {
"restart_after_error_count": 8
},
"enable_cellquery": true,
"enable_cmd13": false,
"enable_cmd30": false,
"enable_esp_temperature": false,
"enable_powermeter": false,
"enable_experimental_commands": false,
"enable_hexdump": false,
"enable_set_wifi": false,
"set_wifi": {
"ssid": "MyWifi",
"password": "***"
},
"enable_set_mqtt": false,
"powermeter": {
"tx_pin": "GPIO6",
"rx_pin": "GPIO7",
"baud_rate": 9600,
"stop_bits": 1
},
"enable_enforce_dod": false,
"enable_powerzero": false,
"powerzero": {
"grid_power_topic": "tibber-esp/sensor/power/state",
"limit_cmd_topic": "openDTU/XXXXXXXXXXXX/cmd/limit_persistent_relative",
"limit_state_topic": "openDTU/XXXXXXXXXXXX/state/limit_relative"
},
"enable_manual_ip": false,
"manual_ip": {
"ip": "192.168.1.100",
"gateway": "192.168.1.1",
"subnet": "255.255.255.0",
"dns": "192.168.1.1"
},
"enable_web_server": true,
"web_server": {
"port": 80,
"ota": true,
"js_include": "./v2/www.js"
},
"enable_ota": true,
"ota": {
"password": "***",
"enable_unprotected_writes": false
},
"enable_fallback_hotspot": true,
"fallback_hotspot": {
"ssid": "ESPHome-b2500",
"enable_captive_portal": true
},
"storages": [
{
"name": "BC2500",
"version": 2,
"mac_address": "***"
},
{
"name": "BC2500",
"version": 2,
"mac_address": "***"
}
],
"password": "my_ota_passwor",
"poll_interval_seconds": 5,
"variant": "esp32",
"idf_platform_version": "",
"enable_timer_query": true
}
wenn ich einen alten ESP32 nehme den ich mit einer yaml datei beschrieben habe über den ESPHome Adapter von IOBroker läuft der ohne Probleme, hier die Config von dem:
esphome:
name: b2500-v2-ble-idf
friendly_name: b2500-v2-ble-idf
# platformio_options:
#board_build.f_cpu: 160000000L
on_boot:
priority: -100
then:
#- switch.turn_off: switch_opendtu_limit
#- switch.turn_off: switch_enhanced_dod
- switch.turn_on: switch_enhanced_cmd0F
#- switch.turn_off: switch_enhanced_cmd30
#- switch.turn_off: switch_powerout_1_1
#- switch.turn_off: switch_powerout_1_2
#- switch.turn_off: switch_powerout_2_1
#- switch.turn_off: switch_powerout_2_2
#- switch.turn_off: switch_pv2_passthrough_1
#- switch.turn_off: switch_pv2_passthrough_2
esp32:
board: az-delivery-devkit-v4
#board: esp32dev
framework:
#platform_version: 6.6.0
#version: 5.2.1
type: esp-idf
sdkconfig_options:
CONFIG_FREERTOS_UNICORE: y
advanced:
ignore_efuse_mac_crc: true
# Enable logging
logger:
level: INFO
on_message:
level: WARN
then:
lambda: |-
if (strstr(message, "btc_transfer_context") != NULL) {
id(mqtt_client).publish("b2500v2/debug","B_T_C FOUND: restart ESP32");
id(controller_restart).press();
}
if (strstr(message, "mode: single") != NULL) {
id(mqtt_client).publish("b2500v2/debug","single mode: restart ESP32");
id(controller_restart).press();
}
if (strstr(message, "handle") != NULL) {
id(internal_error_count)++;
char mvalue[48];
snprintf(mvalue, 48,"handle error counter: %i",id(internal_error_count));
id(mqtt_client).publish("b2500v2/debug",mvalue);
if(id(internal_error_count) > 8) {
id(internal_error_count) = 0;
id(mqtt_client).publish("b2500v2/debug","handle error counter: RESET");
id(controller_restart).press();
}
//id(ble_restart).execute();
//id(controller_restart).press();
//id(btn_device_1_reboot).press();
//id(btn_device_2_reboot).press();
}
ota:
- platform: esphome
password: "XXXXXXXXXX"
wifi:
ssid: FRITZ!Box Denjo
password: XXXXXXXXXXX
reboot_timeout: 0s
fast_connect: True
on_connect:
- esp32_ble_tracker.start_scan:
continuous: true
on_disconnect:
- esp32_ble_tracker.stop_scan:
# Enable fallback hotspot (captive portal) in case wifi connection fails
#ap:
# ssid: "Bc2500-Ble Fallback Hotspot"
#web_server:
# port: 80
#ota: true
#js_include: "./v3/www.js"
# js_include: "./v2/www.js"
# local: true
# js_url: ""
# version: 2
#captive_portal:
mqtt:
id: mqtt_client
broker: 192.168.178.44
port: 1324
username: denjo
password: "XXXXXX"
discovery: False
reboot_timeout: 0s
topic_prefix: b2500v2
log_topic: b2500v2/debug
interval:
- interval: 5s
startup_delay: 20s
then:
- script.execute: ble_process
- delay: 1500ms
#- script.execute: ble_process_cmd0F
- script.execute:
id: ble_runtime_query0F
ble_device_nr: 1
#
- delay: 1500ms
#- script.execute: ble_process_cmd13
#
- script.execute:
id: ble_runtime_query13
ble_device_nr: 1
time:
- platform: sntp
id: sntp_time
timezone: Europe/Berlin
# on_time:
# # Every 10 seconds
# - seconds: 0,10,20,30,40,50
# then:
# - script.stop: ble_process
# - script.execute: ble_process
# - script.wait: ble_process
# # Every 10 seconds
# - seconds: 5,15,25,35,45,55
# then:
# - script.stop: ble_process_cmd0F
# - script.execute: ble_process_cmd0F
# - script.wait: ble_process_cmd0F
# # Every minute ( or hour if minutes enabled )
# - seconds: 3
# #minutes: 1
# then:
# - script.stop: ble_process_cmd30
# - script.execute: ble_process_cmd30
# - script.wait: ble_process_cmd30
globals:
- id: ble_1_connected
type: bool
initial_value: '0'
- id: ble_1_initialized
type: bool
initial_value: '1'
- id: ble_2_connected
type: bool
initial_value: '0'
- id: ble_2_initialized
type: bool
initial_value: '1'
- id: internal_console_dbg
type: bool
initial_value: '0'
- id: internal_console_hexdump
type: bool
initial_value: '1'
- id: internal_error_count
type: int
initial_value: '0'
- id: tmp_timers_1
type: char[22]
initial_value: "{0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0 }"
- id: tmp_timers_2
type: char[22]
initial_value: "{0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0, 0x0,0x0,0x0,0x0,0x0,0x0,0x0 }"
esp32_ble:
id: ble
esp32_ble_tracker:
scan_parameters:
window: 300ms
continuous: false
ble_client:
- mac_address: E8:XX:XX:XX:XX:XX
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
- text.set:
id: txt_A01_1
value: "not connected"
- text.set:
id: txt_A02_1
value: ""
- text.set:
id: txt_A03_1
value: ""
- text.set:
id: txt_A11_1
value: ""
- text.set:
id: txt_A12_1
value: ""
- text.set:
id: txt_scene_1
value: ""
- text.set:
id: txt_region_1
value: ""
# set region
# - script.execute:
# id: ble_command_simple
# ble_device_nr: 1
# ble_cmd: 0x02
# ble_cmd_parm: 0x00
# - script.wait: ble_command_simple
# - delay: 250ms
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: '1'
- text.set:
id: txt_A01_1
value: "not connected"
- text.set:
id: txt_A02_1
value: ""
- text.set:
id: txt_A03_1
value: ""
- text.set:
id: txt_A11_1
value: ""
- text.set:
id: txt_A12_1
value: ""
- text.set:
id: txt_scene_1
value: ""
- text.set:
id: txt_region_1
value: ""
- sensor.template.publish:
id: sensor_device_version_1
state: 0
- mac_address: E8:XX:XX:XX:XX:XX
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
- text.set:
id: txt_A01_2
value: "not connected"
- text.set:
id: txt_A02_2
value: ""
- text.set:
id: txt_A03_2
value: ""
- text.set:
id: txt_A11_2
value: ""
- text.set:
id: txt_A12_2
value: ""
- text.set:
id: txt_scene_2
value: ""
- text.set:
id: txt_region_2
value: ""
# set region
# - script.execute:
# id: ble_command_simple
# ble_device_nr: 2
# ble_cmd: 0x02
# ble_cmd_parm: 0x00
# - script.wait: ble_command_simple
# - delay: 250ms
# - script.execute:
# id: ble_set_time
# ble_device_nr: 2
# - script.wait: ble_set_time
Schaltet den Webserver ab, dann klappt’s auch mit dem Generator.
Siehe Issue tomquist/esphome-b2500#11
Verwendet ihr das ble-mqtt-gateway eigentlich, um regelmäßig den power-output zu setzen? Ich hatte gelesen, dass die Anzahl der Schreibzyklen begrenzt ist, weil der Speicher irgendwann "kaputtgeschrieben" ist. Gibts damit schon Erfahrungen, oder ist das eher ein theoretisches Problem?
Schaltet den Webserver ab, dann klappt’s auch mit dem Generator.
Siehe Issue tomquist/esphome-b2500#11
klappt trotzdem nicht, er erstellt im iobroker zwar alle objekte dann aber ist trotzdem offline
Schaltet den Webserver ab, dann klappt’s auch mit dem Generator.
Siehe Issue tomquist/esphome-b2500#11klappt trotzdem nicht, er erstellt im iobroker zwar alle objekte dann aber ist trotzdem offline
Ist vielleicht dein Smartphone oder ein anderes Gerät, per Bluetooth mit dem Speicher verbunden?
Nein
Schalte doch erst mal alles ab was Du nicht unbedingt benötigst :
- Hexdump
- DOD
- Webserver
- Fallback Hotspot
- Captive Portal
- CMD30
ein log könnte hilfreich ...
entweder per usb oder du kannst ggf vom debug-topic direkt ne ausgabe erzeugen ...
( mosquitto_sub -h <mqtt_host> -t <log_topic> )
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?
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 😁
mir ist gerade bei dem mqtt etwas aufgefallen ...
der v2 mit der fw 214 liefert u.a. den werte für a0-a2 ... wobei a0 mit dem prozentualem wert der kapazitäts anzeige korreliert ...
könnte rückschlüsse auf folgendes geben:
a0 = % intern
a1 = % powerpack1
a2 = % powerpack2
bin gerade echt am überlegen mal das powerpack am v2 zu klemmen und zu verifizieren.
falls jmd. das interne mqtt vom speicher nutzt und nen powerpack dran hat, kann er das ja mal gegenchecken,
würde mir das schleppen ersparen 😁
ggf. auch mal den id wert posten und ggf. welche kiste ihr nutzt ... ( falls ID, wirklich ne ID ist und kein anderes acronym ).
( und die anderen l0-l1 etc. , soviele unbekannte beim v2 gibt es ja nicht ) ...
Ich warte noch auf meine Erweiterung - kann Dir dann aber gern helfen. Bestellt und verschickt ist sie schon.
fragen zum v1 mit v139:
auf dem Screenshot ist eine Ausgangsleistung von 24/26 -> 50 Watt zu sehen. Läuft der Speicher auch noch bei geringerer Ausgangsleistung normal weiter, also zB. bei nur 15 W Gesamtausgang? Da stieg der bei v138 nämlich aus...
Du schreibst, dass die v139 richtig stabil sei. Betrifft das auch das BMS, also das nicht erklärbare Rücksetzen von xx% auf 85%? Denn kaum bin ich mit dem kalbrieren eines Speichers durch, spinnt der andere....
mit der ausgangsleistung, kurz mal angetestet.
nutze 2x v1 an einem hm1500 ... da kann ich ohne probleme bis auf 3% ( 45W) runtergehen.
ab 2% ( 30W ) schwankt es stark aber die verbindung bricht nicht ein ... ( habe jeweils ab 5% abwärts ne minute laufen lassen ) ..
habe jetzt nur die werte aus opendtu genommen und nicht direkt gemessen.
zu dem "richtig stabil": sorry, da war ich zu ungenau. das bezog sich nur auf die BLE verbindung.
ich kann mich dunkel erinnern, das es paar BMS resets gab, vor allem, wenn er ne weile im pt-modus war.
momentan verlasse ich mich auch nicht mehr auf dod und soc, sondern reagiere auf die zellspannungen.
seitdem habe ich auch noch nicht wieder kalibriert und läuft momentan sauber seit wochen durch ( auch ohne korrekte kalibrierung )
müsste ggf. nochmal ne kalibrierung mit dem powerpack machen.
anyway ...
diese bms-demenz dürfte momentan das letzte größere problem bei der v1 sein. zumindestens von dem was ich hier sehe.
schade das die direkte mqtt-steuerung keine zellspannungen liefert.
//edit
habs nochmal kurz mit 1% (15W) getestet ... da schwankt er genauso wie bei 2% ... zw. 1.x W und 8.x W .... wenn er zu lange im unteren bereich bleibt, ist die verbindung zum WR kurz weg ...
Ich habe mir die V139 gerade freischalten lassen. Bin gespannt ob die Reboots des Soeichers wieder zunehmen 🫣 Mit der 135 lief es ja recht stabil.
ok, bei L0 bin ich auch ein stückerl weiter ..
L0
0 = in == out
1 = out > in
2 = out < in
sieht also danach aus, als wenn es darstellt,, ob die batterie geladen oder entladen wird ..... ( dachte erst mos-states, aber bei in==out , wäre das keine 0 ).
bleibt noch L1 😁 , der ist immer 0 ... das einzigste, was da noch geladen werden könnte, wären ja die powerpacks,
welcher aber am V1 seinen dienst verrichtet ...
theor. könnten bisher alle unbekannten werte, wo wir "raten", auch für die v1 sinnvoll sein ...
//edit
@gine78 , bin dann mal auf deine ergebnisse gespannt ...
Lt. Sendungsverfolgung ist der Speicher "in Zustellung". Gibt es noch eine andere Möglichkeit zu kommunizieren? Ich brauch bestimmt Hilfe bei ein zwei Fragen. ;)
fragen bzw. deren antworten, die auch für andere hilfreich sind, sollten im offenen bereich erläutert werden.
ausserdem haben dann andere auch die möglichkeit ihren senf dazuzugeben 😁
es gibt im git eine art mini-forum, dann gehen die fragen/antworten nicht so unter.
die kommentar funktion ist leider nicht sehr übersichtlich und vieles geht unter.
wenn es um nonpublic fragen mit sensiblen daten geht, kannst du mich unter dem gleichen nick im photovoltaik forum finden.
@noone2k wenn du MQTT am Akku aktivierst. Welche Auswirkungen hat das dann auf die powerZero App? geht die dann noch oder leitet er alles dann auf lokal zum MOTT?
lg
meinst du die aktivierung von mqtt durch schuss bzw. der webseite oder meinst du das einrichten ?
nur durch die aktivierung der möglichkeit lokales mqtt zu nutzen, ändert sich in der bedienung nichts.
wenn du dein lokales mqtt eingerichtet hast, über die app:
innerhalb der ble reichweite kannst du mit der app weiterhin auf die kiste zugreifen.
auch die statistiken und updates funktionieren weiterhin.
was dann nicht mehr funktioniert ist die remote-controlle, also wenn du ausser haus bist.
wenn du lokal mqtt nutzt und in deinem smarthome-system einbindest, musst du dann "ausser haus" auf vpn oder deine smarthome-system-cloud zutückgreifen ( wenn die sowas integriert hat ) .
apropos mqtt und ble .... habe mal meinen esp32 für die v2 getauscht. seitdem läuft ble erstmal seit längerem stabil.
werds mal ne weile beobachten.
damit hat sich mqtt erstmal für mich erledigt als backup ...
werde aber ggf. einfach das script für das parsen für oh ins git packen, als anhaltspunkt für interessierte.
damit die kiste in den passthrough wechselt, wenn se voll ist,
müssen die ausgänge deaktiviert werden ...
ein fix dafür sollte im git enthalten sein und schaltet die ausgänge automatisch ab, sobald die kiste fast voll ist.
//edit
und immer warten ... es kann bis zu 4 minuten dauern, bis die gesetzten zustände aktiv werden.
Ja genau, wenn man ausschaltet wechselt es in den Transparentmodus und läßt alles durch.
Aber ist das nicht ein Bug in der Firmware vom Speicher ?
Die V135 hat das von sich aus gemacht 🤔
um zu wissen, ob es ein bug ist, müsste man wissen, was geplant war 😁
die firmware wurde ja öfters den kundenwünschen angepasst,
warum sich das jmd. gewünscht haben sollte, weiss ich aber auch grad nicht 😁
ich kann ja m.h. des esp das verhalten teilw. selbst beeinflussen und meinen wünschen anpasen.
kann mich aber ehrlich nicht daran erinnern, seit wann ich das bei mir durch den esp für mich löse.
müsste nochmals die 135 installieren. um gegenzuprüfen, ob das da auch noch der fall war.
bei der 135 war glaube noch keine lokales mqtt drin, sondern erst ab ~ 136/137 ...
// edit, wenn ich mich recht erinnere, sollte das verhalten des passthroughmit dem treshold gekoppelt sein ...
weiss jetzt aber nicht mehr, in welchem verhältniss ...
Ja, ist doch dann doof wenn der Speicher „abschaltet“ wenn die Batterie voll ist. Wie bekommt es der Speicher denn wieder mit wenn die Batterie benötigt wird ? 🤔
Wenn ich jetzt auch manuell ausschalte und den Speicher so in den Passtrough/Transparent-Modus versetze, da ist doch das gleiche Problem. Wie bekommt die Kiste das denn wieder mit wenn die WRs an der Batterie nuckeln wollen ? 😵
Also für mich macht das wenig Sinn.
ich schalte bei mir die ausgänge wieder ein, entweder wenn der passthrough ein limit unterschreitet
oder gegen 17:00 ( da beginnt für gewöhnlich bei tibber die hochpreisphase ... manchmal ab 16 , manchmal ab 18 ... aber 17 uhr ist ein guter mittelwert ).
wollte das mal direkt mit tibber koppeln, aber irgendwie noch nicht so den richtigen antrieb gefunden, da das realtiv gut passt ...
aber wie gesagt, ich bin der meinung, das das mal mit dem threshold gekoppelt war.
da ich das aber so schon lange nicht mehr nutze, kann ich dazu wenig sagen.
müsste erstmal in früheren versionen gegenchecken. irgendwo in diesen kommentaren habe ich das auch mal relativ ausführlich getestet und beschrieben.
Das ist ja alles gut und schön. Würde im Umkehrschluß bedeuten das man den Speicher standalone nicht mehr laufen lassen kann. Er schaltet bei 100% ab und dann ab einen Threshold (welcher Threshold ?) hoffentlich wieder ein ???
Sorry, es wird immer verwirrender, oder bin ich jetzt in den falschen Zug gestiegen 🤪
zumindestens beim falschen addressaten ... 😁
wenn das für den standalone betrieb deiner meinung ein fehler ist -> meldung an schuss ...
laut deiner beschreibung würde ich das auch so sehen, kann das aber weder bestätigen oder auf die schnelle nachstellen.
ich schalte bei mir die ausgänge wieder ein, entweder wenn der passthrough ein limit unterschreitet oder gegen 17:00 ( da beginnt für gewöhnlich bei tibber die hochpreisphase ... manchmal ab 16 , manchmal ab 18 ... aber 17 uhr ist ein guter mittelwert ). wollte das mal direkt mit tibber koppeln, aber irgendwie noch nicht so den richtigen antrieb gefunden, da das realtiv gut passt ...
Ich mache das ganze über den gemittelten Tagespreis. Sobald ich über den Durchschnitt bin springt mein Wechselrichter an mit der nulleinspeisung. Passiert auch in etwas ab 17...18 Uhr.
OK, die einfachste Llsung ist wohl Schuss wieder zu bitten mir die V135 aufzulegen und den Downgrade zu machen. Schade das man das nicht selbst kann.
Dummerweise ist Herr F. Seit heute Mittag für eine Woche im Urlaub. Naja, ich werde es überleben 😇
Danke für den Test @noone2k !!!
Bei v135 kann ich ohne Probleme den HM-1500 auf 30 W bzw. 2% regeln, ohne das die Speicher aussteigen. Der WR liefert dann zw. 25-40 W... also bleibts bei v135. Hatte auch per Feedback über die App mal gefragt, was der Unterschied zw. v138 und v139 wäre und die Probleme mit der v138 beschrieben. Antwort war, v139 ist für ihre Geräte nicht geeignet, lassen sie so wie es ist...
Der Bypass geht mit v135 auch mit offenen Ausgängen, nur muss da die Entladeschwelle kleiner als die Eingangsleistung sein (und 100% voll).
Das bringt mich auf eine Idee: Könnte man anstatt des BMS-Fixes, der ja die Ausgänge schließt (was wieder ein direktes Eingreifen erfordert, solange man es nicht vergisst 😁) , bei 100% bzw. 2240wh die Entladeschwelle automatisch runtersetzen? Die müsste man halt so individuell anpassen, so dass sie bei einer "Nulleinspeisung" in etwa dem entspricht, was man braucht. Diese sollte dann bei 99% Ladung, wieder hoch gesetzt werden. Wäre das viel Aufwand zu programmieren, so dass es im git implementiert werden könnte oder habe ich da irgendwo einen Denkfehler???
@knickohr
versuchs mal über die Feedback Funktion der App nen Downgrade zu erreichen 😉
Das ist genau der springende Punkt !
Es muß einmal die Eingangsleistung durch die Entladeschwelle laufen dann geht es wieder an. Nur ist halt die nicht fix und ändert sich jede Sekunde was zur Folge hat das man hier äußerst variabel eingreifen muß. In meinen Augen völliger Mist, Sorry. Da hätten sie lieber einen Schalter einbauen können ob man die Funktion will oder nicht. Meinetwegen z.B. einen Wert von -1 einstellen der es disabled.
Whoooohoooo !
Der Tipp mit dem Feedback ist 1a 😎 Innerhalb weniger Minuten war die „alte“ Version bereit gelegt. Kann ich jedem nur empfehlen diesen Weg zu gehen anstatt die armen Supporter bei Schuss zu behelligen 😉
Danke erstmal im voraus für die Umsetzung des Projekts :)
Kurze Frage zum Reboot des ESP via MQTT:
`button:
- platform: restart
id: controller_restart
name: "Restart Controller"
command_topic: b2500/esp32/reboot/set`
Was sende ich als Payload an das o.a. Topic?
OpenHAB sendet für einen Switch ja "ON", aber da bekomme ich folgende Nachricht "[mqtt.button:023]: 'Restart Controller': Received unknown status payload: ON"
Auch wenn ich ein press oder set schicke, dann tut sich nichts.
Was schickt Dein OpenHab?
PRESS
//edit
in der page sieht der code bei mir dann so aus:
- component: oh-list-item
config:
action: command
actionCommand: PRESS
actionItem: B2500_b2500__esp32__reboot
listButton: true
title: ESP32 - Reboot
resultat auf der page:
pic link funktioniert mal wieder nicht ... pic in next post
vllt. noch etwas grundsätzlicher:
bei buttons definierst du am besten den channel/item in OH als string ... ( wenn man bspw. esphome verwendet )
wenn du den button dann "drücken" willst, sendest du "PRESS" an das item ...
Das ist genau der springende Punkt !
Es muß einmal die Eingangsleistung durch die Entladeschwelle laufen dann geht es wieder an. Nur ist halt die nicht fix und ändert sich jede Sekunde was zur Folge hat das man hier äußerst variabel eingreifen muß. In meinen Augen völliger Mist, Sorry. Da hätten sie lieber einen Schalter einbauen können ob man die Funktion will oder nicht. Meinetwegen z.B. einen Wert von -1 einstellen der es disabled.
Ich glaube, da habe ich mich etwas unglücklich ausgedrückt. Ich meinte nicht, das die Entladeschwelle jedesmal bei ner Veränderung neu gesetzt werden sollte, sondern nur einmal bei vollem Akku und zwar auf den Wert, der ungefähr deinem minimalsten Hausverbrauch tagsüber entspricht. Bei mir wären das so ca. 100W. Sobald die Panels das nicht mehr bringen und die Nulleinspeisung verlangt mehr, entlädt der Akku wieder und wenn er dann noch 99% Ladung hat, wird die Entladeschwelle wieder hoch gesetzt auf zB. 999.
Genau das ist es ! In will nicht jedesmal den Wert einstellen wenn die Batterie proppenvoll voll ist. Der Wert steht bei mir fix auf 500W und den erreicht die PV nie. Um aber wieder einzuschalten muß einmal von oben her durch den Wert gefahren werden. Das ist Murks.
Bis zur V135 war es so das einfach eingeschaltet wird wenn der Wert unterschritten ist. Bzw. Es wurde somit bei mir nie abgeschaltet.
Der Jippijajajipijahjeee hat ihn jetzt auch im Angebot :
https://www.hornbach.de/conf/be-cool-erweiterungsbatterie-bc-p2500-2240-wh-2400-w/12149677/
@noone2k
Bist Du schon mit dem Erweiterungsspeicher und deren Auswertung weiter gekommen ? Wie erkenne ich ob es die Batterie von was lädt/entlädt ? Oder ist das jetzt einfach eine Summe der Kapazität ?
mit den bekannten befehlen ist da nichts auszulesen ( v1 ) ...
habe aber die bms/arm befehle ( 0xAA ) noch nicht ausprobiert ...
bei der v2 sieht es so aus, als wenn bei direktem mqtt die kapaizäten getrennt abgefragt werden können ( bisher keine bestätigung ),
mein powerpack ist im livebetrieb in meiner anlage ( v1 basiert ).
habe mir gerade paar kabel und stecker aus china bestellt, um zu sehen,
ob ich die kommunikation zw. powerpack und basis mitlesen kann.
wenn da was möglich ist, kann man theor. den esp32 auch direkt dazwischen klemmen ( 3.3V ).
aber das sind noch theorien und wunschdenken und bei weitem nicht spruchreif 😁
//edit ... kleiner denkfehler, wenn das powerpack leer ist, kommt ja wahrscheinlich auch keine 3.3V mehr an 😁
anyway ....
da das powerpack als zweites geladen wird, kann man sich aus der gesamtkapazität die einzel kapazitäten errechnen.
funktioniert aber nur dann halbwegs präzise, wenn beide ordentlich kalibriert sind ...
Ich habe mir die V139 gerade freischalten lassen. Bin gespannt ob die Reboots des Soeichers wieder zunehmen 🫣 Mit der 135 lief es ja recht stabil.
Die V139 hatte bei mir das gleiche Problem, ich bin auch wieder auf V135 umgestiegen. Seitdem gabs keine Reboots.
Ja, scheint wohl als müssen wir auf der V135 verharren bis vielleicht doch unser Flehen erhört wird und sie da einen Schalter einbauen.
Die Hoffnung stirbt zuletzt.
@noone2k
„ da das powerpack als zweites geladen wird, kann man sich aus der gesamtkapazität die einzel kapazitäten errechnen.
funktioniert aber nur dann halbwegs präzise, wenn beide ordentlich kalibriert sind ...“
Nochmal zum Verständnis : Es kommt also bei der Kapazität dann automatisch die 4480Wh ? Dann ist es doch einfach auf die Kapazität von der Erweiterungsbatterie zu schließen. Und man weiß ja auch das erst die interne Batterie geladen wird, dann die Zusatzbatterie. Und umgekehrt erst die Zusatzbatterie entladen wird, dann die interne.
richtig ... wie gesagt, am v1 ... wie das teil sich an der v2 verhält kann ich momentan nicht sagen ..
mit der kalibierung ist auch nur zweitrangig ... da die erste umschaltet bei ca. 3.65V, ist die erste auf jedenfall voll ( also ~ 2240Wh, jenach drift +/- 100 Wh ).
die detaildaten zum powerpack sind/wären dennoch interessant ...
auch um die kapazitäten/ladezustände einzuschätzen und m.h. von scripten auf die zustände zu reagieren.
und wie auch schonmal erwähnt, beim v2 kann man wahrscheinlich die kapazitäten abrufen ( per mqtt ),
aber diesen werten kann man nur vertrauen, wenn alles ordentlich kalibriert ist.
@noone2k was und wie würdest du als richtige Kalibrierung machen/bezeichnen, das ganze ohn3 externes Netzteil wie es einige machen.
Ich habe teilweise das Problem das sie von 80% auf 100 springt im schlimmsten fall.
Wie kann man die vorhandene Kalibrierung zurücksetzen?
Selbstverständlich wären die Detaildaten interessant. Aber so ist es zumindest schon mal erkennbar was das Ding so treibt.
würde einfach nach einleitung vorgehen ...bzw. einmal mit nem netzteil bei konstanter mittlerer zufuhr volladen...
habs aber schon ne weile nicht mehr gemacht. theor. müsste man das mal mit den neueren fw versionen testen.
aber auch bei der 1.39 habe ich paar bms-resets im pt-modus gesehen.
wenn ich mich richtig erinnere nutzen sinowealth ne interne voltage kalibrierung,
müsste mir aber nochmal die datenblätter dazu reinziehen.
hier kann es aber auch sein, das die arm-mpu irgendwas eigenes macht. ( in/out berechnen, wenn einmal voll , etc.)
kurz: k.a. was da intern gemacht wird: also im zweifel, einfach die anleitung beachten ( RTFM) 😁
zurücksetzen geht über die app ( hw-reset ) oder pin 3+4 kurzschließen.
Was hälst du von der Idee, die Entladeschwelle bei vollem v1 Speicher runter zu setzen, anstatt die Ausgänge zu schließen (BMS-Fix)?
gilt das nur für die fw 1.35 ?
wenn das verhalten so ist, wie ihr beschreibt, könnte man das machen ...
muss die zustandsänderung vor oder bei 100% passieren ?
bei der 1.39 nehme ich bspw. 3.55V ( also kurz vor ) zum abschalten, da das passieren muss, bevor er auf 100% springt.
anscheinend wird der zustand bei der 1.39 nur einmal ausgewertet und zwar wenn er sich ändert.
und welche kriterien müssen eingehalten werden, um den "original" oder gewünschten wert wieder einzustellen ?
wenn man nur sagt 99%, wird dieser ja zweimal durchlaufen .. beim be- und entladen ... oder ist das egal ?
da brauch ich eure erfahrung .... aber so rein theor. sollte das ja egal sein, da das dann der standardwert ist.
wenn das egal ist und die 100% der massstab ist, könnte man einfach sagen:
1.) wenn < 100% setze DEFAULT, wenn nicht DEFAULT
2.) ansonsten senke den threshold ...
die Änderung sollte bei 100% geschehen, weil die Speicher machmal einfach von xx% auf 100% springen, dann aber wieder mal bei 99% laden und laden und laden...
Da ich nicht weiß, wie oft der Batteriestand bei v135 ausgewertet wird und wie oft der Wert in den eprom geschrieben werden kann (?), sollte es kein Nachteil sein bei 99% die Abfrage so zu gestalten, das geschaut wird, wie hoch ist die E-Schwelle, ist sie ungleich 999W, dann schreibe 999W als E-Schwelle, ansonsten mache nix. Ebenso bei 100%, nur da halt mit zB. 100W.
Die Werte (999W/100W) sind jetzt MEINE Werte, bei anderen Nutzern könnten sie anders aussehen. Gäbe es da ne Möglichkeit, das man die Werte individuell einstellen könnte, also anstatt bei 100% - 100W nur 60W?
edit:
argh, das funktioniert so doch nicht, weil wenn die Speicher 100% erreicht haben, die Eingänge deaktiviert werden und so keine Prüfung der Entladeschwelle mehr stattfindet....
Servus, hat jemand eigentlich schon Mal probiert, 2 B2500 in Reihe zu schalten? Müsste ja eigentlich funktionieren, da auch der Ausgang noch DC ist. Spricht aus eurer Sicht war dagegen?
wenn du das bei dir halbwegs hinbekommen hast, kannst du eine kurzanleitung im wiki erstellen.
dann muss ich mich nicht so oft wiederholen :)