tmjo / charger-card

A lovelace card for electrical vehicle (EV) home chargers and charging robots.
MIT License
90 stars 59 forks source link

Complete rewrite - generic card #19

Closed tmjo closed 2 years ago

tmjo commented 2 years ago

Here is a first draft for a generic card which should be fully customizable. Check the readme on how to configure the card.

This is a test for now, please let me know your needs and comments. Testing can be done either by manually downloading and install card from here, or by cloning the branch and run as a developer. After some testing, I plan to merge it and release it as a pre-release also for HACS.

tmjo commented 2 years ago

There is still work to be done on translations and for sure there are some bugs. Please test. I've got the card working now for a VW e-Golf integration, so it should be pretty flexible (this will be added as an example later). The Easee template will also be updated and (if you contribute) several other templates may be added to make the configuration easy for people using the card.

For now, the card must be installed by using development option. Next release (based on inputs) may be a pre-release/beta.

jcsogo commented 2 years ago

Thanks for the effort of making the card generic. I have tried to set it up, with some data from the OpenEVSE integration in this repositorty https://github.com/firstof9/openevse

I have installed this new version by replacing the .js file and reloading the webpage and even homeassistant itself, but I don't notice any change that I made following your readme file. I don't have any clue on how to proceed.

tmjo commented 2 years ago

Thanks for the effort of making the card generic. I have tried to set it up, with some data from the OpenEVSE integration in this repositorty https://github.com/firstof9/openevse

I have installed this new version by replacing the .js file and reloading the webpage and even homeassistant itself, but I don't notice any change that I made following your readme file. I don't have any clue on how to proceed.

@jcsogo Great that you want to test. I hope to release it to HACS as a pre-release soon which will make it much easier, but would be good with some feedback first since there's a million breaking changes.

I think your issue is caching in the browser, I've run into it myself several times. Not sure why/how/when, but the trick I use is to add a ?v18 where 18 is just a number which I increase every time there I know there is a change. Also, I do a hard reload (Ctrl+F5 in Chrome).

I do most of my testing in my devcontainer, there it works with no funny stuff, but in my production HA I've done the same as you and put the testfile directly in www-folder and added resource /local/charger-card.js?v18. You should probably also remove the HACS-reference to the file, but it may work if you just replace the HACS file too.

Let me know if you make it work. PS! I've updated the file recently, so you may want to try the latest one.

tmjo commented 2 years ago

Just as a teaser for everyone else: it should be pretty generic and customizable now, here's a test I did using it for my car instead (or rather in addition) to my charger.

image

jcsogo commented 2 years ago

Thanks @tmjo ! The ?v18 made the trick. I had already tried reloading the browser with no luck. And I love the car card... I only need half the data to be provided by the WeConnect ID that is still missing from the regular WeConnect app so I can show it for my ID.3. Supposedly an update to the car software is about to come soon.

Several comments / issues on the card. I am using your readme example as a basis, but I don't have so many data exported from the openevse integration yet, so I am repeating sensors just for testing purposes:

jcsogo commented 2 years ago

I also think that the very last version has some issue as shown below and doesn't render. Captura de pantalla de 2021-12-28 17-03-45

tmjo commented 2 years ago

@jcsogo ; hmm, that looks like some bad error handling from my side. but it should appear due to some errors in the yaml config. mind sharing the yaml config with me? Remeber to use code formatting so that it is possible to see what is wrong. Thanks for testing.

EDIT: sorry, just saw the last post. Did you use one of the "templates" or manual config? But anyway, you're right - the readme is not updated after I did some changes the last week. Please see below for a complete config like it should be now (will update the readme shortly, please note the details keyword there, I think this is the most important change):


type: custom:charger-card
entity: sensor.CHARGERNAME_status
customCardTheme: theme_custom
chargerImage: Red
brand: easee
show_leds: true
details:
  name:
    entity_id: sensor.CHARGERNAME_status
    attribute: name
  location:
    entity_id: sensor.CHARGERNAME_status
    attribute: site_name
  status:
    entity_id: sensor.CHARGERNAME_status
  substatus:
    entity_id: sensor.CHARGERNAME_reason_for_no_current
  smartcharging:
    entity_id: switch.CHARGERNAME_smart_charging
  currentlimits:
    - 0
    - 6
    - 10
    - 16
    - 20
    - 25
    - 32
  statetext:
    disconnected: disconnected
    awaiting_start: awaiting_start
    charging: charging
    completed: completed
    error: error
    ready_to_charge: ready_to_charge
  collapsiblebuttons:
    group1:
      text: click_for_group1
      icon: mdi:speedometer
    group2:
      text: click_for_group2
      icon: mdi:information
    group3:
      text: click_for_group3
      icon: mdi:cog
  info_left:
    - entity_id: binaryxxx_sensor.CHARGERNAME_online
      text: online
  info_right:
    - entity_id: sensor.CHARGERNAME_voltage
      text: voltage
      unit_show: true
    - entity_id: sensor.CHARGERNAME_power
      text: power
      unit_show: true
  group1:
    - entity_id: sensor.CHARGERNAME_dynamic_charger_limit
      text: dyn_charger_limit
      service: easee.set_charger_dynamic_limit
      service_data:
        charger_id: CHARGERID
        current: '#SERVICEVAL#'
    - entity_id: sensor.CHARGERNAME_dynamic_circuit_limit
      text: dyn_circuit_limit
      service: easee.set_charger_circuit_dynamic_limit
      service_data:
        charger_id: CHARGERID
        currentP1: '#SERVICEVAL#'
    - entity_id: sensor.CHARGERNAME_max_charger_limit
      text: max_charger_limit
      service: easee.set_charger_max_limit
      service_data:
        charger_id: CHARGERID
        current: '#SERVICEVAL#'
    - entity_id: sensor.CHARGERNAME_max_circuit_limit
      text: max_circuit_limit
      service: easee.set_circuit_max_limit
      service_data:
        charger_id: CHARGERID
        currentP1: '#SERVICEVAL#'
    - entity_id: sensor.CHARGERNAME_offline_circuit_limit
      text: offline_circuit_limit
      service: easee.set_charger_circuit_offline_limit
      service_data:
        charger_id: CHARGERID
        currentP1: '#SERVICEVAL#'
  group2:
    - entity_id: binary_sensor.CHARGERNAME_online
      text: online
    - entity_id: sensor.CHARGERNAME_voltage
      text: voltage
      unit_show: true
    - entity_id: sensor.CHARGERNAME_power
      text: power
      unit_show: true
    - entity_id: sensor.CHARGERNAME_current
      text: charger_current
      unit_show: true
    - entity_id: sensor.CHARGERNAME_circuit_current
      text: circuit_current
      unit_show: true
    - entity_id: sensor.CHARGERNAME_energy_per_hour
      text: energy_per_hour
      unit_show: true
    - entity_id: sensor.CHARGERNAME_session_energy
      text: session_energy
      unit_show: true
    - entity_id: sensor.CHARGERNAME_lifetime_energy
      text: lifetime_energy
      unit_show: true
  group3:
    - entity_id: switch.CHARGERNAME_is_enabled
      text: enabled
    - entity_id: switch.CHARGERNAME_enable_idle_current
      text: idle_current
    - entity_id: binary_sensor.CHARGERNAME_cable_locked
      text: cable_locked
    - entity_id: switch.CHARGERNAME_cable_locked_permanently
      text: perm_cable_locked
    - entity_id: switch.CHARGERNAME_smart_charging
      text: smart_charging
    - entity_id: sensor.CHARGERNAME_cost_per_kwh
      text: cost_per_kwh
    - entity_id: binary_sensor.CHARGERNAME_update_available
      text: update_available
    - entity_id: binary_sensor.CHARGERNAME_basic_schedule
      text: schedule
  stats:
    default:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: switch.CHARGERNAME_cable_locked_permanently
        text: cable_locked
      - entity_id: binary_sensor.CHARGERNAME_basic_schedule
        text: schedule
    disconnected:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: switch.CHARGERNAME_cable_locked_permanently
        text: cable_locked
      - entity_id: calculated
        text: used_limit
        unit: A
        unit_show: true
        calc_function: min
        calc_entities:
          - entity_id: sensor.CHARGERNAME_dynamic_charger_limit
          - entity_id: sensor.CHARGERNAME_dynamic_circuit_limit
          - entity_id: sensor.CHARGERNAME_max_charger_limit
          - entity_id: sensor.CHARGERNAME_max_circuit_limit
          - entity_id: sensor.CHARGERNAME_offline_circuit_limit
    awaiting_start:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: binary_sensor.CHARGERNAME_basic_schedule
        text: schedule
      - entity_id: switch.CHARGERNAME_smart_charging
        text: smart_charging
      - entity_id: calculated
        text: used_limit
        unit: A
        unit_show: true
        calc_function: min
        calc_entities:
          - entity_id: sensor.CHARGERNAME_dynamic_charger_limit
          - entity_id: sensor.CHARGERNAME_dynamic_circuit_limit
          - entity_id: sensor.CHARGERNAME_max_charger_limit
          - entity_id: sensor.CHARGERNAME_max_circuit_limit
          - entity_id: sensor.CHARGERNAME_offline_circuit_limit
    charging:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: sensor.CHARGERNAME_energy_per_hour
        text: energy_per_hour
        unit_show: true
      - entity_id: sensor.CHARGERNAME_circuit_current
        text: circuit_current
        unit_show: true
      - entity_id: sensor.CHARGERNAME_output_limit
        text: output_limit
        unit_show: true
      - entity_id: sensor.CHARGERNAME_current
        text: current
        unit_show: true
      - entity_id: sensor.CHARGERNAME_power
        text: power
        unit_show: true
    completed:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: binary_sensor.CHARGERNAME_basic_schedule
        text: schedule
      - entity_id: calculated
        text: used_limit
        unit: A
        unit_show: true
        calc_function: min
        calc_entities:
          - entity_id: sensor.CHARGERNAME_dynamic_charger_limit
          - entity_id: sensor.CHARGERNAME_dynamic_circuit_limit
          - entity_id: sensor.CHARGERNAME_max_charger_limit
          - entity_id: sensor.CHARGERNAME_max_circuit_limit
          - entity_id: sensor.CHARGERNAME_offline_circuit_limit
    error:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: binary_sensor.CHARGERNAME_basic_schedule
        text: schedule
    ready_to_charge:
      - entity_id: sensor.CHARGERNAME_session_energy
        text: session_energy
        unit_show: true
      - entity_id: binary_sensor.CHARGERNAME_basic_schedule
        text: schedule
      - entity_id: calculated
        text: used_limit
        unit: A
        unit_show: true
        calc_function: min
        calc_entities:
          - entity_id: sensor.CHARGERNAME_dynamic_charger_limit
          - entity_id: sensor.CHARGERNAME_dynamic_circuit_limit
          - entity_id: sensor.CHARGERNAME_max_charger_limit
          - entity_id: sensor.CHARGERNAME_max_circuit_limit
          - entity_id: sensor.CHARGERNAME_offline_circuit_limit
  toolbar_left:
    default:
      - {}
    disconnected:
      - {}
    awaiting_start:
      - service: easee.stop
        service_data:
          charger_id: CHARGERID
        text: stop
        icon: hass:stop
      - service: easee.resume
        service_data:
          charger_id: CHARGERID
        text: resume
        icon: hass:play
      - service: easee.override_schedule
        service_data:
          charger_id: CHARGERID
        text: override
        icon: hass:motion-play
    charging:
      - service: easee.stop
        service_data:
          charger_id: CHARGERID
        text: stop
        icon: hass:stop
      - service: easee.pause
        service_data:
          charger_id: CHARGERID
        text: pause
        icon: hass:pause
    completed:
      - service: easee.stop
        service_data:
          charger_id: CHARGERID
        text: stop
        icon: hass:stop
      - service: easee.override_schedule
        service_data:
          charger_id: CHARGERID
        text: override
        icon: hass:motion-play
    error:
      - service: easee.reboot
        service_data:
          charger_id: CHARGERID
        text: reboot
        icon: hass:restart
    ready_to_charge:
      - service: easee.stop
        service_data:
          charger_id: CHARGERID
        text: stop
        icon: hass:stop
      - service: easee.override_schedule
        service_data:
          charger_id: CHARGERID
        text: override
        icon: hass:motion-play
  toolbar_right:
    default:
      - service: persistent_notification.create
        service_data:
          message: Firmware update is available, but only possible when disconnected!
          title: Update
        text: update
        icon: mdi:file-download
        conditional_entity: binary_sensor.CHARGERNAME_update_available
    disconnected:
      - service: easee.update_firmware
        service_data:
          charger_id: CHARGERID
        text: update
        icon: mdi:file-download
        conditional_entity: binary_sensor.CHARGERNAME_update_available
