Skip to content

Instantly share code, notes, and snippets.

@noone2k
Last active June 19, 2024 12:03
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);
}
}
@azazul1980
Copy link

@noone2k es war ziemlich komisch der Timer

2-3 waren aktiv wobei der Timer 2 100w 00:00-00:30 hatte und der Timer 3 auch einen Wert wo ich nicht mehr weiß. Das ist mir 2 x passiert bei dem Versuch über den Speicher zu regeln. Nach dem mir die EPRom Sache in den Kopf kam habe ich es lieber gelassen . Der Speicher soll seine 5000-6000 Zyklen halten.

@noone2k
Copy link
Author

noone2k commented Jun 6, 2024

diese "geregelte" steuerung über timer 3 sollte nur dafür genutzt werden,
mal schnell die steuerung für sich anzupassen und ist dafür "reserviert".

momentan ist die logic im script wie folgt:
timer 1+2 kann man gleichzeitig aktivieren. dabei wird timer 3 immer deaktiviert ( aber keine anderen werte verstellt ).
wenn man timer3 aktiviert, werden timer 1+2 deaktiviert ( und auch hier, ich deaktiviere nur die timer, aber setze keine anderen werte ).

da timer3 im script für die manuelle ansteuerung der ausgabe reserviert ist, sollen die anderen timer sich nicht in die quere kommen.

wenn sich doch andere werte verändern ( zeiten oder power ) , müsste ich mal gegenprüfen unter welchen umständen.

da fällt mir ein, das ich mal gucken könnte welcher timer priorität hat, wenn sich zeiten überlappen ;)
oder falls es jmd weiss, gerne antworten ...

@noone2k
Copy link
Author

noone2k commented Jun 7, 2024

für den v1 habe ich gerade die 1.39 entdeckt ...
sieht auf dem ersten blick nach einen bugfix release aus ... keine neuen funktionen ...

@phoen
Copy link

phoen commented Jun 7, 2024

Ich habe eine Frage, nicht direkt zu diesem Projekt, welches einwandfrei funktioniert, sondern zu einem seltsamen Verhalten meiner Batterien, das mir erst duch die Homeassistant Integration aufgefallen ist. Vielleicht kennt jemand hier dieses Problem und kann dazu etwas sagen.

Ich Verwende 2 v1 Batterien, mit HM-800 Wechselrichtern und Nulleinspeisung mit DTU-Pro. Läuft eigentlich sehr stabil, jedoch ziehen die Wechselrichter nachts, immer wenn der Verbrauch nahezu 0 ist, in scheinbar regelmäßigen Abständen kurz die volle Leistung.
Die DTU dürfte dafür verantwortlich sein, da dies bei beiden Batterien gleichzeitig auftritt. Die in der Grafik erkennbaren Pausen, entstehen, wenn der Kühlschrankkomressor läuft.

Screenshot 2024-06-07 130551

@knickohr
Copy link

knickohr commented Jun 7, 2024

Welche Firmwareversion hast Du ?

Ich habe einen ähnlichen Effekt, ebenfalls V1, das der Speicher hin und wieder kurz die Ausgänge trennt und somit die Wechselrichter ausschaltet. Ganz klar das dann beim Restart die WRs erst mal auf 100% gehen bis die DTU wieder zurück regelt.

Workaround, ein persistentes Limit dem WR geben, bspw. 10W. Dann wird beim Einschalten erst mal auf 10W geregelt und die DTU paßt das dann entsprechend an.

Dieses seltsame Verhalten vom Speicher trat bei mir erstmals mit der V136 auf 😳

@mikerway
Copy link

mikerway commented Jun 7, 2024

@phoen Firmware v138 ? Die hat scheinbar ein Problem, wenn zu wenig an Strom an Out1 ausgegeben wird. Dann macht der Speicher nen Restart/Reset und der WR schaltet sich ab. Dann dauert es ca. 3-4 Minuten bis die Speicher wieder liefern und noch ca. 1 Minute bis der WR wieder geregelt wird. Wenn nur Out2 angeschlossen ist, dann macht er das nicht!
Hast du beide Speicher am HM-800 über Out1 verbunden? Dann teste mal, ob der Anschluss an Out2 Verbesserung bringt. Oder du bittest die Fa. Schuss darum, dir wieder die v135 zur Verfügung zu stellen.

@phoen
Copy link

phoen commented Jun 7, 2024

Danke für den Tipp, ich hatte erst die DTU im Verdacht, weil die Spikes zeitgleich passieren. die BLE Disconnects zeigen aber ein recht eindeutige Bild. Ich habe jeweils beide Ausgänge an die HM-800 angeschlossen.

Die Speicher laufen mit v138. Davor dürfte das Problem nicht aufgetreten sein.

@knickohr Wie kann ich das persistent Limit setzen, ohne das Export Limit zu verändern?

Screenshot 2024-06-08 004439

Nachtrag: mit der Version 139 haben sich die Probleme allesamt erledigt.

@knickohr
Copy link

knickohr commented Jun 8, 2024

Das sollte mit der DTU gehen. Original Hoymiles DTU ?

Es gibt 2 Limits, ein festes und dauerhaftes, das beim Einschalten des WRs gesetzt ist. Dieses verbleibt im EEPROM des WRs. Und ein temporäres das normalerweise für eine Nulleinspeisung genutzt wird und bei dem sich die Werte schnell ändern.

Wie machst Du diese Rebooterkennung ? Auf was fragst Du ab ?

@tbretz65
Copy link

tbretz65 commented Jun 8, 2024

@phoen
Sorry, hab das nicht richtig mitbekommen.
Ich hatte auch mit der 1380 das Problem mit dem Abschalten.
Bei mir war es die Einstellung "Enable Battery Control" = on im Script von neromatrix.
Seit das aus ist, hab ich kein Problem mehr.
Keine Ahnung ob es so was auch hier gibt :-(

@knickohr
Copy link

knickohr commented Jun 9, 2024

Was ist enable battery control ? Bzw. was macht es am Speicher ?

@tomquist
Copy link

tomquist commented Jun 9, 2024

@noone2k Habe auch ein issue im public repo geöffnet, aber hier auch nochmal die Frage. Unter welcher Lizenz steht die yaml Datei?

Hintergrund ist, dass ich die v1 und v2 config files in ein einziges Template gemerged, und dann eine UI drumherum gebaut habe, über die sich bequem bis zu 3 Speicher in beliebiger Version konfigurieren lassen. Am Ende generiert es dann eine yaml, die nur die benötigten Teile enthält. Wollte das veröffentlichen, dachte aber ich frage besser erstmal nach, ob es in Ordnung ist, da in deinem Repo keine Lizenz angegeben ist.

@tbretz65
Copy link

tbretz65 commented Jun 9, 2024

@knickohr
Das gibt es bei neromatrix in seinem yaml. :-)
Ich glaube da werden die ausgänge vom Akku geschaltet.
Bei mir war es so, wenn die Ausgänge geschaltet wurden dann ist die Leistung weggebrochen.

Wenn es so etwas hier nicht gibt, dann hab ich auch nix geschrieben :-)

@phoen
Copy link

phoen commented Jun 9, 2024

@knickohr Genau, es ist eine original Hoymiles DTU. Das setzten des persistent Limit auf hat die Power Spikes und auch die meisten Disconnects zuverlässig verhindert.

Die Homeassistant Integration von neromatrix hat eine esp_ble_disconnects Entity, dadurch kann man die Restarts gut beobachten.

@noone2k
Copy link
Author

noone2k commented Jun 9, 2024

@noone2k Habe auch ein issue im public repo geöffnet, aber hier auch nochmal die Frage. Unter welcher Lizenz steht die yaml Datei?

Hintergrund ist, dass ich die v1 und v2 config files in ein einziges Template gemerged, und dann eine UI drumherum gebaut habe, über die sich bequem bis zu 3 Speicher in beliebiger Version konfigurieren lassen. Am Ende generiert es dann eine yaml, die nur die benötigten Teile enthält. Wollte das veröffentlichen, dachte aber ich frage besser erstmal nach, ob es in Ordnung ist, da in deinem Repo keine Lizenz angegeben ist.

grundsätzlich gebe ich keine lizenz-modelle an, dann bleiben automatisch alle rechte bei mir ;)
will mir da auch keine echten gedanken zu machen. sehe die yaml eher als informations grundlage für eigene entwicklungen.

da ich eher ein freund von opensource bin, neige ich, wenn notwendig, jedoch zu einer copyleft variante.
d.h. frei für die nicht kommerzielle-nutzung und änderungen am quellcode müssen veröffentlicht werden.
da die yaml ja an sich nur "quellcode" ist, ist das an für sich ja garantiert, wenn jmd. änderungen weitergibt.

bei dir scheint das ja etwas anders zu sein, du generierst die yaml neu, aufgrund von vorgaben ...
sagen wir mal so: habe kein problem damit, mit dem was du vorhast ...
gefällt mir sogar, erleichtert den einstieg und dem endbenutzer die anwendung ;)

@knickohr
Copy link

knickohr commented Jun 9, 2024

@tbretz65 @phoen
Das no power waste nutze ich nicht. Dann kanns bei mir nicht daran liegen 😉
Die Ausgänge schalte ich nur 2x am Tage. Morgens ein und Abends aus. Die Aussetzer/Reboots sind aber über den ganzen Tag. Ich denke die V138 hat halt noch einen Bug, bin mal gespannt was die 139 her gibt,

@tomquist
Erzähle mal mehr. Ich habe 4 Speicher und nutze für jeweils 2 einen eigenen ESP. Leider sind beide räumlich zu weit getrennt um alle 4 auf einem ESP laufen zu lassen. Was mich aber mehr interessiert, was kannst Du alles konfigurieren ? Und am Ende kommt dann eine yaml raus die ich einfach flashe ? Wie machst Du das mit den Topics ? Das ist mir schon lange ein Dorn im Auge, muß das jedesmal hündisch anpassen weil es hardcoded ist. Leider verstehe ich nicht viel von der Programmiersprache, ansonsten hätte ich da scho; längst was gebastelt um die Topics über die secret dynamisch anzupassen.

@tomquist
Copy link

tomquist commented Jun 9, 2024

@noone2k

grundsätzlich gebe ich keine lizenz-modelle an, dann bleiben automatisch alle rechte bei mir ;)

Verstehe ich einerseits, dass du dich nicht festlegen willst. Allerdings verhindert das theoretisch jegliche Beteiligung. Ohne eine explizite Lizenzvereinbarung bleibt das Projekt urheberrechtlich geschützt und jede Nutzung ohne ausdrückliche Erlaubnis könnte eine Urheberrechtsverletzung darstellen. Ich glaube ja nicht, dass du deine Rechte durchsetzen wirst, möchte aber trotzdem darauf hinweisen. Ich würde mein Projekt ehrlich gesagt ungern veröffentlichen, ohne dass das eindeutig geklärt ist. Aktuell basiert mein Template ganz klar auf deiner config.

@knickohr Ich teile am Besten einfach ein Screenshot, das ist aussagekräftiger:
Screenshot 2024-06-09 at 12 13 54

@Fuxifux
Copy link

Fuxifux commented Jun 9, 2024

Das ist ja eine super Erleichterung. Also was ihr da alles auf die Beine stellt 👍

@knickohr
Copy link

knickohr commented Jun 9, 2024

Joahhh goil, muß ich haben ! 😉😎

@denjo1982
Copy link

gibt es auch noch die alte yaml datei ohne nulleinspesung und nur mqtt also nicht HA

@noone2k
Copy link
Author

noone2k commented Jun 11, 2024

wenn du in diesem gist oben auf revisionen klickst, siehst du alle versionen ( und änderungen ) , die hier gepostet wurden.
im git selbst findest nur die neueren inkl. nulleinspeisung ...

bei der version für den v2 ( nur im git ) ist keine nulleinspeisung implementiert ...

//edit du kannst auch in den neuen versionen ( v1 ) , die nulleinspeisung einfach deaktivieren .... ( oder entfernen )

@tomquist
Copy link

Über den Config-Generator kann man dann auch einzelne Features wie die Nulleinspeisung ein- und ausschalten, egal ob für den v1 oder v2 Speicher. Sobald das Thema Lizenz geklärt ist, werde ich das Tool veröffentlichen, natürlich auch open source.

Screenshot 2024-06-11 at 17 03 34

@knickohr
Copy link

Es wird immer besser 👍

@vogty79
Copy link

vogty79 commented Jun 11, 2024

Morgen oder übermorgen kommt das Smartmeter, mal sehen ob das schon vernünftig funktioniert…

@gine78
Copy link

gine78 commented Jun 11, 2024

Wo hast du das bestellt?

@noone2k
Copy link
Author

noone2k commented Jun 11, 2024

@tomquist

dazu muss ich mir erstmal die lizenzen durcharbeiten ... nachher stehen da sachen drin, die ich mir so nicht vorgestellt habe oder nicht passen ;)

bis dahin gilt: frei zur nichtkommerziellen nutzung und bei verbreitung müssen änderungen veröffentlicht werden ( was bei einem yaml eigentlich immer zutrifft :) ) ...

eine strictere policy wäre auch gar nicht anwendbar ... die infos habe ich nicht nur aus dem ble-sniff,
sondern auch aus der firmware .... diese zu reversen etc. wird so gut wie in jedem kommerziellen produkt ausgeschlossen.
mein "produkt" besteht u.a. in der analyse eines closed-source blobs ... somit könnte ich gar nicht anders handeln ...
kann also sein, das (l)gpl oder andere lizenzen gar nicht anwendbar sind ...

@noone2k
Copy link
Author

noone2k commented Jun 11, 2024

@vogty79

hast du die möglichkeit den wlan traffic zu sniffen ?

da ich so ein teil nicht brauche, besteht für mich auch keine veranlassungen so ein teil zu kaufen.
sonst würde ich das selbst machen.

ich vermute aber, das der smartmeter kaum einfluss auf dieses project hier hätte.
die genutzte umgebung ( esphome ) hat glaube noch keinen udp/tcp socket support ( mit einwenig fleiss würde das aber trotzdem gehen )

ich gehe momentan aber stark davon aus, das die kommunikation übers wlan ( udp/tcp ) funktioniert.
und alle damit verbundenen vor- und nachteile ...

  • direkte und damit schnellere kommunikation
  • kein zusätzlicher hub / broker / server / whatever notwendig
  • beide müssen per wlan erreichbar sein
  • geräte müssen im gleichen subnetz sein

und vllt. noch paar andere sachen, die mir so auf anhieb nicht einfallen 😁

@vogty79
Copy link

vogty79 commented Jun 11, 2024

Habe einen Mac, reicht da wireshark? Dann kann ich das gerne mal machen und dir bereitstellen

@gine78
Copy link

gine78 commented Jun 11, 2024

@vogty79 kannst du mir die Frage beantworten? Wo konntest du den bestellen?

@noone2k
Copy link
Author

noone2k commented Jun 12, 2024

@vogty79

ja wireshark sollte für den anfang reichen ... damit würde ich erstmal anfangen 😁
ob man dann noch mehr benötigt, kann ich erst hinterher sagen ...

