Solar Panels

From Simon's Help System
Revision as of 13:52, 28 August 2023 by Simon (talk | contribs) (→‎Power Flow Diagram)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

The main code used for the solar system comes from two devices

SolaX Inveters

The invertors are queried using REST and return a JSON package POSTMAN has been pre-configured to do the same queries

#########################################################
#                                                       #
#         SOLAX CLOUD Rear Unit                         #
#                                                       #
#########################################################
  #sensors:
  - platform: rest
    scan_interval: 150
    resource: https://www.solaxcloud.com:9443/proxy/api/getRealtimeInfo.do?tokenId=20210515090442704400044&sn=SWNBESA3MD
    name: "rear solax"
    json_attributes_path: "$.result"
    json_attributes:
      - yieldtoday
      - yieldtotal
      - acpower
      - uploadTime
      - inverterStatus
      - powerdc1
    value_template: "1" # dummy value, not used; avoids the "State max length is 255 characters" error
  - platform: template
    sensors:
      rear_solax_today:
        friendly_name: "Rear Solax today"
        value_template: "{{ state_attr('sensor.rear_solax', 'yieldtoday') }}"
        unit_of_measurement: "KWh"
      rear_solax_total:
        friendly_name: "Rear Solax total"
        value_template: "{{ state_attr('sensor.rear_solax', 'yieldtotal') }}"
        unit_of_measurement: "KWh"
      rear_solax_now:
        friendly_name: "Rear Solax now"
        value_template: "{{ state_attr('sensor.rear_solax', 'acpower') }}"
        unit_of_measurement: "W"
      rear_solax_dc_now:
        friendly_name: "Rear Solax DC now"
        value_template: "{{ state_attr('sensor.rear_solax', 'powerdc1') }}"
        unit_of_measurement: "W"
      rear_solax_upload_time:
        friendly_name: "Rear Solax upload time"
        value_template: "{{ state_attr('sensor.rear_solax', 'uploadTime') }}"
      rear_solax_status:
        friendly_name: "Rear Solax status"
        value_template: >
          {% if state_attr('sensor.rear_solax', 'inverterStatus') == '100' %}Wait
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '101' %}Check
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '102' %}Normal
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '103' %}Fault
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '104' %}Permanent Fault
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '105' %}Update
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '106' %}EPS Check
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '107' %}EPS
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '108' %}Self-test
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '109' %}Idle
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '110' %}Standby
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '111' %}Pv Wake Up Bat
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '112' %}Gen Check
          {% elif state_attr('sensor.rear_solax', 'inverterStatus') == '113' %}Gen Run
          {% else %}I dont know{% endif %}

  #########################################################
  #                                                       #
  #         SOLAX CLOUD Street Unit                       #
  #                                                       #
  #########################################################
  - platform: rest
    scan_interval: 150
    resource: https://www.solaxcloud.com:9443/proxy/api/getRealtimeInfo.do?tokenId=20210515090442704400044&sn=SWNUHG6EEP
    name: "street solax"
    json_attributes_path: "$.result"
    json_attributes:
      - yieldtoday
      - yieldtotal
      - acpower
      - uploadTime
      - inverterStatus
      - powerdc1
    value_template: "1" # dummy value, not used; avoids the "State max length is 255 characters" error
  - platform: template
    sensors:
      street_solax_today:
        friendly_name: "Street Solax today"
        value_template: "{{ state_attr('sensor.street_solax', 'yieldtoday') }}"
        unit_of_measurement: "KWh"
      street_solax_total:
        friendly_name: "Street Solax total"
        value_template: "{{ state_attr('sensor.street_solax', 'yieldtotal') }}"
        unit_of_measurement: "KWh"
      street_solax_now:
        friendly_name: "Street Solax now"
        value_template: "{{ state_attr('sensor.street_solax', 'acpower') }}"
        unit_of_measurement: "W"
      street_solax_dc_now:
        friendly_name: "Street Solax DC now"
        value_template: "{{ state_attr('sensor.street_solax', 'powerdc1') }}"
        unit_of_measurement: "W"
      street_solax_upload_time:
        friendly_name: "Street Solax upload time"
        value_template: "{{ state_attr('sensor.street_solax', 'uploadTime') }}"
      street_solax_status:
        friendly_name: "Street Solax status"
        value_template: >
          {% if state_attr('sensor.street_solax', 'inverterStatus') == '100' %}Wait
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '101' %}Check
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '102' %}Normal
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '103' %}Fault
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '104' %}Permanent Fault
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '105' %}Update
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '106' %}EPS Check
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '107' %}EPS
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '108' %}Self-test
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '109' %}Idle
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '110' %}Standby
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '111' %}Pv Wake Up Bat
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '112' %}Gen Check
          {% elif state_attr('sensor.street_solax', 'inverterStatus') == '113' %}Gen Run
          {% else %}I dont know{% endif %}
  #########################################################
  #                                                       #
  #         SOLAX CLOUD Combined                          #
  #                                                       #
  #########################################################
  - platform: template
    sensors:
      pv_now:
        friendly_name: "PV Now"
        unit_of_measurement: W
        value_template: "{{ (states('sensor.rear_solax_now')|int + states('sensor.street_solax_now')| int) }}"
        icon_template: mdi:power-socket-de
        device_class: power
      pv_today:
        friendly_name: "PV Today"
        unit_of_measurement: "kWh"
        value_template: "{{ (states('sensor.rear_solax_today')|int + states('sensor.street_solax_today')|int) }}"
        icon_template: mdi:solar-panel
      pv_total:
        friendly_name: "PV Total"
        unit_of_measurement: kWh
        value_template: "{{ (states('sensor.rear_solax_total')|int + states('sensor.street_solax_total')|int) }}"
        icon_template: mdi:chart-line
      phev_charging_a:
        value_template: "{{ (states('sensor.meter_power_c')|int - states('sensor.meter_power_b')| int + states('sensor.meter_power_a')| int) }}"
      phev_charging:
        friendly_name: "Power to PHEV"
        unit_of_measurement: 'W'
        device_class: power
        value_template: >
          {% if states('sensor.phev_charging_a')|int < 20 %}
            0
          {% else %}
            {{ (states('sensor.phev_charging_a')|int|abs )}}
          {% endif %}

Iammeter

This three phase device has its own native integration into Home Assistant

  • Phase A = Power from/to the grid +ive is from the grid and -ive is power sent to the grid
  • Phase B = The house meter board, so all power consumption except the SolaX's them selves and the EV Charger
  • Phase C = Solar generation. Should be the same as sensor.pv_now from the calculation above
###############################
#                             #
#       Power Monitor         #
#                             #
###############################
- platform: iammeter
  host: 192.168.1.116
  name: meter
- platform: template
  sensors:
    phev_charging:
      unit_of_measurement: "w"
      value_template: >
        {% if (states('sensor.meter_power_c')|int + states('sensor.meter_power_a')| int - states('sensor.meter_power_b')| int) >500 %}
          {{ states('sensor.meter_power_c')|int + states('sensor.meter_power_a')| int - states('sensor.meter_power_b')| int }}
        {% else %}
          0
        {% endif %}
    phev_amps:
      unit_of_measurement: "A"
      value_template: >
        {{ (((states('sensor.phev_charging')|float ) / (states('sensor.meter_voltage_a')|float)) | round(2)) }}
    grid_consumption:
      friendly_name: "Power from Grid"
      unit_of_measurement: "W"
      device_class: power
      value_template: >
        {% if states('sensor.meter_power_a')|int > 0 %}
          {{ states('sensor.meter_power_a')|int }}
        {% else %}
          0
        {% endif %}
    grid_feed_in:
      friendly_name: "Power to Grid"
      unit_of_measurement: "W"
      device_class: power
      value_template: >
        {% if states('sensor.meter_power_a')|int < 0 %}
          {{ (states('sensor.meter_power_a')|int|abs )}}
        {% else %}
          0
        {% endif %}
    generation_to_house:
      friendly_name: "Solar to house"
      unit_of_measurement: "W"
      device_class: power
      value_template: >
        {% if states('sensor.grid_consumption')|int > 0 %}  
          {{ (states('sensor.meter_power_b')|int + states('sensor.phev_charging')| int - states('sensor.grid_consumption')| int) }}
        {% else %}
          {{ (states('sensor.meter_power_c')|int - states('sensor.grid_feed_in')| int) }}
        {% endif %}

User Interface

The main displays include:

Power Flow Diagram

type: custom:tesla-style-solar-power-card
show_w_not_kw: 1
name: Power Flow
house_entity: sensor.meter_power_b
grid_entity: sensor.grid_consumption
generation_entity: sensor.meter_power_c
generation_to_grid_entity: sensor.grid_feed_in
generation_to_house_entity: sensor.generation_to_house
appliance1_consumption_entity: sensor.phev_charging
grid_to_house_entity: sensor.grid_consumption

Powerflow.png

Generated Power Total

Individual values for each SolaX

type: custom:apexcharts-card
header:
  show: true
  title: Generated Power
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 450
    zoom:
      type: x
      enabled: true
      autoScaleYaxis: false
    toolbar:
      show: true
      autoSelected: zoom
    xaxis.type: datetime
series:
  - entity: sensor.rear_solax_today
    type: column
    group_by:
      func: max
      duration: 24h
  - entity: sensor.street_solax_today
    type: column
    group_by:
      func: max
      duration: 24h
graph_span: 28d
span:
  end: day

Individual.png


Total Values

type: custom:apexcharts-card
header:
  show: true
  title: Total Generated Power
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 350
    zoom:
      type: x
      enabled: true
      autoScaleYaxis: false
    toolbar:
      show: true
      autoSelected: zoom
    xaxis.type: datetime
series:
  - entity: sensor.pv_today
    type: column
    group_by:
      func: max
      duration: 24h
graph_span: 28d
span:
  end: day


Total.png

Charts

Useful Apex custom chart with pan, zoom

type: custom:apexcharts-card
header:
  show: true
  title: Solar Power
  show_states: true
  colorize_states: true
apex_config:
  chart:
    height: 350
    zoom:
      type: x
      enabled: true
      autoScaleYaxis: false
    toolbar:
      show: true
      autoSelected: zoom
    xaxis.type: datetime
  stroke:
    width: 1
    curve: smooth
series:
  - entity: sensor.meter_power_a
    color: red
    group_by:
      func: avg
      duration: 5min
  - entity: sensor.meter_power_b
    group_by:
      func: avg
      duration: 5min
  - entity: sensor.meter_power_c
    color: yellow
    group_by:
      func: avg
      duration: 5min

Solargraph1.png Solar new.jpg