Skip to content

Instantly share code, notes, and snippets.

@noone2k
Last active July 17, 2024 07:16
Show Gist options
  • Save noone2k/2ddea4c9bf116aaaefb8626b064d9a41 to your computer and use it in GitHub Desktop.
Save noone2k/2ddea4c9bf116aaaefb8626b064d9a41 to your computer and use it in GitHub Desktop.
bc2500 info/control with esphome
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);
}
}
@noone2k
Copy link
Author

noone2k commented Jun 27, 2024

die hoymiles sollten eigentlich bei ca. 22V starten, dann aber auch bis runter zu 16V im betrieb bleiben.
auch wenn nur ein string über 16V bleibt. dürfte bei der hms serie nicht anders sein ...

habe den hms-1800 bei mir leider vor ner weile abgegeben, so das ich das nicht mehr testen kann.
hatte bei der v1 einfach bessere resultate mit einem hm-1500.

mit der ungleichen last sieht aber auch stark nach dem masse/bezugspunkt problem der v1 aus.
zumindestens das könnte man mit nem hm-600 nachstellen, der hat auch je port nen tracker.
wenn dem so ist, ist auch hier die hm-(1000-1500) serie besser geeignet ( 1 tracker für 2 ports ).

@noone2k
Copy link
Author

noone2k commented Jun 27, 2024

der vorherige post nicht zu ende geführt, wollt ihn aber nicht komplett wegfallen lassen ... ;)
hatte in der zwischenzeit auch mal die ausgangswerte mit verschiedenen versionen gemessen:

210.22  ~ 32.9V @ 80W
210.23  ~ 32.8V @ 80W
210.26  ~ 33.0V @ 80W

211.1   ~ 22.0V @ 80W
211.2   ~ 22.0V @ 80W
211.10  ~ 33.0V @ 80W

212.18  ~ 22.0V @ 80W

btw. da wo 22.0V ausgegeben wird. kommen real um die 65W an, auch wenn 80W eingestellt ist ,
da müsste man dann also die bezugstabelle W = V *A , wenn es da eine gibt, anpassen ...

und habe gesehen, das es ne 212.18 gibt ...

da gibt es bei mqtt neue werte ( nur mal die letzten bottom werte, der rest ist bekannt ),
was die bedeuten, werden wir hoffentlich noch erfahren ( habe noch nicht geguckt, ob es sich mit irgendwas deckt )

tc - Temp - Alarm - C  : 0
tf - Temp - Alarm - D  : 0
fc - FC41D - Version   : 202310231502
id -  : 5
a0 -  : 72
a1 -  : 0
a2 -  : 0
l0 -  : 1
l1 -  : 0
----------- done -----------

und das, was ich noch als abtastrate aufgeführt hatte ( smartmeter ) , war bei mir immer konstant 100 ..
k.a. ob das unbenannt wurde oder irgendwie ich das falsch übernommen habe, aber der wert ist jetzt bei mir 80.

wir gehen ja davon aus, das das der wert ist, um den sich die ausspeisung per smartmeter pendelt ....

@robbe1912
Copy link

wie komme ich an diese neuen firmware versionen ohne bei dem support zu betteln? die haben meinen nur auf V210 hochgestuft. 211.10 sieht ja vielversprechend aus. das problem ist, dass man bei 2 verbundenen ports pro port nur 40W output haben kann um auf die 80W zu kommen. dann schwankt der output ja auch noch zwischen den beiden ports, sodass einer manchmal runter geht auf 20W und das ist dann definitiv zu niedrig für den wechselrichter. es wäre ja super wenn man einfach einen der ports abstellen könnte wenn man nicht die volle leistung braucht über nacht. morgen kommt endlich mein ESP32 an und dann kann ich mit der yaml rumtesten.

@noone2k
Copy link
Author

noone2k commented Jun 27, 2024

tips oder hinweise, wie man an die versionen kommt, werde ich hier nicht im öffentlichen bereich beschreiben.
die begründung dazu, muss hier irgendwo in den kommentaren stecken ... ( sorry, gibt keine echte suche dafür ).

