[OpenTRV-dev] python opentrv to emoncms script...

Bo Herrmannsen bo.herrmannsen at gmail.com
Tue Oct 6 22:11:39 BST 2015


ok will give it a go....

2015-10-06 23:01 GMT+02:00 Bruno Girin <brunogirin at gmail.com>:

> Bo,
>
> The data is JSON. However, because of the way your code reads the data, it
> starts reading the beginning of the second line. See the additional { in
> the message (first character second line):
>
> {"@":"151f","+":4,"T|C16":336,"O":1,"vac|h":94,"v|%":0}
> *{*Traceback (most recent call last):
>
> So you need to add detection of the newline in your code to ensure that
> the string you pass to json.loads is a single line and if you have more
> characters after that newline, push them to the next. A good way to do this
> would be using a generator function, so something like:
>
> def read_lines_from_serial(ser):
>     while 1:
>        # Read from serial port, blocking
>        data = ser.read(1)
>
>        # If there is more than 1 byte, read the rest
>        n = ser.inWaiting()
>        if n:
>            data = data + ser.read(n)
>            lines = data.splitlines()
>            # iterate over all lines except the last one
>            # (will do nothing if no newlines in data)
>            for l in lines[:-1]:
>                yield l
>            # assign the last line to data so that we can keep appending to
> it
>            data = lines[-1]
>
> Then you should be able to call your function like this:
>
> for d in read_lines_from_serial(ser):
>     j = json.loads(d)
>     # do whatever is sensible with j
>
>
> On 6 October 2015 at 21:40, Bo Herrmannsen <bo.herrmannsen at gmail.com>
> wrote:
>
>> could it be that the data is not json but just looks like it?
>>
>> 2015-10-06 22:00 GMT+02:00 Bo Herrmannsen <bo.herrmannsen at gmail.com>:
>>
>>> now the script is:
>>>
>>> import sys
>>> import serial
>>> import json
>>>
>>> port = "/dev/ttyUSB0"
>>> baud = 4800
>>>
>>> ser = serial.Serial()
>>> ser.port = port
>>> ser.baudrate = baud
>>>
>>> try:
>>>    ser.open()
>>> except:
>>>    sys.stderr.write("Error opening serial port %s\n" % (ser.portstr) )
>>>    sys.exit(1)
>>>
>>> ser.setRtsCts(0)
>>>
>>> while 1:
>>>    # Read from serial port, blocking
>>>    data = ser.read(1)
>>>
>>>    # If there is more than 1 byte, read the rest
>>>    n = ser.inWaiting()
>>>    if n:
>>>        data = data + ser.read(n)
>>>
>>>
>>>
>>>    sys.stdout.write(data)
>>>
>>>    if data.startswith('{'):
>>>
>>>     j = json.loads(data)
>>>     print j['@']
>>>
>>>
>>>
>>> my logic is to print what comes in from serial and that part works fine
>>>
>>> i then want to build on it and if we have a json string then write just
>>> the units id...
>>>
>>> the last part is failing me.. i get:
>>>
>>>
>>> {"@":"151f","+":4,"T|C16":336,"O":1,"vac|h":94,"v|%":0}
>>> {Traceback (most recent call last):
>>>   File "opentrvimport.py", line 35, in <module>
>>>     j = json.loads(data)
>>>   File "/usr/lib/python2.7/json/__init__.py", line 326, in loads
>>>     return _default_decoder.decode(s)
>>>   File "/usr/lib/python2.7/json/decoder.py", line 365, in decode
>>>     obj, end = self.raw_decode(s, idx=_w(s, 0).end())
>>>   File "/usr/lib/python2.7/json/decoder.py", line 381, in raw_decode
>>>     obj, end = self.scan_once(s, idx)
>>> ValueError: Expecting object: line 1 column 0 (char 0)
>>>
>>>
>>> 2015-10-06 17:05 GMT+02:00 Bo Herrmannsen <bo.herrmannsen at gmail.com>:
>>>
>>>> Hi
>>>>
>>>> I started on a script that can read serial data from a rev2 unit and
>>>> send the data on to emoncms.
>>>>
>>>> i get this on the serial line
>>>>
>>>> {"@":"2800","+":4,"T|C16":544,"vC|%":2340,"O":1}
>>>>
>>>>
>>>> and so far i have this python script
>>>>
>>>>
>>>> import serial
>>>> import io
>>>> import time
>>>> ser = serial.Serial('/dev/ttyUSB0',4800)
>>>>
>>>>
>>>> sio = io.TextIOWrapper(io.BufferedRWPair(ser, ser, 1),
>>>> encoding='ascii',newline='\r\n')
>>>>
>>>> while ser.isOpen():
>>>>
>>>>           datastring = sio.readline()
>>>>
>>>> print datastring
>>>>
>>>>
>>>>
>>>>
>>>> the serial data end with CRLF
>>>>
>>>> but it does not print anything.... where am i wrong?
>>>>
>>>> before i used this script:
>>>>
>>>> import serial
>>>> import time
>>>> s = serial.Serial('/dev/ttyUSB0',4800)
>>>>
>>>> while 1:
>>>>    if s.inWaiting():
>>>>       val = s.read(s.inWaiting())
>>>>       print val
>>>>
>>>> but then i got:
>>>>
>>>> {"@":"0950","
>>>> +":
>>>> 5,"
>>>> t
>>>> T|C
>>>> ":
>>>> 1
>>>> 9,"
>>>> vC|%
>>>> ":
>>>> 20
>>>> 0,"
>>>> T|
>>>> C
>>>> 1
>>>> 6":
>>>> 33
>>>> 1}
>>>>
>>>>
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> OpenTRV-dev mailing list
>> OpenTRV-dev at lists.opentrv.org.uk
>> http://lists.opentrv.org.uk/listinfo/opentrv-dev
>>
>>
>
> _______________________________________________
> OpenTRV-dev mailing list
> OpenTRV-dev at lists.opentrv.org.uk
> http://lists.opentrv.org.uk/listinfo/opentrv-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.opentrv.org.uk/pipermail/opentrv-dev/attachments/20151006/455a1622/attachment-0001.html>


More information about the OpenTRV-dev mailing list