From 6ab105694afddd5c559cc143f99e1df0f2f35a12 Mon Sep 17 00:00:00 2001 From: rtrimana Date: Fri, 23 Jun 2017 14:37:54 -0700 Subject: [PATCH] Completing xbee_driver.py with door lock subroutines --- .../other/XbeePythonDriver/xbee_driver.py | 327 +++++++++++++++++- 1 file changed, 319 insertions(+), 8 deletions(-) diff --git a/benchmarks/other/XbeePythonDriver/xbee_driver.py b/benchmarks/other/XbeePythonDriver/xbee_driver.py index 99e93ae..955ed9c 100644 --- a/benchmarks/other/XbeePythonDriver/xbee_driver.py +++ b/benchmarks/other/XbeePythonDriver/xbee_driver.py @@ -16,7 +16,10 @@ import threading # ----------------------------------------------------------------------------- UDP_RECEIVE_PORT = 5005 # port used for incoming UDP data UDP_RECEIVE_BUFFER_SIZE = 4096 # max buffer size of an incoming UDP packet -SYSTEM_MASTER_ADDRESS = ("192.168.2.108", 12345) # ip address and portof the system master node +SYSTEM_MASTER_ADDRESS = ("192.168.1.198", 12345) # ip address and portof the system master node +#SYSTEM_MASTER_ADDRESS = ("192.168.2.108", 22222) # ip address and portof the system master node +#SYSTEM_MASTER_ADDRESS2 = ("192.168.2.108", 11111) +#SYSTEM_MASTER_ADDRESS3 = ("192.168.2.108", 11222) # time for messages to wait for a response before the system clears away that # sequence identifier @@ -79,6 +82,7 @@ doEndFlag = False sendSoceket = socket(AF_INET, SOCK_DGRAM) receiveSoceket = socket(AF_INET, SOCK_DGRAM) + # zigbee address authority list zigbeeAddressAuthorityDict = dict() @@ -369,7 +373,8 @@ def getConnectedRadioLongAddress(): zigbeeConnection.send('at', command="SL") # sleep for a bit to give the radio time to respond before we check again - time.sleep(2) + #time.sleep(2) + time.sleep(0.5) def addressUpdateWorkerMethod(): ''' Method to keep refreshing the short addresses of the known zigbee devices''' @@ -421,7 +426,8 @@ def addressUpdateWorkerMethod(): ) zigbeeConnectionMutex.release() - time.sleep(8) + #time.sleep(8) + time.sleep(1) # ------------- @@ -578,6 +584,8 @@ def processUdpSendAddressMessage(parsedData, addr): zigbeeUnregisteredAddresses.append(parsedData['device_address_long']) zigbeeUnregisteredAddressesMutex.release() + + #made by changwoo def processUdpEnrollmentResponse(parsedData, addr): @@ -791,6 +799,141 @@ def processUdpZclChangeSwitchReqMessage(parsedData, addr): pass +#made by Jiawei +def processUdpZclLockOrUnlockDoorReqMessage(parsedData, addr): + + global zigbeeLongShortAddr + global zigbeeLongShortAddrMutex + global zigeeBindRequestMutex + global zigeeBindRequest + global zigbeeConnectionMutex + global zigbeeConnection + shortAddr = None + + # get the short address for this device long address if possible + zigbeeLongShortAddrMutex.acquire() + if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])): + shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']] + zigbeeLongShortAddrMutex.release() + + + # if there is a short address than we can send the message + # if there is not one then we cannot since we need both the short and + # the long address + if(shortAddr != None): + + # get a request number + seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id']) + + # send back failure + if(seqNumber == -1): + + # send an error message, could not get a sequence number to use at this time + sendUdpSuccessFail(addr, 'lock_or_unlock_door_request', parsedData['packet_id'], False, 'out_of_space') + return + + # get the info for sending + destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long']) + destShortAddr = hexStringToZigbeeHexString(shortAddr) + dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint']) + clusterId = hexStringToZigbeeHexString(parsedData['cluster_id']) + profileId = hexStringToZigbeeHexString(parsedData['profile_id']) + value = hexStringToZigbeeHexString(parsedData['value']) + + # create and send binding command + zigbeeConnectionMutex.acquire() + + zigbeeConnection.send('tx_explicit', + frame_id='\x40', + dest_addr_long=destLongAddr, + dest_addr=destShortAddr, + src_endpoint='\x01', + dest_endpoint=dstEndpoint, + cluster=clusterId, + profile=profileId, + data='\x01'+chr(seqNumber)+value + ) + time.sleep(1) + if value == '\x01': + print '> The door lock is unlocked' + elif value == '\x00': + print '> The door lock is locked' + else: + print '> Unknown door lock value: ' + str(value) + + zigbeeConnectionMutex.release() + + + else: + # send a fail response + sendUdpSuccessFail(addr, 'lock_or_unlock_door_request', parsedData['packet_id'], False, 'short_address_unknown') + + +#made by Jiawei +def processUdpZclReadDoorStatusReqMessage(parsedData, addr): + + global zigbeeLongShortAddr + global zigbeeLongShortAddrMutex + global zigeeBindRequestMutex + global zigeeBindRequest + global zigbeeConnectionMutex + global zigbeeConnection + shortAddr = None + + # get the short address for this device long address if possible + zigbeeLongShortAddrMutex.acquire() + if(zigbeeLongShortAddr.has_key(parsedData['device_address_long'])): + shortAddr = zigbeeLongShortAddr[parsedData['device_address_long']] + zigbeeLongShortAddrMutex.release() + + + # if there is a short address than we can send the message + # if there is not one then we cannot since we need both the short and + # the long address + if(shortAddr != None): + + # get a request number + seqNumber = createSequenceNumberForClient(addr, parsedData['packet_id']) + + # send back failure + if(seqNumber == -1): + + # send an error message, could not get a sequence number to use at this time + sendUdpSuccessFail(addr, 'read_door_status_request', parsedData['packet_id'], False, 'out_of_space') + return + + # get the info for sending + destLongAddr = hexStringToZigbeeHexString(parsedData['device_address_long']) + destShortAddr = hexStringToZigbeeHexString(shortAddr) + dstEndpoint = hexStringToZigbeeHexString(parsedData['device_endpoint']) + clusterId = hexStringToZigbeeHexString(parsedData['cluster_id']) + profileId = hexStringToZigbeeHexString(parsedData['profile_id']) + # framecontrol = hexStringToZigbeeHexString(parsedData['framecontrol']) + # commandframe = hexStringToZigbeeHexString(parsedData['commandframe']) + # attribute_id = hexStringToZigbeeHexString(parsedData['attribute_id']) + + # create and send binding command + zigbeeConnectionMutex.acquire() + + zigbeeConnection.send('tx_explicit', + frame_id='\x40', + dest_addr_long=destLongAddr, + dest_addr=destShortAddr, + src_endpoint='\x01', + dest_endpoint=dstEndpoint, + cluster=clusterId, + profile=profileId, + data='\x10' + chr(seqNumber) + '\x00' + '\x00\x00' + ) + time.sleep(1) + + zigbeeConnectionMutex.release() + print "send read door status" + + else: + # send a fail response + sendUdpSuccessFail(addr, 'read_door_status_request', parsedData['packet_id'], False, 'short_address_unknown') + # made by changwoo def processUdpBroadcastingRouteRecordReqMessage(parsedData, addr): @@ -1102,7 +1245,6 @@ def processUdpZclConfigureReportingMessage(parsedData, addr): sendUdpSuccessFail(addr, 'zcl_configure_reporting', parsedData['packet_id'], False, 'short_address_unknown') pass - def processUdpPolicySet(parsedData, addr): ''' Method handle a policy set message @@ -1116,8 +1258,7 @@ def processUdpPolicySet(parsedData, addr): # do nothing if wrong source #if addr == SYSTEM_MASTER_ADDRESS or addr == SYSTEM_MASTER_ADDRESS2 or addr == SYSTEM_MASTER_ADDRESS3 : - #if addr == SYSTEM_MASTER_ADDRESS : - if addr[0] == SYSTEM_MASTER_ADDRESS[0]: + if addr == SYSTEM_MASTER_ADDRESS : key = (parsedData['ip_address'], int(parsedData['port'])) if (zigbeeAddressAuthorityDict.has_key(key)): zigbeeAddressAuthorityDict[key].append(parsedData['device_address_long']) @@ -1211,6 +1352,170 @@ def processZigbeeRxExplicitCommandMessage(parsedData): global deviceAnnouncementSingleton global seqNumberForNotification + #made by Jiawei + #doorlock response + if (parsedData['cluster'] == '\x01\x01' and parsedData['profile'] == '\x01\x04'): + zclSeqNumber = parsedData['rf_data'][1] + tup = None + zigbeeSeqNumberToClientMutex.acquire() + if(zigbeeSeqNumberToClient.has_key(ord(zclSeqNumber))): + tup = zigbeeSeqNumberToClient[ord(zclSeqNumber)] + del zigbeeSeqNumberToClient[ord(zclSeqNumber)] + zigbeeSeqNumberToClientMutex.release() + + rfdata = parsedData['rf_data'] + framecontrol = rfdata[0] + command = rfdata[2] + + if tup != None: + packetId = tup[2] + + if framecontrol == '\x19': + if(command == '\x00'): + print '' + print "( 0x0101 ) Door Lock: Lock Door Response" + print time.strftime("%H:%M:%S", time.localtime()) + value = rfdata[3] + if(value == '\x00'): + print "Door locked successfully" + else: + print "An error occurred in door locking" + elif(command == '\x01'): + print '' + print "( 0x0101 ) Door Lock: Unlock Door Response" + print time.strftime("%H:%M:%S", time.localtime()) + value = rfdata[3] + if(value == '\x00'): + print "Door unlocked successfully" + else: + print "An error occurred in door unlocking" + return + elif framecontrol == '\x18': + if(command == '\x01'): + attributeId = (ord(rfdata[3]) * 256) + ord(rfdata[4]) + if attributeId == 0x0000: + value = rfdata[7] + print "Door status: " + if value == '\x00': + print "Not fully locked" + elif value == '\x01': + print "Locked" + elif value == '\x02': + print "Unlocked" + else: + print "Unknown value: " + zigbeeHexStringToHexString(value) + + message = "type : zcl_read_attributes_response \n" + message += "packet_id: " + packetId + "\n" + message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n" + message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n" + message += "attributes: " + + attrIdStr = "%0.4x" % attributeId + attrIdStr = changeEndian(attrIdStr) + message += attrIdStr + message += ", " + + zclPayload = parsedData['rf_data'][3:] + zclPayload = zclPayload[3:] + attributeType = zclPayload[0] + message += "%0.2x" % ord(attributeType) + message += ", " + + message += "success" + message += ", " + + message += "%0.2x" % ord(value) + message += ";" + + message += ";" + + message = message[0:len(message) - 1] + message += "\n" + + # no one to send the response to so just move on + if(tup == None): + # cant really do anything here + return + sendSoceket.sendto(message,tup[0]) + elif command == '\x07': + status = rfdata[3] + print '' + print "( 0x0101 ) Door Lock: Configure reporting response" + print 'rfdata : ' + zigbeeHexStringToHexString(rfdata) + if status == '\x00': + print "Configure report successfully" + message = "type : zcl_configure_reporting_response \n" + message += "packet_id: " + packetId + "\n" + message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n" + message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n" + message += "attributes: " + message += "all_success \n"; + + # no one to send the response to so just move on + if(tup == None): + # cant really do anything here + return + sendSoceket.sendto(message,tup[0]) + else: + print "Configure report unsuccessfully, status =", zigbeeHexStringToHexString(status) + elif(command == '\x0A'): + print "New update" + attributeId = (ord(rfdata[3]) * 256) + ord(rfdata[4]) + if attributeId == 0x0000: + value = rfdata[6] + if value == '\x00': + print "Not fully locked" + elif value == '\x01': + print "Locked" + elif value == '\x02': + print "Unlocked" + else: + print "Unknown value: " + zigbeeHexStringToHexString(value) + + message = "type : zcl_read_attributes_response \n" + message += "packet_id: " + ("%0.2x" % ord(zclSeqNumber)) + "\n" + message += "cluster_id: " + zigbeeHexStringToHexString(parsedData['cluster']) + "\n" + message += "profile_id: " + zigbeeHexStringToHexString(parsedData['profile']) + "\n" + message += "attributes: " + + attrIdStr = "%0.4x" % attributeId + attrIdStr = changeEndian(attrIdStr) + message += attrIdStr + message += ", " + + zclPayload = parsedData['rf_data'][3:] + zclPayload = zclPayload[3:] + attributeType = zclPayload[0] + message += "%0.2x" % ord(attributeType) + message += ", " + + message += "success" + message += ", " + + message += "%0.2x" % ord(value) + message += ";" + + message += ";" + + message = message[0:len(message) - 1] + message += "\n" + + # get callback clients to respond to + callbackIndex = (zigbeeHexStringToHexString(parsedData['source_addr_long']), zigbeeHexStringToHexString(parsedData['cluster'])) + retAddr = None + zibeeHACallbackMutex.acquire() + if(zibeeHACallback.has_key(callbackIndex)): + retAddr = zibeeHACallback[callbackIndex] + zibeeHACallbackMutex.release() + + # no one to respond to so do nothing here + if(retAddr == None): + return + for ra in retAddr: + sendSoceket.sendto(message,ra) + return + # if this is a ZDO message/response #print "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" #print parsedData @@ -1744,6 +2049,8 @@ def handleNewZigbeeMessage(parsedData): #print "==================================================================" + + def handleNewUdpPacket(data, addr): ''' Method to parse and handle an incoming UDP packet. @@ -1807,8 +2114,12 @@ def handleNewUdpPacket(data, addr): processUdpBroadcastingRouteRecordReqMessage(parsedData, addr) elif(parsedData["type"] == "zcl_change_switch_request"): #made by changwoo processUdpZclChangeSwitchReqMessage(parsedData, addr) + elif(parsedData["type"] == "zcl_lock_or_unlock_door_request"): #made by Jiawei + processUdpZclLockOrUnlockDoorReqMessage(parsedData, addr) + elif(parsedData["type"] == "zcl_read_door_status_request"): #made by Jiawei + processUdpZclReadDoorStatusReqMessage(parsedData, addr) else: - print "unknown Packet: " + parsedData["type"] + #print "unknown Packet: " + parsedData["type"] pass except: # if we ever get here then something went wrong and so just ignore this @@ -1851,7 +2162,7 @@ def main(): # setup incoming UDP socket and bind it to self and specified UDP port # sending socket does not need to be bound to anything #receiveSoceket.bind(('192.168.2.227', UDP_RECEIVE_PORT)) - receiveSoceket.bind(('192.168.2.192', UDP_RECEIVE_PORT)) + receiveSoceket.bind(('192.168.1.192', UDP_RECEIVE_PORT)) # create the thread that does short address lookups addressUpdateWorkerThread = threading.Thread(target=addressUpdateWorkerMethod) -- 2.34.1