Replacing LuxpowerTek charge and discharge GUI with Home Assistant

LuxpowerTek provides the GUI below to set up to three charging slots for the battery. It also provides the same options for force discharging. Even though I have the Octopus Charge feature turned on, there are times that I want to charge the battery manually. This is also true for discharging. Although this is unlikely to be used during the winter, it does come in handy during the UK Savings Sessions.

LuxpowerTek charging GUI

LuxpowerTek discharging GUI

One evening the LuxpowerTek website was down and I could not charge the battery during a late evening cheap Octopus Agile slot. This seemed an ideal time to try and replace the GUI with something nicer in Home Assistant. Below is what I came up with.

Home Assistant LuxpowerTek charging GUI replacement

Home Assistant LuxpowerTek discharging GUI replacement

The time card is using a time-picker-card. The save and reset buttons are using a button-card. The battery level (the purple slider in the top right hand corner) is using a mushroom-number-card set to a slider. The current settings which are displayed under the time-picker-card are mushroom-entity-card.

The table on the right are the Octopus Agile rates. This is coming from a Node Red integration. This will be covered in another post.

Making the GUI was easy enough, the part I had to learn was how to connect those cards to an action and setting the times and battery charge level I wanted. This is what I will cover below. I will cover one start and end time, this was then repeated for the other two charging and discharging slots. The complete YAML will be provided below.

You have to connect the time-picker-card to a Helper. To make a Helper go to Settings, Devices & Services, then to the Helpers tab. Click on Create Helper and choose, Date and/or time. In my case, I needed Date and time option, not just time. Give it a name. I gave mine a nice battery charge or discharge icon.

Create Date and/or time helper

I also needed to make a number Helper for the battery level. In my case I changed the step to 5. I don’t need to charge the battery to such a granular level.

I made a Helper for every start and end time for both charge and discharging.

List of the Helpers I made

List of the Helpers

Now back at the Dashboard. We need to link the cards to the Helpers. Edit the Dashboard and edit the time-picker-card, using the code editor I added this code. The view_layout: section tells the Dashboard which column to use. Notice the entity: matches the Helper I made above.

Setting charge start time 1

type: custom:time-picker-card
entity: input_datetime.ac_charge_start_time_1
hour_mode: 24
hour_step: 1
minute_step: 5
layout:
  hour_mode: double
  align_controls: center
  name: header
hide:
  seconds: true
name: AC Charge Start Time 1
view_layout:
  column: 1

AC Charge Start Time 1 GUI with YAML code

Setting charge end time 1

type: custom:time-picker-card
entity: input_datetime.ac_charge_end_time_1
hour_mode: 24
hour_step: 1
minute_step: 5
layout:
  hour_mode: double
  align_controls: center
  name: header
hide:
  seconds: true
name: AC Charge End Time 1
view_layout:
  column: 2

AC Charge End Time 1 GUI with YAML code

Setting battery charge level

type: custom:mushroom-number-card
entity: input_number.battery_charge_level
name: Battery Charge Level
icon: mdi:battery-charging-high
fill_container: false
secondary_info: last-changed
icon_color: purple
primary_info: state
tap_action:
  action: call-service
  service: automation.trigger
  target:
    entity_id: automation.solar_card_ac_charge_battery_charge_level
  data:
    skip_condition: false
view_layout:
  column: 3

Set battery charge level GUI with slider

These are now connected, but nothing happens. The Helper values will change, but I need to tell the the Lux entity to use those values. You can check the GUI connections are working by using the Developer Tools below.

Developer Tools entity states

You need to trigger the change in some way. I am sure I could have triggered on changing one of the values, but I didn’t want to send too many requests to the inverter as I changed the minutes and hours. I decided I would add a save button to allow me to set the schedule and then save it. This led me to thinking, I had better have a way to reset everything to default, which is midnight (off).

The way to do this is trigger an automation. Before you can connect the save and reset buttons I needed to make the Automations. Notice neither have a trigger set.

