Handle missing network on start/refactor code
This commit is contained in:
parent
fd1ea198fa
commit
0a212e5752
|
@ -1,3 +1,4 @@
|
||||||
|
.vscode/
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.swp
|
*.swp
|
||||||
chutney.cfg
|
chutney.cfg
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
|
||||||
|
class HaltException(Exception):
|
||||||
|
pass
|
|
@ -1,2 +1,3 @@
|
||||||
from .garage_display import GarageDisplay
|
from .garagedisplayer import GarageDisplayer
|
||||||
from .garage_updater import GarageUpdater
|
from .garagelistener import GarageListener
|
||||||
|
from .garageupdater import GarageUpdater
|
||||||
|
|
|
@ -2,9 +2,9 @@ import chutney.colors as colors
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
|
||||||
class GarageDisplay:
|
class GarageDisplayer:
|
||||||
def __init__(self, symbolDisplay, topRow):
|
def __init__(self, symbolDisplayer, topRow):
|
||||||
self.symbolDisplay = symbolDisplay
|
self.symbolDisplayer = symbolDisplayer
|
||||||
self.topRow = topRow
|
self.topRow = topRow
|
||||||
self.westDoorStartColumn = 1
|
self.westDoorStartColumn = 1
|
||||||
self.eastDoorStartColumn = 12
|
self.eastDoorStartColumn = 12
|
||||||
|
@ -15,7 +15,7 @@ class GarageDisplay:
|
||||||
self.openFillColor = colors.WHITE
|
self.openFillColor = colors.WHITE
|
||||||
self.garageFile = 'data/garage.json'
|
self.garageFile = 'data/garage.json'
|
||||||
|
|
||||||
self.symbolDisplay.clearRow(self.topRow, rowHeight=4)
|
self.symbolDisplayer.clearRow(self.topRow, rowHeight=4)
|
||||||
|
|
||||||
def showGarageState(self):
|
def showGarageState(self):
|
||||||
state = self.getGarageState()
|
state = self.getGarageState()
|
||||||
|
@ -26,7 +26,7 @@ class GarageDisplay:
|
||||||
if self.isGarageStateValid(state):
|
if self.isGarageStateValid(state):
|
||||||
self.showState(state)
|
self.showState(state)
|
||||||
else:
|
else:
|
||||||
self.symbolDisplay.clearRow(self.topRow, rowHeight=4)
|
self.symbolDisplayer.clearRow(self.topRow, rowHeight=4)
|
||||||
|
|
||||||
def getGarageState(self):
|
def getGarageState(self):
|
||||||
try:
|
try:
|
||||||
|
@ -51,7 +51,7 @@ class GarageDisplay:
|
||||||
self.showOpenDoor(self.eastDoorStartColumn)
|
self.showOpenDoor(self.eastDoorStartColumn)
|
||||||
|
|
||||||
def showOpenDoor(self, column):
|
def showOpenDoor(self, column):
|
||||||
self.symbolDisplay.displaySquare(
|
self.symbolDisplayer.displaySquare(
|
||||||
x=column,
|
x=column,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
outlineColor=self.openOutlineColor,
|
outlineColor=self.openOutlineColor,
|
||||||
|
@ -59,7 +59,7 @@ class GarageDisplay:
|
||||||
)
|
)
|
||||||
|
|
||||||
def showClosedDoor(self, column):
|
def showClosedDoor(self, column):
|
||||||
self.symbolDisplay.displaySquare(
|
self.symbolDisplayer.displaySquare(
|
||||||
x=column,
|
x=column,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
outlineColor=self.closedOutlineColor,
|
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
|
import sys
|
||||||
|
|
||||||
from .symbol_display import SymbolDisplay
|
from .exceptions import HaltException
|
||||||
from .garage import GarageDisplay
|
from .garage import GarageDisplayer
|
||||||
|
from .garage import GarageListener
|
||||||
from .garage import GarageUpdater
|
from .garage import GarageUpdater
|
||||||
from .time import TimeDisplay
|
from .symboldisplayer import SymbolDisplayer
|
||||||
from .weather import WeatherDisplay
|
from .time import TimeDisplayer
|
||||||
|
from .weather import WeatherDisplayer
|
||||||
from .weather import WeatherUpdater
|
from .weather import WeatherUpdater
|
||||||
from configparser import ConfigParser
|
|
||||||
from multiprocessing import Event
|
from multiprocessing import Event
|
||||||
from multiprocessing import Process
|
from multiprocessing import Process
|
||||||
from multiprocessing import Queue
|
from multiprocessing import Queue
|
||||||
|
@ -27,14 +26,11 @@ except ImportError:
|
||||||
|
|
||||||
WEATHER_UPDATE_INTERVAL_IN_SECONDS = 60
|
WEATHER_UPDATE_INTERVAL_IN_SECONDS = 60
|
||||||
GARAGE_UPDATE_INTERVAL_IN_SECONDS = 30
|
GARAGE_UPDATE_INTERVAL_IN_SECONDS = 30
|
||||||
|
GARAGE_LISTENER_RETRY_INTERVAL_IN_SECONDS = 120
|
||||||
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()
|
queue = Queue()
|
||||||
haltEvent = Event()
|
haltEvent = Event()
|
||||||
|
@ -44,15 +40,15 @@ def main():
|
||||||
|
|
||||||
unicorn.brightness(0.3)
|
unicorn.brightness(0.3)
|
||||||
|
|
||||||
symbolDisplay = SymbolDisplay(unicorn)
|
symbolDisplayer = SymbolDisplayer(unicorn)
|
||||||
timeDisplay = TimeDisplay(symbolDisplay, topRow=15)
|
timeDisplayer = TimeDisplayer(symbolDisplayer, topRow=15)
|
||||||
weatherDisplay = WeatherDisplay(symbolDisplay, topRow=9)
|
weatherDisplayer = WeatherDisplayer(symbolDisplayer, topRow=9)
|
||||||
garageDisplay = GarageDisplay(symbolDisplay, topRow=3)
|
garageDisplayer = GarageDisplayer(symbolDisplayer, topRow=3)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
timeDisplay.showTime()
|
timeDisplayer.showTime()
|
||||||
weatherDisplay.showWeather()
|
weatherDisplayer.showWeather()
|
||||||
garageDisplay.showGarageState()
|
garageDisplayer.showGarageState()
|
||||||
sleep(DISPLAY_UPDATE_INTERVAL_IN_SECONDS)
|
sleep(DISPLAY_UPDATE_INTERVAL_IN_SECONDS)
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,27 +84,18 @@ def garageLoop(queue):
|
||||||
|
|
||||||
def garageNotifyLoop(queue):
|
def garageNotifyLoop(queue):
|
||||||
signal(SIGTERM, raiseHaltException())
|
signal(SIGTERM, raiseHaltException())
|
||||||
config = ConfigParser()
|
|
||||||
config.read(CONFIG_FILE)
|
|
||||||
|
|
||||||
ntfy = config['garage'].get('ntfy')
|
garageListener = GarageListener(configFile=CONFIG_FILE)
|
||||||
topic = config['garage'].get('topic')
|
isRunning = True
|
||||||
|
|
||||||
|
while isRunning:
|
||||||
try:
|
try:
|
||||||
resp = requests.get(f'https://{ntfy}/{topic}/json', stream=True)
|
garageListener.listenForNotifications(queue)
|
||||||
|
|
||||||
for line in resp.iter_lines():
|
|
||||||
if line:
|
|
||||||
data = json.loads(line.decode('utf-8'))
|
|
||||||
|
|
||||||
if (data['event'] == 'message'):
|
|
||||||
queue.put('update')
|
|
||||||
except HaltException:
|
except HaltException:
|
||||||
pass
|
isRunning = False
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(e, flush=True)
|
print(e, flush=True)
|
||||||
finally:
|
sleep(GARAGE_LISTENER_RETRY_INTERVAL_IN_SECONDS)
|
||||||
resp.close()
|
|
||||||
|
|
||||||
|
|
||||||
def cleanExit(unicorn, haltEvent, queue):
|
def cleanExit(unicorn, haltEvent, queue):
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import chutney.colors as colors
|
import chutney.colors as colors
|
||||||
|
|
||||||
|
|
||||||
class SymbolDisplay:
|
class SymbolDisplayer:
|
||||||
|
|
||||||
def __init__(self, unicorn, minX=0, maxX=15, minY=0, maxY=15):
|
def __init__(self, unicorn, minX=0, maxX=15, minY=0, maxY=15):
|
||||||
self.unicorn = unicorn
|
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
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
class TimeDisplay:
|
class TimeDisplayer:
|
||||||
|
|
||||||
def __init__(self, symbolDisplay, topRow):
|
def __init__(self, symbolDisplayer, topRow):
|
||||||
self.symbolDisplay = symbolDisplay
|
self.symbolDisplayer = symbolDisplayer
|
||||||
self.topRow = topRow
|
self.topRow = topRow
|
||||||
self.currentHour = [-1, -1]
|
self.currentHour = [-1, -1]
|
||||||
self.currentMinute = [-1, -1]
|
self.currentMinute = [-1, -1]
|
||||||
|
@ -37,7 +37,7 @@ class TimeDisplay:
|
||||||
|
|
||||||
def showTimeDots(self):
|
def showTimeDots(self):
|
||||||
if self.color != self.currentColor:
|
if self.color != self.currentColor:
|
||||||
self.symbolDisplay.displayTimeDots(
|
self.symbolDisplayer.displayTimeDots(
|
||||||
x=self.timeDotsColumn,
|
x=self.timeDotsColumn,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
color=self.color
|
color=self.color
|
||||||
|
@ -53,7 +53,7 @@ class TimeDisplay:
|
||||||
self.showDigit(self.minuteStartColumn + 4, minute[1])
|
self.showDigit(self.minuteStartColumn + 4, minute[1])
|
||||||
|
|
||||||
def showDigit(self, x, digit):
|
def showDigit(self, x, digit):
|
||||||
self.symbolDisplay.displayDigit(
|
self.symbolDisplayer.displayDigit(
|
||||||
x=x,
|
x=x,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
digit=digit,
|
digit=digit,
|
||||||
|
@ -61,7 +61,7 @@ class TimeDisplay:
|
||||||
)
|
)
|
||||||
|
|
||||||
def hideDigit(self, x):
|
def hideDigit(self, x):
|
||||||
self.symbolDisplay.clearDigit(
|
self.symbolDisplayer.clearDigit(
|
||||||
x=x,
|
x=x,
|
||||||
y=self.topRow
|
y=self.topRow
|
||||||
)
|
)
|
|
@ -1,2 +1,2 @@
|
||||||
from .weather_display import WeatherDisplay
|
from .weatherdisplayer import WeatherDisplayer
|
||||||
from .weather_updater import WeatherUpdater
|
from .weatherupdater import WeatherUpdater
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import chutney.colors as colors
|
import chutney.colors as colors
|
||||||
|
|
||||||
|
|
||||||
class WeatherDisplay:
|
class WeatherDisplayer:
|
||||||
def __init__(self, symbolDisplay, topRow):
|
def __init__(self, symbolDisplayer, topRow):
|
||||||
self.symbolDisplay = symbolDisplay
|
self.symbolDisplayer = symbolDisplayer
|
||||||
self.topRow = topRow
|
self.topRow = topRow
|
||||||
self.twoDigitStartColumn = 5
|
self.twoDigitStartColumn = 5
|
||||||
self.oneDigitStartColumn = 7
|
self.oneDigitStartColumn = 7
|
||||||
|
@ -17,7 +17,7 @@ class WeatherDisplay:
|
||||||
|
|
||||||
if temperature != self.currentTemperature:
|
if temperature != self.currentTemperature:
|
||||||
self.currentTemperature = temperature
|
self.currentTemperature = temperature
|
||||||
self.symbolDisplay.clearRow(self.topRow)
|
self.symbolDisplayer.clearRow(self.topRow)
|
||||||
|
|
||||||
if self.isTemperatureValid(temperature):
|
if self.isTemperatureValid(temperature):
|
||||||
self.updateColor(temperature)
|
self.updateColor(temperature)
|
||||||
|
@ -68,14 +68,14 @@ class WeatherDisplay:
|
||||||
return abs(int(temperature))//10 == 0
|
return abs(int(temperature))//10 == 0
|
||||||
|
|
||||||
def showNegative(self, column):
|
def showNegative(self, column):
|
||||||
self.symbolDisplay.displayNegative(
|
self.symbolDisplayer.displayNegative(
|
||||||
x=column,
|
x=column,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
color=self.color
|
color=self.color
|
||||||
)
|
)
|
||||||
|
|
||||||
def showDigit(self, column, digit):
|
def showDigit(self, column, digit):
|
||||||
self.symbolDisplay.displayDigit(
|
self.symbolDisplayer.displayDigit(
|
||||||
x=column,
|
x=column,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
digit=digit,
|
digit=digit,
|
||||||
|
@ -83,7 +83,7 @@ class WeatherDisplay:
|
||||||
)
|
)
|
||||||
|
|
||||||
def showDegree(self, column):
|
def showDegree(self, column):
|
||||||
self.symbolDisplay.displayDegree(
|
self.symbolDisplayer.displayDegree(
|
||||||
x=column,
|
x=column,
|
||||||
y=self.topRow,
|
y=self.topRow,
|
||||||
color=self.color
|
color=self.color
|
Loading…
Reference in New Issue