-
-
Save g3ntleman/e7f4349d690aa3ffbc371b8efec30647 to your computer and use it in GitHub Desktop.
Scrape serial port for text data and publish on MQTT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# | |
#simple app to read string from serial port | |
#and publish via MQTT | |
# | |
#uses the Python MQTT client from the Mosquitto project | |
#http://mosquitto.org | |
# | |
#Andy Piper http://andypiper.co.uk | |
#2011/09/15 | |
import serial | |
import os | |
import binascii | |
import time | |
import paho.mqtt.client as mqtt | |
import paho.mqtt.publish as publish | |
serialdev = '/dev/ttyUSB0' | |
broker = "127.0.0.1" | |
port = 1883 | |
#MQTT callbacks | |
def on_connect(rc): | |
if rc == 0: | |
#rc 0 successful connect | |
print("Connected") | |
else: | |
raise Exception | |
def on_publish(val): | |
print("Published ", val) | |
#called on exit | |
#close serial, disconnect MQTT | |
def cleanup(): | |
print("Ending and cleaning up") | |
ser.close() | |
mqttc.disconnect() | |
try: | |
print("Connecting... ", serialdev) | |
#connect to serial port | |
ser = serial.Serial(serialdev, baudrate=9600, timeout=20) | |
except: | |
print("Failed to connect serial") | |
#unable to continue with no serial input | |
raise SystemExit | |
try: | |
ser.flushInput() | |
#create an mqtt client | |
mypid = os.getpid() | |
client_uniq = "power-pub-"+str(mypid) | |
mqttc = mqtt.Client(client_id=client_uniq) | |
#attach MQTT callbacks | |
mqttc.on_connect = on_connect | |
mqttc.on_publish = on_publish | |
#connect to broker | |
mqttc.connect(broker, port, 60) | |
#remain connected to broker | |
#marker byte-sequences: | |
start = '1b1b1b1b01010101' | |
end = '1b1b1b1b1a' | |
data = '' | |
reading = {} | |
lastReading = None | |
while True: | |
bytes = ser.read(1) | |
bytestring = binascii.hexlify(bytes).decode('ascii') | |
data = data + bytestring | |
#print(bytestring + ' ', end='', flush=True) | |
pos = data.find(start) | |
if (pos != -1): | |
data = data[pos:len(data)] | |
pos = data.find(end) | |
if (pos != -1): | |
#print('found ' + data[16:pos] + '\n') | |
search = '070100020800ff' | |
pos = data.find(search) | |
if (pos != -1): | |
pos = pos + len(search) + 20 | |
value = data[pos:pos + 10] | |
scale = pow(10,-1) # todo: read from data | |
energyWatth = int(value, 16) * scale | |
energyKWh = energyWatth / 1000.0 | |
#print('Power Sent (' + search + ') : 0x', value, ' = ', "{:10.3f}".format(energyKWh), ' kWh') | |
publish.single("net-power/sent-total", payload=energyWatth, qos=0, retain=False) | |
reading['sent-total'] = energyWatth | |
search = '070100010800ff' | |
pos = data.find(search) | |
if (pos != -1): | |
pos = pos + len(search) + 20 | |
value = data[pos:pos + 10] | |
scale = pow(10,-1) # todo: read from data | |
energyWatth = int(value, 16) * scale | |
energyKWh = energyWatth / 1000.0 | |
#print('Power Received (' + search + ') : 0x', value, ' = ', "{:10.3f}".format(energyKWh), ' kWh') | |
publish.single('net-power/recieved-total', payload=energyWatth, qos=0, retain=False) | |
reading['received-total'] = energyWatth | |
search = '070100010700ff' | |
pos = data.find(search) | |
if (pos != -1): | |
pos = pos + len(search) + 14 | |
value = data[pos:pos + 8] | |
power = int(value, 16) / 1e2 | |
print ('W: ' + search + ' = ' + value + ' = ' + str(power) + ' W') | |
readingTime = time.time() | |
reading['time'] = readingTime | |
if (lastReading is not None): | |
lastReadingTime = lastReading['time'] | |
duration = readingTime-lastReadingTime | |
if (duration > 10.0): | |
consumptionWh = (reading['received-total'] - lastReading['received-total']) - \ | |
(reading['sent-total'] - lastReading['sent-total']) | |
consumptionWs = consumptionWh * 3600.0; | |
timestamp = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(readingTime)) | |
print(timestamp, 'Average Power Consumption, 10s:', '{:0.1f}'.format(consumptionWs/duration), 'Watt') | |
# Reset reading: | |
lastReading = reading.copy() | |
reading = {} | |
#else: | |
#print('Elapsed', "{:2.1f}".format(duration)+ 's. ', 'Collecting...') | |
#print('lastReading ', str(lastReading)) | |
#print('reading ', str(reading)) | |
else: | |
print('initializing lastRead.') | |
lastReading = reading.copy() # initial setting | |
data = '' | |
# print("got ", line) | |
#split line as it contains V,temp | |
#list = line.split(",") | |
#second list element is temp | |
#temp = 1 | |
#list[1].rstrip() | |
#mqttc.publish("net-power/rec", temp) | |
#pass | |
# handle list index error (i.e. assume no data received) | |
except (IndexError): | |
print("No data received within serial timeout period") | |
cleanup() | |
# handle app closure | |
except (KeyboardInterrupt): | |
print("Interrupt received") | |
cleanup() | |
except (RuntimeError): | |
print("uh-oh! time to die") | |
cleanup() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
# | |
#simple app to read string from serial port | |
#and publish via MQTT | |
# | |
#uses the Python MQTT client from the Mosquitto project | |
#http://mosquitto.org | |
# | |
#Andy Piper http://andypiper.co.uk | |
#2011/09/15 | |
import serial | |
import os | |
import paho.mqtt.client as mqtt | |
serialdev = '/dev/ttyUSB0' | |
broker = "127.0.0.1" | |
port = 1883 | |
#MQTT callbacks | |
def on_connect(rc): | |
if rc == 0: | |
#rc 0 successful connect | |
print("Connected") | |
else: | |
raise Exception | |
def on_publish(val): | |
print("Published ", val) | |
#called on exit | |
#close serial, disconnect MQTT | |
def cleanup(): | |
print("Ending and cleaning up") | |
ser.close() | |
mqttc.disconnect() | |
try: | |
print("Connecting... ", serialdev) | |
#connect to serial port | |
ser = serial.Serial(serialdev, baudrate=9600, bytesize=7, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, timeout=20) | |
except: | |
print("Failed to connect serial") | |
#unable to continue with no serial input | |
raise SystemExit | |
try: | |
ser.flushInput() | |
#create an mqtt client | |
mypid = os.getpid() | |
client_uniq = "arduino_pub_"+str(mypid) | |
mqttc = mqtt.Client(client_id=client_uniq) | |
#attach MQTT callbacks | |
mqttc.on_connect = on_connect | |
mqttc.on_publish = on_publish | |
#connect to broker | |
mqttc.connect(broker, port, 60) | |
#remain connected to broker | |
#read data from serial and publish | |
while mqttc.loop() == 0: | |
line = ser.readline() | |
print("got ", line) | |
#split line as it contains V,temp | |
#list = line.split(",") | |
#second list element is temp | |
temp = 1 | |
#list[1].rstrip() | |
mqttc.publish("net-power/rec", temp) | |
pass | |
# handle list index error (i.e. assume no data received) | |
except (IndexError): | |
print("No data received within serial timeout period") | |
cleanup() | |
# handle app closure | |
except (KeyboardInterrupt): | |
print("Interrupt received") | |
cleanup() | |
except (RuntimeError): | |
print("uh-oh! time to die") | |
cleanup() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment