Receive notifications for garage updates
This commit is contained in:
parent
460be567c9
commit
d1a8769e07
|
@ -1,17 +1,3 @@
|
|||
# There are 4 different types of patterns used when generating a digit that is
|
||||
# to be placed in a rectangle 3X5 pixels. Combinations of these are used to
|
||||
# create a number pattern such as:
|
||||
# * * *
|
||||
# *
|
||||
# * * *
|
||||
# * *
|
||||
# * * *
|
||||
#
|
||||
# 1) * * * Full Row
|
||||
# 2) * * Both Sides
|
||||
# 3) * Right Side
|
||||
# 4) * Left Side
|
||||
|
||||
import colors
|
||||
|
||||
|
||||
|
|
77
chutney.py
77
chutney.py
|
@ -1,10 +1,15 @@
|
|||
import json
|
||||
import requests
|
||||
import sys
|
||||
|
||||
from character_display import CharacterDisplay
|
||||
from configparser import ConfigParser
|
||||
from garage_display import GarageDisplay
|
||||
from garage_updater import GarageUpdater
|
||||
from multiprocessing import Event
|
||||
from multiprocessing import Process
|
||||
from multiprocessing import Queue
|
||||
from queue import Empty
|
||||
from signal import signal
|
||||
from signal import SIGTERM
|
||||
from time import sleep
|
||||
|
@ -21,22 +26,24 @@ except ImportError:
|
|||
|
||||
|
||||
WEATHER_UPDATE_INTERVAL_IN_SECONDS = 10
|
||||
GARAGE_UPDATE_INTERVAL_IN_SECONDS = 10
|
||||
GARAGE_UPDATE_INTERVAL_IN_SECONDS = 30
|
||||
DISPLAY_UPDATE_INTERVAL_IN_SECONDS = 0.5
|
||||
CONFIG_FILE = 'chutney.cfg'
|
||||
|
||||
|
||||
class HaltException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def main():
|
||||
queue = Queue()
|
||||
haltEvent = Event()
|
||||
signal(SIGTERM, cleanExit(unicorn, haltEvent))
|
||||
Process(target=weatherLoop, args=[haltEvent]).start()
|
||||
Process(target=garageLoop, args=[queue]).start()
|
||||
signal(SIGTERM, cleanExit(unicorn, haltEvent, queue))
|
||||
|
||||
unicorn.brightness(0.3)
|
||||
|
||||
weatherThread = Process(target=weatherLoop, args=[haltEvent])
|
||||
weatherThread.start()
|
||||
|
||||
garageThread = Process(target=garageLoop, args=[haltEvent])
|
||||
garageThread.start()
|
||||
|
||||
characterDisplay = CharacterDisplay(unicorn)
|
||||
timeDisplay = TimeDisplay(characterDisplay, topRow=15)
|
||||
weatherDisplay = WeatherDisplay(characterDisplay, topRow=9)
|
||||
|
@ -59,24 +66,68 @@ def weatherLoop(haltEvent):
|
|||
weatherUpdater.clearWeather()
|
||||
|
||||
|
||||
def garageLoop(haltEvent):
|
||||
garageUpdater = GarageUpdater(configFile=CONFIG_FILE)
|
||||
def garageLoop(queue):
|
||||
garageNotify = Process(target=garageNotifyLoop, args=[queue])
|
||||
garageNotify.start()
|
||||
|
||||
while not haltEvent.is_set():
|
||||
garageUpdater = GarageUpdater(configFile=CONFIG_FILE)
|
||||
isRunning = True
|
||||
|
||||
while isRunning:
|
||||
garageUpdater.updateGarageState()
|
||||
haltEvent.wait(timeout=GARAGE_UPDATE_INTERVAL_IN_SECONDS)
|
||||
|
||||
try:
|
||||
item = queue.get(timeout=GARAGE_UPDATE_INTERVAL_IN_SECONDS)
|
||||
isRunning = item != 'halt'
|
||||
except Empty:
|
||||
pass
|
||||
|
||||
garageUpdater.clearGarageState()
|
||||
garageNotify.terminate()
|
||||
|
||||
|
||||
def cleanExit(unicorn, haltEvent):
|
||||
def garageNotifyLoop(queue):
|
||||
signal(SIGTERM, raiseHaltException())
|
||||
config = ConfigParser()
|
||||
config.read(CONFIG_FILE)
|
||||
|
||||
ntfy = config['garage'].get('ntfy')
|
||||
topic = config['garage'].get('topic')
|
||||
|
||||
try:
|
||||
resp = requests.get(f'https://{ntfy}/{topic}/json', stream=True)
|
||||
|
||||
for line in resp.iter_lines():
|
||||
if line:
|
||||
data = json.loads(line.decode('utf-8'))
|
||||
|
||||
if (data['event'] == 'message'):
|
||||
queue.put('update')
|
||||
except HaltException:
|
||||
pass
|
||||
except Exception as e:
|
||||
print(e, flush=True)
|
||||
finally:
|
||||
resp.close()
|
||||
|
||||
|
||||
def cleanExit(unicorn, haltEvent, queue):
|
||||
def _exit_(signum, frame):
|
||||
unicorn.off()
|
||||
haltEvent.set()
|
||||
queue.put('halt')
|
||||
queue.close()
|
||||
sys.exit(0)
|
||||
|
||||
return _exit_
|
||||
|
||||
|
||||
def raiseHaltException():
|
||||
def _exit_(signum, frame):
|
||||
raise HaltException()
|
||||
|
||||
return _exit_
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -7,3 +7,5 @@ lon=lon
|
|||
|
||||
[garage]
|
||||
uri=uri
|
||||
ntfy=ntfy.sh
|
||||
topic=topic
|
||||
|
|
|
@ -18,6 +18,7 @@ class GarageDisplay:
|
|||
def showGarageState(self):
|
||||
state = self.getGarageState()
|
||||
|
||||
# TODO - only update the changed door so the other one doesn't flicker
|
||||
if state != self.currentState:
|
||||
self.currentState = state
|
||||
self.characterDisplay.clearRow(self.topRow, rowHeight=4)
|
||||
|
|
Loading…
Reference in New Issue