kenn mich mit macs nicht aus ...
aber rein techn.: wenn es dafür wireshark gibt ( oder tcpdump/pcapdump/whatever ) und die wireless-card in den promiscuous oder monitor mode geschaltet werden kann, sollte das funktionieren ...

die logs am besten dann über das photovoltaik-forum mir zukommen lassen und hier nicht offen posten ..

@denjo82
Copy link

denjo82 commented Jun 12, 2024

wenn du in diesem gist oben auf revisionen klickst, siehst du alle versionen ( und änderungen ) , die hier gepostet wurden. im git selbst findest nur die neueren inkl. nulleinspeisung ...

bei der version für den v2 ( nur im git ) ist keine nulleinspeisung implementiert ...

//edit du kannst auch in den neuen versionen ( v1 ) , die nulleinspeisung einfach deaktivieren .... ( oder entfernen )

Welche ist denn die für den v2 ohne nulleinspeisung und ohne HA also nur Mqqt?

@tomquist
Copy link

@vogty79 Falls es mit Wireshark nicht klappt, und du zufälligerweise eine FritzBox besitzt, kannst du auch hierüber einen Paketmitschnitt erzeugen: http://fritz.box/support.lua

Wäre auch super an der Funktionsweise der Kommunikation des Smartmeter interessiert, bin aber zu geizig das Geld dafür auszugeben, da ich ihn nicht benötige. Wäre super, wenn man das Kommunikationsprotokoll mit anderen Metern nachbauen könnte.

@denjo1982
Copy link

Über den Config-Generator kann man dann auch einzelne Features wie die Nulleinspeisung ein- und ausschalten, egal ob für den v1 oder v2 Speicher. Sobald das Thema Lizenz geklärt ist, werde ich das Tool veröffentlichen, natürlich auch open source.

Screenshot 2024-06-11 at 17 03 34

genau das bräuchte ich, aber wieso lizenz du verkaufst es ja nicht also ist doch alles gut.

@tomquist
Copy link

genau das bräuchte ich, aber wieso lizenz du verkaufst es ja nicht also ist doch alles gut.

Für das Urheberrecht ist es unerheblich ob etwa weiterverkauft wird oder nicht. Es geht darum, dass die config von @noone2k unter Urheberrecht steht und nicht Open Source im Sinne der Definition ist. Die yaml Datei ist zwar öffentlich einsehbar, das heißt aber nicht automatisch, dass sie modifiziert und weiterverbreiten werden darf. Aber genau das würde ich im Source Code des config generators tun. Eine Open Source Lizenz würde die Rahmenbedingungen klar festlegen, unter welchen Bedingungen der source code weiterverbreitet werden darf.

@denjo82
Copy link

denjo82 commented Jun 12, 2024

Okay. Könntest du mir bitte erklären welche yaml Datei ich nehmen muss für mqtt und den v2 "v1.2" Speicher halt ohne HA und ohne nulleinspeisung. Bin nicht der extreme Profi, sorry.

@denjo1982
Copy link

soll ja aber bei line 589 die Daten für den Power Zero eintragen den ich nicht habe? sorry check das nicht ganz.

@vogty79
Copy link

vogty79 commented Jun 12, 2024 via email

@tomquist
Copy link

Ja habe hier eine FRITZ!Box wäre das dann richtig? „ AP2 (2.4 GHz, ath0) - Schnittstelle 1“ wenn ich das dann mitschneide?

Ja, das müsste die richtige Schnittstelle sein. Der Speicher kann ja wohl nur 2.4 GHz

@denjo1982
Copy link

Die hier: https://github.com/noone2k/hm2500pub/blob/master/config/b2500-v2-ble-idf.yaml

könntest du mir das kurz erklären:

` ### 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: 100
    step: 1
    restore_value: True`

@gine78
Copy link

gine78 commented Jun 12, 2024

@denjo1982 Du musst in der yaml nichts eintragen - alle Eintragungen machst du über die Secrets.yaml. Die Einträge für Power Zero sind optional - das wird hier in diesem Thread aber auch irgendwo erklärt.

@denjo1982
Copy link

Sorry für die fragen, aber ich check es nicht. Bin für jede hilfe dankbar.

also ich mache es immer so das ich die daten bearbeite "mqtt, speicher mac, wlan" eintrage und über esphome auf mein esp installiere

image

mache ich das falsch bzw geht es anders??

wenn ich es halt auf meine weise mache will er die Daten vom Power Zero haben.
was ist denn Secrets.yaml. und wie deaktiviere ich power zero??

@gine78
Copy link

gine78 commented Jun 12, 2024

die Secrets.yaml sammelt alle Deine Daten in einer Datei- so dass Du im Quelltext der Haupt.yaml nichts anpassen musst.

image

die Secrets findest Du auch im git.

https://github.com/noone2k/hm2500pub/tree/master/config

@denjo1982
Copy link

ich habe jetzt die secretz datei bearbeitet und gespeichert:

image

dann habe ich die Datei genommen so wie sie ist, also nix geändert und auf den esp installiert:

https://github.com/noone2k/hm2500pub/blob/master/config/b2500-v2-ble-idf.yaml

