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
|
import colors
|
||||||
|
|
||||||
|
|
||||||
|
|
77
chutney.py
77
chutney.py
|
@ -1,10 +1,15 @@
|
||||||
|
import json
|
||||||
|
import requests
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from character_display import CharacterDisplay
|
from character_display import CharacterDisplay
|
||||||
|
from configparser import ConfigParser
|
||||||
from garage_display import GarageDisplay
|
from garage_display import GarageDisplay
|
||||||
from garage_updater import GarageUpdater
|
from garage_updater import GarageUpdater
|
||||||
from multiprocessing import Event
|
from multiprocessing import Event
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
|
from multiprocessing import Queue
|
||||||
|
from queue import Empty
|
||||||
from signal import signal
|
from signal import signal
|
||||||
from signal import SIGTERM
|
from signal import SIGTERM
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
@ -21,22 +26,24 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
WEATHER_UPDATE_INTERVAL_IN_SECONDS = 10
|
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
|
DISPLAY_UPDATE_INTERVAL_IN_SECONDS = 0.5
|
||||||
CONFIG_FILE = 'chutney.cfg'
|
CONFIG_FILE = 'chutney.cfg'
|
||||||
|
|
||||||
|
|
||||||
|
class HaltException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
queue = Queue()
|
||||||
haltEvent = Event()
|
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)
|
unicorn.brightness(0.3)
|
||||||
|
|
||||||
weatherThread = Process(target=weatherLoop, args=[haltEvent])
|
|
||||||
weatherThread.start()
|
|
||||||
|
|
||||||
garageThread = Process(target=garageLoop, args=[haltEvent])
|
|
||||||
garageThread.start()
|
|
||||||
|
|
||||||
characterDisplay = CharacterDisplay(unicorn)
|
characterDisplay = CharacterDisplay(unicorn)
|
||||||
timeDisplay = TimeDisplay(characterDisplay, topRow=15)
|
timeDisplay = TimeDisplay(characterDisplay, topRow=15)
|
||||||
weatherDisplay = WeatherDisplay(characterDisplay, topRow=9)
|
weatherDisplay = WeatherDisplay(characterDisplay, topRow=9)
|
||||||
|
@ -59,24 +66,68 @@ def weatherLoop(haltEvent):
|
||||||
weatherUpdater.clearWeather()
|
weatherUpdater.clearWeather()
|
||||||
|
|
||||||
|
|
||||||
def garageLoop(haltEvent):
|
def garageLoop(queue):
|
||||||
garageUpdater = GarageUpdater(configFile=CONFIG_FILE)
|
garageNotify = Process(target=garageNotifyLoop, args=[queue])
|
||||||
|
garageNotify.start()
|
||||||
|
|
||||||
while not haltEvent.is_set():
|
garageUpdater = GarageUpdater(configFile=CONFIG_FILE)
|
||||||
|
isRunning = True
|
||||||
|
|
||||||
|
while isRunning:
|
||||||
garageUpdater.updateGarageState()
|
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()
|
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):
|
def _exit_(signum, frame):
|
||||||
unicorn.off()
|
unicorn.off()
|
||||||
haltEvent.set()
|
haltEvent.set()
|
||||||
|
queue.put('halt')
|
||||||
|
queue.close()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
return _exit_
|
return _exit_
|
||||||
|
|
||||||
|
|
||||||
|
def raiseHaltException():
|
||||||
|
def _exit_(signum, frame):
|
||||||
|
raise HaltException()
|
||||||
|
|
||||||
|
return _exit_
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -7,3 +7,5 @@ lon=lon
|
||||||
|
|
||||||
[garage]
|
[garage]
|
||||||
uri=uri
|
uri=uri
|
||||||
|
ntfy=ntfy.sh
|
||||||
|
topic=topic
|
||||||
|
|
|
@ -18,6 +18,7 @@ class GarageDisplay:
|
||||||
def showGarageState(self):
|
def showGarageState(self):
|
||||||
state = self.getGarageState()
|
state = self.getGarageState()
|
||||||
|
|
||||||
|
# TODO - only update the changed door so the other one doesn't flicker
|
||||||
if state != self.currentState:
|
if state != self.currentState:
|
||||||
self.currentState = state
|
self.currentState = state
|
||||||
self.characterDisplay.clearRow(self.topRow, rowHeight=4)
|
self.characterDisplay.clearRow(self.topRow, rowHeight=4)
|
||||||
|
|
Loading…
Reference in New Issue