Using serial sensor for reading JSON output from Arduino?

Hello,

I’m trying to setup serial sensor based on HASS documentation:

So… I wrote sketch on my arduino delivering json results (according to documentation on “sensor.serial”)

local picocom returning following results:

$ picocom -b 115200 /dev/ttyUSB0
...
{"channel_1":1,"temperature_1":15.6,"humidity_1":50,"battery_1":90}

I setup serial sensor on… hass side:

sensor:
  - platform: serial
    baudrate: 115200
    serial_port: /dev/ttyUSB0

It looks like that hass launching serial sensor component properly.

I can see entity:

image

And… nothing is happening… any changes in states or attributes or logs…

logger entries:

  homeassistant.components.sensor: debug
  homeassistant.components.serial: debug
  homeassistant.components.sensor.serial: debug

How can I troubleshoot this situation?

Regards,
M

I run out ideas. anyone?

I’ve tried to use serial_asyncio module directly… using example from asycio page:

import asyncio
import serial_asyncio

class Output(asyncio.Protocol):
    def connection_made(self, transport):
        self.transport = transport
        print('port opened', transport)
        transport.serial.rts = False
        transport.write(b'hello world\n')

    def data_received(self, data):
        print('data received:', repr(data))
        self.transport.close()

    def connection_lost(self, exc):
        print('port closed')
        asyncio.get_event_loop().stop()

loop = asyncio.get_event_loop()
coro = serial_asyncio.create_serial_connection(loop, Output, '/dev/ttyUSB0', baudrate=115200, bytesize=8)
loop.run_until_complete(coro)
loop.run_forever()
loop.close()

And it looks like that there is no problem with this module, I receive proper output:

port opened SerialTransport(<_UnixSelectorEventLoop running=True closed=False debug=False>, <__main__.Output object at 0x764d09b0>, Serial<id=0x764d06b0, open=True>(port='/dev/ttyUSB0', baudrate=115200, bytesize=8, parity='N', stopbits=1, timeout=0, xonxoff=False, rtscts=False, dsrdtr=False))
data received b'{"channel_1":1,"temperature_1":1'
data received b'7.5,"humidity_1":45,"battery_1":'
data received b'90}'
port closed

So… it points into “serial sensor” module in hass…

turn on debugging in logger. According to the source code, a debug line should appear when HA attempts to access the serial sensor:

_LOGGER.debug("Received: %s", line)

@petro: Thank you for sugestion. I have already turned on full logging on hass.

There are initial setup messages for serial sensor in logs:

2018-04-24 19:50:00 INFO (MainThread) [homeassistant.core] Bus:Handling <Event state_changed[L]: old_state=None, new_state=<state sensor.serial_sensor=unknown; friendly_name=Serial Sensor @ 2018-04-24T19:50:00.958557+02:00>, entity_id=sensor.serial_sensor>

However there are no any kind of “Received” entries.

I’ve check the code of serial.py
https://github.com/home-assistant/home-assistant/blob/master/homeassistant/components/sensor/serial.py

And it looks like that it stops on:

line = yield from reader.readline()

Try making a custom component with that serial.py. Add your own debug lines to it to verify. That whole section would be silent. It could be stuck on the while loop after or the serial constructor before.

Thats what I made…

_LOGGER.debug("BEFORE READLINE")
line = yield from reader.readline()
_LOGGER.debug("AFTER READLINE")

As a results I have only:
2018-04-24 19:50:01 DEBUG (MainThread) [homeassistant.components.sensor.serial] BEFORE READLINE

That’s a pretty standard function in python, looks like it can’t read the file/information.

I found the problem!

I answer myself… maybe it helps someone.

The problem was in… lack of “\n” and the end of each line received over serial (readline expects that!).
In my case my arduino sketch sent just json’s lines…without proper line ending.
So I added:
Serial.println();
after sending my json string in my sketch and… it resolved the problem.

@petro: thank you! you helped me a lot. Sometimes just pointing at some direction results in different perspective of the problem.

1 Like

that makes sense. any split line function is looking for the end of a line… its always something simple.

Necro’d this aging thread to mention the wonderful arduinojson.h library… in case others are looking in to setting up a similar thing.

I used this library for the code on my nano that sends 4 raw adc values to hass for doorbell, mains power, ups power, and backup battery voltage. It saved me from having think about formatting print statements… instead I could focus on the app specific stuff, like timing and anti-spam. The library made this the easiest/quickest/shortest arduino project I have ever done (yes I skipped right past the ‘blink’ examples etc lol).

1 Like

I’ve posted this as a bug now, a few years later:

Because I have the same problem and can’t change the transmitted data.

If you have a solution, please comment on the issue. Thanks.

1 Like

the serial sensor integration needs a massive update. +1

What else needs to be updated in serial sensor integration?

If i had to say at random,

allowing a custom string to be set as the ‘end of line’ for each integration, as i have a few usb devices that act differently, some using \r some using \n some using \r and \n.

having a custom ‘polling’ option, as some of my usb devices dont consistenly give a update at a timed interval, where as other devices do send an update every 60 seconds.

and with that option also, being able to set the command sent to poll the device.

I imagine the new ‘template sensor’ can semi-handle the task, but ive yet to try to implement it in a way that suits my needs.

same for a an initial connected command.

I have

  • numerous USB-EZO devices by atlas scientific.
  • A few Numato-USB devices by Numato
  • a few USB-Relays that have their own language by themself, but similar to Dekovis USB relays.

They all work in their own special way.

Then my arduino uno i use to test my usb integration as i cant always tell if what im doing is going to work without debugging from my windows computer.

Working on something similar.
I’ve got the JSON string coming in to a sensor named sensor.nano (verified in the Template editor), but I’m now struggling to pull out the individual values (ie temperature and humidity).
How did you do it?