Question

I have a python (2.7) script that reads incoming data over a serial port in the following form:

ID: 648 Data: 45 77 33 9C 26 9A 1F 42
ID: 363 Data: 35 74 36 BC 26 9D 
...

The data stream contains several different ID's (about 30) that repeat periodically with 2-8 data bytes. The frequency of the ID's ranges from 10-120 ms. Some ID's repeat sooner than others.

Anyway, I have a basic python script that reads this stream into 2 variables, (id and data):

import serial
import re

ser = serial.Serial("COM11", 115200)

while 1:
    reading = ser.readline()
    matchObj = re.match( r'ID:\s([0-9A-F]+)\sData:\s([^\n]+)', reading, re.M|re.I)
    if matchObj:
        id = matchObj.group(1)
        data = matchObj.group(2)
    else:
        print "No match!!"

What I want to do is display this data in real time in a data table format where new ID entries are added to the table and repeated ID entries are updated. This would result in a table that would initially grow with the discovery of the ID's, then update as the data for the ID's changed.

I have seen some examples of table modules that let you add rows to a table, but I also need to be able to modify existing entries as that is what will be happening most often.

I am still pretty new with python and I need an implementation that does not have excessive overhead to keep the data updating as fast as possible.

Any thoughts?? Thanks in advance!

Was it helpful?

Solution

curses is the go-to for terminal displays.

#!/usr/bin/env python
import curses
import time

def updater():
    fakedata = [[1, 78], [2, 97], [1, 45], [2, 2], [3, 89]]
    codes_to_linenums_dict = {}
    last_line = 0
    win = curses.initscr()
    for code, data in fakedata:
        try:
            # if we haven't seen this code before, give it the next line
            if code not in codes_to_linenums_dict:
                codes_to_linenums_dict[code] = last_line
                last_line += 1
            # use the line we set for this code.
            line = codes_to_linenums_dict[code]
            win.addstr(line, 0, '{}: {}    '.format(code, data))
            win.refresh()
            # For display only
            time.sleep(2)
        except KeyboardInterrupt:
            # if endwin isn't called the terminal becomes unuseable.
            curses.endwin()
            raise
    curses.endwin()

if __name__ == '__main__':
    updater()

~

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top