Commit 0889e9a1 authored by Ralf's avatar Ralf
Browse files

complete SpaceAPI integration

parent 615e31f7
__pycache__ __pycache__
config.py
...@@ -5,7 +5,7 @@ import email.mime.text, email.utils ...@@ -5,7 +5,7 @@ import email.mime.text, email.utils
# Logging configuration # Logging configuration
syslogLevel = logging.INFO syslogLevel = logging.INFO
mailLevel = logging.CRITICAL # must be "larger" than syslog level! mailLevel = logging.CRITICAL # must be "larger" than syslog level!
mailAddress = ['post+tuer'+'@'+'ralfj.de', 'vorstand@lists.hacksaar.de'] from config import mailAddress
printLevel = logging.DEBUG printLevel = logging.DEBUG
# Mail logging handler # Mail logging handler
......
from threading import Lock from threading import Lock
from libtuer import ThreadFunction, logger
import urllib.request
from config import spaceApiKey
class SpaceApi: class SpaceApi:
__init__ (self, waker): def __init__ (self, waker):
self._state_to_set = None self._state_to_set = None
self._state_last_set = None self._state_last_set = None
self._running = True self._running = True
...@@ -12,6 +16,20 @@ class SpaceApi: ...@@ -12,6 +16,20 @@ class SpaceApi:
def stop (self): def stop (self):
self.set_state.stop() self.set_state.stop()
def _do_request(self, state):
state_val = 1 if state else 0
try:
logger.info("Setting SpaceAPI to %d" % state_val)
url = "http://spaceapi.hacksaar.de/status.php?action=update&key=%s&status=%d" % (spaceApiKey, state_val)
response = urllib.request.urlopen(url, timeout=5.0)
responseText = response.read().decode('utf-8').strip()
if response.getcode() == 200 and responseText == "UpdateSuccessful": return True
logger.error("SpaceAPI returned unexpected code %d, content %s" % (response.getcode(), responseText))
return False
except urllib.request.URLError as e:
logger.error("SpaceAPI update returned error: %s" % str(e))
return False
# set_state is the asynchronous version of _set_state (see __init__) # set_state is the asynchronous version of _set_state (see __init__)
def _set_state (self, state = None): def _set_state (self, state = None):
'''Sets the state, if None: leave state unchanged and re-try if previous attempts failed''' '''Sets the state, if None: leave state unchanged and re-try if previous attempts failed'''
...@@ -31,10 +49,9 @@ class SpaceApi: ...@@ -31,10 +49,9 @@ class SpaceApi:
# check if there's something we need to do # check if there's something we need to do
if self._state_last_set == state: return if self._state_last_set == state: return
# take action! # take action!
error = do_request(stts) # TODO success = self._do_request(state)
#TODO logging # TODO error too often -> log critical to send mails
#TODO error too often -> log critical to send mails if success:
if not error: self._state_last_set = state
self.state_last_set = stts
finally: finally:
self._set_state_lock.release() self._set_state_lock.release()
from libtuer import ThreadFunction, logger, fire_and_forget from libtuer import ThreadFunction, logger, fire_and_forget, fire_and_forget_cmd
from actor import Actor from actor import Actor
import os, random, time, threading import os, random, time, threading
...@@ -90,6 +90,8 @@ class StateMachine(): ...@@ -90,6 +90,8 @@ class StateMachine():
return self.state_machine.old_pins return self.state_machine.old_pins
def actor(self): def actor(self):
return self.state_machine.actor return self.state_machine.actor
def api(self):
return self.state_machine.api
def handle_event(self,ev,arg): # don't override def handle_event(self,ev,arg): # don't override
if ev == StateMachine.CMD_PINS: if ev == StateMachine.CMD_PINS:
return self.handle_pins_event() return self.handle_pins_event()
...@@ -241,6 +243,7 @@ class StateMachine(): ...@@ -241,6 +243,7 @@ class StateMachine():
nervlist = [(24*60*60, lambda: logger.critical("Space is now open for 24h. Is everything all right?"))] nervlist = [(24*60*60, lambda: logger.critical("Space is now open for 24h. Is everything all right?"))]
super().__init__(sm, nervlist) super().__init__(sm, nervlist)
self.last_buzzed = None self.last_buzzed = None
self.api().set_state(True)
def handle_pins_event(self): def handle_pins_event(self):
pins = self.pins() pins = self.pins()
if pins.bell_ringing and not self.old_pins().bell_ringing: # first thing to check: edge detection if pins.bell_ringing and not self.old_pins().bell_ringing: # first thing to check: edge detection
...@@ -251,6 +254,8 @@ class StateMachine(): ...@@ -251,6 +254,8 @@ class StateMachine():
logger.info("StateMachine: space switch turned off - starting leaving procedure") logger.info("StateMachine: space switch turned off - starting leaving procedure")
return StateMachine.StateAboutToLeave(self.state_machine) return StateMachine.StateAboutToLeave(self.state_machine)
return super().handle_pins_event() return super().handle_pins_event()
def on_leave(self):
self.api().set_state(False)
class StateLocking(AbstractUnlockedState): class StateLocking(AbstractUnlockedState):
def __init__(self,sm): def __init__(self,sm):
...@@ -299,13 +304,16 @@ class StateMachine(): ...@@ -299,13 +304,16 @@ class StateMachine():
return StateMachine.StateAuf(self.state_machine) return StateMachine.StateAuf(self.state_machine)
return super().handle_pins_event() return super().handle_pins_event()
def __init__(self, actor, waker, fallback = False): def __init__(self, actor, waker, api, fallback = False):
self.actor = actor self.actor = actor
self.api = api
self.callback = ThreadFunction(self._callback, name="StateMachine") self.callback = ThreadFunction(self._callback, name="StateMachine")
self.current_state = StateMachine.StateStart(self, fallback=fallback) self.current_state = StateMachine.StateStart(self, fallback=fallback)
self.pins = None self.pins = None
self.old_pins = None self.old_pins = None
waker.register(lambda: self.callback(StateMachine.CMD_WAKEUP), 1.0) # wake up every second waker.register(lambda: self.callback(StateMachine.CMD_WAKEUP), 1.0) # wake up every second
# initially, the space is closed
api.set_state(False)
def stop (self): def stop (self):
self.callback.stop() self.callback.stop()
......
#!/usr/bin/python3 #!/usr/bin/python3
import RPi.GPIO as GPIO import RPi.GPIO as GPIO
import statemachine, actor, pins, tysock, waker import statemachine, actor, pins, tysock, waker, spaceapi
from libtuer import logger from libtuer import logger
import argparse import argparse
...@@ -31,7 +31,8 @@ GPIO.setmode(GPIO.BOARD) ...@@ -31,7 +31,8 @@ GPIO.setmode(GPIO.BOARD)
# bring 'em all up # bring 'em all up
the_actor = actor.Actor() the_actor = actor.Actor()
the_waker = waker.Waker() the_waker = waker.Waker()
the_machine = statemachine.StateMachine(the_actor, the_waker, args.fallback) the_api = spaceapi.SpaceApi(the_waker)
the_machine = statemachine.StateMachine(the_actor, the_waker, the_api, args.fallback)
the_socket = tysock.TySocket(the_machine) the_socket = tysock.TySocket(the_machine)
the_pins = pins.PinsWatcher(the_machine) the_pins = pins.PinsWatcher(the_machine)
...@@ -47,6 +48,7 @@ except KeyboardInterrupt: ...@@ -47,6 +48,7 @@ except KeyboardInterrupt:
the_waker.stop() # this one first, it "randomly" calls other threads the_waker.stop() # this one first, it "randomly" calls other threads
the_pins.stop() # as does this the_pins.stop() # as does this
the_machine.stop() the_machine.stop()
the_api.stop()
the_actor.stop() the_actor.stop()
# shutdown GPIO stuff # shutdown GPIO stuff
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment