PV status widget for sungrow inverters


Widget for showing current PV state. Preconfigured for sungrow inverters.

Changelog

Version 0.1

  • initial release

Resources

uid: sungrowInverterStatus
tags:
  - card
props:
  parameters:
    - default: PV Status
      label: Header Text
      name: headerText
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Total_DC_Power
      label: Solar Power
      name: solarPower
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_PV_Generation
      description: Solar Energy
      label: Solar Energy
      name: solarEnergy
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Load_Power
      description: Current Load Power
      label: Power Consumption Home
      name: loadPower
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_Import_Energy
      label: Daily Import Energy
      name: importEnergy
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_Direct_Energy_Consumption
      description: Daily Direct Energy Consumption
      name: directEnergyConsumption
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Export_Power
      description: Export Power
      name: exportPower
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_Export_Energy
      description: Daily Export Energy
      name: exportEnergy
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Battery_Level
      description: Battery Level
      name: batteryLevel
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_Charge_Energy
      description: Battery Charge Energy
      name: batteryChargeEnergy
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Daily_Battery_Discharge_Energy
      description: Battery Discharge Energy
      name: batteryDischargeEnergy
      required: true
      type: TEXT
    - context: item
      default: Sungrow_Inverter_Battery_Power
      description: Battery Power
      name: batteryPower
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Jul 30, 2023, 10:51:07 PM
component: f7-card
config:
  style:
    height: 385px
    width: 330px
  title: =props.headerText
