Homevolt package 🔋

I’m started to collect my Homevolt battery sensors from the local webserver in a package to access all data in Home-Assistant.

Please use if want, and post comments or improvements.:battery: :electric_plug::zap:

Invite: https://invite.tibber.com/zg5s6hew


  • Enable local webserver on Homevolt
  • Enabled at start or 3s press on left button under the hood
  • Navigate to Homevolt local webserver by http://ip-address
  • Force local webserver to enabled in Params
  • Turn on password, if desired
  • Turn on secure http, if desired
  • Store Params to flash
Guide in swedish

Wi-Fi-guide

Om ditt batteri har dÄlig LTE-anslutning som orsakar lÄngsamma eller misslyckade uppdateringar, kan du manuellt stÀlla in Wi-Fi via batteriets portal:
Aktivera servicelÀge

  • HĂ„ll in knappen pĂ„ vĂ€nstra sidan av vĂ€xelriktaren i 3 sekunder.
  • Anslut till batteriets Wi-Fi
  • Öppna Wi-Fi-instĂ€llningarna pĂ„ din telefon.
  • Anslut till nĂ€tverket som heter HVSM-<QR-kod pĂ„ batteriet>.
  • Konfigurera Wi-Fi via portalen
  • NĂ€r du Ă€r ansluten bör en portal öppnas automatiskt.
  • Klicka “Konfigurera Wi-Fi”.
  • VĂ€lj och anslut till kundens Wi-Fi-nĂ€tverk.

Om portalen inte öppnas automatiskt:

  • Öppna en webblĂ€sare och navigera till: http://10.133.70.1/ eller http://homevolt-.local
  • Hitta serienumret pĂ„ vĂ€xelriktarens förpackning:
  • Det börjar med 68b och ser ut som 68b6b34dcbac

Using custom components in package to calculate income:

to include packages folder to config.

homeassistant:
    packages: !include_dir_named packages

Secrets file

  • Change to http without s if not using local cert
  • Change ip-address in the file.
homevolt_status: "https://192.168.1.100/status.json"
homevolt_ems: "https://192.168.1.100/ems.json"
homevolt_error: "https://192.168.1.100/error_report.json"
homevolt_schedule: "https://192.168.1.100/schedule.json"
homevolt_params: "https://192.168.1.100/params.json"
homevolt_logs: "https://192.168.1.100/logs.json"
homevolt_pass: "password_in_local_webserver"

packages\homevolt.yaml

### Homevolt package
# updated 2025-03-17

# Custom changes
# Uses nordpool integration for the sensor:
#      sensor.nordpool_kwh_se3_sek_3_095

# ip and password in command_line curl
# price for battery and purchased day


# ------------------------------------------------ #
# REST integration
rest:
- resource: !secret homevolt_status
  username: "admin"
  password: !secret homevolt_pass
  verify_ssl: false
  scan_interval: 300
  timeout: 30
  sensor:
  - name: "Homevolt status"
    value_template: "{{ value_json.uptime if 'uptime' in value_json }}"
    icon: "mdi:battery-clock"
    json_attributes:
    - uptime
    - wifi_status
    - lte_status
    - mqtt_status
    - w868_status
    - ems_status
  - name: "Homevolt LTE cellid"
    value_template: >-
      {{ ((value_json.lte_status.cell_id) | replace('"','')) if value_json is defined }}
    icon: "mdi:sim"

