Skip to content

Example: Home Assistant

Thomas Spalinger edited this page Jun 29, 2022 · 6 revisions

Example setup with Home Assistant

Requirements for the examples

If your setup differs, you need to adapt the specific parts.

  • you have shell access to HA by i.e. the "Terminal & SSH" addon
  • your configuration is available at /config
  • 64bit linux (just change the downloaded binary if you have a different platform)
  • you have packages setup with:
    homeassistant:
      packages: !include_dir_named packages

Initial setup

  1. download and install the binary:

    mkdir -p /config/bin
    cd /config/bin
    curl -L https://github.com/spali/go-rscp/releases/download/v0.1.2/e3dc_0.1.2_Linux_x86_64.tar.gz | tar -xzf - e3dc           
  2. create a directory for additional files

    mkdir -p /config/packages/e3dc
  3. create a config file with your details (replace the <> values with your details). The aes key can be changed in the Web-GUI of the e3dc under "Personalisieren" -> "Benutzerprofil".

    cat << _EOF > /config/packages/e3dc/.config
    host <ip>
    user <username>
    password <password>
    key <aes key>
    _EOF

Create a sensor:

  1. file for the request input

    /config/packages/e3dc/e3dc.json

    [
      "INFO_REQ_TIME",
      "EMS_REQ_BAT_SOC",
      "EMS_REQ_POWER_PV",
      "EMS_REQ_POWER_ADD",
      "EMS_REQ_POWER_BAT",
      "EMS_REQ_POWER_HOME",
      "EMS_REQ_POWER_GRID",
      "EMS_REQ_SELF_CONSUMPTION",
      "EMS_REQ_AUTARKY",
      "EMS_REQ_GET_POWER_SETTINGS",
      "EMS_REQ_GET_MANUAL_CHARGE"
    ]
  2. create an example script

    This script uses jq to put the complete result into a object with a key result. This help's later in the sensor setup to not have to define all returned keys as attributes but just have a single attribute result.

    /config/packages/e3dc/e3dc.sh

    #!/bin/sh
    set -e
    export PATH=/config/bin:$PATH
    cd "$(dirname $0)"
    
    e3dc -file ./e3dc.json | jq -cM '{ "result": . }'

    Ensure it has execution rights chmod +x /config/packages/e3dc/e3dc.sh

  3. create a command_line sensor holding the all requested values.

    /config/packages/e3dc.yaml

    sensor:
      - platform: command_line
        name: e3dc
        command: "/config/packages/e3dc/e3dc.sh"
        command_timeout: 1
        scan_interval: 1
        json_attributes:
          - result
        value_template: "OK"
  4. create as many template sensors as required.

    sensor:
      - platform: template
        sensors:
          e3dc_grid_power:
            friendly_name: Netz
            device_class: power
            value_template: "{{ state_attr('sensor.e3dc', 'result')['EMS_POWER_GRID'] }}"
            unit_of_measurement: W

Example script to execute something on E3DC

  1. create a example script for simple requests:

    cat << _EOF > /config/packages/e3dc/e3dc_request.sh
    #!/bin/sh
    set -e
    export PATH=/config/bin:$PATH
    cd "$(dirname $0)"
    
    echo -n "$(date): " >>e3dc_request.log
    echo -n "${1}" >>e3dc_request.log
    e3dc "$(echo -n "${1}")" >>e3dc_request.log 2>&1
    _EOF
    
    chmod +x /config/packages/e3dc/e3dc_request.sh
  2. create a shell command for generic request to E3DC, which can be used for i.e. switch actions as in the example below.

    append to /config/packages/e3dc.yaml

    shell_command:
      e3dc_request: /config/packages/e3dc/e3dc_request.sh '{{ request | tojson }}'
    
    switch:
      - platform: template
        switches:
          e3dc_power_save:
            friendly_name: Power Save
            turn_on:
              service: shell_command.e3dc_request
              data_template:
                request: >-
                  {{ [['EMS_REQ_SET_POWER_SETTINGS', [
                      ['EMS_POWERSAVE_ENABLED', "UChar8", 1]
                  ]]] }}
            turn_off:
              service: shell_command.e3dc_request
              data_template:
                request: >-
                  {{ [['EMS_REQ_SET_POWER_SETTINGS', [
                      ['EMS_POWERSAVE_ENABLED', "UChar8", 0]
                  ]]] }}
            value_template: "{{ state_attr('sensor.e3dc', 'result')['EMS_GET_POWER_SETTINGS']['EMS_POWERSAVE_ENABLED'] if state_attr('sensor.e3dc', 'result') else None }}"

Additional notes

  • I suggest, you split the polling into a fast polling sensor and a slow polling sensor. i.e. the above example could be polled fast with 1 to 5 second interval. You can also create a additional sensor that has a scan_interval of 30 or more for more static data like

    [
      "INFO_REQ_SW_RELEASE",
      "INFO_REQ_MAC_ADDRESS",
      "INFO_REQ_SERIAL_NUMBER",
      "SRV_REQ_IS_ONLINE",
      "EMS_REQ_STATUS",
      "EMS_REQ_GET_SYS_SPECS"
    ]

    you can even go further and do DB_REQ_HISTORY_DATA_DAY requests to get historical data, which usually do not require high interval polling, see Request for historical data for an example.

  • You even more abstract the requests to be reused, i.e. a script for manual charge which can be called by a switch on/off action with the amount filled by data_template from an input_number:

    script:
      e3dc_manual_charge:
        alias: Starte oder stoppe manuelle Ladung
        fields:
          amount:
            description: "Ladungsmenge in Wh"
            example: "4500"
        icon: mdi:flash
        mode: single
        sequence:
          - service: shell_command.e3dc_request
            data_template:
              request: >-
                {{ [['EMS_REQ_START_MANUAL_CHARGE', amount | int if amount is defined else 0]] }}