#!/usr/bin/env python

import paho.mqtt.client as mqtt

from pyA10Lime import i2c

import time

'''
Overall design of the program:

Set up mqtt
set up the PCA9685

sub to relevent channels

how do channels work?

devID/controllerID/pinNum maybe?
so A10-1/0x42/4 would reference pyA10 number 1, with a controller addressed at 0x42, pin 4 (5th pin)

example message contents:
subject: A10-1/0x42/4
message: 75

this would set the above pin to a value of 75

don't bother with the LED_ALL stuff, it is kinda useless
'''


'''
TODO:

maybe get a config file set up
ERROR HANDLING
fade-in and fade-out
maybe randomising start times to minimize peak current draw?

'''


clientID = "A10-1" #maybe change this to the hostmname?

broker = "127.0.0.1" #the URL/IP of the mqtt broker

driverNum = 1 #number of LED drivers needed to initialize


def on_connect(client, userdata, flags, rc):
  print("Connected")
  client.subscribe(clientID + "/#") #subscribe for things



def on_message(client, userdata, msg):
  print("Topic is: " + msg.topic)
  print("Message is: " + msg.payload)

  topic = msg.topic.split("/")

  if topic[0] == clientID:
    devAddr = int(topic[1])
    pin = int(topic[2])
    value = int(msg.payload)
    
    endTime = ((4096 * value) / 100) - 1 #value is percent and you set the end time based on % of 4096
    #the minus 1 is so that it is always under 4096

    register = 6 + (pin * 4) #used to find the register number

    i2c.open(devAddr)
    i2c.write([register, 0x00]) #LEDn_ON_X starts at 0
    register += 1
    i2c.write([register, 0x00])
    register += 1
    i2c.write([register, endTime]) #LEDn_OFF_X is defined by endTime
    register += 1
    i2c.write([register, endTime >> 8])
    i2c.close() #a more efficient way would be to auto-increment

    #might have to auto increment when I implement fading

  else:
    print("Wrong topic") #later I should add diagnostic topics and the such



def init():
  i2c.init("/dev/i2c-0"); #we'll be using i2c-0, I think
  
  client = mqtt.Client() #create a client with an ID
  client.on_connect = on_connect
  client.on_message = on_message

  client.connect(broker)
  client.loop_start() #when do we stop this loop?



def PCA9685_init():
  addr = 0x40
  j = driverNum
  while j > 0:
    i2c.open(addr)
    i2c.write([0x00, 0x80]) #reset
    i2c.write([0x00, 0x10]) #sleep
    i2c.write([0xFE, 0x1E]) #PRE_SCALE to 200Hz
    i2c.write([0x00, 0x00]) #wake up
    i2c.close()

    addr += 1
    j -= 1

init()

PCA9685_init()

while 1:
  print("Waiting...")
  time.sleep(10)
