import logging
from threading import Thread
import time
from twisted.internet import reactor
from pyupnp.event import EventProperty
from pyupnp.device import Device, DeviceIcon
from pyupnp.logr import Logr
from pyupnp.services import register_action, Service, ServiceActionArgument, ServiceStateVariable
from pyupnp.ssdp import SSDP
from pyupnp.upnp import UPnP
from grovepi import *
import time,sys
import RPi.GPIO as GPIO
import smbus


# this device has two I2C addresses
DISPLAY_RGB_ADDR = 0x62
DISPLAY_TEXT_ADDR = 0x3e

# use the bus that matches your raspi version
rev = GPIO.RPI_REVISION
if rev == 2 or rev == 3:
    bus = smbus.SMBus(1)
else:
    bus = smbus.SMBus(0)

# set backlight to (R,G,B) (values from 0..255 for each)
def setRGB(r,g,b):
    bus.write_byte_data(DISPLAY_RGB_ADDR,0,0)
    bus.write_byte_data(DISPLAY_RGB_ADDR,1,0)
    bus.write_byte_data(DISPLAY_RGB_ADDR,0x08,0xaa)
    bus.write_byte_data(DISPLAY_RGB_ADDR,4,r)
    bus.write_byte_data(DISPLAY_RGB_ADDR,3,g)
    bus.write_byte_data(DISPLAY_RGB_ADDR,2,b)

# send command to display (no need for external use)    
def textCommand(cmd):
    bus.write_byte_data(DISPLAY_TEXT_ADDR,0x80,cmd)

# set display text \n for second line(or auto wrap)     
def setText(text):
    textCommand(0x01) # clear display
    time.sleep(.05)
    textCommand(0x08 | 0x04) # display on, no cursor
    textCommand(0x28) # 2 lines
    time.sleep(.05)
    count = 0
    row = 0
    for c in text:
        if c == '\n' or count == 16:
            count = 0
            row += 1
            if row == 2:
                break
            textCommand(0xc0)
            if c == '\n':
                continue
        count += 1
        bus.write_byte_data(DISPLAY_TEXT_ADDR,0x40,ord(c))
		
def hex_to_rgb(value):
	value = value.lstrip('#')
	lv = len(value)
	return tuple(int(value[i:i+lv/3], 16) for i in range(0, lv, lv/3))

class LCDService(Service):
	version = (1, 0)
	serviceType = "urn:schemas-upnp-org:service:LCDService:1"
	serviceId = "urn:upnp-org:serviceId:LCDService"
	line2text = ""
	line1text = "                "

	actions = {
		'SetBackgroundColor': [
			ServiceActionArgument('color','in','ARG_LCD_COLOR_State'),
			ServiceActionArgument('output', 'out', 'ARG_LCD_COLOR_State')
		],
		'SetText':[
			ServiceActionArgument('text','in','ARG_LCD_TEXT_State'),
			ServiceActionArgument('output', 'out', 'ARG_LCD_TEXT_State')
		]
		,
		'SetTextLine1':[
			ServiceActionArgument('text','in','ARG_LCD_TEXT_State'),
			ServiceActionArgument('output', 'out', 'ARG_LCD_TEXT_State')
		]
		,
		'SetTextLine2':[
			ServiceActionArgument('text','in','ARG_LCD_TEXT_State'),
			ServiceActionArgument('output', 'out', 'ARG_LCD_TEXT_State')
		]
	}
	
	stateVariables = [
		# Arguments
		ServiceStateVariable('ARG_LCD_COLOR_State','string'),
		ServiceStateVariable('ARG_LCD_TEXT_State','string'),
        
		# Variables
		ServiceStateVariable('LCD_State','string',sendEvents=True)
	]
	
	state=EventProperty('LCD_State')

	@register_action('SetBackgroundColor')
	def changeColor(self, param):
		print param
		if(param == "red"):
			setRGB(255,0,0)
		elif(param == "green"):
			setRGB(0,255,0)
		elif(param == "blue"):
			setRGB(0,0,255)
		else:
			setRGB(hex_to_rgb(param)[0],hex_to_rgb(param)[1],hex_to_rgb(param)[2])
		return 2
		
		
	@register_action('SetText')
	def changeText(self, param):
		print param
		self.textValue = param
		self.line1text = param[:16]
		self.line2text = "                "
		while len(self.line1text)<=15:
			self.line1text += " "
		setText(param)
		return 2
		
	@register_action('SetTextLine1')
	def changeTextLine1(self, param):
		print param
		self.line1text = param[:16]
		while len(self.line1text)<=15:
			self.line1text += " "
		setText(self.line1text+self.line2text)
		return 2
		
	@register_action('SetTextLine2')
	def changeTextLine2(self, param):
		print param
		self.line2text = param
		setText(self.line1text+self.line2text)
		return 2