- resource: !secret homevolt_ems
  username: "admin"
  password: !secret homevolt_pass
  verify_ssl: false
  scan_interval: 30
  timeout: 30
  sensor:
  - name: "Homevolt EMS"
    value_template: "{{ value_json.ems[0].ems_data.state_str }}"
    icon: >-
      mdi:battery-{{ int((float(value_json.ems[0].ems_data.soc_avg)/100) | round(-1), 0)
        if not float(value_json.ems[0].ems_data.soc_avg) < 5 else 'outline' }}
    json_attributes: 
    - ems
    - aggregated
    - sensors
  - name: "Homevolt EMS error"
    value_template: "{{ (value_json.ems[0].error_str)[:255] }}"
    icon: "mdi:battery-unknown"
    json_attributes_path: "$.ems[0]"
    json_attributes: 
    - error_str
  - name: "Homevolt EMS varning"
    value_template: "{{ (value_json.ems[0].ems_data.warning_str | join(', ') | replace('_', ' ') | replace('ems', 'EMS'))[:255] }}"
    icon: "mdi:battery-unknown"
    json_attributes_path: "$.ems[0].ems_data"
    json_attributes: 
    - warning_str
  - name: "Homevolt EMS info"
    value_template: "{{ (value_json.ems[0].ems_data.info_str | join(', ') | replace('_', ' ') | replace('ems', 'EMS'))[:255] }}"
    icon: "mdi:battery-unknown"
    json_attributes_path: "$.ems[0].ems_data"
    json_attributes: 
    - info_str
  - name: "Homevolt temperatur"
    value_template: "{{ float(value_json.ems[0].ems_data.sys_temp,0)/10 }}"
    icon: "mdi:battery-heart-variant"
    unit_of_measurement: '°C'
    device_class: temperature
  - name: "Homevolt spÀnning L1"
    value_template: "{{ value_json.ems[0].ems_voltage.l1 /10 }}"
    unit_of_measurement: 'V'
    icon: "mdi:meter-electric-outline"
    device_class: voltage
  - name: "Homevolt frekvens"
    value_template: "{{ value_json.ems[0].ems_data.frequency /1000 }}"
    unit_of_measurement: 'Hz'
    icon: "mdi:meter-electric-outline"
    device_class: frequency
  - name: "Homevolt effekt"
    value_template: "{{ value_json.ems[0].ems_data.power }}"
    unit_of_measurement: 'W'
    icon: "mdi:battery-sync-outline"
    device_class: power
  - name: "Homevolt energi producerat"
    value_template: "{{ value_json.ems[0].ems_data.energy_produced /1000 }}"
    unit_of_measurement: 'kW'
    icon: "mdi:battery-positive"
    device_class: power
  - name: "Homevolt energi konsumerat"
    value_template: "{{ value_json.ems[0].ems_data.energy_consumed /1000 }}"
    unit_of_measurement: 'kW'
    icon: "mdi:battery-negative"
    device_class: power
  
  - name: "Homevolt effekt tillgÀnglig"
    value_template: >-
      {{
      float(value_json.ems[0].ems_prediction.avail_ch_pwr,0) - 
      float(value_json.ems[0].ems_prediction.avail_di_pwr,0)
      }}
    unit_of_measurement: 'kW'
    icon: "mdi:battery-negative"
    device_class: power
    json_attributes_path: "$.ems[0].ems_prediction"
    json_attributes: 
    - avail_ch_pwr
    - avail_di_pwr

  - name: "Homevolt konsumerat"
    value_template: "{{ value_json.ems[0].ems_aggregate.exported_kwh }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-positive"
    device_class: energy
    state_class: total
  - name: "Homevolt producerat"
    value_template: "{{ value_json.ems[0].ems_aggregate.imported_kwh }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-negative"
    device_class: energy
    state_class: total

  - name: "Homevolt bat0"
    value_template: "{{ float(value_json.ems[0].bms_data[0].soc)/100 }}"
    unit_of_measurement: '%'
    icon: "mdi:battery-{{ float(value_json.ems[0].bms_data[1].soc)/100 | round(-1) }}"
  - name: "Homevolt bat1"
    value_template: "{{ float(value_json.ems[0].bms_data[1].soc)/100 }}"
    unit_of_measurement: '%'
    icon: "mdi:battery-{{ float(value_json.ems[0].bms_data[1].soc)/100 | round(-1) }}"
  - name: "Homevolt bat0 laddningar"
    value_template: "{{ value_json.ems[0].bms_data[0].cycle_count }}"
    icon: "mdi:battery"
    
  # Pulse CT
  - name: "Homevolt nÀteffekt"
    value_template: "{{ value_json.sensors[0].total_power }}"
    unit_of_measurement: 'W'
    icon: "mdi:battery-negative"
    device_class: power
    state_class: measurement
    json_attributes_path: "$.sensors[0]"
    json_attributes: 
    - phase
  - name: "Homevolt nÀt konsumerat"
    value_template: "{{ value_json.sensors[0].energy_imported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-negative"
    device_class: energy
    state_class: total
  - name: "Homevolt nÀt producerat"
    value_template: "{{ value_json.sensors[0].energy_exported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-positive"
    device_class: energy
    state_class: total
  - name: "Homevolt solcell effekt"
    value_template: "{{ value_json.sensors[1].total_power }}"
    unit_of_measurement: 'W'
    icon: "mdi:battery-positive"
    device_class: power
    state_class: measurement
    json_attributes_path: "$.sensors[1]"
    json_attributes: 
    - phase
  - name: "Homevolt solcell konsumerat"
    value_template: "{{ value_json.sensors[1].energy_imported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-negative"
    device_class: energy
    state_class: total
  - name: "Homevolt solcell producerat"
    value_template: "{{ value_json.sensors[1].energy_exported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-positive"
    device_class: energy
    state_class: total
  - name: "Homevolt hushÄlleffekt"
    value_template: "{{ value_json.sensors[2].total_power }}"
    unit_of_measurement: 'W'
    icon: "mdi:battery-negative"
    device_class: power
    state_class: measurement
    json_attributes_path: "$.sensors.[2]"
    json_attributes: 
    - phase
  - name: "Homevolt batteri konsumerat"
    value_template: "{{ value_json.sensors[2].energy_imported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-negative"
    device_class: energy
    state_class: total
  - name: "Homevolt batteri producerat"
    value_template: "{{ value_json.sensors[2].energy_exported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-positive"
    device_class: energy
    state_class: total

