def __init__(self, device, controller, p2):
     self.device = device
     self.controller = controller
     self.oldcontrollerhash = 0
     self.p2 = p2
     self.exit = False
     threading.Thread.__init__(self)
     #logging.basicConfig( filename="serial.log", level=logging.DEBUG )
     if gSendStats == True:
         self.statsclient = StatsdClient(statsServer, statsPort)
     else:
         self.statsclient = None
 def __init__(self, circuitlist):
     self.circuitlist = circuitlist
     self.watertemp = 70  # deg F
     self.spasettemp = 96  # deg F
     self.poolsettemp = 45  # deg F
     self.airtemp = 70  # deg F
     self.hash = 0  # for caching
     self.oldhash = 1
     self.responsestart = 0
     self.responseflag = False
     self.pooltime = "00:00"
     self.walltime = "00:00"
     self.r = redis.StrictRedis(host='localhost', port=6379, db=0)
     self.password = ''
     if gSendStats == True:
         self.statsclient = StatsdClient(statsServer, statsPort)
     else:
         self.statsclient = None
	def __init__(self, device, controller, p2):
		self.device = device
		self.controller = controller
		self.oldcontrollerhash = 0
		self.p2 = p2
		self.exit = False
		threading.Thread.__init__(self)
		# logging.basicConfig( filename="serial.log", level=logging.DEBUG )
		if gSendStats == True:
                        self.statsclient = StatsdClient( statsServer, statsPort )
                else:
                        self.statsclient = None
예제 #4
0
	def __init__( self, circuitlist ):
		self.circuitlist = circuitlist
		self.watertemp = 70		# deg F
		self.spasettemp = 96		# deg F
		self.poolsettemp = 45		# deg F
		self.airtemp = 70		# deg F
		self.hash = 0			# for caching
		self.oldhash = 1
		self.responsestart = 0
		self.responseflag = False
		self.pooltime = "00:00"
		self.walltime = "00:00"
		self.r = redis.StrictRedis( host='localhost', port=6379, db=0)
		self.password = ''
		if gSendStats == True:
			self.statsclient = StatsdClient( statsServer, statsPort )
		else:
			self.statsclient = None
