Solar Panels

From Simon's Help System
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