- resource: !secret homevolt_schedule
  username: "admin"
  password: !secret homevolt_pass
  verify_ssl: false
  scan_interval: 1800
  sensor:
  - name: "Homevolt schema"
    value_template: >-
      {{ (value_json.schedule | rejectattr('from', '>', (now().timestamp())) | rejectattr('to', '<', (now().timestamp())) | map(attribute='type') | 
      first |
      replace('1', 'Ladda, uttag:') | replace('3', 'VĂ€nta') | replace('4', 'NĂ€t urladdning, ') | replace('2', 'Urladdning, ')) if 'schedule' in value_json
      }} {{ (value_json.schedule | rejectattr('from', '>', (now().timestamp())) | rejectattr('to', '<', (now().timestamp())) | map(attribute='params.setpoint') | first) ~'W' if 'schedule' in value_json and
        (value_json.schedule | rejectattr('from', '>', (now().timestamp())) | rejectattr('to', '<', (now().timestamp())) | map(attribute='params.setpoint') | first) > 0
      }}
    icon: >-
      {% set type = (value_json.schedule | rejectattr('from', '>', (now().timestamp())) | rejectattr('to', '<', (now().timestamp())) | map(attribute='type') | first) %}
      {{ 'mdi:battery-positive' if type == 1 }}
      {{ 'mdi:battery-negative' if type == 2 or type == 4 }}
      {{ 'mdi:battery-clock-outline' if type == 3 }}
    json_attributes: 
    - local_mode
    - schedule
    - schedule_id
  - name: "Homevolt schema nÀsta"
    value_template: >-
      {{ (time_until(as_datetime(float(value_json.schedule[1].from,0)),1)) if 'schedule' in value_json
      }}
      {{ (value_json.schedule[1].type |
      replace('1', 'Ladda, uttag:') | replace('3', 'VĂ€nta') | replace('4', 'NĂ€t urladdning, ') | replace('2', 'Urladdning, ')) if 'schedule' in value_json
      }}{{ (value_json.schedule[1].params.setpoint ) ~'W' if 'schedule' in value_json and 'setpoint' in value_json.schedule[1].params
      }}
    icon: "mdi:calendar-clock-outline"
    
# ------------------------------------------------ #
# Command line integration
# used to fetch json array
command_line:
- sensor:
    name: "Homevolt logs"
    scan_interval: 600
    icon: "mdi:text"
    command: >
      echo "{\"logs\":" $(curl -sk -u 'admin:password' https://192.168.1.100/logs.json) "}"
    value_template: >-
      Error: {{ value_json.logs | selectattr('level','eq', 'error') | list | count }}, 
      Warning: {{ value_json.logs | selectattr('level','eq', 'warning') | list | count }}, 
      Info: {{ value_json.logs| selectattr('level','eq', 'info') | list | count }}, 
      Total: {{ value_json.logs | length if value_json is defined }}
    json_attributes:
      - logs
    # password in curl
      
- sensor:
    name: "Homevolt parametrar"
    scan_interval: 7200
    icon: "mdi:console-line"
    command: >
      echo "{\"params\":" $(curl -sk -u 'admin:password' https://192.168.1.100/params.json) "}"
    value_template: >-
      {{ value_json.params | length if value_json is defined }}
    json_attributes:
      - params
    # password in curl
      
- sensor:
    name: "Homevolt errors"
    scan_interval: 600
    icon: "mdi:battery-alert-variant-outline"
    command: >
      echo "{\"errors\":" $(curl -sk -u 'admin:password' https://192.168.1.100/error_report.json) "}"
    value_template: >-
      {{ (value_json.errors |
      rejectattr('message','in', 
        ['','Throttled','idle','up2date','Rev:1 (435 mV)','Protocol version: 5']) | 
      rejectattr('message','contains', 'OK') | 
      rejectattr('message','contains', 'online') |
      rejectattr('message','contains', 'No ') | 
      rejectattr('message','contains', ' 100.00%') | 
      rejectattr('message','contains', 'RSSI ') | 
      rejectattr('message','contains', ' valid') | 
      rejectattr('message','contains', ' available') | 
      map(attribute='message') | list | join(', '))[:255] 
      if value_json is defined }}
    json_attributes:
      - errors

- sensor:
    name: "Homevolt console"
    scan_interval: 2592000
    icon: "mdi:console"
    command: >-
      echo "{\"result\": \"$( curl -sk -u admin:password -X POST --form cmd='{{
      states('input_text.homevolt_cmd') if
        states('input_text.homevolt_cmd') in ['time uptime','help'] or
        states('input_text.homevolt_cmd').startswith('echo')
        else
        'echo command not accepted to send by HA'
      }}' https://192.168.1.100/console.json | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g' )\"}"
    value_template: >-
      {{ value_json.result[:255] }}
    json_attributes:
      - result
# password in curl


# ------------------------------------------------ #
# Template integration
template:
- sensor:
    name: "Homevolt intÀkt momentant"
    unit_of_measurement: "SEK"
    state: >-
      {{ float(states('sensor.nordpool_kwh_se3_sek_3_095'), 0) * (float(states('sensor.homevolt_effekt'), 0)/1000) | round(2) }}
    device_class: monetary
    icon: "mdi:cash"
- sensor:
    name: "Homevolt nÀt L1"
    unit_of_measurement: "A"
    state: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[0].amp, 0) }}"
    device_class: current
    state_class: measurement
    icon: "mdi:current-ac"
    attributes:
      power: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[0].power,0)  }}"
      volt: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[0].voltage,0)  }}"
- sensor:
    name: "Homevolt nÀt L2"
    unit_of_measurement: "A"
    state: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[1].amp, 0) }}"
    device_class: current
    state_class: measurement
    icon: "mdi:current-ac"
    attributes:
      power: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[1].power,0)  }}"
      volt: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[1].voltage,0)  }}"
