Start a new topic

MQTT Vehicle Session?

Hi,  I can't seem to figure out how to get the most recent charging session informaiton from MQTT (or RAPI).


I see that the web UI can show the last charge energy and elapsed time, but there doesn't seem to be a standard MQTT for this.


Maybe I can get it through a request/response with RAPI but I can't figure that out either.


Thank you!


I've been posting parallel thoughts in this thread on HA: https://community.home-assistant.io/t/hardware-suggestions-to-automate-an-outlet-for-electric-car-charging/94304/15?u=a3a


I bundled almost all the config into a package that's much easier to deal with than having multiple separate files.  The above thread points to my github repo with everything.


Ah HAH! I was a dummy, but I got lucky. It was some variable name stuff. Look what I did!


# Switches
switch:
  - platform: template
    switches:

      openevse_enable:
        friendly_name: "OpenEVSE Enable"
        value_template: >-
          {{- state_attr('sensor.openevse', 'state') | regex_match ( "^[0123]$") -}}
        icon_template: >-
          {%- if state_attr('sensor.openevse', 'state') | regex_match ( "^[0123]$") -%}
            mdi:power-plug
          {%- else -%}
            mdi:power-plug-off
          {%- endif -%}
        turn_off:
          - service: rest_command.openevse_sleep
        turn_on:
          - service: rest_command.openevse_enable

state_attr('sensor.openevse', 'state') was the key variable I needed to look at.


And voila, the beginning of a beautiful thing. I rebooted and saw a nice happy yellow plug in hass.io and now I can sleep soundly.


Thanks Tony!


ps I think we ought to move all this that we came up with in to it's own thread


1 person likes this

I'm having some trouble - My MQTT isn't working right, or it's not integrated right, but I DO have status coming back from my "STATUS" query in rest sensor. I think my trouble is all syntax. Look at the mess I made below..

 

switch:
  - platform: template
    switches:

      openevse_enable:
        friendly_name: "OpenEVSE Enable"
        value_template: >-
          {{- states('sensor.openevse.attributes["state"]') | regex_match ( "^[0123]$") -}}
        icon_template: >-
          {%- if states('sensor.openevse.attributes["state"]') | regex_match ( "^[0123]$") -%}
            mdi:power-plug
          {%- else -%}
            mdi:power-plug-off
          {%- endif -%}
        turn_off:
          - service: rest_command.openevse_sleep
        turn_on:
          - service: rest_command.openevse_enable 

  I don't even know if my variable names are right, and I REALLY am lost with the REGEX_MATCH, and being lazy / not that deep in to C++ or whatever it is, I'm just lost there. 


What I DO know is that the state of the OpenEVSE returns 254 and 255 for sleep and disabled, respectively in my setup, which I've updated to give friendly names as such:


 

  - platform: rest
    force_update: true
    name: OpenEVSE
    value_template: '{{ value_json.state }}'
    json_attributes:
     - srssi
     - amp
     - pilot
     - temp1
     - temp3
     - state
     - elapsed
     - wattsec
     - watthour
    resource: http://10.44.63.30/status/
    method: GET
  - platform: template
    sensors:
      openevse_srssi:
        friendly_name: 'EVSE WiFi Strength'
        unit_of_measurement: 'dBs'
        value_template: '{{ states.sensor.openevse.attributes["srssi"] }}'
      openevse_amp:
        friendly_name: 'EVSE Charge Current'
        unit_of_measurement: 'Amps'
        value_template: '{{ (states.sensor.openevse.attributes["amp"]/1000)|round(1) }}'
      openevse_pilot:
        friendly_name: 'EVSE Pilot Setting'
        unit_of_measurement: 'Amps'
        value_template: '{{ states.sensor.openevse.attributes["pilot"] }}'
      openevse_temp1:
        friendly_name: 'EVSE Temp 1'
        unit_of_measurement: 'ºC'
        value_template: '{{ states.sensor.openevse.attributes["temp1"]/10 }}'
      openevse_temp3:
        friendly_name: 'Temp 3'
        unit_of_measurement: 'ºC'
        value_template: '{{ states.sensor.openevse.attributes["temp3"]/10 }}'
      openevse_state:
        friendly_name: 'EVSE State'
        value_template: >-
          {% if state_attr('sensor.openevse', 'state')==1 %}
            Disconnected
          {% elif state_attr('sensor.openevse', 'state')==2 %}
            Connected
          {% elif state_attr('sensor.openevse', 'state')==3 %}
            Charging
          {% elif state_attr('sensor.openevse', 'state')==4 %}
            Charge Error
          {% elif state_attr('sensor.openevse', 'state')==254 %}
            Sleeping
          {% elif state_attr('sensor.openevse', 'state')==255 %}
            Disabled
          {% else %}
            Parsing failed.
          {% endif %}

 Also hurting me here is that I've never worked with the SWITCH entities, so that could be the problem too. 