und dann bekomme ich folgende error meldung:

image

@gine78
Copy link

gine78 commented Jun 12, 2024

Zeig mal Deine Secrets. Datei bitte.

@denjo1982
Copy link

image

@gine78
Copy link

gine78 commented Jun 12, 2024

Du musst die variablen alle drin haben, oder in der Haupt.yaml auskommentieren.

image

Das MUSS alles in der secrets sein. Die Werte unten kannst du einfach so lassen.

@denjo1982
Copy link

achso, dann war das mein fehler. wieder was gelernt. Thanks, es läuft

@tomquist
Copy link

tomquist commented Jun 12, 2024

bis dahin gilt: frei zur nichtkommerziellen nutzung und bei verbreitung müssen änderungen veröffentlicht werden ( was bei einem yaml eigentlich immer zutrifft :) ) ...

Ok, das reicht mir erstmal für eine erste Version. Der config generator ist hier zu finden: https://tomquist.github.io/esphome-b2500/

Aktuell ist es not Alpha Qualität. Es kann durchaus sein, dass invalide config files erzeugt werden, bei bestimmten Kombinationen von settings. Daher bitte ich im feedback. Gerne einfach ein issue im repository öffnen.

Hier ist beschrieben, wie es funktioniert: https://github.com/tomquist/esphome-b2500#usage

Noch zu erwähnen ist, dass der config-generator (fast) zu 100% im Browser arbeitet. Es werden erstmal keine Daten irgendwo hingeschickt, außer wenn man das "Build Image" feature nutzt. Dieses erlaubt es direkt ein image aus der Konfiguration zu bauen. Dafür werden alle secrets RSA/AES verschlüsselt an eine GitHub action geschickt, die diese dann entschlüsselt um das image zu bauen. In den Build-logs sollten alle secrets maskiert werden und das fertige image wird in eine Passwort-geschützte ZIP Datei gepackt.

@robbe1912
Copy link

hallo! schreibt man mit der lösung via MQTT über bluetooth auch immer wieder neu in den flash speicher? wenn man das alle 5-10 sekunden macht geht dieser ja schnell kaputt, und wenn ich nulleinspeisung schaffen möchte, dann soll ja der output fast sekundengenau angepasst werden. ich mache mir sorgen, dass ich die integration mit home assistant schaffe, aber mir der akku in einem jahr abschmiert, da der flash keine writes mehr aushält.

@noone2k
Copy link
Author

noone2k commented Jun 13, 2024

https://gist.github.com/noone2k/2ddea4c9bf116aaaefb8626b064d9a41?permalink_comment_id=5074626#gistcomment-5074626

sollte ich mal in die readme gross reinschreiben ... hier geht das schnell unter ...

die ble-lösung simuliert praktisch die handy app ( vllt. sogar ein bisserl mehr ) und erlaubt damit dann automationen.

für eine echte nulleinspeisung habe ich auf den ct001 gehofft. die funktionalität könnte man ggf. nachbauen.
es häufen sich aber die hinweise, das auch dort in den eprom oder einen anderen dauerhaften speicher geschrieben wird.
es sind aber wie gesagt momentan nur hinweise/anhaltspunkte.
bei ungewissheit sollte man auf nummer sicher gehen und sich an die hersteller-vorgaben halten.

//edit .. es gibt in der firmware noch 1-2 befehle, die noch nicht eindeutig identifiziert sind.
es besteht ne kleine chance, das diese dafür genutzt werden könnten,, da diese sich im nummernkreis der timer/aussteuerung liegen.

@gine78
Copy link

gine78 commented Jun 13, 2024

Ich bin mir garnicht sicher, ob ein Nulleinspeisung mit dem Speicher möglich ist. Meiner Meinung nach, ist der Speicher viel zu träge. Ein Umschalten, des Wertes für den Output, dauert viel zu lange.

@robbe1912
Copy link

dann werde ich mich wahrscheinlich nach einem wechselrichter umschauen müssen wo man den output sekundengenau anpassen kann und einfach den speicher mit voller leistung laufen lassen. habt ihr da empfehlungen?

@Larvy
Copy link

Larvy commented Jun 13, 2024

@robbe1912
Ich nutze einen Hoymiles HMS-2000-4T. Damit klappt die nulleinspeisung sekunden genau +- 5sek
Auch der rest läuft mit 2 Speichern sehr gut. Ich nutze die NWP2500.yaml um die Daten abzugreifen. Und eine OPENDTU-onBattery um den Wechselrichter bei 0 zuhalten. Der Wechselrichter aber probleme mit den Ausgängen 1 so das man eigentlich nur die 2. Outputs der Speicher nutzen kann. Ich habe das Problem aber mit einem Y-Stecker gelöst und damit laufen alle Ausgänge relativ syncron und werden für die 0 Einspeisung gleich reguliert. Und man hat bei 2 Speicher 2kw Nutzlast und nicht nur 1kw.
Screenshot_20240613_115416_Home Assistant
Screenshot_20240613_115425_Home Assistant

@Snotmann
Copy link