jcsogo commented 2 years ago

OK - following your last 'readme' I moved on to a differnt issue, Captura de pantalla de 2021-12-29 23-17-32

My yaml file is the following


- type: custom:charger-card
  entity: sensor.openevse_charging_status
  customCardTheme: theme_custom
  brand: OpenEVSE
  details:
    name: Charger
    status:
      entity_id: sensor.openevse_charging_status
    currentlimits:
      - 0
      - 6
      - 10
      - 16
      - 20
      - 25
      - 32
    info_right:
    - entity_id: sensor.openevse_charging_voltage
      text: Voltage
      unit_show: true
    - entity_id: sensor.openevse_charging_current
      text: Amp
      unit_show: true
    info_left:
    - entity_id: sensor.openevse_charging_voltage
      text: Voltage
      unit_show: true
    - entity_id: sensor.openevse_charging_current
      text: Amp
      unit_show: true
    group1:
    - entity_id: select.openevse_max_current
      text: Dynamic limit
      unit_show: true
    - entity_id: sensor.openevse_max_amps
      text: Max Amp
      unit_show: true
    stats:
      default:
        - entity_id: sensor.openevse_ambient_temperature
          text: Temperature
          unit_show: true
      disabled:
        - entity_id: sensor.openevse_total_usage
          text: ""
          unit_show: true
        - entity_id: sensor.id3_charge_rate
          text:
          unit_show: true
        - entity_id: sensor.id3_charge_remaining
          text:
          unit_show: true
        - entity_id: sensor.openevse_current_power_usage
          text: Power
          unit_show: true
        - entity_id: select.openevse_max_current
          text: Amp
          unit_show: true
        - entity_id: sensor.openevse_usage_this_session
          text: Energy
          unit_show: true
        - entity_id: sensor.openevse_ambient_temperature
          text: Temperature
          unit_show: true
      active:
        - entity_id: sensor.id3_charge_rate
          text: Km/h
          unit_show: true
        - entity_id: sensor.id3_charge_remaining
          text: To full
          unit_show: true
        - entity_id: sensor.openevse_current_power_usage
          text: Power
          unit_show: true
        - entity_id: sensor.openevse_current_capacity
          text: Amp
          unit_show: true
        - entity_id: sensor.openevse_usage_this_session
          text: Energy
          unit_show: true
        - entity_id: sensor.openevse_ambient_temperature
          text: Temperature
          unit_show: true
    collapsiblebuttons:
      - group1:
          text: Click for limits
          icon: mdi:speedometer
      - group2:
          text: Click for info
          icon: mdi:information
      - group3:
          text: Click for config
          icon: mdi:cog
    statetext:
      disabled: Disconnected
  toolbar_left:
    default:
      - service: persistent_notification.create
        service_data:
          message: test1
          title: test
        text: Schedule
        icon: hass:play-pause
      - service: persistent_notification.create
        service_data:
          message: test1
          title: test
        text: Schedule
        icon: hass:motion-play