- sensor:
    name: "Homevolt nÀt L3"
    unit_of_measurement: "A"
    state: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[2].amp, 0) }}"
    device_class: current
    state_class: measurement
    icon: "mdi:current-ac"
    attributes:
      power: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[2].power,0)  }}"
      volt: "{{ float(state_attr('sensor.homevolt_nateffekt', 'phase')[2].voltage,0)  }}"

- trigger:
  - platform: time_pattern
    hours: "/1"
  sensor:
    name: "Homevolt Ă„terbetalning"
    unit_of_measurement: "SEK"
    state: >-
      {{ float(states('sensor.homevolt_intakt'),0) + float(this.attributes.gridrewards_per_dygn | default(0),0)* int((as_timestamp(now()) - as_timestamp(this.attributes.montage_datum | default('2025-01-01')))/60/60/24, 0) }}
    device_class: monetary
    icon: "mdi:cash"
    attributes:
      kostnad_batteri: "70000"
      montage_datum: "2025-02-10"
      gridrewards_per_dygn: "18.5"
      sparat_nyttjande: "{{ float(states('sensor.homevolt_intakt'),0) }}"
      gridrewards_total: "{{ float(this.attributes.gridrewards_per_dygn,0)* int((as_timestamp(now()) - as_timestamp(this.attributes.montage_datum | default('2025-01-01')))/60/60/24,0) }}"
      beraknad_ater_days: >-
        {% set per_day = ((this.state | default(0)) / int((as_timestamp(now()) - as_timestamp(this.attributes.montage_datum | default('2025-01-01')))/60/60/24, 0)) %}
        {{ int((int(this.attributes.kostnad_batteri,0) - (float(this.state,0))) / per_day, 0) }}
      beraknad_ater: "{{ (int(this.attributes.beraknad_ater_days,0) * (24*60*60) + as_timestamp(now())) | timestamp_custom('%Y-%m-%d', True) }}"


# ------------------------------------------------ #
# Sensor integration
sensor:
- platform: integration
  source: sensor.homevolt_intakt_momentant
  name: Homevolt intÀkt
  #unit_time: h
  method: left
  round: 2

utility_meter:
  yearly_earning:
    source: sensor.homevolt_intakt
    name: Homevolt intÀkt Är
    cycle: yearly
    net_consumption: true
    
  monthly_earning:
    source: sensor.homevolt_intakt
    name: Homevolt intÀkt mÄnad
    cycle: monthly
    net_consumption: true
    
# Input for cmd
input_text:
  homevolt_cmd:
    name: Homevolt cmd input
    initial: time uptime


# ------------------------------------------------ #
# Automation integration
automation:
- alias: Homevolt uppdatera schema varje timme
  id: "homevolt_update"
  description: "Uppdaterar schema sensor varje timme för att fÄ senaste schema | homevolt.yaml"
  trigger:
  - platform: time_pattern
    minutes: 1
  action:
  - action: homeassistant.update_entity
    data:
      entity_id:
      - sensor.homevolt_schema

- alias: Homevolt uppdatera console
  id: "homevolt_update_console"
  description: "Uppdaterar console-frÄga | homevolt.yaml"
  trigger:
  - platform: state
    entity_id: input_text.homevolt_cmd
    for: "00:00:06"
  action:
  - action: homeassistant.update_entity
    data:
      entity_id:
      - sensor.homevolt_console


6 Likes

Homevolt: https://homevolt.com/

ERROR / WARNING / INFO messages

from Tibber support

  • EMS_WARNING_OVER_SOC_MAX_WARNING Systemet minskar effekten pĂ„ grund av hög “State of Charge”, detta förvĂ€ntas vid laddning av batteriet.
  • EMS_WARNING_SOC_IMBALANCE_WARNING InnebĂ€r att batterierna Ă€r för lĂ„ngt ifrĂ„n varandra i SOC för att kunna anslutas.
  • EMS_WARNING_BATTERY_DC_DISCONNECT_WARNING Detta Ă€r en konsekvens av ovanstĂ„ende varning, att ett av de tvĂ„ batterierna Ă€r frĂ„nkopplat frĂ„n DC pĂ„ grund av hög spĂ€nningsskillnad.

Dashboard