hallo! schreibt man mit der lösung via MQTT über bluetooth auch immer wieder neu in den flash speicher? wenn man das alle 5-10 sekunden macht geht dieser ja schnell kaputt, und wenn ich nulleinspeisung schaffen möchte, dann soll ja der output fast sekundengenau angepasst werden. ich mache mir sorgen, dass ich die integration mit home assistant schaffe, aber mir der akku in einem jahr abschmiert, da der flash keine writes mehr aushält.

Ich habe das so gebaut und zwei Wochen am laufen gehabt, funktionierte richtig gut, aber der Speicher wird wohl irgendwann abbrennen bei allen 5 Sekunden neu schreiben.

@Snotmann
Copy link

Ich bin mir garnicht sicher, ob ein Nulleinspeisung mit dem Speicher möglich ist. Meiner Meinung nach, ist der Speicher viel zu träge. Ein Umschalten, des Wertes für den Output, dauert viel zu lange.

ist sehr gut möglich, der Speicher reagiert Sekundenaktuell und blitzschnell

@Snotmann
Copy link

es besteht ne kleine chance, das diese dafür genutzt werden könnten,, da diese sich im nummernkreis der timer/aussteuerung liegen.

welche Werte meinst du genau ?

@gine78
Copy link

gine78 commented Jun 14, 2024

Ich bin mir garnicht sicher, ob ein Nulleinspeisung mit dem Speicher möglich ist. Meiner Meinung nach, ist der Speicher viel zu träge. Ein Umschalten, des Wertes für den Output, dauert viel zu lange.

ist sehr gut möglich, der Speicher reagiert Sekundenaktuell und blitzschnell

Was funktioniert Blitzschnell? Wenn ich den Output setze, dann dauert das gefühlt 5 Minuten, bis er den Output auch wirklich setzt. Wie setzt Du den Output?

@Snotmann
Copy link

Ich bin mir garnicht sicher, ob ein Nulleinspeisung mit dem Speicher möglich ist. Meiner Meinung nach, ist der Speicher viel zu träge. Ein Umschalten, des Wertes für den Output, dauert viel zu lange.

ist sehr gut möglich, der Speicher reagiert Sekundenaktuell und blitzschnell

Was funktioniert Blitzschnell? Wenn ich den Output setze, dann dauert das gefühlt 5 Minuten, bis er den Output auch wirklich setzt. Wie setzt Du den Output?

Ich hab den mit cd=07 blablabla gesetzt in den Speicher direkt, das geht sekundenschnell wie hast du den Wert gesetzt ?

@WolleSoso
Copy link

Hallo miteinander.

Eine Frage. Gibt es hier zu schon ein Addon für openHAB 4...?
Habe mir jetzt einen Marstek B2500 Batteriespeicher angeschafft und möchte diesen in openHAB integrieren.

Danke für die Antwort

@noone2k
Copy link
Author

noone2k commented Jun 14, 2024

diese project ist komplett unabhängig irgendeines smarthome-systems ...
jedes, welches mqtt untersützt, ist nutzbar ...
und wie es der zufall so will: ich nutze das ganze m.h. von openhab ...

@WolleSoso
Copy link

diese project ist komplett unabhängig irgendeines smarthome-systems ... jedes, welches mqtt untersützt, ist nutzbar ... und wie es der zufall so will: ich nutze das ganze m.h. von openhab ...

Kannst du mir dazu einen Leitfaden geben wie du das in openhab eingebunden hast?

@gine78
Copy link

gine78 commented Jun 15, 2024

diese project ist komplett unabhängig irgendeines smarthome-systems ... jedes, welches mqtt untersützt, ist nutzbar ... und wie es der zufall so will: ich nutze das ganze m.h. von openhab ...

Kannst du mir dazu einen Leitfaden geben wie du das in openhab eingebunden hast?

Du kannst die Suchmaschine deines Vertrauens nutzen: openhab mqtt

Um mqtt zu verstehen, solltest du dich damit auseinandersetzen. Am Ende, werden alle Befehle und Values über das mqtt Protokoll versendet und entgegengenommen, deswegen ist dieses Projekt hier auch auf für alle geeignet.

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

ich selbst würde natürlich gerne bei uns im wiki ein tutorial sehen, zu den gebräuchlisten smarthome-system.
da sind dann aber andere gefragt ... tutorials schreiben ist nicht so mein ding ;)

habe dir mal zu openhab ein generelles rausgesucht:
https://bloggingwelt.de/mqtt-in-openhab-3-einrichten/

ansonsten gilt, wie fast überall: erstmal die offizielle dokumentation lesen,
denn tutorials bilden nicht alle möglichkeiten ab, sondern können nur einen kleinen vorgeschmack liefern.
wichtig ist das verstehen der technik ...
wenn man diese versteht kann man auch abseits einer vorlage aufgaben erledigen, die nicht nach schema "f" ablaufen ...

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

habe nochmal schnell aus dem yaml die topics gegreppt und mit sed in eine md-table gepackt.
müsste noch sauber bearbeitet werden und ggf. habe ich das eine oder andere übersehen,
aber im wiki ist jetzt ne liste der (meisten) topics enthalten.

https://github.com/noone2k/hm2500pub/wiki/ESP32-MQTT-TOPICS

