Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # =====================================================================
- # Coulombtelling voor 6x Pace BMS (packages/batterij_coulomb.yaml)
- #
- # Gebaseerd op de logica van BEdashboard (coulomb-core-beta.js):
- # * SOC wordt uit stroom geintegreerd (Ah), onafhankelijk van BMS-SOC
- # * automatische ijking aan de randen: >= 95 % (laden) en <= 10 % (ontladen)
- # * handmatig herijken via script.coulomb_herijk
- # Verschil met het BE-script: dat rekent vermogen (W) om naar Ah met een
- # spanningsprofiel. Jouw BMS levert de stroom (A) rechtstreeks, dus dat
- # profiel is hier niet nodig.
- #
- # Vereist in configuration.yaml:
- # homeassistant:
- # packages: !include_dir_named packages
- #
- # Aanname: sensor.pace_bms_bmsN_current is POSITIEF bij laden.
- # Is dat bij jou andersom: zet bij 'initial' van coulomb_stroomteken -1 (of pas
- # de waarde in de UI aan en draai script.coulomb_herijk). NB: 'initial' zet de
- # waarde bij elke herstart terug.
- # =====================================================================
- input_number:
- coulomb_stroomteken:
- name: Coulomb stroomteken (1 = laden positief, -1 = laden negatief)
- min: -1
- max: 1
- step: 2
- initial: 1 # zonder initial begint een input_number op min (= -1)!
- mode: box
- icon: mdi:plus-minus-variant
- coulomb_drempel_stroom:
- name: Coulomb ijking stroomdrempel (A)
- min: 0
- max: 5
- step: 0.1
- initial: 0.3
- mode: box
- unit_of_measurement: A
- icon: mdi:current-dc
- coulomb_bms1_ah0:
- name: Coulomb BMS1 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- coulomb_bms2_ah0:
- name: Coulomb BMS2 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- coulomb_bms3_ah0:
- name: Coulomb BMS3 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- coulomb_bms4_ah0:
- name: Coulomb BMS4 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- coulomb_bms5_ah0:
- name: Coulomb BMS5 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- coulomb_bms6_ah0:
- name: Coulomb BMS6 Ah-stand bij 0 %
- # -1000000 = nog niet geinitialiseerd (wordt automatisch gezet)
- min: -1000000
- max: 1000000
- step: 0.001
- mode: box
- unit_of_measurement: Ah
- icon: mdi:battery-sync
- sensor:
- - platform: integration
- source: sensor.coulomb_bms1_stroom
- name: Coulomb BMS1 Ah
- unique_id: coulomb_bms1_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- - platform: integration
- source: sensor.coulomb_bms2_stroom
- name: Coulomb BMS2 Ah
- unique_id: coulomb_bms2_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- - platform: integration
- source: sensor.coulomb_bms3_stroom
- name: Coulomb BMS3 Ah
- unique_id: coulomb_bms3_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- - platform: integration
- source: sensor.coulomb_bms4_stroom
- name: Coulomb BMS4 Ah
- unique_id: coulomb_bms4_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- - platform: integration
- source: sensor.coulomb_bms5_stroom
- name: Coulomb BMS5 Ah
- unique_id: coulomb_bms5_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- - platform: integration
- source: sensor.coulomb_bms6_stroom
- name: Coulomb BMS6 Ah
- unique_id: coulomb_bms6_ah
- method: trapezoidal
- unit_time: h
- round: 3
- max_sub_interval: "00:00:30"
- template:
- - sensor:
- - name: Coulomb BMS1 stroom
- unique_id: coulomb_bms1_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms1_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms1_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS2 stroom
- unique_id: coulomb_bms2_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms2_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms2_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS3 stroom
- unique_id: coulomb_bms3_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms3_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms3_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS4 stroom
- unique_id: coulomb_bms4_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms4_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms4_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS5 stroom
- unique_id: coulomb_bms5_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms5_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms5_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS6 stroom
- unique_id: coulomb_bms6_stroom
- unit_of_measurement: A
- device_class: current
- state_class: measurement
- availability: "{{ is_number(states('sensor.pace_bms_bms6_current')) }}"
- state: >-
- {{ (states('sensor.pace_bms_bms6_current') | float(0)
- * states('input_number.coulomb_stroomteken') | float(1)) | round(3) }}
- - name: Coulomb BMS1 SOC
- unique_id: coulomb_bms1_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms1_ah'))
- and states('input_number.coulomb_bms1_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms1_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms1_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms1_ah') | float(0)
- - states('input_number.coulomb_bms1_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms1_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms1_ah') | float(0)
- - states('input_number.coulomb_bms1_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms1_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms1_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms1_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms1_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms1_ah') | float(0)
- - states('input_number.coulomb_bms1_ah0') | float(0)) | round(1) }}
- - name: Coulomb BMS2 SOC
- unique_id: coulomb_bms2_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms2_ah'))
- and states('input_number.coulomb_bms2_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms2_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms2_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms2_ah') | float(0)
- - states('input_number.coulomb_bms2_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms2_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms2_ah') | float(0)
- - states('input_number.coulomb_bms2_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms2_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms2_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms2_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms2_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms2_ah') | float(0)
- - states('input_number.coulomb_bms2_ah0') | float(0)) | round(1) }}
- - name: Coulomb BMS3 SOC
- unique_id: coulomb_bms3_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms3_ah'))
- and states('input_number.coulomb_bms3_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms3_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms3_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms3_ah') | float(0)
- - states('input_number.coulomb_bms3_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms3_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms3_ah') | float(0)
- - states('input_number.coulomb_bms3_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms3_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms3_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms3_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms3_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms3_ah') | float(0)
- - states('input_number.coulomb_bms3_ah0') | float(0)) | round(1) }}
- - name: Coulomb BMS4 SOC
- unique_id: coulomb_bms4_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms4_ah'))
- and states('input_number.coulomb_bms4_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms4_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms4_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms4_ah') | float(0)
- - states('input_number.coulomb_bms4_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms4_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms4_ah') | float(0)
- - states('input_number.coulomb_bms4_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms4_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms4_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms4_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms4_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms4_ah') | float(0)
- - states('input_number.coulomb_bms4_ah0') | float(0)) | round(1) }}
- - name: Coulomb BMS5 SOC
- unique_id: coulomb_bms5_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms5_ah'))
- and states('input_number.coulomb_bms5_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms5_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms5_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms5_ah') | float(0)
- - states('input_number.coulomb_bms5_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms5_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms5_ah') | float(0)
- - states('input_number.coulomb_bms5_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms5_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms5_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms5_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms5_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms5_ah') | float(0)
- - states('input_number.coulomb_bms5_ah0') | float(0)) | round(1) }}
- - name: Coulomb BMS6 SOC
- unique_id: coulomb_bms6_soc
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- availability: >-
- {{ is_number(states('sensor.coulomb_bms6_ah'))
- and states('input_number.coulomb_bms6_ah0') | float(-1000000) > -999999
- and states('sensor.pace_bms_bms6_full_capacity') | float(0) > 0 }}
- state: >-
- {% set cap = [states('sensor.pace_bms_bms6_full_capacity') | float(0), 330] | min %}
- {% set ruw = 100 * (states('sensor.coulomb_bms6_ah') | float(0)
- - states('input_number.coulomb_bms6_ah0') | float(0)) / cap %}
- {{ [0, [100, ruw] | min] | max | round(1) }}
- attributes:
- ongeklemd: >-
- {% set cap = [states('sensor.pace_bms_bms6_full_capacity') | float(0), 330] | min %}
- {{ (100 * (states('sensor.coulomb_bms6_ah') | float(0)
- - states('input_number.coulomb_bms6_ah0') | float(0)) / cap) | round(2) }}
- bms_soc: "{{ states('sensor.pace_bms_bms6_soc') | float(none) }}"
- verschil: >-
- {% set b = states('sensor.pace_bms_bms6_soc') | float(none) %}
- {% set c = states('sensor.coulomb_bms6_soc') | float(none) %}
- {{ (c - b) | round(1) if b is not none and c is not none else none }}
- capaciteit_ah: >-
- {{ [states('sensor.pace_bms_bms6_full_capacity') | float(0), 330] | min }}
- ah_resterend: >-
- {{ (states('sensor.coulomb_bms6_ah') | float(0)
- - states('input_number.coulomb_bms6_ah0') | float(0)) | round(1) }}
- - name: Coulomb SOC totaal
- unique_id: coulomb_soc_totaal
- unit_of_measurement: "%"
- state_class: measurement
- icon: mdi:battery-sync
- state: >-
- {% set ns = namespace(ah=0, cap=0, n=0) %}
- {% for i in range(1, 7) %}
- {% set s = states('sensor.coulomb_bms' ~ i ~ '_soc') %}
- {% set cap = [states('sensor.pace_bms_bms' ~ i ~ '_full_capacity') | float(0), 330] | min %}
- {% if is_number(s) and cap > 0 %}
- {% set ns.ah = ns.ah + (s | float) / 100 * cap %}
- {% set ns.cap = ns.cap + cap %}
- {% set ns.n = ns.n + 1 %}
- {% endif %}
- {% endfor %}
- {{ (100 * ns.ah / ns.cap) | round(1) if ns.cap > 0 else none }}
- attributes:
- modules_online: >-
- {% set ns = namespace(n=0) %}
- {% for i in range(1, 7) %}
- {% if is_number(states('sensor.coulomb_bms' ~ i ~ '_soc')) %}{% set ns.n = ns.n + 1 %}{% endif %}
- {% endfor %}
- {{ ns.n }}
- ah_resterend: >-
- {% set ns = namespace(ah=0) %}
- {% for i in range(1, 7) %}
- {% set a = state_attr('sensor.coulomb_bms' ~ i ~ '_soc', 'ah_resterend') %}
- {% if is_number(a) %}{% set ns.ah = ns.ah + (a | float) %}{% endif %}
- {% endfor %}
- {{ ns.ah | round(1) }}
- automation:
- - id: coulomb_ijking
- alias: Coulomb ijking (initialisatie en randen 10 % / 95 %)
- description: >-
- Zet de Ah-stand bij 0 % zodat de Coulomb-SOC gelijk is aan de BMS-SOC
- (1) bij eerste gebruik, (2) bij laden boven 95 % en (3) bij ontladen
- onder 10 %. Daartussen telt de Coulombtelling zelfstandig verder.
- Bij een wijziging van de BMS-SOC wordt alleen die module bekeken; bij
- HA-start en elke 5 minuten alle zes.
- mode: queued
- max: 20
- triggers:
- - trigger: state
- entity_id:
- - sensor.pace_bms_bms1_soc
- - sensor.pace_bms_bms2_soc
- - sensor.pace_bms_bms3_soc
- - sensor.pace_bms_bms4_soc
- - sensor.pace_bms_bms5_soc
- - sensor.pace_bms_bms6_soc
- - trigger: homeassistant
- event: start
- # vangnet: initialisatie lukt pas als de integratiesensor een waarde heeft
- - trigger: time_pattern
- minutes: "/5"
- actions:
- - repeat:
- for_each: >-
- {{ [trigger.entity_id | replace('sensor.pace_bms_bms', '') | replace('_soc', '') | int]
- if trigger.entity_id is defined else [1, 2, 3, 4, 5, 6] }}
- sequence:
- - variables:
- raw: "{{ states('sensor.pace_bms_bms' ~ repeat.item ~ '_soc') }}"
- ah: "{{ states('sensor.coulomb_bms' ~ repeat.item ~ '_ah') }}"
- cur: "{{ states('sensor.coulomb_bms' ~ repeat.item ~ '_stroom') }}"
- fcc: "{{ states('sensor.pace_bms_bms' ~ repeat.item ~ '_full_capacity') }}"
- ah0: "{{ states('input_number.coulomb_bms' ~ repeat.item ~ '_ah0') | float(-1000000) }}"
- drempel: "{{ states('input_number.coulomb_drempel_stroom') | float(0.3) }}"
- inputs_ok: "{{ is_number(raw) and is_number(ah) and is_number(cur) and is_number(fcc) and (fcc | float) > 0 }}"
- cap: "{{ [fcc | float(0), 330] | min }}"
- ongeinitialiseerd: "{{ ah0 <= -999999 }}"
- rand_hoog: "{{ inputs_ok and (raw | float) >= 95 and (cur | float) >= -drempel }}"
- rand_laag: "{{ inputs_ok and (raw | float) <= 10 and (cur | float) <= drempel }}"
- - if:
- - condition: template
- value_template: "{{ inputs_ok and (ongeinitialiseerd or rand_hoog or rand_laag) }}"
- then:
- - action: input_number.set_value
- target:
- entity_id: "input_number.coulomb_bms{{ repeat.item }}_ah0"
- data:
- value: "{{ ((ah | float) - (raw | float) / 100 * cap) | round(3) }}"
- script:
- coulomb_herijk:
- alias: Coulomb herijken
- description: >-
- Zet de Coulomb-SOC van een module (of alle modules) gelijk aan een
- opgegeven SOC. Laat SOC leeg om de SOC van de BMS over te nemen.
- icon: mdi:battery-sync
- mode: queued
- fields:
- module:
- name: Module
- description: 0 = alle modules, 1 t/m 6 = een enkele module
- default: 0
- selector:
- number:
- min: 0
- max: 6
- mode: box
- soc:
- name: SOC (%)
- description: Leeg laten = SOC van de BMS gebruiken
- required: false
- selector:
- number:
- min: 0
- max: 100
- step: 0.1
- mode: box
- sequence:
- - repeat:
- for_each: >-
- {{ [module | int(0)] if (module | int(0)) > 0 else [1, 2, 3, 4, 5, 6] }}
- sequence:
- - variables:
- ah: "{{ states('sensor.coulomb_bms' ~ repeat.item ~ '_ah') }}"
- fcc: "{{ states('sensor.pace_bms_bms' ~ repeat.item ~ '_full_capacity') }}"
- doel: >-
- {{ soc if soc is defined and is_number(soc)
- else states('sensor.pace_bms_bms' ~ repeat.item ~ '_soc') }}
- - if:
- - condition: template
- value_template: "{{ is_number(ah) and is_number(fcc) and is_number(doel) and (fcc | float) > 0 }}"
- then:
- - action: input_number.set_value
- target:
- entity_id: "input_number.coulomb_bms{{ repeat.item }}_ah0"
- data:
- value: "{{ ((ah | float) - (doel | float) / 100 * ([fcc | float, 330] | min)) | round(3) }}"
Advertisement
Add Comment
Please, Sign In to add comment