type: sections
max_columns: 6
icon: mdi:home-battery
path: batteri
sections:
  - type: grid
    cards:
      - type: tile
        tap_action:
          action: url
          url_path: https://192.168.1.100
        hold_action:
          action: perform-action
          perform_action: homeassistant.update_entity
          target: {}
          data:
            entity_id:
              - sensor.homevolt_ems
              - sensor.homevolt_scheman
              - sensor.homevolt_status
        entity: sensor.homevolt_ems
        name: EMS
        vertical: false
        show_entity_picture: false
        hide_state: false
        state_content:
          - state
          - last_updated
        features_position: bottom
        icon_tap_action:
          action: more-info
      - type: tile
        entity: sensor.homevolt_producerat
        name: Producerat
      - type: tile
        entity: sensor.homevolt_konsumerat
        name: Konsumerat
      - type: tile
        entity: sensor.homevolt_schema
        name: Schema
        features_position: bottom
        vertical: false
        icon_tap_action:
          action: perform-action
          perform_action: homeassistant.update_entity
          target: {}
          data:
            entity_id:
              - sensor.homevolt_schema
      - type: tile
        entity: sensor.homevolt_schema_nasta
        name: Schema nÀsta
        show_entity_picture: false
        vertical: false
        hide_state: false
        hold_action:
          action: more-info
        state_content: state
      - type: markdown
        content: >-
          {{ states('sensor.homevolt_ems_error') if
          states('sensor.homevolt_ems_error') != 'No error' }}

          {{ '**Varning:**' if states('sensor.homevolt_ems_varning') != '' }}

          {{ states('sensor.homevolt_ems_varning') }}

          {{ '**Info:**' if states('sensor.homevolt_ems_info') != '' }}

          {{ states('sensor.homevolt_ems_info') }}


          **{{ states('sensor.homevolt_logs') }}**

          ‱ {{ (state_attr('sensor.homevolt_logs','logs') |
                    rejectattr('level','in', ['info']) |
                    map(attribute='data') |
                    list | join('\n‱ '))[:255] }}
          **Status**

          ‱ {{ states('sensor.homevolt_errors').split(', ') | join('\n‱ ') }}
      - type: tile
        entity: sensor.homevolt_intakt_manad
        name: IntÀkt mÄnad
        features_position: bottom
        vertical: false
        icon: mdi:cash
        state_content: state
      - type: tile
        features_position: bottom
        vertical: false
        entity: sensor.homevolt_aterbetalning
        name: IntÀkt
  - type: grid
    cards:
      - type: gauge
        entity: sensor.homevolt_nateffekt
        max: 14000
        severity:
          green: 0
          yellow: 6000
          red: 10000
        name: NĂ€t
        grid_options:
          rows: auto
          columns: 4
      - type: gauge
        grid_options:
          rows: auto
          columns: 4
        entity: sensor.homevolt_solcell_effekt
        name: Solcell
        max: 5000
      - type: gauge
        entity: sensor.homevolt_hushalleffekt
        max: 5000
        severity:
          green: 0
          yellow: -3000
          red: -5000
        needle: true
        min: -5000
        grid_options:
          columns: 4
          rows: auto
        name: Hus
      - type: gauge
        entity: sensor.homevolt_nat_l1
        severity:
          green: 0
          yellow: 8
          red: 16
        name: L1
        max: 20
        grid_options:
          columns: 3
          rows: 1
      - type: gauge
        entity: sensor.homevolt_nat_l2
        severity:
          green: 0
          yellow: 8
          red: 16
        name: L2
        max: 20
        grid_options:
          columns: 3
          rows: 1
      - type: gauge
        entity: sensor.homevolt_nat_l3
        severity:
          green: 0
          yellow: 8
          red: 16
        name: L3
        max: 20
        grid_options:
          columns: 3
          rows: 1
      - type: gauge
        entity: sensor.homevolt_spanning_l1
        max: 230
        min: 225
        needle: true
        grid_options:
          rows: 1
          columns: 3
        name: " "
      - type: gauge
        entity: sensor.homevolt_effekt
        max: 6000
        name: Effekt
        min: -6000
        needle: false
        grid_options:
          columns: 4
          rows: auto
      - type: gauge
        entity: sensor.homevolt_bat0
        severity:
          green: 60
          yellow: 10
          red: 0
        name: Batteri 0
        grid_options:
          columns: 4
          rows: auto
      - type: gauge
        entity: sensor.homevolt_bat1
        severity:
          green: 60
          yellow: 10
          red: 0
        name: Batteri 1
        grid_options:
          columns: 4
          rows: auto
      - type: gauge
        entity: sensor.nordpool_kwh_se3_sek_3_095
        severity:
          green: 0
          yellow: 2
          red: 3
        needle: true
        max: 4
        grid_options:
          columns: 4
          rows: 1
        name: " "
      - type: tile
        entity: sensor.homevolt_bat0_laddningar
        name: Laddningar
      - show_name: false
        show_icon: true
        type: button
        tap_action:
          action: navigate
          navigation_path: /lovelace-energi/homevolt-consol
        icon: mdi:console
        entity: sensor.homevolt_console
        grid_options:
          columns: 2
          rows: 1
        hold_action:
          action: navigate
          navigation_path: /lovelace-energi/homevolt-consol
      - type: gauge
        entity: sensor.homevolt_temperatur
        max: 60
        min: -10
        grid_options:
          columns: 4
          rows: 1
        name: " "
      - type: tile
        entity: sensor.homevolt_lte_cellid
        name: Cellid
title: Batteri
cards: []
badges: []

Apexcharts

type: custom:apexcharts-card
graph_span: 36h
update_interval: 5min
experimental:
  color_threshold: true
header:
  show: true
  show_states: true
  colorize_states: true
  floating: false
yaxis:
  - id: watt
    decimals: 0
    apex_config:
      tickAmount: 6
    min: -6000
    max: 6000
  - id: lowest
    decimals: 0
    min: 0
    max: 1
    show: false
  - id: SEK
    show: false
    decimals: 1
    opposite: true
    apex_config:
      tickAmount: 6
      title:
        text: kr
    min: ~0
    max: ~2
  - id: procent
    show: false
    decimals: 1
    opposite: true
    apex_config:
      tickAmount: 6
      title:
        text: "%"
    min: -100
    max: 100
