import easywifi, easydraw, machine, gc, ugfx, badge, woezel
from time import ticks_ms, sleep_ms, ticks_diff
from umqtt.simple import MQTTClient

co2   = 0
co2_werkplaats = 0
co2_hoofdruimte = 0
fan   = None
n     = 0
delay_on = 10
delay_off = 600
delay = delay_on
fan_changed = ticks_ms()
space_open = False
lasercutter = 'unknown'

on  = machine.Pin(16, machine.Pin.OUT)
off = machine.Pin(4,  machine.Pin.OUT)

server = "mosquitto.space.revspace.nl"

mqtt = MQTTClient('badge' + str(machine.unique_id()), server)

easywifi.enable(True)
if easywifi.state == False:
  easydraw.msg("Meh unable to connect to network","FAILURE")
  easydraw.msg("Waiting 5 seconds to try again!")
  badge.eink_busy_wait()
  machine.deepsleep(5000)

def reboot(message = "Rebooting"):
  easydraw.msg(message)
  badge.eink_busy_wait()
  machine.deepsleep(1)
  
easydraw.msg("Checking for updates")
try:
  woezel.install('Revfan')
  reboot("Updated! Rebooting now!")
except:
  easydraw.msg("No update available. Starting app!")
  easydraw.msg("Connecting to MQTT")

  
def gt0(x):
  if x == None: return False
  return x > 0
  
def update_display():
  ugfx.clear(ugfx.WHITE)
  ugfx.string(0,  0, "n: "           + str(n), "Roboto_Black22", ugfx.BLACK)
  ugfx.string(0, 25, "CO2: "         + str(co2),  "Roboto_Black22", ugfx.BLACK)
  ugfx.string(0, 50, "Space: "       + ("open" if space_open else "closed"), "Roboto_Black22", ugfx.BLACK)
  ugfx.string(0, 75, "Lasercutter: " + lasercutter, "Roboto_Black22", ugfx.BLACK)
  ugfx.string(0, 100, "Fan: "      + str(fan) + (" (waiting " + \
    str(delay - int(ticks_diff(ticks_ms(), fan_changed) / 1000)) + " s)" if fan_changed else ""), \
  	"Roboto_Black22", ugfx.BLACK)
  
  ugfx.flush()
  sleep_ms(50)

def clear_display():
  ugfx.clear(ugfx.BLACK)
  ugfx.flush()
  sleep_ms(50)
  update_display()

# Received messages from subscriptions will be delivered to this callback
def sub_cb(topic, msg):
  global co2
  global co2_hoofdruimte
  global co2_werkplaats
  global n
  global space_open
  global lasercutter

  print((topic, msg))

  if topic == b"revdebug/fan/reboot" and msg == b"!":
      mqtt.publish("revdebug/fan", "rebooting")
      reboot("Reboot command received")
  if topic == b"revspace/doorduino/checked-in":
      n = int(msg.decode('utf-8').split(' ')[0])
  if topic == b"revspace/sensors/co2":
      co2_hoofdruimte = int(msg.decode('utf-8').split(' ')[0])
  if topic == b"revspace/sensors/snuffelaar/werkplaats/co2":
      co2_werkplaats = int(msg.decode('utf-8').split(' ')[0])
  if topic == b"revspace/state":
      space_open = (msg == b"open")
  if topic == b"revspace/lasercutter":
      lasercutter = msg.decode('utf-8').split(' ')[0]
  
  co2 = max(co2_hoofdruimte, co2_werkplaats)

def update_fan():
    global fan
    global fan_changed
    global delay
    
    newfan = 0
    #if co2 > 1400: newfan += 1
    #if co2 > 1100: newfan += 1
    #if co2 >  800: newfan += 1
    if co2 >=  500: newfan += 1
    #if humi < 37:  newfan -= 1
    #if humi < 34:  newfan -= 1
    if n >= 3: newfan += 1
    #if space_open: newfan += 1
    if lasercutter == 'connected': newfan += 10  # override

    update_display()

    if newfan != fan:
      mqtt.publish("revspace/fan", str(newfan) + " (updated)", True)

    if bool(newfan > 0) != bool(gt0(fan)):
      fan_changed = now
      delay = delay_on if gt0(newfan) else delay_off

    fan = newfan

def switch_fan(fan):
  mqtt.publish("revspace/fan/state", "on" if gt0(fan) else "off")
  pin = on if gt0(fan) else off;
  pin.value(1)
  sleep_ms(600)  # min. 50 ms, but emptying the capacitor is better
  pin.value(0)

###      

mqtt.set_callback(sub_cb)
mqtt.connect()
mqtt.subscribe(b"revspace/doorduino/checked-in")
mqtt.subscribe(b"revspace/sensors/co2")
mqtt.subscribe(b"revspace/sensors/snuffelaar/werkplaats/co2")
mqtt.subscribe(b"revspace/state")
mqtt.subscribe(b"revspace/lasercutter")
mqtt.subscribe(b"revdebug/fan/reboot")
mqtt.publish("revdebug/fan", "started")

easydraw.msg("MQTT Connected", title = 'Still MQTT Anyway...', reset = True)
mqtt.check_msg()

badge.leds_init();
badge.leds_enable();

lastupdate = ticks_ms()
lastheartbeat = ticks_ms()
while True:
  gc.collect()
  mqtt.check_msg()
  now = ticks_ms()
  
  if ticks_diff(now, lastheartbeat) > 5000:
    lastheartbeat = now
    mqtt.publish("revdebug/fan", "alive")
    mqtt.publish("revspace/fan", str(fan), True)

  if ticks_diff(now, lastupdate) > 1000:
    lastupdate = now
    update_fan()

  if fan_changed and ticks_diff(now, fan_changed) > delay * 1000:
    fan_changed = None
    switch_fan(fan)
    clear_display()

  sleep_ms(100)