Behavior is that the switch always looks "Off" in hass, and when I toggle it on, it toggles back to off in a second or two, and the EVSE sees nothing. BUT those URLs do the job when I send them from a browser, so I know that much is working.  Sorry I'm a dummy, but I'm doing my best!



Oops my Regex above isn't good enough... need "^[0123]$" in order to constrain the match correctly.

It's relatively easy to send commands via RAPI, I haven't tried setting charge rates or timers but simple enable/disable is easy:


The following creates a Home Assistant template switch that will put the OpenEVSE into sleep mode or (re)enable it if it sleeping or disabled: 

rest_command:
  openevse_enable:
    url: 'http://openevse.local./r?json=1&rapi=$FE'
    username: !secret OPENEVSE_USERNAME
    password: !secret OPENEVSE_PASSWORD
    headers:
        User-Agent: Home Assistant
  openevse_disable:
    url: 'http://openevse.local./r?json=1&rapi=$FD'
    username: !secret OPENEVSE_USERNAME
    password: !secret OPENEVSE_PASSWORD
    headers:
        User-Agent: Home Assistant
  openevse_sleep:
    url: 'http://openevse.local./r?json=1&rapi=$FS'
    username: !secret OPENEVSE_USERNAME
    password: !secret OPENEVSE_PASSWORD
    headers:
        User-Agent: Home Assistant

# Switches
switch:
  - platform: template
    switches:

      openevse_enable:
        friendly_name: "OpenEVSE Enable"
        value_template: >-
          {{- states('sensor.openevse_mqtt_state') | regex_match ("[0123]") -}}
        icon_template: >-
          {%- if states('sensor.openevse_mqtt_state') | regex_match ("[0123]") -%}
            mdi:power-plug
          {%- else -%}
            mdi:power-plug-off
          {%- endif -%}
        turn_off:
          - service: rest_command.openevse_sleep
        turn_on:
          - service: rest_command.openevse_enable

 Note that you can't use the HA "rest_switch" since that requires a service that use POST for updates and RAPI uses GET.

Since i found the REST RAPI services to be flaky -- lots of `none` and `unknown` values ending up in my history -- I stuck with MQTT for everything that I can get reliably from there and only created a REST sensor for Session Energy since I haven't figured out how to asynchronously link RAPI MQTT responses.


I will have to check to see if /status is more reliable for me -- thanks for posting.

Here's what I came up with RESTful and a sensor template for reading (only) values from the OpenEVSE in to sensors for Homeassistant / hass.io - and HERE IT IS!


This snippet will live under "sensors" in your configuration.yaml file in homeassistant. Obviously change the IP address to match your charger, which you'll have static if you know what's good for you, and if you have authentication on your OpenEVSE, you'll need to figure that out on your own. 


Enjoy

 