möchte hier auch nochmal drauf hinweisen das gerne auch contributionen im wiki gesehen sind.
am besten, wenn jmd. auch hier unterstützung erfahren hat, das er diese dann dort teilt.
dann muss man ein thema nicht immer wiederholen ( vorallem, weil in der kommentarfunktion gerne etwas untergeht ).

//edit
btw. seht die liste nicht als statisch an ... da muss noch viel editiert werden aber ist ein anfang.
auch vorschläge zur umbenennung oder an der level-structur können gemacht werden.
das ist alles noch von den anfangszeiten und einiges ist überholt oder könnte besser einsortiert werden.

//edit 2nd
es gibt die option zur auto-discovery ... wenn die aktiviert ist, sollte auch OH die topics erkennen,
wenn der broker eingerichtet ist.
ich selbst mache das alles manuell, kann daher nicht sagen, was da am ende bei rauskommt.
zumindestens bei HA gibt es schon bestätigungen, das das so halbwegs gut funktioniert ....

@knickohr
Copy link

knickohr commented Jun 16, 2024

@noone2k

Bei den Batterie-Topics ist das X wohl auf die falsche Seite gerutscht ? 😉

Auch nochmal die Frage : Ist es möglich den ESP auch über MQTT manuell zu booten. Würde gerne einen Watchdog in meine Node-Red Flows einbauen wenn die abatterien sich nach X Minuten nicht mehr gemeldet haben. Bei mir steigen die regelmäßig um 3 Uhr nochwas aus 🤔 Ein Reboot des ESPs behebt zu 99% das Problem.

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

jaein, da ging es erstmal um das bereitsstellen der topics ...
und der rest war ein c&p, was da noch alles rein kann ...
bei den cells muss das kreuz in beide spalten ;)

aber ich kann ja für euch auch noch ein bisserl was zum arbeiten übriglassen 😁

der gesuchte reboot ist unter "b2500/esp32/reboot/set" zu finden ... ( bei notes sollen noch beschreibungen rein ) ...
einfach "PRESS" als msg senden ... ( das gilt für alle buttons in esphome ) ...

@WolleSoso
Copy link

ich selbst würde natürlich gerne bei uns im wiki ein tutorial sehen, zu den gebräuchlisten smarthome-system. da sind dann aber andere gefragt ... tutorials schreiben ist nicht so mein ding ;)

habe dir mal zu openhab ein generelles rausgesucht: https://bloggingwelt.de/mqtt-in-openhab-3-einrichten/

ansonsten gilt, wie fast überall: erstmal die offizielle dokumentation lesen, denn tutorials bilden nicht alle möglichkeiten ab, sondern können nur einen kleinen vorgeschmack liefern. wichtig ist das verstehen der technik ... wenn man diese versteht kann man auch abseits einer vorlage aufgaben erledigen, die nicht nach schema "f" ablaufen ...

Vielen Dank für deine Arbeit.

MQTT habe ich schon ein paar Mal eingerichtet, das ist soweit auch nicht das problem.
Woran es oft scheitert sind in openHAB die MQTT State und Command Topics, also die Zustands und Schaltbefehle.
Hierzu habe ich noch nichts gefunden und wenn hier schon einer evtl. ein Addon gebastelt hat greif ich natürlich liebend gerne darauf zurück.

@azazul1980
Copy link

Hallo,

ich hoffe jemand hatte hier auch schon das Problem Mir haut es immer wieder den Timer 3 Raus und der Accu entlädt nicht mehr. Ich habe auch schon verschiedene Regeln eingerichtet das der Controller ( HA Automatisierung) den Timer wieder neu setzen soll. Leider Funktioniert dies äußerst unzuverlässig bzw. übernimmt teilweise nicht die Befehle. Ich kann leider nicht sagen wieso und warum aber es passiert Sporadisch und das mindestens 1x am Tag. Einen Hardwarereset habe ich auch schon durchgeführt hatte aber leider keinen Erfolg gebracht.

@knickohr
Copy link

knickohr commented Jun 16, 2024

„aber ich kann ja für euch auch noch ein bisserl was zum arbeiten übriglassen“

Tja, wenn ich das editieren könnte ohne den ganzen Schlonz erst mal lokal auf meinen PC zu laden … ☹️

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

habe mal editieren im wiki für alle freigegeben ...

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

@azazul1980

es gibt im script eine funktion, die alle timer deaktiviert, sobald eine zelle 3.1V unterschreitet.
das soll helfen, falls die kiste mal nen bms reset hinlegt und die dod-einsttellung somit nicht mehr richtig funktionieren kann.

kann natürlich sein, das es das ist.
wenn zeit dafür, kann ich das switchable machen ...
diese funktionen habe ich eigentlich nur in meinen lokalen v1 scripten,
beim adaptieren für den v2 ist das aber irgendwie mit durchgerutscht
und ich habe das dann gleich für den v2 angepasst ( anstatt rauszunehmen ).

allerdings habe ich bei der kiste noch keinen echten bms reset gesehen.

@azazul1980
Copy link

@noone2k das wird es sein. Dieses Verhalten tritt immer auf wenn der Accu bei < 15 Soc ist. Ich mache jetzt auch eine Kalibrierung des Accus durch.