The time.set_value services is being called and telling Home Assistant to set time.lux_ac_charge_start1 to input_datetime.ac_charge_start_time_1. It then repeats that for time.lux_ac_charge_end1. That is then again repeated for 2 and 3.

Notice that the reset button is a static midnight and the battery charge level is set to 20%. Both Automations then send messages for each slot to confirm the times have been set or reset.

 

Automation to send charging times to inverter

alias: Solar Card - Set Overnight Charging
description: Solar Card - Set Overnight Charging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_start_time_1') }}"
    target:
      entity_id: time.lux_ac_charge_start1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_end_time_1') }}"
    target:
      entity_id: time.lux_ac_charge_end1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_start_time_2') }}"
    target:
      entity_id: time.lux_ac_charge_start2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_end_time_2') }}"
    target:
      entity_id: time.lux_ac_charge_end2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_start_time_3') }}"
    target:
      entity_id: time.lux_ac_charge_start3
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_charge_end_time_3') }}"
    target:
      entity_id: time.lux_ac_charge_end3
  - service: number.set_value
    data:
      value: "{{states ('input_number.battery_charge_level') }}"
    target:
      entity_id: number.lux_ac_battery_charge_level
  - service: notify.notify
    data:
      message: |
        Charging1 will start at {{
        states("time.lux_ac_charge_start1") }} o'clock 

        Charging1 will end at {{
        states("time.lux_ac_charge_end1") }} o'clock
      title: Overnight charging1 set
  - service: notify.notify
    data:
      message: |
        Charging2 will start at {{
        states("time.lux_ac_charge_start2") }} o'clock 

        Charging2 will end at {{
        states("time.lux_ac_charge_end2") }} o'clock 
      title: Overnight charging2 set
  - service: notify.notify
    data:
      message: |
        Charging3 will start at {{
        states("time.lux_ac_charge_start3") }} o'clock 

        Charging3 will end at {{
        states("time.lux_ac_charge_end3") }} o'clock 
      title: Overnight charging3 set
  - service: notify.notify
    data:
      message: >
        Battery will charge to {{ states("number.lux_ac_battery_charge_level")
        }}
      title: Overnight battery charging set
mode: single

GUI version of the Save automation

 

Automation to send charging reset times to inverter

alias: Solar Card - Reset Overnight Charging
description: Solar Card - Reset Overnight Charging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_start1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_end1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_start2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_end2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_start3
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_ac_charge_end3
  - service: number.set_value
    data:
      value: "20"
    target:
      entity_id: number.lux_ac_battery_charge_level
  - service: notify.notify
    data:
      message: |
        Overnight charging has been reset1
        Charging1 will start at {{
        states("time.lux_ac_charge_start1") }} o'clock 

        Charging1 will end at {{
        states("time.lux_ac_charge_end1") }} o'clock 
      title: Overnight charging reset1
  - service: notify.notify
    data:
      message: |
        Overnight charging has been reset2
        Charging2 will start at {{
        states("time.lux_ac_charge_start2") }} o'clock 

        Charging2 will end at {{
        states("time.lux_ac_charge_end2") }} o'clock 
      title: Overnight charging reset2
  - service: notify.notify
    data:
      message: |
        Overnight charging has been reset3
        Charging3 will start at {{
        states("time.lux_ac_charge_start3") }} o'clock 

        Charging3 will end at {{
        states("time.lux_ac_charge_end3") }} o'clock 
      title: Overnight charging reset3
  - service: notify.notify
    data:
      message: |
        Battery will charge to {{ states("number.lux_ac_battery_charge_level")
        }}
      title: Overnight battery reset
mode: single

GUI version of the Reset automation

Now we have the Automations setup, we need to connect them to the buttons. You can see the save button is calling the auotmation.trigger service which is told to run automation.solar_card_set_overnight_charging. The reset calls automation, automation.solar_card_reset_overnight_charging.

 

Run the automation to set charging times

show_name: true
show_icon: true
type: custom:button-card
style: |
  ha-card {
  height:120px !important;
  }
tap_action:
  action: call-service
  service: automation.trigger
  target:
    entity_id:
      - automation.solar_card_set_overnight_charging
  data: {}
show_state: true
icon: mdi:content-save-settings
color_type: icon
color: green
name: Save settings
view_layout:
  column: 1

Save button with YAML code

 

Run the automation to reset charging times

type: custom:button-card
card_mod: null
style: |
  ha-card {
  height:120px !important;
  }
show_name: true
show_icon: true
tap_action:
  action: call-service
  service: automation.trigger
  target:
    entity_id: automation.solar_card_reset_overnight_charging
  data: {}
show_state: true
icon: mdi:content-save-settings
color_type: icon
color: red
name: Reset
view_layout:
  column: 1

Reset button with YAML code

The one thing I would like to be able to do is, reset the GUI to the current value. Even though the reset button resets the values to midnight, the GUI will show the last values I set. This is why I added the live inverter values underneath. I really should run the reset Automation each morning. It is very unlikely I will want to do this two days running.

Below is the code for the discharge. You will see it is very similar to the charging. The Helpers are made the same way as before. You can see there names in the Helpers screenshot.

Setting discharge start time 1

type: custom:time-picker-card
entity: input_datetime.ac_discharge_start_time_1
hour_mode: 24
hour_step: 1
minute_step: 5
layout:
  hour_mode: double
  align_controls: center
  name: header
hide:
  seconds: true
name: AC Charge Discharge Start Time 1
view_layout:
  column: 1

Automation to send discharging times to inverter

alias: Solar Card - Set Overnight Discharging
description: Solar Card - Set Overnight Discharging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_1') }}"
    target:
      entity_id: time.lux_force_discharge_start1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_1') }}"
    target:
      entity_id: time.lux_force_discharge_end1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_2') }}"
    target:
      entity_id: time.lux_force_discharge_start2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_2') }}"
    target:
      entity_id: time.lux_force_discharge_end2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_3') }}"
    target:
      entity_id: time.lux_force_discharge_start3
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_3') }}"
    target:
      entity_id: time.lux_force_discharge_end3
  - service: notify.notify
    data:
      message: |
        Discharging1 will start at {{
        states("time.lux_force_discharge_start1") }} o'clock 

        Discharging1 will end at {{
        states("time.lux_force_discharge_end1") }} o'clock
      title: Overnight discharging1 set
  - service: notify.notify
    data:
      message: |
        Discharging2 will start at {{
        states("time.lux_force_discharge_start2") }} o'clock 

        Discharging2 will end at {{
        states("time.lux_force_discharge_end2") }} o'clock 
      title: Overnight discharging2 set
  - service: notify.notify
    data:
      message: |
        Discharging3 will start at {{
        states("time.lux_force_discharge_start3") }} o'clock 

        Discharging3 will end at {{
        states("time.lux_force_discharge_end3") }} o'clock 
      title: Overnight discharging3 set
mode: single

Run the automation to set discharging times

alias: Solar Card - Set Overnight Discharging
description: Solar Card - Set Overnight Discharging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_1') }}"
    target:
      entity_id: time.lux_force_discharge_start1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_1') }}"
    target:
      entity_id: time.lux_force_discharge_end1
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_2') }}"
    target:
      entity_id: time.lux_force_discharge_start2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_2') }}"
    target:
      entity_id: time.lux_force_discharge_end2
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_start_time_3') }}"
    target:
      entity_id: time.lux_force_discharge_start3
  - service: time.set_value
    data:
      time: "{{states ('input_datetime.ac_discharge_end_time_3') }}"
    target:
      entity_id: time.lux_force_discharge_end3
  - service: notify.notify
    data:
      message: |
        Discharging1 will start at {{
        states("time.lux_force_discharge_start1") }} o'clock 

        Discharging1 will end at {{
        states("time.lux_force_discharge_end1") }} o'clock
      title: Overnight discharging1 set
  - service: notify.notify
    data:
      message: |
        Discharging2 will start at {{
        states("time.lux_force_discharge_start2") }} o'clock 

        Discharging2 will end at {{
        states("time.lux_force_discharge_end2") }} o'clock 
      title: Overnight discharging2 set
  - service: notify.notify
    data:
      message: |
        Discharging3 will start at {{
        states("time.lux_force_discharge_start3") }} o'clock 

        Discharging3 will end at {{
        states("time.lux_force_discharge_end3") }} o'clock 
      title: Overnight discharging3 set