- platform: rest
    force_update: true
    name: OpenEVSE
    value_template: '{{ value_json.state }}'
    json_attributes:
     - srssi
     - amp
     - pilot
     - temp1
     - temp3
     - state
     - elapsed
     - wattsec
     - watthour
    resource: http://10.44.63.30/status/
    method: GET
  - platform: template
    sensors:
      openevse_srssi:
        friendly_name: 'EVSE WiFi Strength'
        unit_of_measurement: 'dBs'
        value_template: '{{ states.sensor.openevse.attributes["srssi"] }}'
      openevse_amp:
        friendly_name: 'EVSE Charge Current'
        unit_of_measurement: 'Amps'
        value_template: '{{ (states.sensor.openevse.attributes["amp"]/1000)|round(1) }}'
      openevse_pilot:
        friendly_name: 'EVSE Pilot Setting'
        unit_of_measurement: 'Amps'
        value_template: '{{ states.sensor.openevse.attributes["pilot"] }}'
      openevse_temp1:
        friendly_name: 'EVSE Temp 1'
        unit_of_measurement: 'ºC'
        value_template: '{{ states.sensor.openevse.attributes["temp1"]/10 }}'
      openevse_temp3:
        friendly_name: 'Temp 3'
        unit_of_measurement: 'ºC'
        value_template: '{{ states.sensor.openevse.attributes["temp3"]/10 }}'
      openevse_state:
        friendly_name: 'EVSE State'
        value_template: >-
          {% if state_attr('sensor.openevse', 'state')==1 %}
            Disconnected
          {% elif state_attr('sensor.openevse', 'state')==2 %}
            Connected
          {% elif state_attr('sensor.openevse', 'state')==3 %}
            Charging
          {% elif state_attr('sensor.openevse', 'state')==4 %}
            Charge Error
          {% else %}
            Parsing failed.
          {% endif %}

        
        
      openevse_elapsed:
        friendly_name: 'Elapsed Time'
        unit_of_measurement: 'minutes'
        value_template: '{{ (states.sensor.openevse.attributes["elapsed"]/60)|int }}'
      openevse_wattsec:
        friendly_name: 'EVSE Session kWh'
        unit_of_measurement: 'kWh'
        value_template: '{{( states.sensor.openevse.attributes["wattsec"] / 3600000) | round(2) }}'
      openevse_watthour:
        friendly_name: 'EVSE Lifetime kWh'
        unit_of_measurement: 'kWh'
        value_template: '{{( states.sensor.openevse.attributes["watthour"] / 1000)| int }}'

Change the line with the     resource: http://10.44.63.30/status/   to whatever YOUR charger IP is, and you should be all set. 


I'm too dumb to set up write access for Homeassistant, so I'll have to pass the baton. 

 For the REST API, a specific example is:


Replace:

  • `openevse.local` with your OpenEVSE WiFi IP address
  • `user` with the username
  • `pass` with the password
curl --digest --user 'user:pass' 'http://openevse.local/r?json=1&rapi=$GU'
$OK 40629846 165327^27


1 person likes this

Here is a document for HTTP.



pdf

Speaking of the HTTP REST API for Home Assistant - What does your resource URL look like? I can't seem to figure out how to configure my RESTful sensor...


Also, there's apparently a "real" openEVSE integration in HomeAssistant, but it's broken and has not yet been fixed, in spite of my best efforts at using the forked version. So that's that and I'm not using it.


Any helpful hints you have would be greatly appreciated with the RESTful approach.


Andy

To get the most-recent charging session (since last unplugged) energy use, publish a message to openevse/rapi/in/$GU and it will respond to openevse/rapi/out with something like $OK 40629846 165327^27


The first number is the most recent session energy in watt-seconds and the second number is the total energy in watt-hours (the ^27 is a checksum from what I read in the source code.)


Unfortunately since every RAPI message is published to a generic topic (/rapi/out), it is impossible to know for sure that message is in response to a particular request.  With my current level-of-knowlege, I cannot use the MQTT RAPI reliably.  I wish that the MQTT RAPI API published the responses to something like /rapi/out/$XX instead of just /rapi/out, then it would be trivial to assign responses correctly even in a multithreaded environment.


Fortunately there is the HTTP REST API and that is what I am using with Home Assistant at the moment.


Login or Signup to post a comment