From 95943c42227174994aea9131e206f4b64d441022 Mon Sep 17 00:00:00 2001 From: uhi22 Date: Thu, 6 Jun 2024 09:10:06 +0200 Subject: [PATCH 1/2] feature: listenerNoGui logs the chargers MAC and GPS coords to http --- addressManager.py | 10 +++++ doc/pyPlc.ini.template | 3 ++ listenerNoGui.py | 93 ++++++++++++++++++++++++++++++++++++++++++ pyPlcHomeplug.py | 8 ++-- starter.sh | 3 +- 5 files changed, 112 insertions(+), 5 deletions(-) create mode 100755 listenerNoGui.py diff --git a/addressManager.py b/addressManager.py index 28a2a36..fc8e5fa 100644 --- a/addressManager.py +++ b/addressManager.py @@ -27,6 +27,8 @@ class addressManager(): self.pevIp="" self.SeccIp="" self.SeccTcpPort = 15118 # just a default. Will be overwritten during SDP if we are pev. + self.evseMacIsUpdated = False + self.evseMac = [0, 0, 0, 0, 0, 0] pass def findLinkLocalIpv6Address(self): @@ -157,8 +159,16 @@ class addressManager(): def setEvseMac(self, evseMac): # During the SLAC, the MAC of the EVSE was found out. Store it, maybe we need it later. self.evseMac = evseMac + self.evseMacIsUpdated = True print("[addressManager] evse has MAC " + prettyMac(self.evseMac)) + def getEvseMacAsStringAndClearUpdateFlag(self): + self.evseMacIsUpdated = False + return prettyMac(self.evseMac) + + def isEvseMacNew(self): + return self.evseMacIsUpdated + def setPevIp(self, pevIp): # During SDP, the IPv6 of the PEV was found out. Store it, maybe we need it later. if (type(pevIp)==type(bytearray([0]))): diff --git a/doc/pyPlc.ini.template b/doc/pyPlc.ini.template index cd947f8..dba1cf1 100644 --- a/doc/pyPlc.ini.template +++ b/doc/pyPlc.ini.template @@ -145,3 +145,6 @@ soc_callback_enabled = False soc_callback_endpoint = http://1.1.1.1 # Fallback value to use if the vehicle does not support the EVEnergyCapacity.Value soc_fallback_energy_capacity = 2700 + +# The URL where to send some logging data. +logging_url = http://enteryourhosthere.org/pyPlcLogging/addLog.php diff --git a/listenerNoGui.py b/listenerNoGui.py new file mode 100755 index 0000000..5e4c05a --- /dev/null +++ b/listenerNoGui.py @@ -0,0 +1,93 @@ +#!/usr/bin/python3 +# The non-GUI variant of the listener + +# Functionality: +# - gets the GPS location from a GPS daemon (gpsd on linux) +# - gets the chargers MAC address from the address manager +# - sends the location and the chargers MAC to a server via http request + +import time +import pyPlcWorker +from pyPlcModes import * +import sys # for argv +from configmodule import getConfigValue, getConfigValueBool +import urllib.request +import gps # the gpsd interface module + +startTime_ms = round(time.time()*1000) +GPSsession = gps.gps(mode=gps.WATCH_ENABLE) +strGpsPos = "no_pos" +strLoggingUrl = getConfigValue("logging_url") + +def cbAddToTrace(s): + currentTime_ms = round(time.time()*1000) + dT_ms = currentTime_ms - startTime_ms + print("[" + str(dT_ms) + "ms] " + s) + +def cbShowStatus(s, selection=""): + pass + +def trySomeHttp(): + print("***************trying some http********************") + strChargerMac = "chargerMac=na" + if (worker.addressManager.isEvseMacNew()): + strChargerMac = "chargerMac=" + worker.addressManager.getEvseMacAsStringAndClearUpdateFlag().replace(":", "") + strParams = strChargerMac + strParams = strParams + "&loops="+str(nMainloops)+"&pos="+strGpsPos + try: + contents = urllib.request.urlopen(strLoggingUrl + "?" + strParams).read() + except Exception as err: + contents = "(no contents received) " + str(err) + print(contents) + +def GpsMainfunction(): + global strGpsPos + GPSsession.read() + if (gps.MODE_SET & GPSsession.valid): + print('Mode: %s(%d) Time: ' % + (("Invalid", "NO_FIX", "2D", "3D")[GPSsession.fix.mode], + GPSsession.fix.mode), end="") + # print time, if we have it + if gps.TIME_SET & GPSsession.valid: + print(GPSsession.fix.time, end="") + else: + print('n/a', end="") + + if ((gps.isfinite(GPSsession.fix.latitude) and + gps.isfinite(GPSsession.fix.longitude))): + print(" Lat %.6f Lon %.6f" % + (GPSsession.fix.latitude, GPSsession.fix.longitude)) + strGpsPos = str(GPSsession.fix.latitude)+"_"+str(GPSsession.fix.longitude) + else: + print(" Lat n/a Lon n/a") + strGpsPos = str(0.0)+"_"+str(0.0) + print(strGpsPos) + +myMode = C_LISTEN_MODE + + +isSimulationMode=0 +if (len(sys.argv) > 1): + if (sys.argv[1] == "S"): + isSimulationMode=1 + +print("starting in LISTEN_MODE") +print("press Ctrl-C to exit") + +worker=pyPlcWorker.pyPlcWorker(cbAddToTrace, cbShowStatus, myMode, isSimulationMode) + +nMainloops=0 +httpTime_ms = round(time.time()*1000) +intervalForHttpLogging_ms = 15000 # each 15s send the logging data to the server + +while (1): + time.sleep(.03) # 'do some calculation' + nMainloops+=1 + currentTime_ms = round(time.time()*1000) + if ((currentTime_ms-httpTime_ms)>intervalForHttpLogging_ms) or (worker.addressManager.isEvseMacNew()): + trySomeHttp() + httpTime_ms = currentTime_ms + worker.mainfunction() + GpsMainfunction() + +#--------------------------------------------------------------- diff --git a/pyPlcHomeplug.py b/pyPlcHomeplug.py index ed3c382..793ef58 100644 --- a/pyPlcHomeplug.py +++ b/pyPlcHomeplug.py @@ -711,6 +711,10 @@ class pyPlcHomeplug(): self.pevSequenceDelayCycles = 4 # original Ioniq is waiting 200ms self.enterState(STATE_SLAC_PARAM_CNF_RECEIVED) # enter next state. Will be handled in the cyclic runPevSequencer if ((self.iAmListener==1) or (self.iAmPev==1)): + # Take the MAC of the charger from the frame, and store it for later use. + for i in range(0, 6): + self.evseMac[i] = self.myreceivebuffer[6+i] # source MAC starts at offset 6 + self.addressManager.setEvseMac(self.evseMac) if getConfigValueBool("log_the_evse_mac_to_file"): # Write the MAC address of the charger to a log file self.addToTrace("SECC MAC is " + self.getSourceMacAddressAsString()) @@ -752,10 +756,6 @@ class pyPlcHomeplug(): if (self.pevSequenceState==STATE_WAIT_FOR_ATTEN_CHAR_IND): # we were waiting for the AttenCharInd # todo: Handle the case when we receive multiple responses from different chargers. # Wait a certain time, and compare the attenuation profiles. Decide for the nearest charger. - # Take the MAC of the charger from the frame, and store it for later use. - for i in range(0, 6): - self.evseMac[i] = self.myreceivebuffer[6+i] # source MAC starts at offset 6 - self.addressManager.setEvseMac(self.evseMac) self.AttenCharIndNumberOfSounds = self.myreceivebuffer[69] self.addToTrace("[PEVSLAC] number of sounds reported by the EVSE (should be 10): " + str(self.AttenCharIndNumberOfSounds)) self.composeAttenCharRsp() diff --git a/starter.sh b/starter.sh index ee38ce4..cdb6a85 100755 --- a/starter.sh +++ b/starter.sh @@ -69,7 +69,8 @@ ip addr >> "$logfile" pwd >> "$logfile" # call the pyPlc python script -PYTHONUNBUFFERED=1 /usr/bin/python3 pevNoGui.py | tee -a "$logfile" +#PYTHONUNBUFFERED=1 /usr/bin/python3 pevNoGui.py | tee -a "$logfile" +PYTHONUNBUFFERED=1 /usr/bin/python3 listenerNoGui.py | tee -a "$logfile" pwd >> "$logfile" date >> "$logfile" From 91b9963cd359caf1a4dbd0bb65a409d52a83a7c6 Mon Sep 17 00:00:00 2001 From: uhi22 Date: Sun, 9 Jun 2024 15:03:24 +0200 Subject: [PATCH 2/2] listenerNoGui makes beep-patterns in case of MAC detection and http log. cyclic log each 2 minutes. --- listenerNoGui.py | 62 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/listenerNoGui.py b/listenerNoGui.py index 5e4c05a..49b23b8 100755 --- a/listenerNoGui.py +++ b/listenerNoGui.py @@ -13,6 +13,7 @@ import sys # for argv from configmodule import getConfigValue, getConfigValueBool import urllib.request import gps # the gpsd interface module +import RPi.GPIO as GPIO # for controlling hardware pins of the raspberry startTime_ms = round(time.time()*1000) GPSsession = gps.gps(mode=gps.WATCH_ENABLE) @@ -27,15 +28,35 @@ def cbAddToTrace(s): def cbShowStatus(s, selection=""): pass +def testBlockingBeep(patternselection): + if (patternselection==1): + p.ChangeDutyCycle(10) + p.ChangeFrequency(1200) + time.sleep(0.2) + p.ChangeFrequency(1300) + time.sleep(0.2) + p.ChangeFrequency(1400) + time.sleep(0.2) + p.ChangeDutyCycle(0) + if (patternselection==2): + p.ChangeDutyCycle(10) + p.ChangeFrequency(1600) + time.sleep(0.2) + p.ChangeFrequency(1500) + time.sleep(0.2) + p.ChangeDutyCycle(0) + def trySomeHttp(): print("***************trying some http********************") strChargerMac = "chargerMac=na" if (worker.addressManager.isEvseMacNew()): + testBlockingBeep(1) strChargerMac = "chargerMac=" + worker.addressManager.getEvseMacAsStringAndClearUpdateFlag().replace(":", "") strParams = strChargerMac strParams = strParams + "&loops="+str(nMainloops)+"&pos="+strGpsPos try: contents = urllib.request.urlopen(strLoggingUrl + "?" + strParams).read() + testBlockingBeep(2) except Exception as err: contents = "(no contents received) " + str(err) print(contents) @@ -63,6 +84,27 @@ def GpsMainfunction(): strGpsPos = str(0.0)+"_"+str(0.0) print(strGpsPos) + + + + + +def mytestfunction(): + global soundstate + #testBlockingBeep(2) + #if (soundstate==0): + # p.ChangeDutyCycle(10) + # p.ChangeFrequency(1000) + #if (soundstate==1): + # p.ChangeDutyCycle(10) + # p.ChangeFrequency(1200) + #if (soundstate==2): + # p.ChangeDutyCycle(0) + #soundstate+=1 + #if (soundstate>=3): + # soundstate=0 + + myMode = C_LISTEN_MODE @@ -78,7 +120,22 @@ worker=pyPlcWorker.pyPlcWorker(cbAddToTrace, cbShowStatus, myMode, isSimulationM nMainloops=0 httpTime_ms = round(time.time()*1000) -intervalForHttpLogging_ms = 15000 # each 15s send the logging data to the server +testTime_ms = httpTime_ms +intervalForHttpLogging_ms = 120*1000 # each 2 minutes send the logging data to the server + +soundstate = 0 +GPIO.setmode(GPIO.BCM) +GPIO.setup(23, GPIO.OUT) +p=GPIO.PWM(23, 500) # 500 Hz +p.start(0) +p.ChangeDutyCycle(50) +time.sleep(0.1) +p.ChangeDutyCycle(0) +time.sleep(0.1) +p.ChangeDutyCycle(50) +time.sleep(0.1) +p.ChangeDutyCycle(0) + while (1): time.sleep(.03) # 'do some calculation' @@ -87,6 +144,9 @@ while (1): if ((currentTime_ms-httpTime_ms)>intervalForHttpLogging_ms) or (worker.addressManager.isEvseMacNew()): trySomeHttp() httpTime_ms = currentTime_ms + if ((currentTime_ms-testTime_ms)>2000): + mytestfunction() + testTime_ms = currentTime_ms worker.mainfunction() GpsMainfunction()