mode: single

Setting discharge end time 1

type: custom:time-picker-card
entity: input_datetime.ac_discharge_end_time_1
hour_mode: 24
hour_step: 1
minute_step: 5
layout:
  hour_mode: double
  align_controls: center
  name: header
hide:
  seconds: true
name: AC Charge Discharge End Time 1
view_layout:
  column: 2

Automation to send reset discharging times to inverter

alias: Solar Card - Reset Overnight Discharging
description: Solar Card - Reset Overnight Discharging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start3
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end3
  - service: notify.notify
    data:
      message: |
        Overnight discharging has been reset1
        Discharging1 will start at {{
        states("time.lux_force_discharge_start1") }} o'clock 

        Discharging1 will end at {{
        states("time.lux_force_discharge_end1") }} o'clock 
      title: Overnight discharging reset1
  - service: notify.notify
    data:
      message: |
        Overnight discharging has been reset2
        Discharging2 will start at {{
        states("time.lux_force_discharge_start2") }} o'clock 

        Discharging2 will end at {{
        states("time.lux_force_discharge_end2") }} o'clock 
      title: Overnight discharging reset2
  - service: notify.notify
    data:
      message: |
        Overnight charging has been reset3
        Discharging3 will start at {{
        states("time.lux_force_discharge_start3") }} o'clock 

        Discharging3 will end at {{
        states("time.lux_force_discharge_end3") }} o'clock 
      title: Overnight discharging reset3
mode: single

Run the automation to reset discharging times

alias: Solar Card - Reset Overnight Discharging
description: Solar Card - Reset Overnight Discharging
trigger: []
condition: []
action:
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end1
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end2
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_start3
  - service: time.set_value
    data:
      time: "00:00:00"
    target:
      entity_id: time.lux_force_discharge_end3
  - service: notify.notify
    data:
      message: |
        Overnight discharging has been reset1
        Discharging1 will start at {{
        states("time.lux_force_discharge_start1") }} o'clock 

        Discharging1 will end at {{
        states("time.lux_force_discharge_end1") }} o'clock 
      title: Overnight discharging reset1
  - service: notify.notify
    data:
      message: |
        Overnight discharging has been reset2
        Discharging2 will start at {{
        states("time.lux_force_discharge_start2") }} o'clock 

        Discharging2 will end at {{
        states("time.lux_force_discharge_end2") }} o'clock 
      title: Overnight discharging reset2
  - service: notify.notify
    data:
      message: |
        Overnight charging has been reset3
        Discharging3 will start at {{
        states("time.lux_force_discharge_start3") }} o'clock 

        Discharging3 will end at {{
        states("time.lux_force_discharge_end3") }} o'clock 
      title: Overnight discharging reset3
mode: single
Michael Curtis

My introduction to computers started at my middle school in 1981 when our maths teacher brought in a ZX80. That led the computer club being founded and using a Research Machine 380Z

My first computer was a 48K ZX Spectrum which I loved to programme. Once I left school I worked as a photocopier engineer, then a fax engineer and finally moving on the Apple computers.

For the next 30 years I worked as a system administrator. I now work in the cyber security industry as a Sophos Professional Services consultant

https://www.bazmac.me
Previous
Previous

Sunsynk power flow card for LuxpowerTek Inverter (Update 2)

Next
Next

October Solar Generation and Export Numbers