apex_config:
  chart:
    height: 360px
    animations:
      enabled: false
      easing: easeinout
      speed: 800
      animateGradually:
        enabled: true
        delay: 150
  annotations:
      xaxis:
      - x: EVAL:new Date().setHours(16,0,0)
        x2: EVAL:new Date().setHours(20,0,0)
        label:
          text: KvÀll
          borderWidth: 0
          style:
            background: "#0000"
  tooltip:
    enabled: true
  zoom:
    enabled: true
    type: x
    autoScaleYaxis: true
    zoomedArea:
      fill:
        color: "#90CAF9"
        opacity: 0.4
      stroke:
        color: "#0D47A1"
        opacity: 0.4
        width: 1
  legend:
    show: true
    floating: false
    offsetY: -2
hours_12: false
span:
  start: hour
  offset: "-32h"
now:
  show: false
  color: grey
  label: Nu
all_series_config:
  show:
    legend_value: true
    datalabels: false
    extremas: false
    in_header: false
  float_precision: 0
  invert: false
  stroke_width: 1
  curve: stepline
  yaxis_id: watt
  extend_to: now
series:
  - entity: sensor.nordpool_kwh_se3_sek_3_095
    name: El hist.
    stroke_width: 0
    curve: stepline
    color: grey
    type: area
    yaxis_id: SEK
    opacity: 0.2
    extend_to: now
    show:
      legend_value: false
      extremas: false
      in_header: false
      header_color_threshold: true
    color_threshold:
      - value: 0
        color: green
      - value: 1.5
        color: orange
      - value: 3
        color: darkred
      - value: 4.5
        color: red
      - value: 6
        color: black
  - entity: sensor.nordpool_kwh_se3_sek_3_095
    stroke_width: 0
    curve: stepline
    color: black
    type: area
    yaxis_id: SEK
    opacity: 0.2
    float_precision: 2
    show:
      legend_value: false
      extremas: true
      in_header: false
      header_color_threshold: true
    data_generator: |
      return (entity.attributes.raw_today.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_today[index]["value"]];
      })).concat(entity.attributes.raw_tomorrow.map((start, index) => {
        return [new Date(start["start"]).getTime(), entity.attributes.raw_tomorrow[index]["value"]];
      }));
    color_threshold:
      - value: 0
        color: green
      - value: 1.5
        color: orange
      - value: 3
        color: darkred
      - value: 4.5
        color: red
      - value: 6
        color: black
  - entity: binary_sensor.nordpool_billigast_6h
    name: Billigast 6h
    stroke_width: 0
    curve: stepline
    type: area
    yaxis_id: lowest
    opacity: 0.1
    show:
      in_header: false
      legend_value: false
    transform: "return x === 'on' ? 1 : 0;"
  - entity: sensor.homevolt_effekt
    name: Batteri
    stroke_width: 1
    opacity: 1
    curve: stepline
    yaxis_id: watt
    show:
      in_header: false
    group_by:
      duration: 10min
      func: avg
  - entity: sensor.homevolt_nateffekt
    name: NĂ€t
    stroke_width: 1
    opacity: 0.6
    curve: stepline
    yaxis_id: watt
    transform: return -x
    show:
      in_header: false
    group_by:
      duration: 10min
      func: avg
  - entity: sensor.homevolt_bat0
    name: Batteri0
    stroke_width: 1
    opacity: 1
    curve: smooth
    yaxis_id: procent
    show:
      in_header: false
  - entity: sensor.homevolt_bat1
    name: Batteri1
    stroke_width: 1
    opacity: 1
    curve: smooth
    yaxis_id: procent
    show:
      in_header: false
3 Likes

It seems to work very well!
Thanks!!!

1 Like

Hi and thanks @fatuuse

Do you also built a page for showing all the info?

I will have a look to see how other battery integration are built and see if we can built something similar.

Translated to English :

### Homevolt package
# updated 2025-02-17

# Uses nordpool integration for the sensor:
#      sensor.nordpool_kwh_se3_sek_3_095
#  in the template: part