slots:
  default:
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="80" x2="150" y2="205" style="stroke:lightgrey;stroke-width:2"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="80" x2="150" y2="205" style="stroke:orange;stroke-width:2"/><polygon points="144,140 156,140 150,147" fill="orange"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.solarPower].state) > 0
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205" x2="250" y2="267" style="stroke:lightgrey;stroke-width:2"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205" x2="250" y2="267" style="stroke:orange;stroke-width:2"/><polygon points="194,236 206,236 200,243" fill="orange" transform="rotate(120 200 236)"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.exportPower].state) < 0
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205" x2="50" y2="267" style="stroke:lightgrey;stroke-width:2"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><line x1="150" y1="205" x2="50" y2="267" style="stroke:orange;stroke-width:2"/><polygon points="94,236 106,236 100,243" fill="orange" transform="rotate(-120 100 236)"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.batteryPower].state) > 0 && Number.parseFloat(items[props.loadPower].state) > Number.parseFloat(items[props.solarPower].state)
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125 0 0 1 250 267" stroke="lightgrey" stroke-width="2" fill="none"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125 0 0 1 250 267" stroke="orange" stroke-width="2" fill="none"/><polygon points="239,133 251,133 245,128" fill="orange" transform="rotate(140 245 133)"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.exportPower].state) > 0
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125 0 0 0 50 267" stroke="lightgrey" stroke-width="2" fill="none"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 150 80 A 125 125 0 0 0 50 267" stroke="orange" stroke-width="2" fill="none"/><polygon points="61,133 49,133 55,138" fill="orange" transform="rotate(40 55 133)"/></svg>')
          border-style: solid
          border-width: 0px
          height: 300px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.batteryPower].state) > 0 && Number.parseFloat(items[props.loadPower].state) < Number.parseFloat(items[props.solarPower].state)
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 257 267 A 125 125 0 0 1 50 267" stroke="lightgrey" stroke-width="2" fill="none"/></svg>')
          border-style: solid
          border-width: 0px
          height: 327px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg"><path d="M 257 267 A 125 125 0 0 1 50 267" stroke="orange" stroke-width="2" fill="none"/><polygon points="144,323 156,323 150,328" fill="orange" transform="rotate(270 150 322)"/></svg>')
          border-style: solid
          border-width: 0px
          height: 330px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 35px
          width: 300px
        visible: =Number.parseFloat(items[props.batteryPower].state) > 0 && Number.parseFloat(items[props.loadPower].state) > Number.parseFloat(items[props.solarPower].state) && Number.parseFloat(items[props.batteryPower].state) > Number.parseFloat(items[props.loadPower].state)
    - component: f7-block
      config:
        style:
          background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
          border-color: orange
          border-radius: 50%
          border-style: solid
          border-width: 2px
          height: 60px
          left: 120px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 85px
          width: 60px
    - component: f7-block
      config:
        style:
          background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
          border-color: orange
          border-radius: 50%
          border-style: solid
          border-width: 2px
          height: 60px
          left: 120px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 200px
          width: 60px
    - component: f7-block
      config:
        style:
          background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
          border-color: orange
          border-radius: 50%
          border-style: solid
          border-width: 2px
          height: 60px
          left: 216px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 272px
          width: 60px
    - component: f7-block
      config:
        style:
          background-color: '=themeOptions.dark === "dark" ? "black" : "white"'
          border-color: orange
          border-radius: 50%
          border-style: solid
          border-width: 2px
          height: 60px
          left: 20px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 272px
          width: 60px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m80-80 80-400h640l80 400H80Zm40-740v-60h120v60H120Zm34 680h296v-110H176l-22 110Zm80-460-43-42 85-85 43 42-85 85Zm-46 290h262v-110H210l-22 110Zm292-390q-74 0-125-52.5T300-880h60q3 50 37 85t83 35q49 0 83-35t37-85h60q-4 75-55 127.5T480-700Zm0-180Zm-30 360v-120h60v120h-60Zm60 380h296l-22-110H510v110Zm0-170h262l-22-110H510v110Zm216-291-85-85 42-42 86 84-43 43Zm-6-219v-60h120v60H720Z" fill="orange"/></svg>')
          background-position: center
          background-repeat: no-repeat
          background-size: 100% 100%
          height: 35px
          left: 133px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 97px
          width: 35px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="m286-79 171-307-337-40 495-455h59L503-574l337 40L345-79h-59Zm167-187 252-223-297-36 99-169-253 224 297 35-98 169Zm27-214Z" fill="orange"/></svg>')
          background-position: center
          background-repeat: no-repeat
          background-size: 100% 100%
          height: 35px
          left: 228px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 285px
          width: 35px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M220-180h150v-250h220v250h150v-390L480-765 220-570v390Zm-60 60v-480l320-240 320 240v480H530v-250H430v250H160Zm320-353Z" fill="orange"/></svg>')
          background-position: center
          background-repeat: no-repeat
          background-size: 100% 100%
          height: 35px
          left: 133px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 211px
          width: 35px
    - component: f7-block
      config:
        style:
          background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" height="48" viewBox="0 -960 960 960" width="48"><path d="M174-280q-12.75 0-21.375-8.625T144-310v-90H80v-160h64v-90q0-12.75 8.625-21.375T174-680h676q12.75 0 21.375 8.625T880-650v340q0 12.75-8.625 21.375T850-280H174Zm30-60h616v-280H204v280Z" fill="orange"/></svg>')
          background-position: center
          background-repeat: no-repeat
          background-size: 100% 100%
          height: 35px
          left: 32px
          margin-left: auto
          margin-right: auto
          margin-top: auto
          position: absolute
          top: 275px
          width: 35px
    - component: f7-block
      config:
        style:
          border-style: solid
          border-width: 0px
          height: 350px
          left: 0px
          margin-left: auto
          margin-right: auto
          margin-top: 10px
          position: absolute
          text-align: right
          width: 350px
      slots:
        default:
          - component: Label
            config:
              style:
                font-size: 12px
                left: 130px
                position: absolute
                top: 0px
                width: 50px
              text: =(items[props.solarPower].state)
          - component: Label
            config:
              style:
                font-size: 12px
                left: 130px
                position: absolute
                top: 15px
                width: 50px
              text: =(items[props.solarEnergy].state)
          - component: Label
            config:
              style:
                font-size: 12px
                left: 90px
                position: absolute
                top: 105px
                width: 50px
              text: = Math.min(Number.parseFloat(items[props.loadPower].state), Number.parseFloat(items[props.solarPower].state)) + " " + items[props.loadPower].state.split(" ")[1]
          - component: Label
            config:
              style:
                font-size: 12px
                left: 90px
                position: absolute
                top: 120px
                width: 50px
              text: =(items[props.directEnergyConsumption].state)
          - component: Label
            config:
              style:
                font-size: 12px
                left: 120px
                position: absolute
                top: 215px
                width: 50px
              text: =(items[props.loadPower].state)
          - component: Label
            config:
              style:
                font-size: 12px
                left: 120px
                position: absolute
                top: 230px
                width: 50px
              text: = (Number.parseFloat(items[props.importEnergy].state) + Number.parseFloat(items[props.directEnergyConsumption].state) + Number.parseFloat(items[props.batteryDischargeEnergy].state)).toFixed(1) + " " + items[props.importEnergy].state.split(" ")[1]
          - component: Label
            config:
              style:
                font-size: 12px
                left: 250px
                position: absolute
                top: 80px
                width: 60px
              text: "=Number.parseFloat(items[props.exportPower].state) > 0 ? items[props.exportPower].state : '0 W'"
          - component: Label
            config:
              style:
                font-size: 12px
                left: 250px
                position: absolute
                top: 95px
                width: 60px
              text: =items[props.exportEnergy].state
          - component: Label
            config:
              style:
                font-size: 12px
                left: 180px
                position: absolute
                top: 185px
                width: 60px
              text: "=Number.parseFloat(items[props.exportPower].state) < 0 ? Math.abs(Number.parseFloat(items[props.exportPower].state)) + ' W' : '0 W'"
          - component: Label
            config:
              style:
                font-size: 12px
                left: 180px
                position: absolute
                top: 200px
                width: 60px
              text: =items[props.importEnergy].state
          - component: Label
            config:
              style:
                font-size: 12px
                left: -10px
                position: absolute
                top: 80px
                width: 60px
              text: "=Number.parseFloat(items[props.loadPower].state) < Number.parseFloat(items[props.solarPower].state) ? items[props.batteryPower].state : '0 W'"
          - component: Label
            config:
              style:
                font-size: 12px
                left: -10px
                position: absolute
                top: 95px
                width: 60px
              text: =items[props.batteryChargeEnergy].state
          - component: Label
            config:
              style:
                font-size: 12px
                left: 40px
                position: absolute
                top: 185px
                width: 60px
              text: "=Number.parseFloat(items[props.loadPower].state) > Number.parseFloat(items[props.solarPower].state) ? items[props.batteryPower].state : '0 W'"
          - component: Label
            config:
              style:
                font-size: 12px
                left: 40px
                position: absolute
                top: 200px
                width: 60px
              text: =items[props.batteryDischargeEnergy].state
          - component: Label
            config:
              style:
                font-size: 12px
                left: 10px
                position: absolute
                top: 245px
                width: 60px
              text: =items[props.batteryLevel].displayState
          - component: Label
            config:
              style:
                font-size: 12px
                left: 120px
                position: absolute
                top: 310px
                width: 50px
              text: "=Number.parseFloat(items[props.batteryPower].state) <= 0 || Number.parseFloat(items[props.loadPower].state) < Number.parseFloat(items[props.solarPower].state) || Number.parseFloat(items[props.batteryPower].state) <= Number.parseFloat(items[props.loadPower].state) ? '0 W' : (Number.parseFloat(items[props.batteryPower].state) - Number.parseFloat(items[props.loadPower].state)).toFixed(1) + ' W'"

3 Likes