Der Programmablauf ist folgender:
1. Initialisieren der Logdatei, der seriellen Schnittstelle und einem zyklischen Timer
2. Senden einer Requestbotschaft über RS232 an den Laderegler (zyklisch alle 10 Sekunden für 24h)
3. Empfangen der Antwort und Schreiben der Werte in eine Zeile der CSV-Datei (Logdatei) / (genau wie 2. auch zyklisch in gleicher Funktion)
4. Schließen der Logdatei
Code: Alles auswählen
#!/usr/bin/env python3
import serial
import repeat_timer
import csv
import time
import sys
import random
import array
import socket
#Example for response: eb90eb90eb9000a0180102030405060708090a0b0c0d0e0f101112131415161718ffff7f
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
udphost = "xxx.no-ip.biz"
udpport = 50000
log_filename = "Log_Solarlogger_" + time.strftime("Date_%d_%m_%y_Time_%H_%M_%S_number")+ str(random.randint(1, 10000)) + ".csv"
timer_period = 10
period_counter = 0
time_to_complete = 86400
if sys.platform == "linux2":
directory = "//home//pi//"
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BOARD)
GPIO.setup(12, GPIO.OUT)
GPIO.output(12, GPIO.HIGH)
if sys.platform == "win32":
directory = "C://Python34//"
request_cmd = array.array('B',[0xEB,0x90,0xEB,0x90,0xEB,0x90,0x01,0xA0,0x01,0x03,0xbd,0xbb,0x7f]).tostring()
response_no_of_bytes = 36
try:
csv_file = open(directory + log_filename,'w', newline='')
csv_handler = csv.writer(csv_file)
except:
print ("Error: Can not open file for write access. File may be open")
print (sys.exc_info())
csv_file.close()
exit(-1)
if sys.platform == "linux2":
si = serial.Serial()
si.port = "/dev/ttyAMA0"
if sys.platform == "win32":
si = serial.Win32Serial()
si.port = 2
si.baudrate = 9600
si.dsrdtr = False
si.parity = 'N'
si.timeout = 5
def request_data(req,response_no_of_bytes):
global s, udphost, udpport, si, time_start, csv_handler, csv_file, period_counter
try:
period_counter += 1
if (period_counter%2==0):
GPIO.output(12, GPIO.LOW)
else:
GPIO.output(12, GPIO.HIGH)
si.write(req)
time_since_start = time.time() - time_start
print("Request from logger @ " + str(time_since_start) + "s")
resp = si.read(response_no_of_bytes)
si.flush()
time_since_start = time.time() - time_start
if (len(resp)== response_no_of_bytes):
print("Response from charger @ " + str(time_since_start) + "s, Response Length: " + str(len(resp)) + ", Response: " + str(resp))
try:
s.sendto(resp, (udphost, udpport))
except socket.error:
print("No network connection")
csv_handler.writerow([time.asctime(),time_since_start,resp[6],resp[7],resp[8],(resp[9] + resp[10]*256)/100,(resp[11] + resp[12]*256)/100,(resp[15] + resp[16]*256)/100,(resp[17] + resp[18]*256)/100,(resp[19] + resp[20]*256)/100,resp[21],resp[22],resp[23],resp[25],resp[26],resp[27],resp[28],resp[29]-30,(resp[30] + resp[31]*256)/100])
else:
print("No response from charger @ "+ str(time_since_start) +"s, Response length: " + str(len(resp)) + " !")
try:
s.sendto(b"hallo", (udphost, udpport))
except socket.error:
print("No network connection")
csv_handler.writerow([time.asctime(),time_since_start,"","","","","","","","","","","","","","","","",""])
except:
print("Error @ " + str(time_since_start) + "s ,Reason: " + sys.exc_info())
csv_handler.writerow(["Error @ "+ str(time_since_start) + "s", "Period " + str(period_counter)])
csv_file.close()
try:
si.open()
print("Serial port " + si.name + " opened")
except serial.serialutil.SerialException:
print ("Error: Can not open serial port. Serial port may be open already")
exit(-2)
except:
print(sys.exc_info())
exit(-2)
try:
if (si.isOpen()):
print("Starting cyclic request of data")
csv_handler.writerow(["Logging start: " + time.strftime("%H %M %S")," Logging period: " + str(timer_period)," Logging time: " + str(time_to_complete)])
csv_handler.writerow(["Time","Time since Start","ID","Command","Number of Bytes","Battery Voltage","PV Voltage","Load Current","Overdischarge Voltage","Full Voltage","Load detected?","Overloaded?","Short circuit?","Overcharged?","Battery voltage too low?","Batter voltage full?","Charging?","Temperature","Charging current"])
print("Cyclic timer started (period = "+ str(timer_period) + "s). Logging for " + str(time_to_complete) +"s ...")
time_start = time.time()
cyclic_timer = repeat_timer.RepeatedTimer(timer_period,True,request_data,request_cmd,response_no_of_bytes)
time.sleep(time_to_complete)
cyclic_timer.stop()
time.sleep(1) #wait for cyclic timer thread to stop
print("Cyclic timer stopped. Logging finished")
print("Finished cyclic request of data")
except:
print("Error 1")
print(sys.exc_info())
finally:
if (si.isOpen()):
print("Closed serial port")
si.close()
if (csv_file.closed == False):
print("Closing file")
csv_file.close()
if sys.platform == "linux2":
GPIO.output(12, GPIO.LOW)
GPIO.cleanup()
print("End")
exit(0)
Logging start: 20 04 24, Logging period: 10, Logging time: 86400
Time,Time since Start,ID,Command,Number of Bytes,Battery Voltage,PV Voltage,Load Current,Overdischarge Voltage,Full Voltage,Load detected?,Overloaded?,Short circuit?,Overcharged?,Battery voltage too low?,Batter voltage full?,Charging?,Temperature,Charging current
Thu Jul 17 20:04:24 2014,0.05801510810852051,0,160,24,12.7,18.17,0.0,11.22,14.35,1,0,0,0,0,0,1,31,0.29
... alle 10 sekunden ein Eintrag
Thu Jul 17 22:03:26 2014,7142.438544988632,0,160,24,12.59,1.87,0.03,11.17,14.46,1,0,0,0,0,0,0,28,0.0
das war der letzte Eintrag
Und so sieht es aus wenn ich die Ausgabe in der Bash in Linux umleite auf eine Datei:
Serial port /dev/ttyAMA0 opened
Starting cyclic request of data
Cyclic timer started (period = 10s). Logging for 86400s ...
Request from logger @ 0.003033161163330078s
Response from charger @ 0.05801510810852051s, Response Length: 36, Response: b'\xeb\x90\xeb\x90\xeb\x90\x00\xa0\x18\xf6\x04\x19\x07\x00\x00\x00\x00b\x04\x9b\x05\x01\x00\x00/\x00\x00\x00\x01=\x1d\x00\x00\xf9i\x7f'
Request from logger @ 10.00679898262024s
... und so weiter....
Request from logger @ 7582.3808760643005s
Response from charger @ 7582.4358241558075s, Response Length: 36, Response: b'\xeb\x90\xeb\x90\xeb\x90\x00\xa0\x18\xe9\x04;\x00\x00\x00\x03\x00]\x04\xa6\x05\x01\x00\x00*\x00\x00\x00\x00:\x00\x00\x00D\xc8\x7f'
Das war die letzte Zeile