Chutney [main]

Handle missing network on start/refactor code

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