def pin_to_HighState(): #BCM numbering:\ log.debug("Putting pin 19 high.") GPIO.setmode(GPIO.BCM) #set to output mode = adapter will not modify its value GPIO.setup(19, GPIO.OUT) #chanGPIOe state to LOW/HIGH GPIO.output(19, GPIO.HIGH) time.sleep(1) GPIO.cleanup()
def zacniBlikat(verzieBlikania): #zaregistruj sa na siet #verzieBlikania su True/False/2 if verzieBlikania == True: return 0 elif verzieBlikania == 2: log.debug("Zda sa, ze siet sa pripaja, cakam par sekund.") time.sleep(7) #pockaj par sekund a snad uz to bude ok return 0 elif verzieBlikania == False: log.error("Nepodarilo sa pripojit na operator <=> NET neblika pomaly.") return 1
def zapniInternetVopred(intInfTep, intInfGps): #zapni internet ak je potrebny #ak je informovanie neziaduce, tak zadaj velke hodnoty ktore neprejdu podmienkou dole: intInfTep = 99999999 if intInfTep == None else intInfTep intInfGps = 99999999 if intInfGps == None else intInfGps #priprav odosielanie len ak odpocet je rovny (aby som to spustil len raz a nie neustale kvoli <> znakom) #predpriprava nie je narocna na adpater, zvycajne bud zapneInternet alebo ak internetByMalBytZapnuty == True tak len overi ci CIPSTATUS = IP INITIAL if intInfTep == ZP.PREDPRIPRAVA_ODOSIELANIA or intInfGps == ZP.PREDPRIPRAVA_ODOSIELANIA: try: log.debug("Internet je potrebny, priprav odosielanie.") ZP.adapterJob_prioDeq.put('pripravOdosielanie') except: log.warning( "Prikaz 'pripravOdosielanie' ignorovany - ManagerThread je zaneprazdneny" )
def otazkaOdpoveda(): #vyprazdni queue log.debug("Odpoveda adapter na prikazy?") if ZP.adapterOdpoveda_queue.full(): ZP.adapterOdpoveda_queue.get() #ak nie tak repripoj/restartuj Rpi. lebo moze byt pripojeny (ttyUSB existuje) ale moze byt OFF try: serialPort.write(b'AT\r\n') ZP.adapterOdpoveda_queue.get(timeout=2) #cakam na odpoved, par sekund log.debug("Adapter odpoveda na prikazy.") ZP.troubleMonitor.adapterNotRestarting_resetCount() return True except: log.warning("Adapter neodpoveda na prikazy!") ZP.troubleMonitor.adapterNotRestarting_addCount() return False
def pripojAdapter(): #len pri zapnuti RPI global serialPort try: #v pripade ze subor /dev/ttyUSB* chyba, restaruj USB porty resp. RPI adapterFile = os.popen('ls /dev/ttyUSB*').readlines()[0][:-1] serialPort = serial.Serial(adapterFile, 115200) log.debug("Pripojil som adapter.") ZP.event_cakajNaPripojenie.set() # time.sleep(2) return 0 except: serialPort = None log.exception("EXCEPTION!") log.error("Adapter sa nepodarilo pripojit!") return 1
def prijmiSpravu(): global prijataSpravaOsekana for pocetZlyhani in range( 3 ): #normally there is just one loop because there a return statement appears. try: prijataSpravaOsekana = 1 #prepare to return 1 in case serialRead didn't read any better value for the message if queueSocket.full(): queueSocket.get() log.debug("Prijmam spravu...") #initiate connection serialPort.reset_input_buffer() serialPort.write(prikazyPrijmiSpravu[0]) q_get = queueSocket.get( timeout=10 ) #raises queue.Empty when serialRead doesnt reply and we run another loop of this function if q_get == 'cipstartOKspravaPrijata': prijataSprava = prijataSpravaOsekana return prijataSprava elif q_get == 'alreadyConnect': ZP.troubleMonitor.alreadyConnect_addCount() log.error("Already connected.") return 1 #this return will make manager redo 'posta' work but only if above count is not exceeded. elif q_get == 'serverUnreachable': ZP.troubleMonitor.serverUnreachable_addCount() log.error("Server unreachable.") return 2 #this return will make manager redo 'posta' work but only if above count is not exceeded. else: log.error("Vyskytla sa neznama chyba, restartujem internet!") return 1 #this can be repeating infinitelly as long as serialRead doesnt get fixed. I expect this to not happen. except queue.Empty: if pocetZlyhani >= 2: #only when we tried 3 times, restart adapter ZP.adapterJob_prioDeq.put( 'pwrKeyAdapter', delete=False ) #keep other jobs pending as we are just fixing something return 1 #this can be repeating infinitelly as long as serialRead doesnt get fixed. I expect this to not happen. log.exception( "Spravu sa asi nepodarilo PRIJAT - serial neodpoveda. Pokus " + str(pocetZlyhani) + "/3. Potom restartujem.")
def posliSpravu(response): #this function, in order to work properly, has to follow prijmiSpravu() function in serial logic for pocetZlyhani in range(3): try: #initiate sending: serialPort.write(prikazyPosliSpravu[0]) #cakaj na ODOSIELANIE: if queueSocket.get(timeout=10) == 'cipsendOK': serialPort.write(bytes(response, 'utf-8') + b'\x1a\r\n') else: log.error("Serial neprijal spravu na odoslanie.") return 1 #AdapterManager o tom upozorni ale tento pripad zatial ignorujeme. #cakaj na SEND OK: if queueSocket.get(timeout=10) == 'sendOK': log.info("Sprava odoslana.")\ #serialPort.write(prikazyPosliSpravu[1]) #ignoruj, socket sa zatvara automaticky else: log.critical( "Serial odpoved na odoslanie spravy je necakana. SERVER neodpoveda?!" ) return 1 #AdapterManager o tom upozorni ale tento pripad zatial ignorujeme. #cakaj na closed: if queueSocket.get(timeout=10) == 'closed': log.debug("Socket closed.") cistyCipshut() else: log.warning("Socket closed didn't work but I ignore it.") #ak nenastal problem, return 0: return 0 #message was sent at this point except queue.Empty: if pocetZlyhani >= 2: #only when we tried 3 times, restart adapter ZP.adapterJob_prioDeq.put( 'pwrKeyAdapter', delete=False ) #keep other jobs pending as we are just fixing something return 1 #AdapterManager o tom upozorni ale tento pripad zatial ignorujeme. log.exception( "Spravu sa asi nepodarilo odoslat - serial neodpoveda. Pokus " + str(pocetZlyhani) + "/3. Potom restartujem.")
def vypniInternet(): try: #funguje len ak bezi thread serialRead() #VYPNI INTERNET: #najprv vymaz queue if queueVypni.full(): queueVypni.get() log.info("Vypinam internet...") serialPort.write(prikazyNaVypni[0]) try: if queueVypni.get(timeout=3) == 'cipcloseOK': log.debug("cipclose OK") serialPort.write(prikazyNaVypni[1]) #cipshut else: log.error( "A postup nebol dodrzany alebo sa vyskytla chyba, restartuj internet" ) return 1 except: log.error("Nepodarilo sa.") return 1 try: if queueVypni.get(timeout=5) == 'cipshutOK': log.info("AT+CIPSHUT > SHUT OK.") return 0 else: log.error( "postup nebol dodrzany alebo sa vyskytla chyba, restartuj internet" ) return 1 except: log.error("Nepodarilo sa.") return 1 except queue.Empty: log.exception("serialRead neodpovedal nacas!") except: log.exception("EXCEPTION!")
def otazkaNETblika(): log.debug("Blika NET (sim registrovana)?") #vyprazdni queue if ZP.netBlika_queue.full(): ZP.netBlika_queue.get() try: serialPort.write(b'AT+CREG?\r\n') q_get = ZP.netBlika_queue.get(timeout=7) if q_get == 1: #cakam na odpoved, do 10 sekund log.debug("Net blika - home network") return True elif q_get == 5: #cakam na odpoved, do 10 sekund log.debug("Net blika - roaming network") return True elif q_get == 2: #cakam na odpoved, do 10 sekund log.error("Net neblika - hlada siet ...") return 2 elif q_get == 3: #cakam na odpoved, do 10 sekund log.error("Net neblika - registracia zamietnuta") return False elif q_get == 4: #cakam na odpoved, do 10 sekund log.error("Net neblika - neznamy problem") return False else: log.error("serialRead nevratil co bolo ocakavane.") return False except: log.error("serialRead neodpovedal nacas!") return False
def otazkaSignalOk(): log.debug("Signal ok?") if queueSignal.full(): queueSignal.get() try: serialPort.write(b'AT+CSQ\r') q_get = queueSignal.get(timeout=5) specialne.ulozSiluSignalu(q_get) if type(q_get) is int: if q_get in [0, 99]: log.error("Ziaden signal!") return False elif q_get in [1, 2, 3, 4]: log.debug("Slaby signal: " + str(q_get)) return True else: log.debug("Sila signalu dostacujuca: " + str(q_get)) return True else: log.error("Serial vratil chybu!") return False except: log.error("serialRead neodpovedal nacas!") return False
def pwrKeyAdapter(): try: log.debug("Posielam signal na spinac adaptera!") #BCM numbering: GPIO.setmode(GPIO.BCM) #set to output mode = adapter will not modify its value GPIO.setup(19, GPIO.OUT) #change state to LOW/HIGH GPIO.output(19, GPIO.LOW) time.sleep(4) GPIO.output(19, GPIO.HIGH) GPIO.cleanup() log.debug( "Poslal som signal na spinac adaptera. Cakam par sekund na nacitanie SIM." ) time.sleep(7) log.debug("hotovo") return 0 except: log.exception("EXCEPTION!")
def read(): novyRiadok = b'' CastSpravy = None serverUnreachable_count = 0 while True: try: ZP.event_cakajNaPripojenie.wait() predoslyRiadok = novyRiadok novyRiadok = worker.serialPort.readline() logSerial.debug('line: ' + str(novyRiadok)) #SIGNAL OK? najdi = re.search(r'b\'\+CSQ: (\d+),', str(novyRiadok)) if najdi != None: try: signal = int(najdi.group(1)) except: worker.queueSignal.put("CHYBA") log.error("SerialRead nacital neznamu hodnotu signalu: " + str(najdi.group(1))) else: if signal < 100: worker.queueSignal.put(signal) if b'+CSQ: 15,0' in novyRiadok: worker.queueSignal.put() #NET BLIKA? if b'AT+CREG?' in predoslyRiadok: if b'+CREG: 0,1' in novyRiadok: #registered, home network ZP.netBlika_queue.put(1) elif b'+CREG: 0,2' in novyRiadok or b'+CREG: 0,0' in novyRiadok: #Not registered, but MT is currently searching a new operator to register to ZP.netBlika_queue.put(2) elif b'+CREG: 0,3' in novyRiadok: #registration denied ZP.netBlika_queue.put(3) elif b'+CREG: 0,4' in novyRiadok: #unknown ZP.netBlika_queue.put(4) elif b'+CREG: 0,5' in novyRiadok: #registered, roaming ZP.netBlika_queue.put(5) else: log.error("CHYBA: cgreg odpoved:" + str(novyRiadok)) #ODPOVEDA? if b'AT\r' in predoslyRiadok and b'OK\r' in novyRiadok: ZP.adapterOdpoveda_queue.put(1) #VYPNI internet: #CIPCLOSE if b'AT+CIPCLOSE' in predoslyRiadok: #-2 pretoze serial sam prida dva znaky do vystupu if (b'OK' in novyRiadok or b'ERROR' in novyRiadok): logSerial.debug("cipclose OK") worker.queueVypni.put('cipcloseOK') else: log.error("CHYBA: cipclose odpoved:" + str(novyRiadok)) worker.queueVypni.put('chyba') #CIPSHUT if b'AT+CIPSHUT' in predoslyRiadok: #-2 pretoze serial sam prida dva znaky do vystupu if (b'SHUT OK' in novyRiadok): logSerial.debug("cipshut OK") worker.queueVypni.put('cipshutOK') else: log.error("CHYBA: cipshut odpoved:" + str(novyRiadok)) worker.queueVypni.put('chyba') #PDP DEACT problem #tento problem podla mna nastava ked nevypnem poriadne internet pred vypnutim RPI. #to by sa nemalo stavat ak do toho nekafrem pri debugovani #nie celkom slusny pokus o vyriesenie problemu s +pdp deact po cipshut prikaze # if (b'+PDP: DEACT' in novyRiadok): # print ("PDP FOUND") # worker.queueVypni.put('pdpDeactProblem') #CIPSTATUS: if (b'STATE:' in novyRiadok): if (b'STATE: IP INITIAL' in novyRiadok): worker.queueZapni.put('IP INITIAL') elif (b'STATE: IP STATUS' in novyRiadok): worker.queueZapni.put('IP STATUS') # elif (b'STATE: TCP CLOSED' in novyRiadok): # worker.queueZapni.put('TCP CLOSED') else: log.error("CHYBA: CIPSTATUS odpoved:" + str(novyRiadok)) worker.queueZapni.put('chyba') #ZAPNI internet: #CSTT if worker.prikazyNaZapni[ 0] in predoslyRiadok: #-2 pretoze serial sam prida dva znaky do vystupu if (b'OK' in novyRiadok): worker.queueZapni.put('csttOK') else: log.error("CHYBA: CSTT odpoved:" + str(novyRiadok)) worker.queueZapni.put('chyba') #CIICR if worker.prikazyNaZapni[ 1] in predoslyRiadok: #-2 pretoze serial sam prida dva znaky do vystupu if (b'OK' in novyRiadok): worker.queueZapni.put('ciicrOK') else: log.error("CHYBA: CIICR odpoved:" + str(novyRiadok)) worker.queueZapni.put('chyba') #CIFSR if worker.prikazyNaZapni[ 2] in predoslyRiadok: #-2 pretoze serial sam prida dva znaky do vystupu if re.search(r'b\'\d+.\d+.\d+.\d+', str(novyRiadok)) != None: worker.queueZapni.put('cifsrOK') else: log.warning("CHYBA: CIFSR odpoved:" + str(novyRiadok)) worker.queueZapni.put('chyba') #SOCKET: if b'ALREADY CONNECT' in novyRiadok: worker.queueSocket.put('alreadyConnect') if b'CONNECT FAIL' in novyRiadok: worker.queueSocket.put('serverUnreachable') if b'CONNECT OK' in predoslyRiadok and b'STATE:' not in predoslyRiadok: #reset counters since connection was successful ZP.troubleMonitor.alreadyConnect_resetCount() ZP.troubleMonitor.serverUnreachable_resetCount() dlzSpravy_code = novyRiadok[:2] #2byte dlzSpravy_int = ZP.CODE.index(dlzSpravy_code.decode()) if dlzSpravy_int == 0: #server nema ziadnu spravu od androidu, poslal default: b'\x00\x00\x00\x00' worker.prijataSpravaOsekana = '00' else: #nacitaj prijatu spravud worker.prijataSpravaOsekana = novyRiadok.decode()[:-2] log.debug("prijataSprava " + str(worker.prijataSpravaOsekana)) worker.queueSocket.put('cipstartOKspravaPrijata') #CIPSEND, ak dostanes cerstvu poziadavnku na odosielanie tak len pockaj chvilu a daj zelenu: if worker.prikazyPosliSpravu[0] in novyRiadok: time.sleep(0.3) worker.queueSocket.put('cipsendOK') if b'SEND OK' in novyRiadok: worker.queueSocket.put( 'sendOK' ) #put sendOK just now so that Socket() reads message just now if b'CLOSED' in novyRiadok and b'TCP CLOSED' not in novyRiadok and b'CLOSE OK' not in novyRiadok and b'STATE:' not in novyRiadok: #TCP CLOSED is when connection fails. we dont want to mistaken it for successful communication (CLOSED) worker.queueSocket.put('closed') time.sleep(0.01) except AttributeError: log.error("SerialRead hlasi nepripojeny adapter! (ser == None)") ZP.event_cakajNaPripojenie.clear() except serial.serialutil.SerialException: log.error( "SerialRead hlasi nepripojeny adapter! (SerialException)") ZP.event_cakajNaPripojenie.clear() except: if datetime.datetime.now().microsecond % 999000 == 0: log.exception("serialRead problem!") else: pass
def adapterNotRestarting_resetCount(self): log.debug("Resetujem counter adapterNotRestarting.") self.adapterNotRestarting_count = 0 self.adapterNotRestarting_tryAgain = True
def uspiRpi(trvanieSpanku, pociatok): try: '''tato funkcia: 1.vypina RPI a zapise default odpocet 2.uspava RPI a odrata dlzku spanku z odpoctu 3.len chvilu caka(ak sa neoplati spat alebo ide o DEBUG mod), odrata dlzku cakania z odpoctu ''' #1. vypni RPI: if trvanieSpanku == None: log.info( "Vypinam RPI natrvalo! Zapisujem defaultne hodnoty do konfig.json a odpocet.json." ) #2. uspi pomocou WittyPi: else: trvanieSpanku = round(trvanieSpanku) systemTimeToRtc() time.sleep(4) #pociatok je nadiktovany uz v Main pri vypocte oddychu casZapnutia = pociatok + datetime.timedelta( seconds=trvanieSpanku) #datetime object if trvanieSpanku < 60: #sekundova schedule sluzi len pre RPI restart wittySched = "?? ?? ?? " + str(casZapnutia.second) log.info("Pozadovany spanok je " + str(trvanieSpanku) + "s. Pociatok: " + str(pociatok) + ". Zapisujem Witty Startup Time:" + str(wittySched)) elif trvanieSpanku < 3600: #minutova schedule wittySched = "?? ?? " + str(casZapnutia.minute) + " " + str( casZapnutia.second) log.info("Pozadovany spanok je " + str(trvanieSpanku) + "s. Pociatok: " + str(pociatok) + ". Zapisujem Witty Startup Time:" + str(wittySched)) else: #hodinova schedule BUG = 2 #v set_startup_time.sh je nejaka chyba a zapisany spanok ma inu hodnotu ako ten pozadovany, toto to opravi #to co sa zobrazuje vo wittyPi.sh skripte je to co wittyPi respektuje wittySched_bezBUGU = "?? " + str(casZapnutia.hour) + " " + str( casZapnutia.minute) + " " + str(casZapnutia.second) wittySched = "?? " + str(casZapnutia.hour - BUG) + " " + str( casZapnutia.minute) + " " + str(casZapnutia.second) log.info("Pozadovany spanok je " + str(trvanieSpanku) + "s. Pociatok: " + str(pociatok) + ". Zapisujem Witty Startup Time:" + str(wittySched_bezBUGU)) startupTime(wittySched) #turn off GPS if it is running active_threads = [x.name for x in threading.enumerate()] if 'MerajGps' in active_threads: log.debug("Vypinam spustene GPS.") Meraj.vypni_GPS() time.sleep(5) #in case we are in debug mode, dont shut down RPI, just stop the program debugModeON = isDebugMode() log.debug("debug?: " + str(debugModeON)) if (debugModeON): log.debug("Debug je zapnuty, nevypinam RPI") else: log.debug("RPI sa vypina!") vypniRpiPomocouWittyPi() sys.exit(0) except: log.exception("EXCEPTION!")
def praca(): #spusti serial reader v predstihu: threading.Thread(target=reader.read, name='serialRead', daemon=True).start() pocet_pokusov = 3 while True: try: q_get = ZP.adapterJob_prioDeq.get() log.info("pracujem na: '" + str(q_get) + "', zbytok Q:" + str(ZP.adapterJob_prioDeq.deqList)) if q_get == 'pripojAdapter': worker.pripojAdapter() assistant.zarucOdpAPripojenie() elif q_get == 'restartujInternet': worker.restartujInternet() elif q_get == 'telefonuj': #ak sa nepodari ani pripravit telefonovanie tak ho urcite vloz naspat do queue if assistant.pripravTelefonovanie() == 0: #telefonuj: #a v pripade, ze sa nepodari tak vloz telefonovanie naspat do queue if worker.telefonuj() == 1: ZP.adapterJob_prioDeq.put('telefonuj') else: ZP.adapterJob_prioDeq.put('telefonuj') elif q_get == 'posta': ZP.AdapterNeodosielaSpravu = False assistant.pripravOdosielanie() prijataSprava = worker.prijmiSpravu() #neosekana #if no new instructions were received, just reply with current KonfigD if prijataSprava == 1: log.error( "Sprava neodoslana (server prestal reagovat alebo AlreadyConnect error). Restartujem internet !" ) if (ZP.troubleMonitor.alreadyConnect_tryAgain ): #try again if required. log.error( "Novy pokus cislo" + str(ZP.troubleMonitor.alreadyConnect_count) + "/" + str(ZP.troubleMonitor.alreadyConnect_MAXcount)) #restartuj internet kedze alreadyConnect sa len tak nevyriesi.. ZP.adapterJob_prioDeq.put( 'restartujInternet', delete=False ) #do not delete other jobs - keep them pending as we are just fixing something if specialne.MessageNotInAdapterQueue(): ZP.adapterJob_prioDeq.put("posta") else: log.error( "Pocet pokusov vyprsal. Pravdepodobne nie je server vobec dostupny. Nastavujem informovanie na minimalne 3 min." ) #load the property, it will be used at the beginning of the next main run ZP.troubleMonitor.konfigD_modifiedProperties = ZP.troubleMonitor.alreadyConnect_konfigD ZP.troubleMonitor.alreadyConnect_tryAgain = True #(reset) opakuj pokusy pri dalsich korespondenciach elif prijataSprava == 2: log.error("Sprava neodoslana (server unreachable) !") if (ZP.troubleMonitor.serverUnreachable_tryAgain ): #try again if required. log.error( "Novy pokus cislo" + str(ZP.troubleMonitor.serverUnreachable_count) + "/" + str(ZP.troubleMonitor.serverUnreachable_MAXcount)) if specialne.MessageNotInAdapterQueue(): ZP.adapterJob_prioDeq.put("posta") else: log.error("Pocet pokusov vyprsal, vzdavam to!") ZP.troubleMonitor.serverUnreachable_tryAgain = True #opakuj pokusy pri dalsich korespondenciach elif prijataSprava == None: log.critical( "Socket vratil prijatu spravu NONE, skontroluj co to je za problem." ) else: if len( prijataSprava ) < 6: #no new instructions is something like this b'\x00\x00\r\n' log.debug("Neprisla sprava.") prijataSprava = None #neviem uz preco... odpoved = korespondencia.sformulujOdpoved(ZP.konfigD) #if new instructions were received, reply with updated konfigD(dummy for this moment) first. else: log.debug("Prijata sprava zpracovana: " + str(prijataSprava)) prijataSprava_obj = korespondencia.Rozbal( prijataSprava) #ak prisla sprava, zapis konfigy do txt a z toho txt nacitaj premenne. Nenacitavaj premenne znova v kazdom While loope ale len ak prisla sprava. #nacitaj ZP.konfigD a odpocetD (ak neprisla sprava tak nastavenia su 1.defaultne alebo 2.relax mod) print("ZP.konfigD PRED:", ZP.konfigD) konfigD_dummy = specialne.aktualizujKonfigDSpravou( prijataSprava_obj) print("konfigD_dummy", konfigD_dummy) print("ZP.konfigD PO:", ZP.konfigD) with ZP.prijataSprava_dequelock: ZP.prijataSprava_deque.append( (prijataSprava_obj, konfigD_dummy)) #loguj data z prijatej spravy log.info("Prijata sprava!: "+ " " + str(prijataSprava_obj.intervalMerTep) + " " + str(prijataSprava_obj.intervalMerGps) + " " + str(prijataSprava_obj.intervalInfTep) \ + " " + str(prijataSprava_obj.intervalInfGps) + " " + str(prijataSprava_obj.tolerLow) + " " + str(prijataSprava_obj.tolerHigh) + " " + str(prijataSprava_obj.onOffAlarmPark) + " " + str(prijataSprava_obj.aktBoxy)) odpoved = korespondencia.sformulujOdpoved( konfigD_dummy) if worker.posliSpravu(odpoved) == 1: log.critical( 'Nepodarilo sa odoslat spravu. Necakana chyba!') else: pass #odosle spravu ZP.AdapterNeodosielaSpravu = True elif q_get == 'pripravOdosielanie': assistant.pripravOdosielanie() elif q_get == 'pripravTelefonovanie': assistant.pripravTelefonovanie() elif q_get == 'vypniInternet': #nie je treba sa ani pytat, proste to skus worker.vypniInternet() elif q_get == 'pwrKeyAdapter': worker.pwrKeyAdapter() worker.pripojAdapter() except: pocet_pokusov -= 1 if pocet_pokusov == 0: log.exception( "AdapterManager zlyhal vela krat, restartujem ho!") ZP.adapterJob_prioDeq.put( 'pwrKeyAdapter', delete=False ) #keep other jobs pending as we are just fixing something pocet_pokusov = 3 else: log.exception("Adapter zlyhal, restartujem po dalsich " + str(pocet_pokusov) + " zlyhaniach.")
def restartujInternet(): log.debug("Restartujem internet...") vypniInternet() zapniInternet()
def otazkaPripravenyNaSpojenie(): global internetByMalBytPripraveny #otazka: AT+CIPSTATUS #odpoved: STATE: TCP CLOSED je status po uspesnej komunikacii (odoslanej sprave) #odpoved: STATE: CONNECT OK je status po cerstom cipstart pripojeni (po prijati spravy) na server pred odoslanim spravy #odpoved: STATE: IP INITIAL je pred spustenim internetu (=cerstvy adapter pred AT+CSTT>AT+CIICR>AT+CIFSR procedurou) # je aj po CIPSHUT ale po procedure AT+CSTT>AT+CIICR>AT+CIFSR #odpoved: STATE: IP STATUS je zapnuty internet (cifsr odpoved je IPcka) = pripraveny na AT+CIPSTART komunikaciu so serverom #odpoved: STATE: IP START je ked je cstt o2internet ale ciicr este nie je nic #odpoved: STATE: IP GPRSACT je ked je ciicr OK (po cstt) ale cisfr este nie je nic # cipshut je recommended pred cipstart stale ak status nie je IP STATUS / IP INITIAL #vyprazdni queue log.debug("Zapnuty internet?") if queueZapni.full(): queueZapni.get() try: serialPort.write(b'AT+CIPSTATUS\r') q_get = queueZapni.get(timeout=5) if q_get == "IP STATUS": log.debug( "Internet zapnuty. status: IP STATUS (pripraveny na komunikaciu CIPSTART)" ) return True if q_get == "IP INITIAL": log.debug("status: IP INITIAL") # log.debug("INTERNET PRIPRAVENY VARIABLE: " + str(internetByMalBytPripraveny)) if internetByMalBytPripraveny == True: #ak si uz zapinal internet (stane sa pri spusteni RPI) tak vrat true a ani sa nepytaj na cifsr nech nezatazujeme adapter pri kazdej sprave return True #ak by to bol problem (co by standardne nemal) tak ten sa vyriesi nejak sam v druhom pokuse serialPort.write(b'AT+CIFSR\r') if queueZapni.get( timeout=5 ) == "cifsrOK": #ak nevrati cifsrOK, tak sa dostaneme dole restartujeme internet log.debug("Internet zapnuty. AT+CIFSR vratil IP") return True # if q_get == "TCP CLOSED": # log.debug("Internet zapnuty. status: TCP CLOSED (predosla komuniakcia prebehla uspesne).\ # Riskujem lebo v manualy nie je explicitne uvedene, ze tento status je ok na nasledny CIPSTART.") # return True #return false vo vsetkych pripadoch okrem IP STATUS a IP INITIAL + CIFSR OK. Pretoze aj ked je mozno internet pripojeny, #nie sme v spravnom stave (ako je uvedene v manuale) vypniInternet( ) #toto je poistka pre PDP DEACT problem. v inych pripadoch by stacilo raz. #vypniInternet je lepsie ako priamo volat CIPSHUT lebo skript v druhom pripade necaka na odpoved a prepisuje adapter halabala. return False #teraz ocakavam, ze volajuca funkcia zavola AT+CIPSHUT + zapniInternet() #STARE: # try: # serialPort.write(b'AT+CIFSR\r') # if queueZapni.get(timeout = 5) == "cifsrOK": # log.debug("Internet zapnuty") # return True # else: # log.warning("Internet nie je zapnuty.") # return False except: log.error("serialRead neodpovedal nacas!") return False
def otazkaPripojeny(): #vrati true ak ser je pripojeny na serial, problem je ak sa medzicasom odpojil preto tuto funkciu vynechavam pripojeny = type(serialPort) is serial.serialposix.Serial log.debug("Adapter je pripojeny? True/False: " + str(pripojeny)) return pripojeny
def main(): try: log.debug("RPI STARTED!") loop_count = 0 #just informative pociatokSpanku = 0 #used for calculating sleeping periode cas_celkoveho_behu = 0 #time of the whole run counter '''load main konfiguration dictionary ZP.konfigD for the current run konfig.json file contains: - settings written at the end of previous run (<= we are in relaxing mode) - default settings due to user explicit request to shut down the machine. Or if crash of this program happens during running process - this is why we keep konfig.json on default values during running of this program. See overwriting of this file few lines bellow... ''' ZP.konfigD = vseobecne.Pomoc.precitajJsonFile(ZP.MAIN_DIR + "konfig.json") #load main counter dictionary odpocetD that keeps current value of counter for each interval (if counter is == 0, activity is run). Counter is decresead be ZP.FREQ value after each main loop odpocetD = vseobecne.Pomoc.precitajJsonFile(ZP.MAIN_DIR + "odpocet.json") #rewrite odpocet.json to default value just in case program crashes - it will restart with default values. specialne.zapisDefaultnyOdpocet() '''since we just started the program. Add some pre-load time to every interval-counter value. This makes sure we run mesuring of temperature or gps beforehand so that we have some values to work when counter == 0. This is because the sensors' controls are starting at counter == 0 and they need some current temperatures mesurements to work with. It also secures the cases when gps/temp mesuring is not started at the same time''' for prem in ZP.INTERVALOVE_PREMENNE: #for synchronisation purpose we are assigning ZP.LOADING_CAS to each of 4 interval-counters if odpocetD[ prem] != None: #interval-counter == None means this activity is to be ignored (requested by user) odpocetD[prem] = odpocetD[prem] + ZP.LOADING_CAS #rewrite konfig.json to default value in case program crashes. It will then restart with default configuration. specialne.zapisDefaultnyKonfig() """Create troubleMonitor object to monitor all troubles in one place and manage runLevels through it.""" ZP.troubleMonitor = pomocneObj.TroubleMonitor() """Create logger for one run per line logging.""" ZP.logPerRun = pomocneObj.LogPerRun( ) #prefill with these specific names or dummy (None) value. Otherwise they would be ignored <- see 'run' variable in pomocneObj.LogPerRun for i in range(ZP.POCET_SENZOROV): with ZP.logPerRun_lock: ZP.logPerRun.addItem( itemName=str(ZP.SENZORY[i]), itemValue=None, itemPosition=i + 150, specialType='osilacie_a_zaseknutia' ) #to have the header of all controls in the log even if some won't run ZP.logPerRun.addItem( itemName= "((ZP.rozptylTep, ZP.rozptylVlh), ZP.VELKOST_OKNA_MERANI, ZP.MINIMALNA_TOLEROVANA_KVALITA)", itemValue=str(((ZP.rozptylTep, ZP.rozptylVlh), ZP.VELKOST_OKNA_MERANI, ZP.MINIMALNA_TOLEROVANA_KVALITA)), itemPosition=250, specialType=None ) #just one log of current constants setup: ZP.rozptylTep, ZP.rozptylVlh ZP.logPerRun.addItem( itemName=str(ZP.SENZORY[i]), itemValue=None, itemPosition=i + 170, specialType='filter' ) #to have the header of all controls in the log even if some won't run #THREADS: '''create and start thread (running in the background) that manages GPRS adapter work over serial port It is necessary that there is only one access to serial port at a time because of the serial port nature. Therefore we can assign any work for the adapter through the following thread (specifically through it's custom made queue defined here: pomocneObj.PrioDeque). This queue has defined priorities and special order of specific activities. AdapterManager is working on them based on this given order. ''' adapterManager_thread = threading.Thread(target=adapterManager.praca, name='AdapterManager', daemon=True) adapterManager_thread.start() #adapter is booted together with RPI (unconvenient GPIOs setup at boot that is difficult to modify) but it doesnt work well so it's better to restart it. #so shut it down: sysfun.pin_to_HighState( ) #first put it to high state (necessary, otherwise adapter doesn't work properly) ZP.adapterJob_prioDeq.put( 'pwrKeyAdapter', delete=False) #first shutdown/startup is necessary in all cases #pripojAdapter work is already included in pwrKeyAdapter work #adapter jobs are running in the background so just give adapter some time to restart log.debug( "Giving adapter some time to start/shutdown before proceeding...") time.sleep(12) if not adapterWorker.otazkaOdpoveda( ): #at this time we are checking if adapter was started or shut down. in latter case, turn it back on log.debug("Adapter je zrejme vypnuty. Startujem...") #it's now turned OFF so start it again: ZP.adapterJob_prioDeq.put('pwrKeyAdapter', delete=False) # time.sleep(4) - we cannot put sleep here because it would change starting time if there was problem with adapter else: time.sleep( 1.9 ) #if it's replying, hw.Adapter.otazkaOdpoveda will return faster than if it's not. so wait for about otazkaOdpoveda timeout time #start AlarmCheck thread that is assigning 'telefonuj' work to AdapterManager in case alarm is on alarmCheckThread = threading.Thread( target=specialne.initiatePhoneCallOnAlarm, name='AlarmCheck', daemon=True) alarmCheckThread.start() #for each of the sensors, create one sensor-check thread that is checking it's proper functionality and heat index healthy range: for snz in ZP.SENZORY[:6]: meno = 'kontrolaThread' + snz kntrl = threading.Thread(target=kontrola.run, args=(snz, ), name=meno, daemon=True) kntrl.start() sysfun.clearStartupTime() ### MAIN LOOP: #this is the core code. It runs every ZP.FREQ seconds (6 seconds) from the start of RPI until shutdown is called. while True: log.info("BEH CISLO: " + str(loop_count)) start_cas = time.time() #1. ############################# # MESSAGE RECEIVED? # # # #check if new message was received, if so, load requested configuration: with ZP.prijataSprava_dequelock: if len( ZP.prijataSprava_deque ) == 1: #this is only == 1 if adapterManager filled it prijataSprava_deque with a newly received message log.debug("Nacitavam novy konfigD (lebo prisla sprava).") with ZP.konfigD_lock: ( prijataSprava, ZP.konfigD ) = ZP.prijataSprava_deque.pop( ) #left side of this assignment is what this deque normally contains #reset interval-counters for simplicity. Mainly to keep intervals synchronized in case one of them is to be modified by the message. log.debug("Resetujem odpocetD (lebo prisla sprava).") odpocetD = specialne.resetujOdpocetD(ZP.konfigD, ZP.FREQ) '''reset all sensor-checks mainly to avoid controling some old state that the user is no longer interested in. (Run them with empty lists and set all semaphores True): ''' log.debug("Resetujem kontroly (lebo prisla sprava).") ZP.resetujKontroly = True for q in ZP.Q: q.put(1) q.join() #all sensor-checks were just run "unloaded". ZP.resetujKontroly = False '''Negate information about sensors' issues because the user just requested to turn off the alarm: In case there are still problems with sensors, they will be rediscovered on freshly started sensor-checks which are triggered by just received message.''' if not ZP.troubleMonitor.isOn_mainAlarm( ): #reset the information about troubles to all ok ZP.nezdraveTep_senzory = "00000000" ZP.oscilujuceTep_senzory = "00000000" ZP.zaseknute_senzory = "00000000" ################################ #2. ########################### # TROUBLES? # # # #Check if you there are some troubles and if necessary, modify the running intervals. #1. main alarm is ON => configD will be modified to default intervals no matter what user has requested. if (ZP.troubleMonitor.isOn_mainAlarm()): log.debug( "Alarm je zapnuty, prepisujem konfiguraciu (konfiD) na neustaly rezim." ) with ZP.konfigD_lock: for i in ZP.troubleMonitor.mainAlarm_konfigD: ZP.konfigD[i] = ZP.troubleMonitor.mainAlarm_konfigD[ i] #modify running intervals to restless mode for i in ZP.troubleMonitor.mainAlarm_konfigD: #reset odpocetD in case it is not aware of new configuration. This condition is true at most one time after alarm was started #further times, this condition will always be false because interval-counters will never get bigger than konfigD corresponding values if odpocetD[i] == None or odpocetD[i] > ZP.konfigD[i]: odpocetD = specialne.resetujOdpocetD(ZP.konfigD, 0) ############################### #3. ########################### # INFORMING # # # #when the time comes, perform informing ( = receive instructions if any AND send current configuration and results). This work is assigned to AdapterManager. if odpocetD["intervalInfTep"] == 0 or odpocetD[ "intervalInfGps"] == 0: ZP.adapterJob_prioDeq.put('posta') ################################ ############################### # some side tasks # # # #ZP.adapterJob_prioDeq.put('pripravTelefonovanie') #no longer necessary #make adapter ready in advance for communication with the server (ZP.PREDPRIPRAVA_ODOSIELANIA seconds ahead) #(this code isn't crucial for proper functionality, it's only convenient to prepare the adapter beforehand): specialne.zapniInternetVopred(odpocetD['intervalInfTep'], odpocetD['intervalInfGps']) #inicializations for logging: ZP.DEBUG = { 'snz1': {}, 'snz2': {}, 'snz3': {}, 'snz4': {}, 'snz5': {}, 'snz6': {}, 'snz7': {}, 'snz8': {} } ZP.filterVysledkyD = {'snz1': (), 'snz2': (), 'snz3': (), 'snz4': (), 'snz5': (), \ 'snz6': (), 'vonkajsi': (('-','-'), '-', '-'), 'rpi': (('-','-'), '-', '-'), 'wittyPi': (('-','-'), '-', '-')} #logging "per line" of current sensors with issues: ZP.logPerRun.addItem('nezdraveTep_senzory', ZP.nezdraveTep_senzory, 200) ZP.logPerRun.addItem('oscilujuceTep_senzory', ZP.oscilujuceTep_senzory, 201) ZP.logPerRun.addItem('zaseknute_senzory', ZP.zaseknute_senzory, 202) #logging of current konfigD and odpocetD: log.info(" {} {} {} {} {} {} {} {}".format( 'mT', 'mG', 'iT', 'iG', 'tLow', 'tHigh', 'onOff', 'aktBoxy')) znenie = '' for i in ZP.VOLBY_ANDROID: hodnota = str(ZP.konfigD[i]) if hodnota == "123456789": znenie += '\t' + "off" else: znenie += '\t' + str(ZP.konfigD[i]) log.info("konfigD: " + znenie) znenie = '' for i in ZP.INTERVALOVE_PREMENNE: znenie += '\t' + str(odpocetD[i]) log.info("odpocetD: " + znenie) ############################## #4. ######################### # MESURING # #Run temperature mesuring ahead of time (ZP.LOADING_CAS) if measuring is required or if sensor-checks didn't yet confirm all checks ok onSenzory = ZP.SENZORY[: 9] #just FYI that we are mesuring all sensors every time. if odpocetD[ 'intervalMerTep'] != None: #since GPS mesuring is not yet available, this is always True if (odpocetD['intervalMerTep'] <= ZP.LOADING_CAS or not all(ZP.Kntrl_tep_succesfully_finished) ): #meraj uz v predstihu resp. pri kontrole tepMer_thread = threading.Thread( target=meranie.TemperatureHumidity.ofSensors, name="MerajTep", args=(onSenzory, ), daemon=False) tepMer_thread.start() #IGNORED. GPS feature is not fully implemented yet meranieGpsJePozadovane = False # meranieGpsJePozadovane = True if odpocetD['intervalMerGps'] != None else False if meranieGpsJePozadovane: if odpocetD[ 'intervalMerGps'] <= ZP.LOADING_CAS or not ZP.Kntrl_gps_OK: #meraj uz v predstihu resp. pri kontrole if False: startGps_thread = threading.Thread( target=mka.Gps.startuj_GPS, name="StartGps") gpsMer_thread = threading.Thread( target=mka.Gps.meraj_GPS, name="MerajGps") #spustanie gps pocas behu: if event_gpsNastartovane.is_set(): gpsMer_thread.start() else: startGps_thread.start() print("startGPS started") #should be moved few lines bellow if 'MerajGps' in active_threads: gpsMer_thread.join() #Temperature mesuring. Lasts maximum 5.1 seconds. In case it's not yet finished, wait for it to finish. active_threads = [x.name for x in threading.enumerate()] if 'MerajTep' in active_threads: tepMer_thread.join() casMerania = time.time() - ZP.merTepCas_debug if casMerania > 5.9: log.warning( "Meranie teploty prebehlo nezvycajne pomaly, trvalo:" + str(casMerania)) ZP.merTepCas_debug = 0 ############################# #5. ######################### # SENSORS-CHECKS # # # #first clear all checks' events to not check sensors that are not active (empty cages). for e in ZP.kntrlEventy: e.clear() #started exactly on mesuring intervals counter == 0 (odpocetD[intervalMerTep]) if odpocetD['intervalMerTep'] == 0: #INITIATE CHECKS - only for non-empty cages (konfigD[aktBoxy]) for ix in range(ZP.POCET_SENZOROV): if ZP.konfigD['aktBoxy'][ix] == '1': ZP.kntrlEventy[ix].set() else: #this is just for logging: ZP.filterVysledkyD[ZP.SENZORY[ix]] = (('-', '-'), '-', '-') #CONTINUE with running checks until they all confirm their check value True if odpocetD['intervalMerTep'] == 0 or not all( ZP.Kntrl_tep_succesfully_finished): for ix in range(ZP.POCET_SENZOROV): if ZP.konfigD['aktBoxy'][ix] == '1': ZP.Q[ix].put(1) for q in ZP.Q: q.join() #6. ################################### # WRITE-OFF INTERVAL-COUNTERS # # # #work has been performed, write-off the counter for each activity #work to be performed on the next run will have it's counter == 0 for inter in ZP.INTERVALOVE_PREMENNE: if odpocetD[inter] != None: if odpocetD[inter] == 0: odpocetD[inter] = ZP.konfigD[inter] - ZP.FREQ else: odpocetD[inter] -= ZP.FREQ if ZP.konfigD[inter] == 123456789: odpocetD[inter] = None ####################################### ############################### # some side tasks # # # log.debug("Tabulka kontrol:") i = 0 for senz in ZP.SENZORY[:6]: znenie = '' for k in ZP.DEBUG[senz]: znenie += str(ZP.DEBUG[senz][k]) + "\t" log.debug(znenie) # log.debug("kontorly:" + str(ZP.Kntrl_tep_succesfully_finished)) log.debug("adapterManagerQ:" + str(ZP.adapterJob_prioDeq.deqList)) ZP.logPerRun.printHlavicku() ZP.logPerRun.print() ############################### #7. ################################### # SHUTDOWN / SLEEP / CONTINUE # # # #check if there is a need to shutdown RPI (sleep or shutdown forever) #1. specialny pripad - restaruj RPI ak adapter neodpoveda na restarty: if (ZP.troubleMonitor.adapterNotRestarting_tryAgain == False): vseobecne.Pomoc.prepisJsonFile(ZP.konfigD, ZP.MAIN_DIR + "konfig.json") #resetuj odpocet.json na nuly aby sa vsetko spustilo pri zapnuti RPI for i in ZP.INTERVALOVE_PREMENNE: odpocetD[i] = 0 if odpocetD[i] != None else None vseobecne.Pomoc.prepisJsonFile(odpocetD, "odpocet.json") log.warning( "Restartujem RPI kvoli problemu s restartovanim adaptera!") sysfun.uspiRpi(ZP.TRVANIE_RESTARTU, datetime.now()) # THIS LINE ENDS THE! #if above didn't end the program, then we continue here: #check if there are any intervals in ZP.konfigD different than None nieNoneOdpocty = [x for x in odpocetD.values() if x != None] #if all intervals in ZP.konfigD == None (nieNoneOdpocty is []) if nieNoneOdpocty == []: #then it's signal to shutdown RPI forever: oddych = None #this value is used at the bottom (outside of Main loop) specialne.zapisDefaultnyOdpocet() #for fresh RPI start specialne.zapisDefaultnyKonfig() #for fresh RPI start log.info("Dostal som instrukcie na vypnutie RPI.") break #breaks the main loop, jumps at the bottom to shut down RPI else: #else, check if there is a need to sleep pozadovany_oddych = min( nieNoneOdpocty ) #the minimum interval-counter is the maximum possible "sleep" time of RPI cas_do_konca_behu = ZP.FREQ - (time.time() - start_cas) korekcia = 0 #correction to make the sleep time fit perfectly. 0 means no correction needed #oddych sa vyratava zlozitejsou formulkou ale plati, ze cas do konca behu nie je podstatny pretoze sa prekryva s SOME_TIME_TO_FINISH_ADA.JOBS #sysfun.uspiRpi() rata spanok od "pociatokSpanku" po dobu "oddych" oddych = round(pozadovany_oddych + cas_do_konca_behu - ZP.RPI_BOOTUP_CAS - ZP.LOADING_CAS + korekcia) log.debug("Vyratany oddych (min Odpocet):" + str(pozadovany_oddych) + ", Skutocny mozny oddych:" + str(oddych)) #now check that new message wasn't received around this moment #we dont' want to ignore that new message so don't proceed with shutdown if received if len(ZP.prijataSprava_deque) == 0: #also check other stuff before shutting down: if (oddych > ZP.MIN_ODDYCH and not ZP.troubleMonitor.isOn_mainAlarm() and all(ZP.Kntrl_tep_succesfully_finished) and ZP.AdapterNeodosielaSpravu and specialne.MessageNotInAdapterQueue()): log.info("Uspavam RPI.") log.debug( "Uspavam RPI pretoze 1. oddych > 90 sekund, 2.nie je zapnuty alarm, 3. nebezi ziadna kontrola, 4. AdapterNeodosielaSpravu a 5. sprava nie je v adapterQueue: " ) #store current configuration in a file for it to be used for next run vseobecne.Pomoc.prepisJsonFile( ZP.konfigD, ZP.MAIN_DIR + "konfig.json") #since we are putting RPI to sleep, we need to write-off interval-counters by the lenght of the sleep so that they are ready for the new run for i in ZP.INTERVALOVE_PREMENNE: odpocetD[i] = odpocetD[ i] - pozadovany_oddych if odpocetD[ i] != None else None vseobecne.Pomoc.prepisJsonFile(odpocetD, "odpocet.json") pociatokSpanku = datetime.now() break #breaks the main loop, jumps at the bottom to shut down RPI ####################################### #8. ################################### # CONTINUE WITH THE MAIN LOOP # # # loop_count += 1 #assure the run is no shorter than 6 seconds, then repeat the Main loop: end_cas = time.time() cas_behu = end_cas - start_cas if cas_behu < ZP.FREQ: cakaj = ZP.FREQ - cas_behu else: cakaj = 0 log.warning("Beh prebehol prilis pomaly, trval" + str(cas_behu) + "sekund!") cas_celkoveho_behu += (cas_behu + cakaj) log.info("Cas celkoveho behu: " + str(cas_celkoveho_behu) + " sekund.") log.info("") time.sleep(cakaj) ####################################### ################################### # WE ARE SHUTTING DOWN # # # """We will get here only if "all runs" of Main loop were succesfully finished (RPI wasn't physically shut down):""" #there is no more "posta" jobs in adapter queue so we can shut down the adapter: ZP.adapterJob_prioDeq.put( 'pwrKeyAdapter', delete=False) #shut down adapter functionality gracefully """adapter might have some jobs to do and we are already shuting the device down - but there are only 2 crucial jobs that might be of concern: 1. phone calling in alarm situation - this wont happen because we wouldnt ask for Rpi shutdown in case of alarm 2. message sending - if we got to this line it means that either there is no need for informing in this DAY or ... in any case we give adapter SOME_TIME_TO_FINISH_ADAPTER_JOBS anyway.""" log.info("Giving adapterManager some time to finish assigned jobs: " + str(ZP.SOME_TIME_TO_FINISH_ADAPTER_JOBS) + " seconds") time.sleep(ZP.SOME_TIME_TO_FINISH_ADAPTER_JOBS) sysfun.uspiRpi(oddych, pociatokSpanku) #program is shut down by this function ################################### except: log.exception("EXCEPTION!") sys.exit()