Skip to content

Commit

Permalink
Should fix #4
Browse files Browse the repository at this point in the history
  • Loading branch information
Mike Townsley authored and Mike Townsley committed Dec 15, 2019
1 parent d589f33 commit c59b015
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 19 deletions.
36 changes: 36 additions & 0 deletions src/generics.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ class GenericRelay:
def __init__(self, function: ThermostatState):
self.__function = function
self.__isOpen = None
self.__callbackList = []

@property
def isOpen(self):
Expand All @@ -232,14 +233,31 @@ def function(self):
""" Gets the ThermostatState function this relay handles """
return self.__function

def addCallback(self, callback):
""" Provide a callback in the form of callback(isOpening: boolean) to
notify when the relay is openign or closing """
self.__callbackList.append(callback)

def openRelay(self):
""" Open the relay, break circuit, disabling the function """
for callback in self.__callbackList:
callback(False)
self._openRelay()
self.__isOpen = True

def closeRelay(self):
""" Close the relay, connect circuit, enabling the function """
for callback in self.__callbackList:
callback(True)
self._closeRelay()
self.__isOpen = False

def _openRelay(self):
pass

def _closeRelay(self):
pass


class UserThermostatInteractionEvent(Event):
MODE_NEXT = 1
Expand All @@ -264,7 +282,10 @@ def __init__(self,
relays: list):
self.__lcd = lcd
self.__sensor = sensor
self.__relayIsClosing = False
self.__relayMap = {r.function: r for r in relays}
for relay in relays:
relay.addCallback(self.__relayCallback)
if ThermostatState.OFF not in self.__relayMap:
self.__relayMap[ThermostatState.OFF] = \
GenericRelay(ThermostatState.OFF)
Expand Down Expand Up @@ -296,6 +317,9 @@ def setServiceProvider(self, provider: ServiceProvider):
frequency=self.__backlightTimeoutDuration,
handlers=self.__backlightTimeout,
oneShot=True)
self.__relayClosingTimeoutInvoker = self._installTimerHandler(
frequency=3.0, handlers=self.__relayClosingTimeout,
oneShot=True)
self.__drawRowTwoInvoker = self._installTimerHandler(
frequency=3.0,
handlers=[
Expand Down Expand Up @@ -329,6 +353,10 @@ def state(self):
""" Current state of the thermostat """
return self.__state

@property
def relayIsClosing(self):
return self.__relayIsClosing

def __checkSchedule(self):
settings = self._getService(Settings)
eventBus = self._getService(EventBus)
Expand Down Expand Up @@ -448,6 +476,14 @@ def __changeState(self, newState: ThermostatState):
self.__state = newState
self._fireEvent(ThermostatStateChangedEvent(newState))

def __relayCallback(self, isClosing: bool):
if isClosing:
self.__relayIsClosing = True
self.__relayClosingTimeoutInvoker.reset()

def __relayClosingTimeout(self):
self.__relayIsClosing = False

def __fanRunout(self):
settings = self._getService(Settings)

Expand Down
13 changes: 8 additions & 5 deletions src/hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ def __init__(self, function: ThermostatState, pinIn: int, pinOut: int):
GPIO.setup(self.__pinOut, GPIO.OUT)
self.openRelay()

def openRelay(self):
def _openRelay(self):
super().openRelay()

# NEGATIVE 3V from IN->OUT opens the relay
Expand All @@ -197,7 +197,7 @@ def openRelay(self):
sleep(0.1)
GPIO.output(self.__pinOut, False)

def closeRelay(self):
def _closeRelay(self):
super().closeRelay()

# POSITIVE 3V from IN->OUT opens the relay
Expand Down Expand Up @@ -239,7 +239,7 @@ def __init__(self):
relays=(
PanasonicAgqRelay(ThermostatState.FAN, 5, 17),
PanasonicAgqRelay(ThermostatState.HEATING, 6, 27),
PanasonicAgqRelay(ThermostatState.COOLING, 13, 22),
PanasonicAgqRelay(ThermostatState.COOLING, 13, 22)
)
)

Expand Down Expand Up @@ -272,5 +272,8 @@ def __subscribeToButton(self, pin: int, button: Button):
pin, GPIO.RISING, callback=self.__buttonCallback, bouncetime=200)

def __buttonCallback(self, channel):
button = self.__pinToButtonMap[channel]
self._fireEvent(ButtonPressedEvent(button))
""" Callback happens on another thread, so this method is marshaling
ButtonPressedEvent instances to the main thread to handle """
if not super().relayIsClosing:
button = self.__pinToButtonMap[channel]
self._fireEvent(ButtonPressedEvent(button))
2 changes: 1 addition & 1 deletion src/power.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,4 +67,4 @@ def __powerPriceChanged(self, event: PowerPriceChangedEvent):
self.__startUpdatePriceHandler.reset(frequency=event.nextUpdate)
log.info(
f"Power price is now {event.price:.4f}/kW*h, next update "
f"in {event.nextUpdate}s")
f"in {event.nextUpdate}s")
28 changes: 15 additions & 13 deletions src/terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,30 +47,27 @@ def __init__(self, function: ThermostatState,
super().__init__(function)

self.__displayWin = curses.newwin(1, 16, row, col)
self.__isClosed = None
self.__colorPair = curses.color_pair(colorPair)

def redraw(self):
self.__displayWin.clear()
if self.__isClosed is None:
if self.isOpen is None:
self.__displayWin.addstr(
0, 0, self.function.name + ' UNKNOWN')
elif self.__isClosed:
elif self.isOpen:
self.__displayWin.addstr(
0, 0, self.function.name + ' CLOSED',
curses.A_REVERSE | self.__colorPair)
0, 0, self.function.name + ' OPEN')
else:
self.__displayWin.addstr(
0, 0, self.function.name + ' OPEN')
0, 0, self.function.name + ' CLOSED',
curses.A_REVERSE | self.__colorPair)

self.__displayWin.refresh()

def openRelay(self):
self.__isClosed = False
def _openRelay(self):
self.redraw()

def closeRelay(self):
self.__isClosed = True
def _closeRelay(self):
self.redraw()


Expand Down Expand Up @@ -155,11 +152,16 @@ def __keyPressedHandler(self, event: KeyPressedEvent):
super()._fireEvent(PowerPriceChangedEvent(
price=self.__lastPrice+0.25, nextUpdate=1))
elif char == ord('1'):
super()._modifyComfortSettings(1)
if not super().relayIsClosing:
super()._modifyComfortSettings(1)
elif char == ord('2'):
super()._modifyComfortSettings(-1)
if not super().relayIsClosing:
super()._modifyComfortSettings(-1)
elif char == ord('3'):
super()._nextMode()
if not super().relayIsClosing:
super()._nextMode()
else:
log.debug("Ignoring button during relay closure")
elif char == curses.KEY_UP:
self.__environmentSensor.temperature += 1
self._fireEvent(SensorDataChangedEvent(
Expand Down

0 comments on commit c59b015

Please sign in to comment.