class serialThread(threading.Thread):
    def __init__(self, device, controller, p2):
        self.device = device
        self.controller = controller
        self.oldcontrollerhash = 0
        self.p2 = p2
        self.exit = False
        threading.Thread.__init__(self)
        #logging.basicConfig( filename="serial.log", level=logging.DEBUG )
        if gSendStats == True:
            self.statsclient = StatsdClient(statsServer, statsPort)
        else:
            self.statsclient = None

    def stop(self):
        self.exit = True

    def run(self):
        logging.info("Starting serial thread")
        self.ser = serial.Serial(self.device, baudrate=9600, timeout=1)
        scanlen = 50
        inputBuffer = []
        while self.exit == False:

            output = self.ser.read(scanlen)
            for i in output:
                inputBuffer.append(ord(i))  # append bytes
                d = ord(i)
                #print d,"\t",hex(d),"\t","{0:08b}".format(d)

            #data.append(ord(output))
            #ascdata += output

            if len(inputBuffer) > 50:  # start searching for packet header
                ## find start of packet
                #start=[255,255,255,255,0,255,165,39]
                start = [0xff, 0x00, 0xff, 0xa5]

                startByte = 0
                offsetlist = []
                for x in range(len(inputBuffer) - 5):
                    if inputBuffer[x] == start[0] and startByte == 0:
                        if inputBuffer[x + 1] == start[1]:
                            if inputBuffer[x + 2] == start[2]:
                                #if inputBuffer[x+3] == start[3]:

                                offsetlist.append(x)

                                #sys.stdout.write(" : ")
                                #sys.stdout.flush()
                                #for y in range(x,x+20):
                                #	sys.stdout.write( hex(data[y]) + " " )
                                #print

                                #if data[x+4]==start[4]:
                                #	if data[x+5]==start[5]:
                                #		if data[x+6]==start[6]:
                                #			if data[x+7]==start[7]:
                                #				startBit=x+6
                                # now print all the matching lines

                # we now have all the sync markers, but the last one could
                # possibly be the start of the next message that is
                # coming in, so we will not process that message yet
                for s in range(len(offsetlist) - 1):
                    begin = offsetlist[s]
                    end = offsetlist[s + 1]
                    # process message packet here -- starts at begin
                    # to end inclusive
                    message = inputBuffer[begin:end]
                    self.processMessage(message)
                # shift this off the front of inputBuffer
                inputBuffer = inputBuffer[offsetlist[-1]:]

                # check for any action from http thread
                while not cmdQueue.empty():
                    cmdLock.acquire()
                    if not cmdQueue.empty():
                        cmd = cmdQueue.get()
                    cmdLock.release()
                    # process command
                    self.processCommand(cmd)

    def processCommand(self, cmd):
        # command is of the form:  SET CIRCUIT 1 0
        logging.debug("Serial command is %s " % cmd)
        action = 'DUMMY'
        object = 'NONE'
        num = '0'
        val = '0'

        try:
            action, object, num, val, elapsedtime = cmd.split()
        except ValueError:
            try:
                action, object, num, elapsedtime = cmd.split()
            except ValueError:
                logging.debug("bad split from command")

        if action == "SET":  # continue
            if object == "CIRCUIT":  # do circuit functions
                if int(num) > 0 and int(num) < 19:  # valid circuit numbers
                    # check value
                    nval = int(val)
                    # nval can be 0 or 1
                    if nval > 1:
                        nval = 1
                    # look up mapping from circuit number to command circuit
                    cmdchannel = remotebuttonmap[int(num)]

                    # now form packet
                    # wireless address is learned from status message
                    header = [
                        0xFF, 0x00, 0xFF, 0xA5, self.wirelessaddr, 0x10, 0x20
                    ]
                    command = [0x86]
                    length = [0x02]
                    args = [cmdchannel, nval]

                    output = header + command + length + args

                    self.sendPacket(output)
                    self.controller.setResponseStart(float(elapsedtime))
                    self.controller.setResponseFlag(True)

            if object == "POOLTEMP" or object == "SPATEMP":
                if int(num) >= 35 and int(num) <= 104:
                    if object == "POOLTEMP":
                        poolt = int(num)
                        spat = int(self.controller.getspasettemp())
                    else:
                        poolt = int(self.controller.getpoolsettemp())
                        spat = int(num)

                    # now form packet
                    header = [0xFF, 0x00, 0xFF, 0xA5, 0x31, 0x10, 0x20]
                    command = [0x88, 0x04, poolt, spat, 0x05, 0x00]
                    output = header + command
                    self.sendPacket(output)
                    self.controller.setResponseStart(float(elapsedtime))
                    self.controller.setResponseFlag(True)
        return True

    def sendPacket(self, output):
        # compute checksum
        chksum = 0
        for i in range(3, len(output)):
            chksum += output[i]
        chkhi = int(chksum / 256)
        chklo = int(chksum % 256)

        output += [chkhi, chklo, 0xff, 0xff]

        logging.debug("-----------------output packet-------------")
        p = ''
        for i in output:
            p += "%02x " % i
        logging.debug(p)
        # now make string and write it out
        packet = array.array('B', output).tostring()
        logging.debug("length of packet is %d" % len(packet))

        self.ser.write(packet)
        time.sleep(0.3)
        self.ser.write(packet)
        time.sleep(0.3)

    def processMessage(self, message):

        if len(message) < 11:
            logging.debug("ERR: Message short:")
            h = ''
            for y in message:
                h += "%02x " % y
            logging.debug(h)
            if gSendStats == True:
                self.statsclient.count("pool.shortmsg", 1)
            return

        wirelessaddr = message[4]
        dest = message[5]
        src = message[6]
        cmd = message[7]
        length = message[8]
        chkhi = 0
        chklo = 0

        chksum = 0
        if len(message) >= length + 9 + 2:  # good
            #compute checksum
            for x in range(3,
                           8 + length + 1):  # 8 bytes + len + 1 for range func

                chksum += message[x]
            chkhi = message[length + 9]
            chklo = message[length + 10]
        else:
            logging.debug("ERR: message not match length size")
            if gSendStats == True:
                self.statsclient.count("pool.lengthnotmatchmsg", 1)
            return

        # print out messages we are interested in
        if (dest == 0x0f or dest == 0x20) or src == 0x20:
            self.wirelessaddr = wirelessaddr
            logging.debug("wireless addr is %02x" % wirelessaddr)
            f = ''
            for y in range(length + 9 + 2):
                f += "%02x " % message[y]
            logging.debug(f)
            logging.debug(
                " dest %02x, src %02x, cmd %02x, len %02x, chksum %02x %02x" %
                (dest, src, cmd, length, chksum / 0x100, chksum % 0x100))

        if dest == 0x0f and src == 0x10 and cmd == 0x02 and length == 0x1d and chksum == chkhi * 256 + chklo:  # status
            if gSendStats == True:
                self.statsclient.count("pool.statusmsg", 1)
            self.decodeStatus(message)
        elif dest == 0x0f and src == 0x10 and cmd == 0x08 and length == 0x0d and chksum == chkhi * 256 + chklo:  # status
            if gSendStats == True:
                self.statsclient.count("pool.temperaturemsg", 1)
            self.decodeTemperatureStatus(message)
        else:
            if gSendStats == True:
                self.statsclient.count("pool.othermsg", 1)

    def decodeTemperatureStatus(self, data):
        waterTemp = 10
        airTemp = 11
        poolsetTemp = 12
        spasetTemp = 13

        # update controller values
        #print "--pool Set temp is ", data[poolsetTemp]
        #print "--spa Set temp is ", data[spasetTemp]
        self.controller.setpoolsettemp(data[poolsetTemp])
        self.controller.setspasettemp(data[spasetTemp])
        self.controller.save()  # to database

    def decodeStatus(self, data):
        waterTemp = 23
        heaterTemp = 24
        airTemp = 27
        solarTemp = 28
        heatMode = 31
        clockHours = 9
        clockMinutes = 10

        t = time.localtime()
        localtime = time.strftime("%H:%M", t)
        pooltime = "%02d:%02d" % (data[clockHours], data[clockMinutes])
        logging.debug("  Wallclock %s, Pool Time %s" % (localtime, pooltime))
        self.controller.setwallclocktime(localtime)
        self.controller.setpoolclocktime(pooltime)

        heatModeStr = {
            0: "off",
            1: "heater",
            2: "solarpref",
            3: "solar",
        }[data[heatMode]]

        #print "  Air %s, Water %s" % (data[airTemp], data[waterTemp])
        #print "  Heater Temperature: ",data[heaterTemp]
        #print "  Solar Temperature: ",data[solarTemp]
        #print "  Heat Mode: ",heatModeStr

        equip = ["{0:08b}".format(data[11]), "{0:08b}".format(data[12])]
        for i in range(len(equip)):
            logging.debug("  Equipment%d : %s" % (i, equip[i]))

        # update controller values
        self.controller.setwatertemp(data[waterTemp])
        self.controller.setairtemp(data[airTemp])
        self.controller.setsolartemp(data[solarTemp])
        for byte in range(2):
            for bit in range(8):
                abit = 7 - bit
                self.controller.setcircuit(byte + 1, bit,
                                           equip[byte][abit:abit + 1])
        self.controller.save()  # to database