ich habe aber mal die tests durchgemacht um zu schauen, ob es eine 210er version gibt, die auch auf ~22V geht,
um dein problem ggf. anhand der 22V festzumachen bzw. auszuschließen.
es gibt momentan keine möglichkeit, zu erkennen, welche subversion bei installiert ist ( oder ich habe die noch nicht gesehen ).
und da ich schon dabei war, gleich die anderen auch mal durchgespielt.

denn meine vermutung geht eher in die richtung, das das zusammenspiel von deinem wr und der kiste irgendwo das problem ist.
vergleichbar mit dem v1 ...
nur habe ich momentan kein hms modell mehr hier.
da wird aller wahrscheinlichkeit die 211.10 nichts bringen, wenn es an den 22V liegt. die 210er haben ja alle 33V, wie die 211.10 auch.

du kannst natürlich versuchen bei schuss anzufragen , wegen einer neuen version ( kann aber sein, das bestimmte updates nicht im system sind ... kenne mich mit den internas da nicht aus ).
wenn, dann mit genauer fehlerbeschreibung ... ggf. kennen die das problem und haben eine version, die das fixt.
aber wichtig: erstmal melden. ohne meldung, kann man nicht versuchen, fehler zu identifizieren.

alles was ich mache, ist mit einem relativ hohen risiko verbunden, das ich selbst eingehe,
denn wenn was schief geht, kann ich mir im normalfall helfen ( ausser bei nem echt harten brick ).

@Larvy
Copy link

Larvy commented Jun 27, 2024

Was kann ich machen das der Grid Power gelesen wird. Den Pfad habe ich in der secret richtig angelegt. Aber irgendwie bekommt er keine Daten. Es bleibt auf Unbekannt stehen.

@noone2k
Copy link
Author

noone2k commented Jun 28, 2024

v1 oder v2 ?
bei der v2 wird die grid power nicht verwendet/benötigt, da keine nulleinspeisung integriert ...

da die grid power per mqtt bezogen wird, kannst du auch in deinem smarthome auf das original topic zugreifen.
anonsten sollte das topic vom original auf "{prefix}/sensor/mqtt__grid_power/state" "gespiegelt" werden,
vorrausgesetzt, das mqtt topic wurde korrekt eingerichtet ...

@robbe1912
Copy link

robbe1912 commented Jun 28, 2024

Laut ESP32 output habe ich einen HMA-1 aber nur die yaml für den v1 geht. v2 verbindet zwar mit dem bluetooth aber gibt keine werte aus. Ich habe das tool von @tomquist benutzt.
Kann man OUT1 und OUT2 jeweils an und aus schalten?
Was bedeutet "PV transparent"?
diese buttons scheinen nichts beim speicher auszurichten und ich habe noch keine erklärung für diese gefunden :/
image

kann man beim modus "laden vor entladen" einen schwellenwert einstellen? momentan geht PV-in bei 100% ladung aus und die batterie feuert in den wechselrichter bis dann 99% ladung da ist, wo output wieder auf 0 und PV-in wieder an geht. schön wäre es wenn primär die batterie geladen wird, und dann der überschuss in den wechselrichter geht, also nicht PV-in aus, sondern gleich weitergeleitet.

ich würde gerne die drossellung in der batterie schaffen, da der wechselrichter nur alle strings gleichmäßig drosseln kann. Wenn ich also 800W verbrauche, die 3 solarmodulports jeweils 350W potential haben werden auch diese gedrosselt(200W * 4), statt nur den batterie port zu drosseln und so viel von den modulen durchzulassen wie möglich. bin für alle tipps offen :)

Ich habe mal eine email an Schuss gesendet wegen dem spannungsproblem und die sind leider nicht hilfsbereit.
"Da der Strom in diesem Fall von einer Batterie kommt, muss so wie Sie bereits erkannt haben eine gewisse Mindestspannung erreicht werden, damit der Wechselrichter aktiviert werden kann. Da sich sehr viele unterschiedliche Wechselrichter auf dem Markt befinden, können wir die Ausgabe nicht spezifisch für ein Modell anpassen."
Einstellungsmöglichkeiten via MQTT wären aber echt schön, damit es jeder auf seinen anpassen kann.

Wenn ich nachts einfach einen der beiden output ports ausschalten könnte, hätte ich das problem gar nicht, da der strom nicht über 2 ports halbiert werden muss.

EDIT:
Passthrough modus schickt auch die volle leistung der batterie, und nicht nur das von einem panel anscheinend.

@eshopsrc
Copy link

Alles fein 👍

IMG_2604

Man muß nur wissen das man die Batterie erst dazu bitten muß 🤪

wie hast du die Werte in Node-Red weiter verarbeitet?

@robbe1912
Copy link

Haben die B2500 speicher bei den outputs Blocking Dioden, damit man diese parallel mit modulen laufen lassen kann?

@noone2k
Copy link
Author

noone2k commented Jun 28, 2024

@robbe1912

HMA-X sind die v1.2/v2 modelle .. und da solltest du das v2-script verwenden ...

die befehle und möglichkeiten sind bei beiden unterschiedlich ...

beim v2 kann man bspw. die output ( momentan ??? ) nicht getrennt schalten ...
auch der passthrough/transparent ( durchschalten des "in" auf den "out" ) kann man beim v2 ( noch ??? ) nicht steuern ...

@noone2k
Copy link
Author

noone2k commented Jun 28, 2024

@robbe1912

ich muss nochmal schauen, wegen den passthrough beim v2 und der fw 212.18, da scheint das nicht ganz zu funktionieren.
damit zum zeitpunkt der passthrough funktioniert, habe ich die timer deaktiviert und/oder auf laden/entladen gleichzeitig geschaltet,
kurz bevor die 3.6V max erreicht wurden.

bin mir da aber gerade nicht sicher, denn mit der aktuell getesteten version konnte ich damit den pt nicht aktivieren.
oder ich war mal wieder zu ungeduldig ;)
dauert immer ne weile bis bestimmte zustände auch vom soll in den ist zustand schalten ..
kann bis zu 4 minuten dauern - wobei beim v2 ich noch keine zeitmessungen durchgeführt habe ...

aber erst morgen wieder, wenn die sonne scheint ...

btw. der befehl zum pt ist in der firmware noch drin ... der schaltet momentan aber nur zwischen laden/entladen gleichzeitig und erst laden um ... ( irgendwie und nicht richtig )
kann aber gut sein, das der irgendwann erweitert wird, damit die mos (?) direkt durchschalten ( passthrough ).
vllt da mal morgen ein bisserl weiter gucken, wenn sich die zeit findet ...

@knickohr
Copy link

Hast Du einen Schaltplan von der V1 ? Würde mich mal interessieren was hier geschaltet wird und was noch machbar wäre.

@noone2k
Copy link
Author

noone2k commented Jun 28, 2024

nein ... wenn ich den offiziell bekommen hätte, würde ich ihn auch nicht einfach rausgeben ... ( sowas bekommt man normalerweise nur mit nda .. )

@ugath
Copy link

ugath commented Jun 29, 2024

Hi!
Hat hier jemand einen Tipp warum die Werte nicht ausgefüllt werden?

grafik
grafik

Habe die b2500-v2-ble-idf.yaml benutzt und Speicher ist ein Marstek mit V2.1.2.
Wenn ich die tomquist/esphome-b2500 benutze, sind diese Daten da aber da fehlen mir ein paar andere Sachen (für die 3 Timer werden keine Datenpunkte angelegt).

Gruß

@robbe1912
Copy link

robbe1912 commented Jun 29, 2024

ich muss nochmal schauen, wegen den passthrough beim v2 und der fw 212.18, da scheint das nicht ganz zu funktionieren. damit zum zeitpunkt der passthrough funktioniert, habe ich die timer deaktiviert und/oder auf laden/entladen gleichzeitig geschaltet, kurz bevor die 3.6V max erreicht wurden.

