import RPi.GPIO as GPIO
import signal
import sys
from gpiozero import CPUTemperature
import time
from pathlib import Path
import configparser
from lib_oled96 import ssd1306
from PIL import Image, ImageDraw, ImageFont
from smbus import SMBus

i2cbus = SMBus(1)
oled = ssd1306(i2cbus)
canvas = oled.canvas
#LED1 = 19 # BCM naming system
#LED2 = 13
#LED3 = 6
#LED4 = 5
# BOARD naming
LED1 = 35
LED2 = 33
LED3 = 31
LED4 = 29

interval = 0.2

GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
GPIO.setup(LED1, GPIO.OUT)
GPIO.setup(LED2, GPIO.OUT)
GPIO.setup(LED3, GPIO.OUT)
GPIO.setup(LED4, GPIO.OUT)

leds= [LED1,LED2, LED3, LED4]

# initializing GPIO, setting mode to BOARD.
# Default pin of fan is physical pin 8, GPIO14
Fan = 8
GPIO.setwarnings(False)
GPIO.setup(Fan, GPIO.OUT)

def handle_exit(signum, frame):
  print(f"Signal {signum} received, setting fan to 100%")
  p.ChangeDutyCycle(100)
  cleanUp()
  time.sleep(0.5)  # waiting to ensure that PWM is set
  p.stop()
  GPIO.cleanup()
  sys.exit(0)

#initialize GPIO for fan
p = GPIO.PWM(Fan, 50)
p.start(0)

signal.signal(signal.SIGTERM, handle_exit)
signal.signal(signal.SIGINT, handle_exit)  # optional (Ctrl+C)

def read_config():
  confparser = configparser.ConfigParser()
  f = Path("/boot/config.txt")
  if f.is_file():
   confparser.read('/boot/config.txt')
  else:
   f = Path('/boot/firmware/config.txt')
   if f.is_file():
    confparser.read('/boot/firmware/config.txt')
    

  return confparser
confparser = read_config()

def parse_config():
  confparser = read_config()
  stages= []
  
  stage0_temp = float(confparser['fan']['fan_temp0_temp'])
  stage0_speed = float(confparser['fan']['fan_temp0_speed'])
  stage1_temp = float(confparser['fan']['fan_temp1_temp'])
  stage1_speed = float(confparser['fan']['fan_temp1_speed'])
  stage2_temp = float(confparser['fan']['fan_temp2_temp'])
  stage2_speed = float(confparser['fan']['fan_temp2_speed'])

  stages.append({'temp': stage0_temp,'speed': stage0_speed})
  stages.append({'temp': stage1_temp,'speed': stage1_speed})
  stages.append({'temp': stage2_temp,'speed': stage2_speed})
  return stages

stages = parse_config()
print(f'stages={stages}')

def clear_display():
  canvas.rectangle((0, 0, oled.width-1, oled.height-1), outline=0, fill=0)
  oled.display()

def cleanUp():
  #all LED to off.
  for l in leds:
    GPIO.output(l,GPIO.LOW)
# ensure on exit that fan runs full speed
  p.ChangeDutyCycle(100)
  clear_display()

def set_LED(stage):
  for l in leds:
    GPIO.output(l, GPIO.LOW)
  print(f'setting LED {stage}/{leds[stage]} to high.')
  GPIO.output(leds[stage],GPIO.HIGH)

def test_blinking():
  for l in leds:
      GPIO.output(l,GPIO.HIGH)
      time.sleep(0.5)
      GPIO.output(l,GPIO.LOW)
try:
    # clear oled
    clear_display()
    test_blinking()
    stage= oldstage = 0
    fnt = ImageFont.truetype("./FreeMono.ttf",8)
    canvas.text((1,1),f'stage:{stage}',fill=1,font=fnt)
    oled.display()
    while True:
        cpu = CPUTemperature()
        temperature = cpu.temperature

        #print(f'temperature={temperature}/{temp}')
        clear_display()

        if temperature < stages[0]['temp']:
            stage = 0
        elif temperature > stages[1]['temp'] and temperature < stages[2]['temp']:
            stage = 1
        elif temperature > stages[2]['temp']:
            stage = 2

        print(f'stage={stage},oldstage={oldstage}')
        if stage != oldstage:
          oldstage = stage
          print(f'stage={stage},temperature={temperature}°C')
          p.ChangeDutyCycle(stages[stage]['speed'])
          canvas.text((1,1),f'stage:{stage}',fill=1,font=fnt)
          oled.display()

        print('duty cycle changed now setting LED.')
        set_LED(stage)

        time.sleep(0.2)
except KeyboardInterrupt:
  pass
finally:
  p.stop()
  GPIO.cleanup()