tmjo commented 2 years ago

@jcsogo ; sorry, you're right. I did some last minute changes recently (allowing for units on name and location, which doesn't make sense really, but I used it for my e-Golf test where I put a value in location instead of location). Should be fixed now if you download the latest file in /tmp

jcsogo commented 2 years ago

Good, with the change is back.

Can you elaborate a bit more on the 'templates' for the brands? I have been working in adding more missing sensors to the OpenEVSE integration, and now I can provide something more meaningful, although there is still work to be completed for the actions.

tmjo commented 2 years ago

Great! My idea with the templates is just to make it easy for users that are not comfortable with huge YAML-code. So anyone that is happy doing YAML can do whatever they want, but I'm hoping to make some templates for different integrations which just make it simple to apply everything in a click and your done.

I'd be happy to make a brand template for OpenEVSE in cooperation with you!

See if the contribution guidelines give you anything, and take a look at the template. It is basically a JSON-formatted setup of your YAML-code and then with some special tokens that will be replaced when doing the UI-editor (to make it simple).

Long story short: My idea is that advanced user do what they want, while other users can apply a template which (hopefully) take them straight to a complete solution based on the brand templates.

tmjo commented 2 years ago

@jcsogo ; take a look at the last commit I did in between here. Added a very early draft for openEVSE based on your yaml. This is how it could look like. I would need to know a bit more on what service calls are available and which data should be sent when calling them. Are you using the official openEVSE-integration?

