Montag, 13. April 2020

Make old S300TH sensors work with Home Assistant

Years ago the S300TH was one of the cheapest wireless temperature sensor you could buy. I managed to buy eight of them for 5 Euros a piece. Its broadcasting on the 868Mhz band and the batteries last for years. When switching from OpenHab to Home Assistant, integrating these sensors was the hardest part so far, since I could not find any HA support for S300TH, FS20 or similar.

In FHEM and OpenHab the sensors are integrated using the busware.de CUL USB-stick using the custom firmware CULFW (see step 1 for flashing the stick, I am using v1.44). After this, receiving data is as easy as listening to a serial stream from /dev/ttyACM0. This can be easily tested on your Mac or Linux computer, and is described in the CULFW Reference under "quicktest".

One data package comes in the form:   "KaaTTHTHH", where 
  • K is the code for S300TH,
  • aa is the device number
  • T is temperature, 
  • and H is humidity.
How to decode this was not entirely clear from the reference page, but this post helped:

H = line.charAt( 7 ) + line.charAt( 8 ) + "." + line.charAt( 5 );
T = line.charAt( 6 ) + line.charAt( 3 ) + "." + line.charAt( 4 );

Two example packages and its decoding:

K1122623436 => Sensor 1: T22.2 H34.6
K41106245E7 => Sensor 2: T21.0 H45.6


Now we have everything we need to integrate with home assistant.
We are going to use the HA serial sensor platform to listen to /dev/ttyACM0.

Add the following to your configuration.yaml to receveive the temperature values for sensor 0:




sensor:
  - platform: serial
    serial_port: /dev/ttyACM0
  

  - platform: template
    sensors:
      temperature_sensor0:
        friendly_name: Temperature Room 0
        unit_of_measurement: "°C"
        value_template: >
          {% if states('sensor.serial_sensor')[1] == '0' %}
          {{ (states('sensor.serial_sensor')[6] ~ states('sensor.serial_sensor')[3] ~ states('sensor.serial_sensor')[4]) | float / 10 }}
          {% else %}
          {{ states('sensor.temperature_sensor0') }}
          {% endif %}



Note, the decoding of the "6-4-3" pattern using templates. Also we have to decode the sensor device number and ignore all other sensors that are not "0". In this case we will just report the current value (line before endif). This is not a nice solution, sine it will create additional data points in the data base, but I haven't found a better solution yet.


To decode the other sensors, simply add a temperature_sensor1, etc. and change '0' to '1' and also return 'temperature_sensor1'. Add sensor entries for humiditiy accordingly.

After adding this code, you will notice, that nothing will happen. The reason is, that you first have to tell the CUL to report incoming packets. Unfortunately, the Home Assistant serial platform does not support sending, only receiving. Instead we will use a simple 'echo' shell command. Add the following to configuration.yaml:


shell_command:
  start_cul: "echo -e 'X21\x0a' > /dev/ttyACM0"



Now call this command from an automation action. Add the following to automation.yaml:

- id: '1586784995017'
  alias: Start CUL
  description: ''
  trigger:
  - minutes: /5
    platform: time_pattern
  condition: []
  action:
  - data: {}
    service: shell_command.start_cul


We could have used an even trigger "homeassistant" and only call the shell_command on start up, but I was not sure about the start up sequence (I guess, serial has to configure the connection parameters first).

This work smoothly for my seven sensors so far and saved me some money for buying newer (and fancier) sensors.

Donnerstag, 9. April 2020

Home Assistant with ESPEasy Switch and REST

I flashed a cheap Sonoff S20 power plug switch with ESPEasy years ago (see this blog post) and wanted to see how easy I could add this switch to my new Home Assistant environment.

The common way to control this from a home automation environment seems to be MQTT -  including all kind of problems. Since ESPEasy provides a simple REST api there must be a direct way to integrate the switch into Home Assistant.


Turning the switch on is a simple http GET call with the last number beeing 0 for off and 1 for on:


Reading the state is also simple:

First try was using the RESTful Switch from HA, but it expects the switch command to be a http POST. Unfortunately ESPEasy expects a GET command.

Finally, I used the command_line switch from HA in combination with simple curl calls. This is the working code from configuration.yam:


switch:

  - platform: command_line
    scan_interval: 5
    switches:
      connection_octoprint:
        friendly_name: "ESPEasy Switch"
        command_on: "curl http://192.168.178.63/control?cmd=GPIO,12,1"
        command_off: "curl http://192.168.178.63/control?cmd=GPIO,12,0"
        command_state: "curl http://192.168.178.63/control?cmd=status,GPIO,12"
        value_template: "{{ '\"state\": 1' in value }}"


And do not forget to add the following rule to your ESPEasy device (using the ESPEasy web interface):

On Button#State=1 do
  if [Relay#State]=0
    gpio,12,1
  else
    gpio,12,0
  endif
endon

This way the switch works in both directions: pressing the button on the device or by switching from HA - and the state is correctly displayed in HA and on the device using the LED. Note the delay of 5 seconds for showing the switch state in HA after pressing the device button. This is due to the polling interval. 

Switch in Home Assistant

Configuration of ESPEasy