Ich hoffe das outputs getrennt schalten oder bei niedriger stromabgabe automatisch einen port ausschalten bei der V2 bald funktionieren wird. ich habe darüber nachgedacht eine neue batterie dazuzukaufen und dann bei allen 4 ports meines hms 2000 die outputs der batterien anstecke, aber wenn ich nachts nur 150W brauche würde mindestens eine ja(momentan) aus gehen. ich würde mich natürlich über jeglichen support mit der V2 freuen, und auch helfen mit hex dumps falls das was bringen würde.

@tomquist
Copy link

Habe die b2500-v2-ble-idf.yaml benutzt und Speicher ist ein Marstek mit V2.1.2. Wenn ich die tomquist/esphome-b2500 benutze, sind diese Daten da aber da fehlen mir ein paar andere Sachen (für die 3 Timer werden keine Datenpunkte angelegt).

@ugath Habe es in deinem issue auch schon kommentiert. Die timer werden nicht angelegt, da du deinen Speicher als v1 konfiguriert hast. Ein v1 hat keine timer. Lässt sich beheben indem du bei Version eine 2 eingibst.

@ugath
Copy link

ugath commented Jun 29, 2024

Habe die b2500-v2-ble-idf.yaml benutzt und Speicher ist ein Marstek mit V2.1.2. Wenn ich die tomquist/esphome-b2500 benutze, sind diese Daten da aber da fehlen mir ein paar andere Sachen (für die 3 Timer werden keine Datenpunkte angelegt).

@ugath Habe es in deinem issue auch schon kommentiert. Die timer werden nicht angelegt, da du deinen Speicher als v1 konfiguriert hast. Ein v1 hat keine timer. Lässt sich beheben indem du bei Version eine 2 eingibst.

@tomquist Ja, sorry... Hatte diese Einstellung irgendwie komplett übersehen und mich gefragt, wo der Fehler liegen könnte. Wenn man es dann richtig macht, funktioniert es auch. Danke für die Arbeit!

@tomquist
Copy link

Gibt es irgendwo schon eine Aufstellung der aller Gerätetypen und und welche Marke/Speichergeneration dahinter steckt? Wenn nicht, würde ich mal eine im Wiki anfangen, kenne aber nur meine beiden Geräte.

@noone2k
Copy link
Author

noone2k commented Jun 29, 2024

eine liste ist mir nicht bekannt ... nur das, was im (mageren) wiki selbst verstreut ist ...

HMB-X = 1st gen (x=4 bc)
HMA-X = 2nd gen (x=2 bp )
HMK-X = 3rd gen

in der firmware gibs aber auch hinweise auf:

HMA-[1-14] - ( HM_B2500 )
HMB-[0-6] - ( HM_B2500 )
HMD-[0-7] - ( M oder A Modelle - 1200/2200/3600 )
HMF-[0-6] - ( HM_B1200 )
HMG-[1-6] - ( HM_B2500 )
HMK-[1-11] - ( HM_B2500 )

ggf. mit paar zahlenlücken dazwischen ...

hatte schonmal angefangen paar daten zu notieren und bei irgendeinem wiki push sind die dateien ausversehen schon reingerutscht :)
https://github.com/noone2k/hm2500pub/wiki/HW-compare

//edit
bei pearl gibs ja solche geräte und irgendein bauzubehör-lieferant oder so .. und und und ...
also da gibs etliche labels ... in der offiziellen app, findet man auch hinweise, zu den labels ...

@noone2k
Copy link
Author

noone2k commented Jun 29, 2024

bin für heute erstmal wieder afk ... einer dieser tage, wo die birne nicht so richtig aufwachen will ... schieben wir das mal auf das wetter 😁

@7Netler
Copy link

7Netler commented Jun 30, 2024

eine liste ist mir nicht bekannt ... nur das, was im (mageren) wiki selbst verstreut ist ...

HMB-X = 1st gen (x=4 bc) HMA-X = 2nd gen (x=2 bp ) HMK-X = 3rd gen

Dann hab ich ja ne Gen 3 mit HMK-2 gibts dazu auch schon ein Script ?

@noone2k
Copy link
Author

noone2k commented Jun 30, 2024

