Chutney [main]
Handle missing network on start/refactor code
[1mdiff --git a/.gitignore b/.gitignore[m
[1mindex 19bfbb7..409ef35 100644[m
[1m--- a/.gitignore[m
[1m+++ b/.gitignore[m
[36m@@ -1,3 +1,4 @@[m
[32m+[m[32m.vscode/[m
__pycache__/[m
*.swp[m
chutney.cfg[m
[1mdiff --git a/chutney/exceptions.py b/chutney/exceptions.py[m
[1mnew file mode 100644[m
[1mindex 0000000..6196ff0[m
[1m--- /dev/null[m
[1m+++ b/chutney/exceptions.py[m
[36m@@ -0,0 +1,3 @@[m
[32m+[m
[32m+[m[32mclass HaltException(Exception):[m
[32m+[m[32m pass[m
[1mdiff --git a/chutney/garage/__init__.py b/chutney/garage/__init__.py[m
[1mindex fc2456e..b8321f4 100644[m
[1m--- a/chutney/garage/__init__.py[m
[1m+++ b/chutney/garage/__init__.py[m
[36m@@ -1,2 +1,3 @@[m
[31m-from .garage_display import GarageDisplay[m
[31m-from .garage_updater import GarageUpdater[m
[32m+[m[32mfrom .garagedisplayer import GarageDisplayer[m
[32m+[m[32mfrom .garagelistener import GarageListener[m
[32m+[m[32mfrom .garageupdater import GarageUpdater[m
[1mdiff --git a/chutney/garage/garage_display.py b/chutney/garage/garagedisplayer.py[m
[1msimilarity index 83%[m
[1mrename from chutney/garage/garage_display.py[m
[1mrename to chutney/garage/garagedisplayer.py[m
[1mindex efd7a98..d9e5d72 100644[m
[1m--- a/chutney/garage/garage_display.py[m
[1m+++ b/chutney/garage/garagedisplayer.py[m
[36m@@ -2,9 +2,9 @@[m [mimport chutney.colors as colors[m
import json[m
[m
[m
[31m-class GarageDisplay:[m
[31m- def __init__(self, symbolDisplay, topRow):[m
[31m- self.symbolDisplay = symbolDisplay[m
[32m+[m[32mclass GarageDisplayer:[m
[32m+[m[32m def __init__(self, symbolDisplayer, topRow):[m
[32m+[m[32m self.symbolDisplayer = symbolDisplayer[m
self.topRow = topRow[m
self.westDoorStartColumn = 1[m
self.eastDoorStartColumn = 12[m
[36m@@ -15,7 +15,7 @@[m [mclass GarageDisplay:[m
self.openFillColor = colors.WHITE[m
self.garageFile = 'data/garage.json'[m
[m
[31m- self.symbolDisplay.clearRow(self.topRow, rowHeight=4)[m
[32m+[m[32m self.symbolDisplayer.clearRow(self.topRow, rowHeight=4)[m
[m
def showGarageState(self):[m
state = self.getGarageState()[m
[36m@@ -26,7 +26,7 @@[m [mclass GarageDisplay:[m
if self.isGarageStateValid(state):[m
self.showState(state)[m
else:[m
[31m- self.symbolDisplay.clearRow(self.topRow, rowHeight=4)[m
[32m+[m[32m self.symbolDisplayer.clearRow(self.topRow, rowHeight=4)[m
[m
def getGarageState(self):[m
try:[m
[36m@@ -51,7 +51,7 @@[m [mclass GarageDisplay:[m
self.showOpenDoor(self.eastDoorStartColumn)[m
[m
def showOpenDoor(self, column):[m
[31m- self.symbolDisplay.displaySquare([m
[32m+[m[32m self.symbolDisplayer.displaySquare([m
x=column,[m
y=self.topRow,[m
outlineColor=self.openOutlineColor,[m
[36m@@ -59,7 +59,7 @@[m [mclass GarageDisplay:[m
)[m
[m
def showClosedDoor(self, column):[m
[31m- self.symbolDisplay.displaySquare([m
[32m+[m[32m self.symbolDisplayer.displaySquare([m
x=column,[m
y=self.topRow,[m
outlineColor=self.closedOutlineColor,[m
[1mdiff --git a/chutney/garage/garagelistener.py b/chutney/garage/garagelistener.py[m
[1mnew file mode 100644[m
[1mindex 0000000..939e1f7[m
[1m--- /dev/null[m
[1m+++ b/chutney/garage/garagelistener.py[m
[36m@@ -0,0 +1,28 @@[m
[32m+[m[32mimport json[m
[32m+[m[32mimport requests[m
[32m+[m
[32m+[m[32mfrom configparser import ConfigParser[m
[32m+[m
[32m+[m
[32m+[m[32mclass GarageListener:[m
[32m+[m[32m def __init__(self, configFile):[m
[32m+[m[32m config = ConfigParser()[m
[32m+[m[32m config.read(configFile)[m
[32m+[m
[32m+[m[32m ntfy = config['garage'].get('ntfy')[m
[32m+[m[32m topic = config['garage'].get('topic')[m
[32m+[m
[32m+[m[32m self.ntfyUri = f'https://{ntfy}/{topic}/json'[m
[32m+[m
[32m+[m[32m def listenForNotifications(self, queue):[m
[32m+[m[32m resp = requests.get(self.ntfyUri, stream=True)[m
[32m+[m
[32m+[m[32m try:[m
[32m+[m[32m for line in resp.iter_lines():[m
[32m+[m[32m if line:[m
[32m+[m[32m data = json.loads(line.decode('utf-8'))[m
[32m+[m
[32m+[m[32m if (data['event'] == 'message'):[m
[32m+[m[32m queue.put('update')[m
[32m+[m[32m finally:[m
[32m+[m[32m resp.close()[m
[1mdiff --git a/chutney/garage/garage_updater.py b/chutney/garage/garageupdater.py[m
[1msimilarity index 100%[m
[1mrename from chutney/garage/garage_updater.py[m
[1mrename to chutney/garage/garageupdater.py[m
[1mdiff --git a/chutney/runner.py b/chutney/runner.py[m
[1mindex 151c613..0f486ef 100644[m
[1m--- a/chutney/runner.py[m
[1m+++ b/chutney/runner.py[m
[36m@@ -1,14 +1,13 @@[m
[31m-import json[m
[31m-import requests[m
import sys[m
[m
[31m-from .symbol_display import SymbolDisplay[m
[31m-from .garage import GarageDisplay[m
[32m+[m[32mfrom .exceptions import HaltException[m
[32m+[m[32mfrom .garage import GarageDisplayer[m
[32m+[m[32mfrom .garage import GarageListener[m
from .garage import GarageUpdater[m
[31m-from .time import TimeDisplay[m
[31m-from .weather import WeatherDisplay[m
[32m+[m[32mfrom .symboldisplayer import SymbolDisplayer[m
[32m+[m[32mfrom .time import TimeDisplayer[m
[32m+[m[32mfrom .weather import WeatherDisplayer[m
from .weather import WeatherUpdater[m
[31m-from configparser import ConfigParser[m
from multiprocessing import Event[m
from multiprocessing import Process[m
from multiprocessing import Queue[m
[36m@@ -27,14 +26,11 @@[m [mexcept ImportError:[m
[m
WEATHER_UPDATE_INTERVAL_IN_SECONDS = 60[m
GARAGE_UPDATE_INTERVAL_IN_SECONDS = 30[m
[32m+[m[32mGARAGE_LISTENER_RETRY_INTERVAL_IN_SECONDS = 120[m
DISPLAY_UPDATE_INTERVAL_IN_SECONDS = 0.5[m
CONFIG_FILE = 'chutney.cfg'[m
[m
[m
[31m-class HaltException(Exception):[m
[31m- pass[m
[31m-[m
[31m-[m
def main():[m
queue = Queue()[m
haltEvent = Event()[m
[36m@@ -44,15 +40,15 @@[m [mdef main():[m
[m
unicorn.brightness(0.3)[m
[m
[31m- symbolDisplay = SymbolDisplay(unicorn)[m
[31m- timeDisplay = TimeDisplay(symbolDisplay, topRow=15)[m
[31m- weatherDisplay = WeatherDisplay(symbolDisplay, topRow=9)[m
[31m- garageDisplay = GarageDisplay(symbolDisplay, topRow=3)[m
[32m+[m[32m symbolDisplayer = SymbolDisplayer(unicorn)[m
[32m+[m[32m timeDisplayer = TimeDisplayer(symbolDisplayer, topRow=15)[m
[32m+[m[32m weatherDisplayer = WeatherDisplayer(symbolDisplayer, topRow=9)[m
[32m+[m[32m garageDisplayer = GarageDisplayer(symbolDisplayer, topRow=3)[m
[m
while True:[m
[31m- timeDisplay.showTime()[m
[31m- weatherDisplay.showWeather()[m
[31m- garageDisplay.showGarageState()[m
[32m+[m[32m timeDisplayer.showTime()[m
[32m+[m[32m weatherDisplayer.showWeather()[m
[32m+[m[32m garageDisplayer.showGarageState()[m
sleep(DISPLAY_UPDATE_INTERVAL_IN_SECONDS)[m
[m
[m
[36m@@ -88,27 +84,18 @@[m [mdef garageLoop(queue):[m
[m
def garageNotifyLoop(queue):[m
signal(SIGTERM, raiseHaltException())[m
[31m- config = ConfigParser()[m
[31m- config.read(CONFIG_FILE)[m
[31m-[m
[31m- ntfy = config['garage'].get('ntfy')[m
[31m- topic = config['garage'].get('topic')[m
[31m-[m
[31m- try:[m
[31m- resp = requests.get(f'https://{ntfy}/{topic}/json', stream=True)[m
[31m-[m
[31m- for line in resp.iter_lines():[m
[31m- if line:[m
[31m- data = json.loads(line.decode('utf-8'))[m
[31m-[m
[31m- if (data['event'] == 'message'):[m
[31m- queue.put('update')[m
[31m- except HaltException:[m
[31m- pass[m
[31m- except Exception as e:[m
[31m- print(e, flush=True)[m
[31m- finally:[m
[31m- resp.close()[m
[32m+[m
[32m+[m[32m garageListener = GarageListener(configFile=CONFIG_FILE)[m
[32m+[m[32m isRunning = True[m
[32m+[m
[32m+[m[32m while isRunning:[m
[32m+[m[32m try:[m
[32m+[m[32m garageListener.listenForNotifications(queue)[m
[32m+[m[32m except HaltException:[m
[32m+[m[32m isRunning = False[m
[32m+[m[32m except Exception as e:[m
[32m+[m[32m print(e, flush=True)[m
[32m+[m[32m sleep(GARAGE_LISTENER_RETRY_INTERVAL_IN_SECONDS)[m
[m
[m
def cleanExit(unicorn, haltEvent, queue):[m
[1mdiff --git a/chutney/symbol_display.py b/chutney/symboldisplayer.py[m
[1msimilarity index 99%[m
[1mrename from chutney/symbol_display.py[m
[1mrename to chutney/symboldisplayer.py[m
[1mindex f8124ac..3590e0a 100644[m
[1m--- a/chutney/symbol_display.py[m
[1m+++ b/chutney/symboldisplayer.py[m
[36m@@ -1,7 +1,7 @@[m
import chutney.colors as colors[m
[m
[m
[31m-class SymbolDisplay:[m
[32m+[m[32mclass SymbolDisplayer:[m
[m
def __init__(self, unicorn, minX=0, maxX=15, minY=0, maxY=15):[m
self.unicorn = unicorn[m
[1mdiff --git a/chutney/time/__init__.py b/chutney/time/__init__.py[m
[1mindex 8804a97..a34a969 100644[m
[1m--- a/chutney/time/__init__.py[m
[1m+++ b/chutney/time/__init__.py[m
[36m@@ -1 +1 @@[m
[31m-from .time_display import TimeDisplay[m
[32m+[m[32mfrom .timedisplayer import TimeDisplayer[m
[1mdiff --git a/chutney/time/time_display.py b/chutney/time/timedisplayer.py[m
[1msimilarity index 88%[m
[1mrename from chutney/time/time_display.py[m
[1mrename to chutney/time/timedisplayer.py[m
[1mindex 2796f57..a924643 100644[m
[1m--- a/chutney/time/time_display.py[m
[1m+++ b/chutney/time/timedisplayer.py[m
[36m@@ -3,10 +3,10 @@[m [mimport chutney.colors as colors[m
from datetime import datetime[m
[m
[m
[31m-class TimeDisplay:[m
[32m+[m[32mclass TimeDisplayer:[m
[m
[31m- def __init__(self, symbolDisplay, topRow):[m
[31m- self.symbolDisplay = symbolDisplay[m
[32m+[m[32m def __init__(self, symbolDisplayer, topRow):[m
[32m+[m[32m self.symbolDisplayer = symbolDisplayer[m
self.topRow = topRow[m
self.currentHour = [-1, -1][m
self.currentMinute = [-1, -1][m
[36m@@ -37,7 +37,7 @@[m [mclass TimeDisplay:[m
[m
def showTimeDots(self):[m
if self.color != self.currentColor:[m
[31m- self.symbolDisplay.displayTimeDots([m
[32m+[m[32m self.symbolDisplayer.displayTimeDots([m
x=self.timeDotsColumn,[m
y=self.topRow,[m
color=self.color[m
[36m@@ -53,7 +53,7 @@[m [mclass TimeDisplay:[m
self.showDigit(self.minuteStartColumn + 4, minute[1])[m
[m
def showDigit(self, x, digit):[m
[31m- self.symbolDisplay.displayDigit([m
[32m+[m[32m self.symbolDisplayer.displayDigit([m
x=x,[m
y=self.topRow,[m
digit=digit,[m
[36m@@ -61,7 +61,7 @@[m [mclass TimeDisplay:[m
)[m
[m
def hideDigit(self, x):[m
[31m- self.symbolDisplay.clearDigit([m
[32m+[m[32m self.symbolDisplayer.clearDigit([m
x=x,[m
y=self.topRow[m
)[m
[1mdiff --git a/chutney/weather/__init__.py b/chutney/weather/__init__.py[m
[1mindex ef5fa67..9ba00c3 100644[m
[1m--- a/chutney/weather/__init__.py[m
[1m+++ b/chutney/weather/__init__.py[m
[36m@@ -1,2 +1,2 @@[m
[31m-from .weather_display import WeatherDisplay[m
[31m-from .weather_updater import WeatherUpdater[m
[32m+[m[32mfrom .weatherdisplayer import WeatherDisplayer[m
[32m+[m[32mfrom .weatherupdater import WeatherUpdater[m
[1mdiff --git a/chutney/weather/weather_display.py b/chutney/weather/weatherdisplayer.py[m
[1msimilarity index 88%[m
[1mrename from chutney/weather/weather_display.py[m
[1mrename to chutney/weather/weatherdisplayer.py[m
[1mindex c65d953..24276e8 100644[m
[1m--- a/chutney/weather/weather_display.py[m
[1m+++ b/chutney/weather/weatherdisplayer.py[m
[36m@@ -1,9 +1,9 @@[m
import chutney.colors as colors[m
[m
[m
[31m-class WeatherDisplay:[m
[31m- def __init__(self, symbolDisplay, topRow):[m
[31m- self.symbolDisplay = symbolDisplay[m
[32m+[m[32mclass WeatherDisplayer:[m
[32m+[m[32m def __init__(self, symbolDisplayer, topRow):[m
[32m+[m[32m self.symbolDisplayer = symbolDisplayer[m
self.topRow = topRow[m
self.twoDigitStartColumn = 5[m
self.oneDigitStartColumn = 7[m
[36m@@ -17,7 +17,7 @@[m [mclass WeatherDisplay:[m
[m
if temperature != self.currentTemperature:[m
self.currentTemperature = temperature[m
[31m- self.symbolDisplay.clearRow(self.topRow)[m
[32m+[m[32m self.symbolDisplayer.clearRow(self.topRow)[m
[m
if self.isTemperatureValid(temperature):[m
self.updateColor(temperature)[m
[36m@@ -68,14 +68,14 @@[m [mclass WeatherDisplay:[m
return abs(int(temperature))//10 == 0[m
[m
def showNegative(self, column):[m
[31m- self.symbolDisplay.displayNegative([m
[32m+[m[32m self.symbolDisplayer.displayNegative([m
x=column,[m
y=self.topRow,[m
color=self.color[m
)[m
[m
def showDigit(self, column, digit):[m
[31m- self.symbolDisplay.displayDigit([m
[32m+[m[32m self.symbolDisplayer.displayDigit([m
x=column,[m
y=self.topRow,[m
digit=digit,[m
[36m@@ -83,7 +83,7 @@[m [mclass WeatherDisplay:[m
)[m
[m
def showDegree(self, column):[m
[31m- self.symbolDisplay.displayDegree([m
[32m+[m[32m self.symbolDisplayer.displayDegree([m
x=column,[m
y=self.topRow,[m
color=self.color[m
[1mdiff --git a/chutney/weather/weather_updater.py b/chutney/weather/weatherupdater.py[m
[1msimilarity index 100%[m
[1mrename from chutney/weather/weather_updater.py[m
[1mrename to chutney/weather/weatherupdater.py[m