class controller(object):
    def __init__(self, circuitlist):
        self.circuitlist = circuitlist
        self.watertemp = 70  # deg F
        self.spasettemp = 96  # deg F
        self.poolsettemp = 45  # deg F
        self.airtemp = 70  # deg F
        self.hash = 0  # for caching
        self.oldhash = 1
        self.responsestart = 0
        self.responseflag = False
        self.pooltime = "00:00"
        self.walltime = "00:00"
        self.r = redis.StrictRedis(host='localhost', port=6379, db=0)
        self.password = ''
        if gSendStats == True:
            self.statsclient = StatsdClient(statsServer, statsPort)
        else:
            self.statsclient = None

    def getwallclocktime(self):
        return self.walltime

    def getpoolclocktime(self):
        return self.pooltime

    def setwallclocktime(self, t):
        self.walltime = t

    def setpoolclocktime(self, t):
        self.pooltime = t

    def setResponseStart(self, t):
        self.responsestart = t

    def setResponseFlag(self, f):
        self.responseflag = f

    def setpassword(self, pw):
        self.password = pw

    def getpassword(self):
        return self.password

    def setwatertemp(self, temp):
        if self.watertemp != temp:
            if gSendStats == True:
                self.statsclient.gauge("pool.watertemp", temp)
            self.watertemp = temp
            self.updatehash()

    def setspasettemp(self, temp):
        if self.spasettemp != temp:
            self.spasettemp = temp
            self.updatehash()

    def setpoolsettemp(self, temp):
        if self.poolsettemp != temp:
            self.poolsettemp = temp
            self.updatehash()

    def setairtemp(self, temp):
        if self.airtemp != temp:
            if gSendStats == True:
                self.statsclient.gauge("pool.airtemp", temp)
            self.airtemp = temp
            self.updatehash()

    def getwatertemp(self):
        return self.watertemp

    def getspasettemp(self):
        return self.spasettemp

    def getpoolsettemp(self):
        return self.poolsettemp

    def getairtemp(self):
        return self.airtemp

    def updatehash(self):
        h = 0
        for a in self.circuitlist:
            h += a.getHash()
        h += int(self.watertemp) * 1000
        h += int(self.spasettemp) * 100
        h += int(self.poolsettemp) * 50
        h += int(self.airtemp) * 10
        self.hash = h
        return h

    def gethash(self):
        return self.hash

    def appendcircuit(self, c):
        self.circuitlist.append(c)

    def setcircuit(self, equipbyte, equipbit, val):
        # find circuit and set to val
        retval = False
        for c in self.circuitlist:
            if c.match(equipbyte, equipbit):
                #if val == 1:
                #	print "setting %s to %s" % (c.getname, val)
                c.setState(val)
                self.updatehash()
                retval = True
                break
        return retval

    def getcircuitlist(self):
        return self.circuitlist

    def getcircuitnumstate(self, circuitnum):
        for c in self.circuitlist:
            if c.getNumber() == circuitnum:
                return c.getState()
        return -1  # not found

    # save to redis as a hash with values
    def save(self):
        if self.responseflag == True:
            t = (time.time() - self.responsestart) * 1000  # for ms
            self.responseflag = False
            if gSendStats == True:
                self.statsclient.timing("pool.cmdresponse", t)
        # only save if we have to
        if self.oldhash == self.hash:
            return False
        else:
            d = {}
            for c in self.circuitlist:
                d[c.getNumber()] = json.dumps(c.todict())
            d["airtemp"] = self.airtemp
            d["watertemp"] = self.watertemp
            d["spasettemp"] = self.spasettemp
            d["poolsettemp"] = self.poolsettemp
            d["hash"] = self.hash
            d["pooltime"] = self.pooltime
            d["walltime"] = self.walltime
            # pool is the redis hash key, so you can do a
            # redis-cli hgetall pool
            # to see all the data stored in redis
            self.r.hmset("pool", d)
            self.oldhash = self.hash
            # we are never going to save the password, only
            # the set_password.py script will do this

    def load(self):
        # get dictionary from redis
        d = self.r.hgetall("pool")
        # and sort it all out
        self.circuitlist = []  # empty
        for k in d.keys():
            if k == "hash":
                self.hash = d[k]
            elif k == "pooltime":
                self.pooltime = d[k]
            elif k == "walltime":
                self.walltime = d[k]
            elif k == "airtemp":
                self.airtemp = d[k]
            elif k == "watertemp":
                self.watertemp = d[k]
            elif k == "spasettemp":
                self.spasettemp = d[k]
            elif k == "poolsettemp":
                self.poolsettemp = d[k]
            elif k == "0" or k == "1" or k == "2" or k == "3" or \
             k == "4" or k == "5" or k == "6" or k == "7" or \
             k == "8" or k == "9" or k == "10" or k == "11" or \
             k == "12" or k == "13" or k == "14" or k == "15" or \
             k == "16" or k == "17" or k == "18": # circuit
                # decode json sting
                cdict = json.loads(d[k])
                self.circuitlist.append(
                    circuit.circuit(k, cdict["name"], cdict["byte"],
                                    cdict["bit"], cdict["value"]))
            elif k == "password":
                self.password = d[k]
            else:
                #print "bad key %s found in load" % k
                a = 1
        self.oldhash = self.hash
예제 #7
0
class controller(object):
	def __init__( self, circuitlist ):
		self.circuitlist = circuitlist
		self.watertemp = 70		# deg F
		self.spasettemp = 96		# deg F
		self.poolsettemp = 45		# deg F
		self.airtemp = 70		# deg F
		self.hash = 0			# for caching
		self.oldhash = 1
		self.responsestart = 0
		self.responseflag = False
		self.pooltime = "00:00"
		self.walltime = "00:00"
		self.r = redis.StrictRedis( host='localhost', port=6379, db=0)
		self.password = ''
		if gSendStats == True:
			self.statsclient = StatsdClient( statsServer, statsPort )
		else:
			self.statsclient = None

	def getwallclocktime( self ):
		return self.walltime

	def getpoolclocktime( self ):
		return self.pooltime

	def setwallclocktime( self, t ):
		self.walltime = t

	def setpoolclocktime( self, t ):
		self.pooltime = t

	def setResponseStart( self, t ):
		self.responsestart = t

	def setResponseFlag( self, f):
		self.responseflag = f

	def setpassword( self, pw):
		self.password = pw

	def getpassword( self ):
		return self.password

	def setwatertemp( self, temp ):
		if self.watertemp != temp:
			if gSendStats == True:
				self.statsclient.gauge( "pool.watertemp", temp )
			self.watertemp = temp
			self.updatehash()

	def setspasettemp( self, temp ):
		if self.spasettemp != temp:
			self.spasettemp = temp
			self.updatehash()

	def setpoolsettemp( self, temp ):
		if self.poolsettemp != temp:
			self.poolsettemp = temp
			self.updatehash()

	def setairtemp( self, temp ):
		if self.airtemp != temp:
			if gSendStats == True:
				self.statsclient.gauge( "pool.airtemp", temp )
			self.airtemp = temp
			self.updatehash()

	def getwatertemp( self ):
		return self.watertemp

	def getspasettemp( self ):
		return self.spasettemp

	def getpoolsettemp( self ):
		return self.poolsettemp

	def getairtemp( self ):
		return self.airtemp

	def updatehash(self):
		h = 0
		for a in self.circuitlist:
			h += a.getHash()
		h += int(self.watertemp) * 1000
		h += int(self.spasettemp) * 100
		h += int(self.poolsettemp) * 50
		h += int(self.airtemp) * 10
		self.hash = h
		return h

	def gethash( self ):
		return self.hash
	
	def appendcircuit( self, c ):
		self.circuitlist.append( c )

	def setcircuit( self, equipbyte, equipbit, val ):
		# find circuit and set to val
		retval = False
		for c in self.circuitlist:
			if c.match( equipbyte, equipbit ):
				#if val == 1:
				#	print "setting %s to %s" % (c.getname, val)
				c.setState( val )
				self.updatehash()
				retval = True
				break
		return retval

	def getcircuitlist( self ):
		return self.circuitlist

	def getcircuitnumstate( self, circuitnum ):
		for c in self.circuitlist:
			if c.getNumber() == circuitnum:
				return c.getState()
		return -1	# not found

	# save to redis as a hash with values
	def save( self ):
		if self.responseflag == True:
			t = (time.time() - self.responsestart) * 1000   # for ms
			self.responseflag = False
			if gSendStats == True:
				self.statsclient.timing( "pool.cmdresponse", t )
		# only save if we have to
		if self.oldhash == self.hash:
			return False
		else:
			d = {}
			for c in self.circuitlist:
				d[c.getNumber()] = json.dumps(c.todict())
			d["airtemp"] = self.airtemp
			d["watertemp"] = self.watertemp
			d["spasettemp"] = self.spasettemp
			d["poolsettemp"] = self.poolsettemp
			d["hash"] = self.hash
			d["pooltime"] = self.pooltime
			d["walltime"] = self.walltime
			# pool is the redis hash key, so you can do a 
			# redis-cli hgetall pool
			# to see all the data stored in redis
			self.r.hmset( "pool", d )
			self.oldhash = self.hash
			# we are never going to save the password, only
			# the set_password.py script will do this

	def load( self ):
		# get dictionary from redis
		d = self.r.hgetall( "pool" )
		# and sort it all out
		self.circuitlist = []		# empty
		for k in d.keys():
			if k == "hash":
				self.hash = d[k]
			elif k == "pooltime":
				self.pooltime = d[k]
			elif k == "walltime":
				self.walltime = d[k]
			elif k == "airtemp":
				self.airtemp = d[k]
			elif k == "watertemp":
				self.watertemp = d[k]
			elif k == "spasettemp":
				self.spasettemp = d[k]
			elif k == "poolsettemp":
				self.poolsettemp = d[k]
			elif k == "0" or k == "1" or k == "2" or k == "3" or \
				k == "4" or k == "5" or k == "6" or k == "7" or \
				k == "8" or k == "9" or k == "10" or k == "11" or \
				k == "12" or k == "13" or k == "14" or k == "15" or \
				k == "16" or k == "17" or k == "18":	# circuit
				# decode json sting
				cdict = json.loads(d[k])				
				self.circuitlist.append( circuit.circuit(k,
								cdict["name"],
								cdict["byte"],
								cdict["bit"],
								cdict["value"] ))
			elif k =="password":
				self.password = d[k]
			else:
				#print "bad key %s found in load" % k
				a = 1				
		self.oldhash = self.hash
