import os import logging DEBUG = os.environ.get('DEBUG', False) logging.basicConfig( format='[%(asctime)s] %(levelname)s %(module)s/%(funcName)s - %(message)s', level=logging.DEBUG if DEBUG else logging.INFO) import asyncio from statistics import mean from signal import * import time import w1therm import relays import data import requests HI_SETPOINT = 40.0 LO_SETPOINT = HI_SETPOINT - 5.0 PUMP_RELAY = relays.RELAY1 FAN_RELAY = relays.RELAY3 def controller_message(message): payload = dict(misc=message) r = requests.post('https://tbot.tannercollin.com/message', data=payload, timeout=10) if r.status_code == 200: return True else: logging.exception('Unable to communicate with controller! Message: ' + message) return False def set_fan_on(): relays.set_relay(FAN_RELAY, relays.RELAY_ON) def set_fan_off(): relays.set_relay(FAN_RELAY, relays.RELAY_OFF) def set_pump_on(): relays.set_relay(PUMP_RELAY, relays.RELAY_ON) async def get_temp(): temps = await w1therm.get_temperatures() if len(temps) != len(data.PROBES): raise temperature_log = [] for id_, temp in temps.items(): temperature_log.append('{}: {} C'.format(data.PROBES[id_], temp)) logging.info('Temperature probe ' + ', '.join(temperature_log)) temperature_list = list(temps.values()) temperature_mean = mean(temperature_list) return temperature_mean async def run_thermostat(): while True: try: temperature_mean = await get_temp() except: logging.error('Problem reading temperature probes! Turning fan on and sleeping 60s.') relays.set_relay(FAN_RELAY, relays.RELAY_ON) await asyncio.sleep(60) continue if temperature_mean > HI_SETPOINT: logging.info('Turning fan on') set_fan_on() elif temperature_mean < LO_SETPOINT: logging.info('Turning fan off') set_fan_off() await asyncio.sleep(10) def run_on_exit(*args): logging.info('Cryptosoak exiting, turning pump and fan on.') controller_message('Cryptosoak exiting.') set_pump_on() set_fan_on() exit() async def feed_watchdog(): while True: with open('/dev/watchdog', 'w') as wdt: wdt.write('1') await asyncio.sleep(5) def init(): relays.init_relays() set_pump_on() for sig in (SIGABRT, SIGILL, SIGINT, SIGSEGV, SIGTERM): signal(sig, run_on_exit) logging.info('Signals initialized') async def main(): controller_message('Cryptosoak booting up...') logging.info('Initialization complete') await run_thermostat() if __name__ == '__main__': init() if not DEBUG: logging.info('Waiting 60 seconds to boot...') time.sleep(60) loop = asyncio.get_event_loop() loop.run_until_complete(main()).add_done_callback(run_on_exit) if not DEBUG: loop.run_until_complete(feed_watchdog()) loop.close()