# ------------------------------------------------ #
# REST integration
rest:
  - resource: "http://10.0.2.101/status.json"
    scan_interval: 300
    timeout: 30
    sensor:
      - name: "Homevolt status"
        value_template: "{{ value_json.uptime }}"
        icon: "mdi:battery-clock"
        json_attributes:
          - uptime
          - wifi_status
          - lte_status
          - mqtt_status
          - w868_status
          - ems_status
      - name: "Homevolt LTE cellid"
        value_template: >-
          {{ (value_json.lte_status.cell_id) | replace('"','') }}

  - resource: "http://10.0.2.101/ems.json"
    scan_interval: 60
    sensor:
      - name: "Homevolt EMS"
        value_template: "{{ value_json.ems[0].ems_data.state_str }}"
        json_attributes:
          - ems
          - aggregated
          - sensors
      - name: "Homevolt EMS error"
        value_template: "{{ (value_json.ems[0].error_str)[:255] }}"
        icon: "mdi:battery-unknown"
        json_attributes_path: "$.ems[0]"
        json_attributes:
          - error_str
      - name: "Homevolt EMS warning"   # translated from varning
        value_template: "{{ (value_json.ems[0].ems_data.warning_str | join(', ') | replace('_', '') | capitalize)[:255] }}"
        icon: "mdi:battery-unknown"
        json_attributes_path: "$.ems[0].ems_data"
        json_attributes:
          - warning_str
      - name: "Homevolt EMS info"
        value_template: "{{ (value_json.ems[0].ems_data.info_str | join(', ') | replace('_', '') | capitalize)[:255] }}"
        icon: "mdi:battery-unknown"
        json_attributes_path: "$.ems[0].ems_data"
        json_attributes:
          - info_str
      - name: "Homevolt temperature"   # translated from temperatur
        value_template: "{{ value_json.ems[0].ems_data.sys_temp /100 }}"
        icon: "mdi:battery-heart-variant"
        unit_of_measurement: "°C"
        device_class: temperature
      - name: "Homevolt voltage L1"    # translated from spÀnning L1
        value_template: "{{ value_json.ems[0].ems_voltage.l1 /10 }}"
        unit_of_measurement: "V"
        icon: "mdi:meter-electric-outline"
        device_class: voltage
      - name: "Homevolt frequency"
        value_template: "{{ value_json.ems[0].ems_data.frequency /1000 }}"
        unit_of_measurement: "Hz"
        icon: "mdi:meter-electric-outline"
        device_class: frequency
      - name: "Homevolt power"         # translated from effekt
        value_template: "{{ value_json.ems[0].ems_data.power }}"
        unit_of_measurement: "W"
        icon: "mdi:battery-sync-outline"
        device_class: power
      - name: "Homevolt energy produced"   # translated from energi producerat
        value_template: "{{ value_json.ems[0].ems_data.energy_produced /1000 }}"
        unit_of_measurement: "kW"
        icon: "mdi:battery-positive"
        device_class: power
      - name: "Homevolt energy consumed"   # translated from energi konsumerat
        value_template: "{{ value_json.ems[0].ems_data.energy_consumed /1000 }}"
        unit_of_measurement: "kW"
        icon: "mdi:battery-negative"
        device_class: power
      - name: "Homevolt available power"   # translated from effekt tillgÀnglig
        value_template: >-
          (value_json.ems[0].ems_prediction.avail_ch_pwr) - 
          (value_json.ems[0].ems_prediction.avail_di_pwr)
          }}
        unit_of_measurement: "kW"
        icon: "mdi:battery-negative"
        device_class: power
        json_attributes_path: "$.ems[0].ems_prediction"
        json_attributes:
          - avail_ch_pwr
          - avail_di_pwr
      - name: "Homevolt exported"      # translated from producerat
        value_template: "{{ value_json.ems[0].ems_aggregate.exported_kwh }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-positive"
        device_class: energy
        state_class: total
      - name: "Homevolt imported"      # translated from konsumerat
        value_template: "{{ value_json.ems[0].ems_aggregate.imported_kwh }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt net usage"     # translated from sum
        value_template: >-
          {{ value_json.ems[0].ems_aggregate.imported_kwh - 
          value_json.ems[0].ems_aggregate.exported_kwh }}
        unit_of_measurement: "kWh"
        icon: "mdi:battery"
        device_class: energy
        state_class: measurement
      - name: "Homevolt battery 0"     # translated from bat0
        value_template: "{{ float(value_json.ems[0].bms_data[0].soc)/100 }}"
        unit_of_measurement: "%"
        icon: "mdi:battery-{{ float(value_json.ems[0].bms_data[1].soc)/100 | round(-1) }}"
      - name: "Homevolt battery 1"     # translated from bat1
        value_template: "{{ float(value_json.ems[0].bms_data[1].soc)/100 }}"
        unit_of_measurement: "%"
        icon: "mdi:battery-{{ float(value_json.ems[0].bms_data[1].soc)/100 | round(-1) }}"
      - name: "Homevolt battery 0 charge cycles"  # translated from bat0 laddningar
        value_template: "{{ value_json.ems[0].bms_data[0].cycle_count }}"
        icon: "mdi:battery"

      # Pulse CT
      - name: "Homevolt grid power"    # translated from nÀteffekt
        value_template: "{{ value_json.sensors[0].total_power }}"
        unit_of_measurement: "W"
        icon: "mdi:battery-negative"
        device_class: power
        state_class: measurement
        json_attributes_path: "$.sensors.[0].phase"
        json_attributes:
          - "0"
          - "1"
          - "2"
      - name: "Homevolt grid imported" # translated from nÀt konsumerat
        value_template: "{{ value_json.sensors[0].energy_imported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt grid exported" # translated from nÀt producerat
        value_template: "{{ value_json.sensors[0].energy_exported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt solar power"   # translated from solar
        value_template: "{{ value_json.sensors[1].total_power }}"
        unit_of_measurement: "W"
        icon: "mdi:battery-negative"
        device_class: power
        state_class: measurement
        json_attributes_path: "$.sensors[1].phase"
        json_attributes:
          - 0
          - 1
          - 2
      - name: "Homevolt solar imported"   # translated from solcell konsumerat
        value_template: "{{ value_json.sensors[1].energy_imported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt solar exported"   # translated from solcell producerat
        value_template: "{{ value_json.sensors[1].energy_exported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt load"          # translated from belastning
        value_template: "{{ value_json.sensors[2].total_power }}"
        unit_of_measurement: "W"
        icon: "mdi:battery-negative"
        device_class: power
        state_class: measurement
        json_attributes_path: "$.sensors.[2].phase"
        json_attributes:
          - 0
          - 1
          - 2
      - name: "Homevolt battery imported"  # translated from batteri konsumerat
        value_template: "{{ value_json.sensors[2].energy_imported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total
      - name: "Homevolt battery exported"  # translated from batteri producerat
        value_template: "{{ value_json.sensors[2].energy_exported }}"
        unit_of_measurement: "kWh"
        icon: "mdi:battery-negative"
        device_class: energy
        state_class: total

  - resource: "http://10.0.2.101/error_report.json"
    scan_interval: 300
    sensor:
      - name: "Homevolt error"
        value_template: "{{ value_json[0].details | list }}"
        icon: "mdi:battery-alert-variant-outline"
        json_attributes:
          - "0"
          - "1"
          - "2"
          - "3"
          - "4"
          - "5"
          - "6"
          - "7"
          - "9"
          - "10"
          - 11
          - 12
          - 13
          - 14
          - 15
          - 16
          - 17
          - 18
          - 19
          - 20
          - 21
          - 22
          - 23
          - 24
          - 25
          - 26
          - 27
          - 28

  - resource: "http://10.0.2.101/schedule.json"
    scan_interval: 1800
    sensor:
      - name: "Homevolt schedules"   # translated from scheman
        value_template: "{{ value_json.schedule | count }}"
        icon: "mdi:calendar-clock-outline"
        json_attributes:
          - local_mode
          - schedule
          - schedule_id
      - name: "Homevolt schedule"    # translated from schema
        value_template: >-
          {{ value_json.schedule | rejectattr('from', '>', (now().timestamp())) | rejectattr('to', '<', (now().timestamp())) | map(attribute='type') | 
          join(',') |
          replace('1', 'Charging') | replace('3', 'Idle') | replace('4', 'Grid Discharge')
          }}
        icon: "mdi:calendar-clock-outline"

# ------------------------------------------------ #
# Template integration
template:
  - sensor:
      name: "Homevolt instant cost"   # translated from kostnad momentant
      unit_of_measurement: "SEK"
      state: >-
        {{ (states('sensor.nordpool_kwh_nl_eur_3_10_009') | float(0) * (states('sensor.homevolt_power') | float(0))/1000) | round(2) }}
      device_class: monetary
      state_class: measurement
      icon: "mdi:cash"

# ------------------------------------------------ #
# Sensor integration
sensor:
  - platform: integration
    source: sensor.homevolt_cost
    name: Homevolt cost   # translated from kostnad
    unit_time: h
    method: left
    round: 2
2 Likes

IstĂ€llet för att behöva leta upp och byta IP sĂ„ kan man lĂ€gga in nĂ„got som detta i secrets.yaml tibber_rest: “http://192.168.0.22/status.json”

I ditt script lÀgger man dÄ till nÄgot som detta:

  • resource: !secret tibber_rest

DÄ blir det bara ett stÀllet man behöver updater IP pÄ.

Japp. men Àven till: /error_report.json & /schedule.json
Jag har inte hittat nÄgon sÀtt att slÄ ihop en secret med ett annat vÀrde.

I made a sensor to input commands till Homevolt console :slightly_smiling_face:

Then you should be able to add custom schemas.
Use at you on own risk


command_line:
- sensor:
    name: "Homevolt console"
    scan_interval: 2592000
    icon: "mdi:console"
    command: >-
      echo "{\"result\": \"$( curl -sk -X POST -u admin:polis28bat  --form cmd='{{
      states('input_text.homevolt_cmd') if
        states('input_text.homevolt_cmd') in ['time uptime','help'] or
        states('input_text.homevolt_cmd').startswith('echo')
        else
        'echo command not accepted to send by HA'
      }}' https://192.168.1.18/console.json | sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/\\n/g' )\"}"
    value_template: >-
      {{ value_json.result[:255] }}
    json_attributes:
      - result

input_text:
  homevolt_cmd:
    name: Homevolt cmd input
    initial: time uptime

automation:
- alias: Homevolt uppdatera console
  id: "homevolt_update_console"
  description: "Uppdaterar console-frÄga | homevolt.yaml"
  trigger:
  - platform: state
    entity_id: input_text.homevolt_cmd
    for: "00:00:06"
  action:
  - action: homeassistant.update_entity
    data:
      entity_id:
      - sensor.homevolt_console

1 Like

Should not these be state_class: total_increasing?

  - name: "Homevolt batteri konsumerat"
    value_template: "{{ value_json.sensors[2].energy_imported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-negative"
    device_class: energy
    state_class: total
  - name: "Homevolt batteri producerat"
    value_template: "{{ value_json.sensors[2].energy_exported }}"
    unit_of_measurement: 'kWh'
    icon: "mdi:battery-positive"
    device_class: energy
    state_class: total

I believe it won’t matter until you change battery.
Total can decrease, but I trust measurements from battery data.
Total increasing can’t decrease .

NÄgon som vÄgat skicka nÄgot annat kommando Àn echo & help??
Skulle vara kul och veta om det gÄr att ersÀtta en rad i schemat :grin:

Package updated in first post.
https://community.home-assistant.io/t/homevolt-package/845654