JKBMS s Pylontech simulací
Souhrn tématu
V diskusi je popsáno, jak připojit pět let starý JKBMS k měniči s Pylontech protokolem pomocí ESPHome a ESP32. Autor využívá UART GPS port JKBMS a RS485 optoizolátor pro simulaci Pylontech baterie, čímž umožňuje monitorování bez nutnosti kupovat nový BMS. Sdílený kód a nastavení pomáhají zájemcům integrovat starší JKBMS do moderních systémů s Pylontech protokolem.
-
proasnet
- Příspěvky: 425
- Registrován: čtv kvě 27, 2021 12:06 pm
- Reputace: 43
- Lokalita: Rajecké Teplice
- Systémové napětí: 48V
- Výkon panelů [Wp]: 5000
- Kapacita baterie [kWh]: 14,5
JKBMS s Pylontech simulací
Už tu je něco podobného nespočetněkrát, ale jestli to někomu pomůže, řešil jsem jak připojit svoji 5 letou JKBMS k měniči s pylontech protokolem, která už byla monitorovaná pomocí ESPHome.
Samotná BMS nemá RS485, jenom port GPS (UART) a tam jsem měl připojený ESP32. Kupovat novou s pylontech se mi nechtělo, tak jsem hledal řešení, jak to zkloubit do jednoho ESP.
K ESP kromě JKBMS je připojený také RS485 optoizolátor, který je následně připojený k měniči, a ten vidí Pylontech baterii
Samotná BMS nemá RS485, jenom port GPS (UART) a tam jsem měl připojený ESP32. Kupovat novou s pylontech se mi nechtělo, tak jsem hledal řešení, jak to zkloubit do jednoho ESP.
K ESP kromě JKBMS je připojený také RS485 optoizolátor, který je následně připojený k měniči, a ten vidí Pylontech baterii
Kód: Vybrat vše
substitutions:
name: "jk-bms"
device_description: "Monitor a JK-BMS using the GPS port (UART-TTL)"
external_components_source: github://syssi/esphome-jk-bms@main
esphome:
name: ${name}
comment: ${device_description}
min_version: 2024.6.0
project:
name: "syssi.esphome-jk-bms"
version: 2.1.0
esp32:
board: wemos_d1_mini32
framework:
type: esp-idf
external_components:
- source: ${external_components_source}
refresh: 0s
- source: github://fahmula/esphome-pylontech-rs485@main
refresh: 0s
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "JKBMS"
password: "Jirutka8011"
captive_portal:
web_server:
port: 80
auth:
username: !secret web_server_username
password: !secret web_server_password
ota:
- platform: esphome
- platform: web_server
logger:
level: DEBUG
api:
globals:
- id: g_heartbeat_enabled
type: bool
restore_value: yes
initial_value: 'true'
- id: g_force_charge_requested
type: bool
restore_value: yes
initial_value: 'false'
- id: g_max_v
type: float
restore_value: yes
initial_value: '54.5'
- id: g_min_v
type: float
restore_value: yes
initial_value: '48.0'
- id: g_max_charge_i
type: float
restore_value: yes
initial_value: '80.0'
- id: g_max_discharge_i
type: float
restore_value: yes
initial_value: '120.0'
time:
- platform: sntp
id: sntp_time
servers: "pool.ntp.org"
uart:
- id: uart_0
baud_rate: 115200
rx_buffer_size: 384
tx_pin: GPIO17
rx_pin: GPIO16
- id: pylontech
tx_pin: GPIO22
rx_pin: GPIO21
baud_rate: 9600
jk_modbus:
- id: modbus0
uart_id: uart_0
rx_timeout: 50ms
jk_bms:
- id: bms0
jk_modbus_id: modbus0
update_interval: 5s
sensor:
# JKBMS
- platform: jk_bms
total_voltage:
name: "bms0 total voltage"
id: bms_total_voltage
min_cell_voltage:
name: "${name} min cell voltage"
id: bms_min_cell_voltage
internal: true
max_cell_voltage:
name: "${name} max cell voltage"
id: bms_max_cell_voltage
internal: true
current:
name: "bms0 current"
id: bms_current
power:
name: "bms0 power"
id: bms0_power
temperature_sensor_1:
name: "bms0 temperature sensor 1"
id: bms_temperature_1
temperature_sensor_2:
name: "bms0 temperature sensor 2"
id: bms_temperature_2
power_tube_temperature:
name: "bms0 power tube temperature"
id: bms_mosfet_temp
capacity_remaining:
name: "bms0 capacity remaining"
id: bms_capacity
charging_cycles:
name: "bms0 charging cycles"
id: bms_cycles
errors_bitmask:
name: "bms0 errors bitmask"
id: bms_errors_bitmask
cell_voltage_1:
name: "bms0 cell voltage 1"
id: bms_cell_voltage_1
cell_voltage_2:
name: "bms0 cell voltage 2"
id: bms_cell_voltage_2
cell_voltage_3:
name: "bms0 cell voltage 3"
id: bms_cell_voltage_3
cell_voltage_4:
name: "bms0 cell voltage 4"
id: bms_cell_voltage_4
cell_voltage_5:
name: "bms0 cell voltage 5"
id: bms_cell_voltage_5
cell_voltage_6:
name: "bms0 cell voltage 6"
id: bms_cell_voltage_6
cell_voltage_7:
name: "bms0 cell voltage 7"
id: bms_cell_voltage_7
cell_voltage_8:
name: "bms0 cell voltage 8"
id: bms_cell_voltage_8
cell_voltage_9:
name: "bms0 cell voltage 9"
id: bms_cell_voltage_9
cell_voltage_10:
name: "bms0 cell voltage 10"
id: bms_cell_voltage_10
cell_voltage_11:
name: "bms0 cell voltage 11"
id: bms_cell_voltage_11
cell_voltage_12:
name: "bms0 cell voltage 12"
id: bms_cell_voltage_12
cell_voltage_13:
name: "bms0 cell voltage 13"
id: bms_cell_voltage_13
cell_voltage_14:
name: "bms0 cell voltage 14"
id: bms_cell_voltage_14
cell_voltage_15:
name: "bms0 cell voltage 15"
id: bms_cell_voltage_15
cell_voltage_16:
name: "bms0 cell voltage 16"
id: bms_cell_voltage_16
- platform: template
name: "BMS Charging current"
id: "bms_charging_current"
unit_of_measurement: W
lambda: |-
if(id(bms0_power).state > 0 ) {
return id(bms0_power).state;
} else return 0;
- platform: template
name: "BMS Discharging current"
id: "bms_discharging_current"
unit_of_measurement: W
lambda: |-
if(id(bms0_power).state < 0 ) {
return (id(bms0_power).state * -1);
} else return 0;
# Energie
- platform: total_daily_energy
name: BMS Charging Energy
state_class: total_increasing
device_class: energy
unit_of_measurement: kWh
accuracy_decimals: 2
power_id: bms_charging_current
restore: True
filters:
- multiply: 0.001
- platform: total_daily_energy
name: BMS Discharging Energy
state_class: total_increasing
device_class: energy
unit_of_measurement: kWh
accuracy_decimals: 2
power_id: bms_discharging_current
restore: True
filters:
- multiply: 0.001
- platform: template
id: link_heartbeat
name: "Inverter Heartbeat"
unit_of_measurement: "ms"
icon: "mdi:heart-pulse"
- platform: template
id: live_max_v
lambda: return id(input_max_v).state;
unit_of_measurement: "V"
update_interval: 3s
- platform: template
id: live_min_v
lambda: return id(input_min_v).state;
unit_of_measurement: "V"
update_interval: 3s
- platform: template
id: live_max_charge_i
lambda: return id(input_max_charge_i).state;
unit_of_measurement: "A"
update_interval: 3s
- platform: template
id: live_max_discharge_i
lambda: return id(input_max_discharge_i).state;
unit_of_measurement: "A"
update_interval: 3s
number:
- platform: template
id: input_max_v
name: "BMS Max Voltage"
unit_of_measurement: "V"
update_interval: 3s
min_value: 50.0
max_value: 58.6
mode: BOX
step: 0.1
lambda: return id(g_max_v);
set_action:
- globals.set:
id: g_max_v
value: !lambda 'return x;'
- platform: template
id: input_min_v
name: "BMS Min Voltage"
unit_of_measurement: "V"
update_interval: 3s
min_value: 44.0
max_value: 48.0
mode: BOX
step: 0.1
lambda: return id(g_min_v);
set_action:
- globals.set:
id: g_min_v
value: !lambda 'return x;'
- platform: template
id: input_max_charge_i
name: "BMS Max Charge Current"
unit_of_measurement: "A"
update_interval: 3s
min_value: 0.0
max_value: 120.0
mode: BOX
step: 0.5
lambda: return id(g_max_charge_i);
set_action:
- globals.set:
id: g_max_charge_i
value: !lambda 'return x;'
- platform: template
id: input_max_discharge_i
name: "BMS Max Discharge Current"
unit_of_measurement: "A"
update_interval: 3s
min_value: 0.0
max_value: 120.0
mode: BOX
step: 0.5
lambda: return id(g_max_discharge_i);
set_action:
- globals.set:
id: g_max_discharge_i
value: !lambda 'return x;'
binary_sensor:
- platform: jk_bms
balancing:
name: "bms0 balancing"
balancing_switch:
name: "bms0 balancing switch"
charging:
name: "bms0 charging"
discharging:
name: "bms0 discharging"
dedicated_charger_switch:
name: "bms0 dedicated charger switch"
online_status:
name: "bms0 online status"
- platform: template
id: rs485_link_status
name: "RS485 Link Status"
device_class: connectivity
- platform: template
id: bms_cell_ov
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x01;"
internal: true
- platform: template
id: bms_cell_uv
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x02; "
internal: true
- platform: template
id: bms_total_ov
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x04;"
internal: true
- platform: template
id: bms_total_uv
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x08;"
internal: true
- platform: template
id: bms_chg_oc
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x10;"
internal: true
- platform: template
id: bms_dischg_oc
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x20;"
internal: true
- platform: template
id: bms_temp_high
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x140;" # Bity 6 (chg) a 8 (dischg)
internal: true
- platform: template
id: bms_temp_low
lambda: "return (uint32_t)id(bms_errors_bitmask).state & 0x280;" # Bity 7 (chg) a 9 (dischg)
internal: true
switch:
- platform: jk_bms
charging:
name: "${name} charging"
discharging:
name: "${name} discharging"
# balancer:
# name: "bms0 balancer"
- platform: template
name: "Enable Inverter Heartbeat Sensor"
id: link_heartbeat_enable
lambda: return id(g_heartbeat_enabled);
turn_on_action:
- globals.set: { id: g_heartbeat_enabled, value: 'true' }
turn_off_action:
- globals.set: { id: g_heartbeat_enabled, value: 'false' }
text_sensor:
# JKBMS
- platform: jk_bms
errors:
name: "bms0 errors"
total_runtime_formatted:
name: "bms0 total runtime formatted"
button:
# JKBMS
- platform: restart
name: "ESP_Restart"
pylontech_rs485:
uart_id: pylontech
update_timeout: 60s
# --- RS485 Link Monitoring ---
rs485_status: rs485_link_status
inverter_heartbeat: link_heartbeat
heartbeat_switch: link_heartbeat_enable
# --- Link ALL sensors to the component ---
# Core data
state_of_charge: bms_capacity
voltage: bms_total_voltage
current: bms_current
temperature: bms_temperature_1
# Health data
cycle_count: bms_cycles
# Cell voltage data
max_cell_voltage: bms_max_cell_voltage
min_cell_voltage: bms_min_cell_voltage
# MOSFET temperature data
mosfet_temperature: bms_mosfet_temp
# BMS temperature data
bms_temperature: bms_temperature_1
# Alarms and warnings
# Alarm Status 1
total_voltage_high_alarm: bms_total_ov
total_voltage_low_alarm: bms_total_uv
cell_voltage_high_alarm: bms_cell_ov
cell_voltage_low_alarm: bms_cell_uv
#cell_temp_high_alarm: alarm_cell_temp_high
#cell_temp_low_alarm: alarm_cell_temp_low
#mosfet_temp_high_alarm: alarm_mosfet_temp_high
#cell_imbalance_alarm: alarm_cell_imbalance
charge_overcurrent_alarm: bms_chg_oc
discharge_overcurrent_alarm: bms_dischg_oc
# Alarm Status 2
#cell_temp_imbalance_alarm: alarm_cell_temp_imbalance
#charge_overcurrent_alarm: alarm_charge_over_current
#discharge_overcurrent_alarm: alarm_discharge_over_current
# Protection Status 1
#module_overvoltage_protection: protection_module_overvoltage
#module_undervoltage_protection: protection_module_undervoltage
#cell_overvoltage_protection: protection_cell_overvoltage
#cell_undervoltage_protection: protection_cell_undervoltage
#cell_overtemp_protection: protection_cell_over_temperature
#cell_undertemp_protection: protection_cell_under_temperature
#mosfet_overtemp_protection: protection_mosfet_over_temperature
# Protection Status 2
#charge_overcurrent_protection: protection_charge_over_current
#discharge_overcurrent_protection: protection_discharge_over_current
#system_fault_protection: protection_system_fault
# Dynamic battery limits (for command 63)
max_voltage: live_max_v
min_voltage: live_min_v
max_charge_current: live_max_charge_i
max_discharge_current: live_max_discharge_i
#requested_force_charge: my_force_charge_sensorOffgrid 11kW, Lifepo4
Kdo je online
Uživatelé prohlížející si toto fórum: Claudebot [Bot] a 0 hostů