@noone2k
Copy link
Author

noone2k commented Jun 16, 2024

@knickohr

big thx ... 👍

@knickohr
Copy link

knickohr commented Jun 16, 2024

Noch nicht fertig 😉

V1.2 kann ich nicht viel dazu sagen. Und einige Topics habe ich nicht gefunden 😳 Überbleibsel, Altlasten, Schreibfehler, wasauchimmer …

@knickohr
Copy link

knickohr commented Jun 17, 2024

Tja, wenn die Connand_Topics auch bei den Buttons mit drin wären, würde es auch mit der Nachbarin, ähhh den MQTT-Reboots funktionieren 😉 Wenn ich das richtig gesehen habe fehlen alle esp32-Command_topics.

@noone2k
Copy link
Author

noone2k commented Jun 17, 2024

habe mal gepushed ...

die liste entstand aus meinen lokalen versionen.
anscheinend habe ich da was übersehen, beim aufräumen / einbetten / entfernen ...

einiges von den commands sind auch nicht in den öffentlichen versionen verfügbar ...

ich gehe die liste nochmals durch und entferne sachen. sonst kommt man da durcheinander ...

@knickohr
Copy link

Kein Blutdruck ! Solange ich das noch selbst raus finde und einbauen kann ist alles OK. Nur laufen halt Deine Version und meine immer weiter auseinander. Man kann das jetzt schon nicht mehr automatisch zusammenführen 😢

@noone2k
Copy link
Author

noone2k commented Jun 17, 2024

fehler passieren ... wenn man nicht darauf hingewiesen wird, kann man diese auch nicht beheben ( wenn es welche sind und es notwendig ist ).

mein selbstwertgefühl ist stark genug um fehler einzugestehen 😁

//edit

meine "produktive" version ist auch anders als die im git ... das ist ne grundlage für alle ...
nur funktionen, die allgemein nützlich sind, werden ins git portiert.
und dabei passieren fehler ;)

wenn du was allgemein nützliches hast, kannst du auch pull request machen ( oder fehler für alle korrigieren )...
nicht alle änderungen, die ich hier nutze, sind für alle nützlich ...

@jmk777jmk
Copy link

@noone2k
Erstmal super Arbeit...ich wünschte ich könnte das auch so...
Da ich leider gar nicht programmieren kann und auch eher nur so ein Bisschen in FHEM rum bastele, hab ich versucht über diese Möglichkeit und MQTT die Speicher in FHEM einzubinden, was Dank deiner Arbeit auch super funktioniert hat.
Da der ESP aber alle 5sek published und ich noch eine ganze Menge anderer Sensoren und Aktoren habe, ist der Raspberry recht ausgelastet.
Und daher meine Frage ob und wo man was verändern kann, damit der ESP nicht ganz so viel "redet". Mir würde das durchaus auch alle 30 sek reichen...
schöne Grüße

@noone2k
Copy link
Author

noone2k commented Jun 18, 2024

suche mal im script nach interval ...

bei der version für den v2: https://github.com/noone2k/hm2500pub/blob/c9b159f5cc4d9c7b8cc980e8c650165c81389f42/config/b2500-v2-ble-idf.yaml#L104

habe gerade gesehen, das bei der v1 version noch die timer-funktion des sntp genutzt wird.
da nach "sntp" suchen:
https://github.com/noone2k/hm2500pub/blob/c9b159f5cc4d9c7b8cc980e8c650165c81389f42/config/bc2500-ble-idf.yaml#L87

@jmk777jmk
Copy link

suche mal im script nach interval ...

bei der version für den v2: https://github.com/noone2k/hm2500pub/blob/c9b159f5cc4d9c7b8cc980e8c650165c81389f42/config/b2500-v2-ble-idf.yaml#L104

habe gerade gesehen, das bei der v1 version noch die timer-funktion des sntp genutzt wird. da nach "sntp" suchen: https://github.com/noone2k/hm2500pub/blob/c9b159f5cc4d9c7b8cc980e8c650165c81389f42/config/bc2500-ble-idf.yaml#L87

Klasse ... Danke für den Hinweis

@robbe1912
Copy link

sollte der power knopf am b2500 was machen? in der anleitung steht nichts davon und aus geht der vom drücken nicht. was ist der unterschied zwischen passthrough und charge and discharge? steht auch gar nichts in der anleitung dazu. schon mal vielen dank für die hilfe!
@Larvy soll ich bei den timern in der batterie einfach nur den ersten anhaben und von 0:00 bis 23:59 auf 800W setzen? habe mir jetzt auch einen Hoymiles HMS-2000-4T zugelegt, jetzt fehlen nur noch ein paar verlängerungskabel und das openDTU. spricht was dagegen den wechselrichter output sekundengenau anzupassen? mein auslesegerät am zähler sendet auch jede sekunde updates.
wie sollte ich die solarplatten, die batterie und den wechselrichter am besten zusammenstecken damit diese am effizientesten zusammenarbeiten? Ich habe 4x 415W und 1x 440W, die batterie und jetzt den HMS-2000-4T.

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