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

complete SpaceAPI integration

parent 615e31f7
__pycache__
config.py
......@@ -5,7 +5,7 @@ import email.mime.text, email.utils
# Logging configuration
syslogLevel = logging.INFO
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
# Mail logging handler
......
from threading import Lock
from libtuer import ThreadFunction, logger
import urllib.request
from config import spaceApiKey
class SpaceApi:
__init__ (self, waker):
def __init__ (self, waker):
self._state_to_set = None
self._state_last_set = None
self._running = True
......@@ -12,6 +16,20 @@ class SpaceApi:
def stop (self):
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__)
def _set_state (self, state = None):
'''Sets the state, if None: leave state unchanged and re-try if previous attempts failed'''
......@@ -31,10 +49,9 @@ class SpaceApi:
# check if there's something we need to do
if self._state_last_set == state: return
# take action!
error = do_request(stts) # TODO
#TODO logging
#TODO error too often -> log critical to send mails
if not error:
self.state_last_set = stts
success = self._do_request(state)
# TODO error too often -> log critical to send mails
if success:
self._state_last_set = state
finally:
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
import os, random, time, threading
......@@ -90,6 +90,8 @@ class StateMachine():
return self.state_machine.old_pins
def actor(self):
return self.state_machine.actor
def api(self):
return self.state_machine.api
def handle_event(self,ev,arg): # don't override
if ev == StateMachine.CMD_PINS:
return self.handle_pins_event()
......@@ -241,6 +243,7 @@ class StateMachine():
nervlist = [(24*60*60, lambda: logger.critical("Space is now open for 24h. Is everything all right?"))]
super().__init__(sm, nervlist)
self.last_buzzed = None
self.api().set_state(True)
def handle_pins_event(self):
pins = self.pins()
if pins.bell_ringing and not self.old_pins().bell_ringing: # first thing to check: edge detection
......@@ -251,6 +254,8 @@ class StateMachine():
logger.info("StateMachine: space switch turned off - starting leaving procedure")
return StateMachine.StateAboutToLeave(self.state_machine)
return super().handle_pins_event()
def on_leave(self):
self.api().set_state(False)
class StateLocking(AbstractUnlockedState):
def __init__(self,sm):
......@@ -299,13 +304,16 @@ class StateMachine():
return StateMachine.StateAuf(self.state_machine)
return super().handle_pins_event()
def __init__(self, actor, waker, fallback = False):
def __init__(self, actor, waker, api, fallback = False):
self.actor = actor
self.api = api
self.callback = ThreadFunction(self._callback, name="StateMachine")
self.current_state = StateMachine.StateStart(self, fallback=fallback)
self.pins = None
self.old_pins = None
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):
self.callback.stop()
......
#!/usr/bin/python3
import RPi.GPIO as GPIO
import statemachine, actor, pins, tysock, waker
import statemachine, actor, pins, tysock, waker, spaceapi
from libtuer import logger
import argparse
......@@ -31,7 +31,8 @@ GPIO.setmode(GPIO.BOARD)
# bring 'em all up
the_actor = actor.Actor()
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_pins = pins.PinsWatcher(the_machine)
......@@ -47,6 +48,7 @@ except KeyboardInterrupt:
the_waker.stop() # this one first, it "randomly" calls other threads
the_pins.stop() # as does this
the_machine.stop()
the_api.stop()
the_actor.stop()
# 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