class serialThread (threading.Thread):
	def __init__(self, device, controller, p2):
		self.device = device
		self.controller = controller
		self.oldcontrollerhash = 0
		self.p2 = p2
		self.exit = False
		threading.Thread.__init__(self)
		# logging.basicConfig( filename="serial.log", level=logging.DEBUG )
		if gSendStats == True:
                        self.statsclient = StatsdClient( statsServer, statsPort )
                else:
                        self.statsclient = None

	def stop(self):
		self.exit = True

	def run(self):
		logging.info( "Starting serial thread" )
		self.ser = serial.Serial(self.device, baudrate=9600, timeout=1)
		scanlen = 50
		inputBuffer = []
		while self.exit == False:
			
			output = self.ser.read(scanlen)
			for i in output:
				inputBuffer.append( ord(i) )		# append bytes

			#data.append(ord(output))
			#ascdata += output
			#print x,"\t",d,"\t",hex(d),"\t","{0:08b}".format(d)

			if len(inputBuffer) > 50:	# start searching for packet header
  				## find start of packet
				#start=[255,255,255,255,0,255,165,39]
				start=[ 0xff, 0x00, 0xff, 0xa5]

				startByte=0;
				offsetlist = []
				for x in range(len(inputBuffer)-5):
					if inputBuffer[x] == start[0] and startByte == 0:
						if inputBuffer[x+1] == start[1]:
							if inputBuffer[x+2] == start[2]:
								#if inputBuffer[x+3] == start[3]:

								offsetlist.append(x)

								#sys.stdout.write(" : ")
								#sys.stdout.flush()
								#for y in range(x,x+20):
								#	sys.stdout.write( hex(data[y]) + " " )
								#print

								#if data[x+4]==start[4]:
								#	if data[x+5]==start[5]:
								#		if data[x+6]==start[6]:
								#			if data[x+7]==start[7]:
								#				startBit=x+6
								# now print all the matching lines

				# we now have all the sync markers, but the last one could
				# possibly be the start of the next message that is
				# coming in, so we will not process that message yet
				for s in range( len( offsetlist ) - 1 ):
					begin = offsetlist[s]
					end = offsetlist[ s + 1 ]
					# process message packet here -- starts at begin
					# to end inclusive
					message = inputBuffer[begin:end]
					self.processMessage( message )
				# shift this off the front of inputBuffer
				inputBuffer = inputBuffer[offsetlist[-1]:]

				# check for any action from http thread
				while not cmdQueue.empty():
					cmdLock.acquire()
					if not cmdQueue.empty():
						cmd = cmdQueue.get()
					cmdLock.release()
					# process command
					self.processCommand( cmd )

	def processCommand( self, cmd ):
		# command is of the form:  SET CIRCUIT 1 0
		logging.debug("Serial command is %s " % cmd)
		action = 'DUMMY'
		object = 'NONE'
		num = '0'
		val = '0'
		
		try:
			action, object, num, val, elapsedtime = cmd.split()
		except ValueError:
			try:
				action, object, num, elapsedtime = cmd.split()
			except ValueError:
				logging.debug("bad split from command")

		if action == "SET":		# continue
			if object == "CIRCUIT":		# do circuit functions
				if int(num) > 0 and int(num) < 19:	# valid circuit numbers
					# check value
					nval = int(val)
					# nval can be 0 or 1
					if nval > 1:
						nval = 1
					# look up mapping from circuit number to command circuit
					cmdchannel = remotebuttonmap[int(num)]
					
					# now form packet
					# wireless address is learned from status message
					header = [ 0xFF, 0x00, 0xFF, 0xA5, self.wirelessaddr, 0x10, 0x20 ]
					command = [ 0x86 ]
					length = [ 0x02 ]
					args = [ cmdchannel, nval ]

					output = header + command + length + args

					self.sendPacket( output )
					self.controller.setResponseStart(float(elapsedtime))
					self.controller.setResponseFlag(True)

			if object == "POOLTEMP" or object == "SPATEMP":
				if int(num) >= 35 and int(num) <= 104:
					if object == "POOLTEMP":
						poolt = int(num)
						spat = int(self.controller.getspasettemp())
					else:
						poolt = int(self.controller.getpoolsettemp())
						spat = int(num)
						
					# now form packet
					header = [ 0xFF, 0x00, 0xFF, 0xA5, 0x31, 0x10, 0x20 ]
					command = [ 0x88, 0x04, poolt, spat, 0x05, 0x00 ]
					output = header + command
					self.sendPacket( output )
					self.controller.setResponseStart(float(elapsedtime))
					self.controller.setResponseFlag(True)
		return True

	def sendPacket( self, output ):
		# compute checksum
		chksum = 0
		for i in range(3,len(output)):
			chksum += output[i]
		chkhi = int(chksum / 256)
		chklo = int(chksum % 256)

		output += [chkhi, chklo, 0xff, 0xff]
				
		logging.debug("-----------------output packet-------------")
		p = ''
		for i in output:
			p +=  "%02x " % i 
		logging.debug( p )
		# now make string and write it out
		packet = array.array('B', output).tostring()
		logging.debug("length of packet is %d" % len(packet))
					
		self.ser.write(packet)
		time.sleep(0.3)
		self.ser.write(packet)
		time.sleep(0.3)


	def processMessage( self, message ):

		if len(message) < 11:
			logging.debug( "ERR: Message short:" )
			h = ''
			for y in message:
				h +=  "%02x " % y 
			logging.debug( h )
			if gSendStats == True:
                                self.statsclient.count( "pool.shortmsg", 1 )
			return
				
		wirelessaddr = message[4]
		dest = message[5]
		src = message[6]
		cmd = message[7]
		length = message[8]
		chkhi = 0
		chklo = 0	
	
		chksum = 0;
		if len(message) >= length + 9 + 2:	# good
			#compute checksum
			for x in range( 3, 8 + length + 1):	# 8 bytes + len + 1 for range func
				
				chksum += message[x];
			chkhi = message[length+9]
			chklo = message[length+10]
		else:
			logging.debug( "ERR: message not match length size" )
			if gSendStats == True:
                                self.statsclient.count( "pool.lengthnotmatchmsg", 1 )
			return

		# print out messages we are interested in
		if (dest == 0x0f or dest == 0x20) or src == 0x20:
			self.wirelessaddr = wirelessaddr
			logging.debug( "wireless addr is %02x" % wirelessaddr );
			f = ''
			for y in range(length+9+2):
				f +=  "%02x " % message[y] 
			logging.debug( f )	
			logging.debug( " dest %02x, src %02x, cmd %02x, len %02x, chksum %02x %02x" % (dest, src, cmd, length, chksum / 0x100, chksum % 0x100) )


		if dest == 0x0f and src == 0x10 and cmd == 0x02 and length == 0x1d and chksum == chkhi*256+chklo:	# status
			if gSendStats == True:
                                self.statsclient.count( "pool.statusmsg", 1 )
			self.decodeStatus( message )
		elif dest == 0x0f and src == 0x10 and cmd == 0x08 and length == 0x0d and chksum == chkhi*256+chklo:	# status
			if gSendStats == True:
                                self.statsclient.count( "pool.temperaturemsg", 1 )
			self.decodeTemperatureStatus( message )
		else:
			if gSendStats == True:
                                self.statsclient.count( "pool.othermsg", 1 )
			
	
	def decodeTemperatureStatus( self, data ):
			waterTemp=10
			airTemp=11
			poolsetTemp=12
			spasetTemp=13

			# update controller values
			#print "--pool Set temp is ", data[poolsetTemp]
			#print "--spa Set temp is ", data[spasetTemp]
			self.controller.setpoolsettemp( data[poolsetTemp] )
			self.controller.setspasettemp( data[spasetTemp] )
			self.controller.save()		# to database

	def decodeStatus( self, data ):
			waterTemp=23
			heaterTemp=24
			airTemp=27
			clockHours=9
			clockMinutes=10

			t=time.localtime()
			localtime = time.strftime("%H:%M",t)
			pooltime = "%02d:%02d" % (data[clockHours], data[clockMinutes])
			logging.debug( "  Wallclock %s, Pool Time %s" % (localtime, pooltime))
			self.controller.setwallclocktime( localtime )
			self.controller.setpoolclocktime( pooltime )
	
			#print "  Air %s, Water %s" % (data[airTemp], data[waterTemp])
			#print "  Heater Temperature: ",data[heaterTemp]

			equip = [ "{0:08b}".format(data[11]), "{0:08b}".format(data[12]) ]
			for i in range(len(equip)):
				logging.debug( "  Equipment%d : %s" % (i,equip[i]))

			# update controller values
			self.controller.setwatertemp( data[waterTemp] )
			self.controller.setairtemp( data[airTemp] )
			for byte in range(2):
				for bit in range(8):
					abit = 7 - bit
					self.controller.setcircuit(byte+1, bit, equip[byte][abit:abit+1] )
			self.controller.save()		# to database