PS! For brand templates, I won't allow mixing car and charger. I see why you want to do it, and I may even do it myself for my setup, but that's why it is customizable - so people can do what they like. But for templates it should be strictly one template per integration, otherwise it will become a huge mess I think.

jcsogo commented 2 years ago

@jcsogo ; take a look at the last commit I did in between here. Added a very early draft for openEVSE based on your yaml. This is how it could look like. I would need to know a bit more on what service calls are available and which data should be sent when calling them. Are you using the official openEVSE-integration?

PS! For brand templates, I won't allow mixing car and charger. I see why you want to do it, and I may even do it myself for my setup, but that's why it is customizable - so people can do what they like. But for templates it should be strictly one template per integration, otherwise it will become a huge mess I think.

I am going to be offline for some days but I will be able to look at it next weekend. Some of the data I was using was a bit nonsensical as I was testing the card I just wanted some sensor for testing purposes. In the meantime I have been contributing code to the integration to add more sensors, and it is providing more interesting data now. I will create a template that makes sense for most of the users.

The integration is not the official, though, because it is quite outdated. It is discussed here and I am using this integration

Regarding mixing car and charger, your consideration of not doing it in the template makes complete sense. Actually the charger publishes that data as well, so I can use it from it and be completely independent of the car implementation.

tmjo commented 2 years ago

Sounds good @jcsogo! Appreciate your contributions. Wish you a happy new year's celebration!

Ulrar commented 2 years ago

Hi there,

I have a couple of myenergi Zappi chargers and I'd love to try this out when it becomes available in HACS. Just asking since it's been a couple of months since the last update, are we getting closer to a pre-release in there ?

Thanks

tmjo commented 2 years ago

Hi there,

I have a couple of myenergi Zappi chargers and I'd love to try this out when it becomes available in HACS. Just asking since it's been a couple of months since the last update, are we getting closer to a pre-release in there ?

Thanks

Hi @Ulrar - sounds good! I've been running the card myself, but didn't get much feedback from anyone else, so I didn't stress it. But I guess it is time to push to pre-release in HACS, I'll see if I can do it soon!

dr-waterstorm commented 2 years ago

This sounds nice :) I'd also like to try it with my Mennekes Amtron once it's in HACS. Thanks for your work!