sollte befehlstechnisch mit der gen2 kompatibel sein ( nutzen die gleiche firmware ) ...
es gibt da keine groben unterscheidungen in den befehlen ...
habe aber natürlich nicht den ganzen blob bis aufs letzte bit untersucht, sondern nur partiell die bereiche die für mich interessant sind ( ble ) ...

wenn du irgendwelche technischen daten beisteuern kannst: https://github.com/noone2k/hm2500pub/wiki/HW-compare

HMK-2 ist welche marke/label ?

//edit du warst schonmal im git/issue .... marstek, wenn ich mich recht erinnere ?
//2nd edit .. warst du doch nicht 😁 .. aber habe gesehen, HMA-3 scheint green-solar zu sein ..

@7Netler
Copy link

7Netler commented Jun 30, 2024

sollte befehlstechnisch mit der gen2 kompatibel sein ( nutzen die gleiche firmware ) ... es gibt da keine groben unterscheidungen in den befehlen ... habe aber natürlich nicht den ganzen blob bis aufs letzte bit untersucht, sondern nur partiell die bereiche die für mich interessant sind ( ble ) ...

wenn du irgendwelche technischen daten beisteuern kannst: https://github.com/noone2k/hm2500pub/wiki/HW-compare

HMK-2 ist welche marke/label ?

//edit du warst schonmal im git/issue .... marstek, wenn ich mich recht erinnere ? //2nd edit .. warst du doch nicht 😁 .. aber habe gesehen, HMA-3 scheint green-solar zu sein ..

Greensolar hab ich HMK-2

@7Netler
Copy link

7Netler commented Jun 30, 2024

Habs mittlerweile geschafft Daten erfolgreich an den Speicher zu senden. Somit Kann ich Die Entladung etc. meines Speichers direkt steuern. Jedoch empfange ich keine Daten.

In der Doku in der App heisst es nur "How to read the device information: Subscribe Topic: hame_energy/HMK-2/device/BLEMAC/ctrl/#"
Hat jemand eine Idee was ich falsch mache ? So sieht das bei mir aktuelle in Nodered aus:

Screenshot 2024-06-30 165305

@noone2k
Copy link
Author

noone2k commented Jun 30, 2024

während du subscribed bist, musst du den befehl cd=01 an "App" senden ... ( bspw. in nem loop oder so ).
wie schon öfters betont, kenn ich mich mit HA/NodeRed/etc. nicht aus ...
da musst du gucken, wie du den loop in nem script oder so packst und alle 5 sekunden den befehl sendest ...

@7Netler
Copy link

7Netler commented Jun 30, 2024

während du subscribed bist, musst du den befehl cd=01 an "App" senden ... ( bspw. in nem loop oder so ). wie schon öfters betont, kenn ich mich mit HA/NodeRed/etc. nicht aus ... da musst du gucken, wie du den loop in nem script oder so packst und alle 5 sekunden den befehl sendest ...

Genau das wars. Vielen Dank dir :)

@noone2k
Copy link
Author

noone2k commented Jul 1, 2024

wenn du das bei dir halbwegs hinbekommen hast, kannst du eine kurzanleitung im wiki erstellen.
dann muss ich mich nicht so oft wiederholen :)

@robbe1912
Copy link

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?

@noone2k
Copy link
Author

noone2k commented Jul 1, 2024

wie war der wert vmin zu dem zeitpunkt ?

@robbe1912
Copy link

1000032918
Von der v2 Batterie kann ich nichts auslesen soweit ich weiß, aber die Spannung am Inverter ist sofort weg

@noone2k
Copy link
Author

noone2k commented Jul 1, 2024

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.

@noone2k
Copy link
Author

noone2k commented Jul 1, 2024

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 ...

@Fuxifux
Copy link

Fuxifux commented Jul 1, 2024

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 ! 😉

@Fuxifux
Copy link

Fuxifux commented Jul 1, 2024

Offizieller ChangeLog:

  1. Optimize Mqtt and Ble connect!
  2. Compatible with pad phone
  3. Add some new feature.
  4. Add pull to refresh for update data.
  5. Fix some bugs.

@WolleSoso
Copy link

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.

@azazul1980
Copy link

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 ?

@noone2k
Copy link
Author

noone2k commented Jul 5, 2024

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 😁

@tomquist
Copy link

tomquist commented Jul 5, 2024

@azazul1980 Du kannst dir hierüber eine Config für bis zu 3 Akkus generieren: https://tomquist.github.io/esphome-b2500/

@azazul1980
Copy link

@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😔.

@azazul1980
Copy link

@noone2k wäre cool wenn irgend wann ein zweiter Accu mit dieser Funktion reinkommen würde.

@noone2k
Copy link
Author

noone2k commented Jul 6, 2024

@tomquist

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 ).

@denjo82
Copy link

denjo82 commented Jul 6, 2024

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.

@ugath
Copy link

ugath commented Jul 6, 2024

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.

Ich habe den Gleichen mit CH340 und der funktioniert einwandfrei. Der Unterschied ist doch nur der USB to serial chip...

@denjo1982
Copy link

denjo1982 commented Jul 6, 2024

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?

@ugath
Copy link

ugath commented Jul 6, 2024

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?

So hab ich alles eingestellt:
grafik

@denjo1982
Copy link

ja danke, aber keine chance. er verbindet sich nur einmal ganz kurz zu mein mqtt server und dann wird er als offline angezeigt.

@denjo1982
Copy link

denjo1982 commented Jul 7, 2024

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

@knickohr
Copy link

knickohr commented Jul 8, 2024

Schaltet den Webserver ab, dann klappt’s auch mit dem Generator.

Siehe Issue tomquist/esphome-b2500#11

@olympic1337
Copy link

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?

@denjo1982
Copy link

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

@ugath
Copy link

ugath commented Jul 10, 2024

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

Ist vielleicht dein Smartphone oder ein anderes Gerät, per Bluetooth mit dem Speicher verbunden?

@denjo82
Copy link

denjo82 commented Jul 10, 2024

Nein

@knickohr
Copy link

Schalte doch erst mal alles ab was Du nicht unbedingt benötigst :

  • Hexdump
  • DOD
  • Webserver
  • Fallback Hotspot
  • Captive Portal
  • CMD30

@noone2k
Copy link
Author

noone2k commented Jul 10, 2024

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> )

@gine78
Copy link

gine78 commented Jul 10, 2024

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?

@noone2k
Copy link
Author

noone2k commented Jul 10, 2024

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 ;)

@gine78
Copy link

gine78 commented Jul 10, 2024

Na dann bestell ich mal - mal gucken ob Du uns bis dahin was gezaubert hast. Gibt eigentlich einen "donatebutton" irgendwo? ;)

@noone2k
Copy link
Author

noone2k commented Jul 10, 2024

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 ...

@gine78
Copy link

gine78 commented Jul 10, 2024

Ich erhoffe mir ja, dass der Speicher das erkannt und das Ganze als "einen" sieht. Aber mal sehen, kannst ja gern mal berichten.

@noone2k
Copy link
Author

noone2k commented Jul 11, 2024

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 ...

@gine78
Copy link

gine78 commented Jul 11, 2024

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)

@noone2k
Copy link
Author

noone2k commented Jul 12, 2024

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.

@JoeBue1
Copy link

JoeBue1 commented Jul 12, 2024

@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.

@knickohr
Copy link

Also wird der Zusatzspeicher im Script (noch) nicht erkannt ?

@noone2k
Copy link
Author

noone2k commented Jul 12, 2024

man sieht beide nur als eine einheit und kann nur die cell/temp werte der hauptbatterie abfragen.
die firmware sieht nicht vor, irgendwelche werte direkt vom zusatzspeicher abzufragen.

Screenshot 2024-07-12 at 09-46-33 openHAB

@knickohr
Copy link

knickohr commented Jul 12, 2024

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.

@noone2k
Copy link
Author

noone2k commented Jul 13, 2024

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 ...

@noone2k
Copy link
Author

noone2k commented Jul 13, 2024

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.

@noone2k
Copy link
Author

noone2k commented Jul 17, 2024

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.

Screenshot 2024-07-17 at 08-38-07 openHAB

Screenshot 2024-07-17 at 08-38-51 openHAB

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 😁

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