Handle missing network on start/refactor code
This commit is contained in:
parent
fd1ea198fa
commit
0a212e5752
|
@ -1,3 +1,4 @@
|
|||
.vscode/
|
||||
__pycache__/
|
||||
*.swp
|
||||
chutney.cfg
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
class HaltException(Exception):
|
||||
pass
|
|
@ -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
|
||||
|
|
|
@ -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,
|
|
@ -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()
|
|
@ -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')
|
||||
garageListener = GarageListener(configFile=CONFIG_FILE)
|
||||
isRunning = True
|
||||
|
||||
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()
|
||||
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):
|
||||
|
|
|
@ -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
|
|
@ -1 +1 @@
|
|||
from .time_display import TimeDisplay
|
||||
from .timedisplayer import TimeDisplayer
|
||||
|
|
|
@ -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
|
||||
)
|
|
@ -1,2 +1,2 @@
|
|||
from .weather_display import WeatherDisplay
|
||||
from .weather_updater import WeatherUpdater
|
||||
from .weatherdisplayer import WeatherDisplayer
|
||||
from .weatherupdater import WeatherUpdater
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue