ich beschäftige mich seit quasi gestern Abend mit Python [...].
Ich arbeite seit einigen Wochen an batteriebetriebenen Funk-Temperatursensoren auf ATTiny84-Basis, die ihre Daten an einen zentralen Arduino per 433 Mhz funken.
Bisher war das ein kleiner Arduino Ethernet, der die Daten direkt an ein PHP-Webscript übergeben hat - da ich aber dadurch "Kabelgebunden" bin (da gibts kein WLan...), wollte ich mich mal versuchen einen einfachen Arduino an einen Raspberry Pi zu klemmen: Der läuft mit einem WLan-Stick und frisst die Arduino-Daten per COM.
Okay, soviel dazu: Mein Arduino spuckt die Daten am Raspberry Pi aus. Ich habe es auch geschafft, per python3-serial die Daten auszulesen, und per urllib.request an mein Webscript zu übergeben (GET).
Nachfolgend mal der Code:
Code: Alles auswählen
# Benötigt: python3-serial
import serial
import urllib.request
import sys
import datetime
#sys.stdout = open('/dev/null', 'w')
#sys.stdout = open('/var/log/serialread.log', 'w')
ser = serial.Serial('/dev/ttyACM0', 9600)
while 1:
time = datetime.datetime.now()
rs232 = ser.readline().decode("ascii")
print("Uhrzeit: ", time, end="\n")
print("Empfangene Daten: ", rs232, end="\n")
url = 'http://www.xxx.de/attiny/parse.php?r=1&key=xxxxx&' + rs232 #.decode("ascii")
urlrequest = urllib.request.urlopen(url).read()
urlrequest = urlrequest.decode("ascii")
print("URL: ", url, end="\n")
print("Ergebnis: ", urlrequest, end="\n")
print("--------", end="\n")
Manchmal macht das - aus welchem Grund auch immer - Probleme, den manchmal kommt beim Raspberry nicht der komplette Datenstring an, sondern nur ein Teil - oder ein kauderwelsch aus zwei Datenstrings, Beispiel: s=1s=3&t=1990&h=6840&v=4615.
Der Part "s=1" gehört zum vorherigen Datenpaket - allerdings fängt das damit an; wo der Rest dessen geblieben ist, weiß ich nicht.
Kurzum: Kommt nicht alles an, spuckt er mir folgende Meldung aus:
Code: Alles auswählen
pi@raspi01 ~/serialread $ python3 serialread.py
Uhrzeit: 2013-12-28 20:51:16.024846
Empfangene Daten: ss=3&t=1979&h=6830&v=4635
Traceback (most recent call last):
File "serialread.py", line 21, in <module>
urlrequest = urlrequest.decode("ascii")
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe4 in position 226: ordinal not in range(128)
Was ich aber nicht verstehe: Die Daten die von der seriellen Schnittstelle gelesen werden MÜSSEN doch ASCII sein; schließlich klappts ja - wenn der Fehler nicht gleich auftaucht - ohne Probleme.
Wie kann ich soetwas abfangen oder verhindern? Später soll das Script als Daemon oder per Cronjob täglich gestartet werden - wenn's einmal aussteigt, kriege ich das vermutlich nicht mit, und mir fehlen dann (im schlimmsten Fall) einen ganzen Tag Messwerte.
*Update*
Ich habe mal von ASCII auf UTF-8 umgeschwenkt; wenn ich mich richtig erinnere, sind alle Standard-Strings in Python 3 UTF-8 kodiert - kann also nicht schaden.
Anscheinend passiert obiger Fehler auch vereinzelt bei der Antwort der WebRequest:
Code: Alles auswählen
Traceback (most recent call last):
File "serialread.py", line 23, in <module>
urlrequest = urllib.request.urlopen(url).read().decode("utf-8") # Web-Parse-Request absetzen und Statusausgabe in UTF-8 konvertieren
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe4 in position 226: invalid continuation byte