def test_encode_context_tag(self): for c, encoding, data in ((tag.Context(6, '\x00'),'\x69\x00','\x00'), (tag.Context(0, ''),'\x08', '')): if c.data != data: raise 'Encoded data incorrectly' if c.encoding != encoding: raise 'Rencoded incorrectly'
def read_property_g3(device, prop, timeout=3.0, **keywords): object = prop[0] instance = prop[1] property = prop[2] arrayidx = None if len(prop) > 3 : arrayidx = prop[3] rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 12 objID = tag.Context(0,data.BACnetObjectIdentifier(object,instance)) propID = tag.Context(1,data.encode_enumerated(property)) rp.data = objID.encoding + propID.encoding if arrayidx is not None and arrayidx != -1: rp.data = rp.data + \ tag.Context(2,data.encode_unsigned_integer(arrayidx)).\ encoding if keywords.has_key('callback'): keywords['callback'].callback(_read_property_callback) request_id = network.send_request(device, rp, timeout, **keywords) return keywords['callback'] else: #block until answer else let tsm handle callback request_id = network.send_request(device, rp, timeout) r = recv_response(request_id, timeout) response = tag.decode(r.data) return sequence.ReadPropertyACK(decode=response.value)
def cov_subscription_request(device, prop_tuple, subscription_type, \ lifetime, subscription_pid, **keywords): object = prop_tuple[0] instance = prop_tuple[1] rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 5 # Subscribe COV Request rp.data = tag.Context(0,data.\ encode_unsigned_integer(subscription_pid)).encoding objID = tag.Context(1,data.BACnetObjectIdentifier(object,instance)) rp.data = rp.data + objID.encoding rp.data = rp.data + \ tag.Context(2,data.\ encode_boolean(subscription_type)).encoding rp.data = rp.data + \ tag.Context(3,data.\ encode_unsigned_integer(lifetime)).encoding if keywords.has_key('callback'): keywords['callback'].callback(_cov_subscription_callback) request_id = network.send_request(device, rp, **keywords) return keywords['callback'] else: #block until answer else let tsm handle callback request_id = network.send_request(device, rp) r = recv_response(request_id) return r
def read_property_multiple_real2(device, properties): results = [] rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 14 rp.data = array.array('c') for prop in properties: object = prop[0] instance = prop[1] property = prop[2] objID = tag.Context(0,data.BACnetObjectIdentifier(object,instance)) if len(prop) < 4 or prop[3] == -1: propID = tag.Construct( 1,[tag.Context(0,data.encode_enumerated(property))] ) else: arrayidx = prop[3] propID = tag.Construct( 1,[tag.Context(0, data.encode_enumerated(property)), tag.Context(1, data.encode_unsigned_integer(arrayidx))] ) rp.data.fromstring(objID.encoding) rp.data.fromstring(propID.encoding) request_id = network.send_request(device, rp) r = recv_response(request_id) responses = tag.decode(r.data) for response in responses.value: # Now if we felt like it, we could extract the BACnetIdentifierObject from # the response data, at response.number 0. But we won't because # we don't need it at the moment. if response.number == 1: # Property id/value list. for p in response.value: # Again, if we felt like it, we could extract the property # ID from tag.number 2. But we won't because we don't use # it. If we wrote code to match the request to response, # we would need it. if p.number == 4: # Property value list p_value = p.value[0].value if p_value is None: pass p_bacnet_value_type = p.value[0].number results.append((p_value, p_bacnet_value_type)) elif p.number == 3: # Property value list p_value = p.value[0].value p_bacnet_value_type = p.value[0].number results.append((p_value, p_bacnet_value_type)) elif p.number == 5: # error code results.append((None, None)) return results
def write_property(device, object, instance, property, arrayidx, priority, value, btype): rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 15 objectIdentifier = tag.Context(0,data.BACnetObjectIdentifier(object,instance)) propertyIdentifier = tag.Context(1,data.encode_enumerated(property)) propertyArrayIndex = None # @fixme Support arrayidx propertyValue = tag.Construct(3) if (priority): priorityTag = tag.Context(4,data.encode_enumerated(priority)) if btype == 0: propertyValue.value.append(tag.Null()) elif btype == 1: propertyValue.value.append(tag.Boolean(int(value))) elif btype == 2: propertyValue.value.append(tag.UnsignedInteger(int(value))) elif btype == 3: propertyValue.value.append(tag.SignedInteger(int(value))) elif btype == 4: propertyValue.value.append(tag.Real(float(value))) elif btype == 5: propertyValue.value.append(tag.Double(float(value))) elif btype == 6: propertyValue.value.append(tag.OctetString(value)) elif btype == 7: if type(value) == types.StringValue or type(value) == array.ArrayType: propertyValue.value.append(tag.CharacterString(data.ANSI_String(value))) else: propertyValue.value.append(tag.CharacterString(value)) elif btype == 8: propertyValue.value.append(tag.BitString(value)) elif btype == 9: propertyValue.value.append(tag.Enumerated(int(value))) elif btype == 10: propertyValue.value.append(tag.Date(value)) elif btype == 11: propertyValue.value.append(tag.Time(value)) elif btype == 12: propertyValue.value.append(tag.BACnetObjectIdentifier(value)) else: raise EInvalidValue("btype", btype) if propertyArrayIndex is None: rp.data = objectIdentifier.encoding + propertyIdentifier.encoding + \ propertyValue.encoding else: rp.data = objectIdentifier.encoding + propertyIdentifier.encoding + \ propertyArrayIndex.encoding + propertyValue.encoding if (priority): #optional priority tag rp.data = rp.data + priorityTag.encoding request_id = network.send_request(device, rp) r = recv_response(request_id) return r
def read_property(device, prop): object = prop[0] instance = prop[1] property = prop[2] arrayidx = None if len(prop) > 3 : arrayidx = prop[3] rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 12 objID = tag.Context(0,data.BACnetObjectIdentifier(object,instance)) propID = tag.Context(1,data.encode_enumerated(property)) rp.data = objID.encoding + propID.encoding if arrayidx is not None and arrayidx != -1: rp.data = rp.data + \ tag.Context(2,data.encode_unsigned_integer(arrayidx)).\ encoding request_id = network.send_request(device, rp) r = recv_response(request_id) response = tag.decode(r.data) return response
def _read_property_multiple_g3(device, properties, timeout=3.0, **keywords): rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 14 rp.data = array.array('c') for prop in properties: object = prop[0] instance = prop[1] property = prop[2] objID = tag.Context(0,data.BACnetObjectIdentifier(object,instance)) if isinstance(property, types.TupleType): tags = [] for pid in property: #loop through list of properties if isinstance(pid, types.TupleType): #may have index if len(pid) > 1: #index tags.append(tag.Context(0, data.encode_enumerated(pid[0]))) tags.append(tag.Context(1, data.encode_unsigned_integer(pid[1]))) continue pid = pid[0] #doen't need to be tuple tags.append(tag.Context(0,data.encode_enumerated(pid))) propID = tag.Construct(1,tags) #frame it in contruct tags else: if len(prop) < 4 or prop[3] == -1: propID = tag.Construct( 1,[tag.Context(0,data.encode_enumerated(property))] ) else: arrayidx = prop[3] propID = tag.Construct( 1,[tag.Context(0, data.encode_enumerated(property)), tag.Context(1, data.encode_unsigned_integer(arrayidx))] ) rp.data.fromstring(objID.encoding) rp.data.fromstring(propID.encoding) #return rp if DEBUG: for c in rp.data: print hex(ord(c)),' ', print '' if keywords.has_key('callback'): keywords['callback'].callback(_read_property_multiple_callback) network.send_request(device, rp, timeout, **keywords) return keywords['callback'] #used as flag request_id = network.send_request(device, rp, timeout) r = recv_response(request_id, timeout) responses = tag.decode(r.data) return sequence.context_read_access_result_list(responses)
def read_private_object_list(device, vendor, object_type, start_index=0): """## # Return a list of lists of object names and identifiers. # @param device address number, vendor number, object type number. # @return A list, each element of which is a list with the first item an object name, # the second item a BacnetObjectIndentifier object.""" results = [] identifier_list = [] answer = [] last_instance = 0 max_tags = 0 rp = APDU() rp.pdu_type = BACNET_CONFIRMED_SERVICE_REQUEST_PDU rp.choice = 18 #ConfirmedPrivateTransferRequest rp.data = array.array('c') vendorID = tag.Context(0,data.encode_unsigned_integer(vendor)) service = tag.Context(1,data.encode_unsigned_integer(0x81)) instanceTag = tag.Construct(2,[ tag.Context(0,data.encode_unsigned_integer(object_type)), tag.Context(1,data.encode_unsigned_integer(start_index)), tag.Context(2,data.encode_unsigned_integer(50))]) rp.data.fromstring(vendorID.encoding) rp.data.fromstring(service.encoding) rp.data.fromstring(instanceTag.encoding) request_id = network.send_request(device, rp) r = recv_response(request_id) responses = tag.decode(r.data) for response in responses.value: # Now if we felt like it, we could extract the BACnetIdentifierObject from # the response data, at response.number 0. But we won't because # we don't need it at the moment. if response.number == 2: #context 2 contains instance tag replay parameters # reply parameters list. for p in response.value: # we could match tag 0 with requested object type if p.number == 1: # last Instance retrieved last_instance = data.BACnetObjectIdentifier(decode=p.data).instance_number if p.number == 2: # Max tags returned. If equals 50, ask for more max_tags = ord(p.data) if p.number == 3: #yet another open context # Identifier list for i in p.value: if i.number == 4: #this is the bacnet object identifier # bnoi = data.data_decode_bacnet_object_identifier(i.data) bnoi = data.BACnetObjectIdentifier(decode=i.data) #finially we get to add one to the list identifier_list.append(bnoi) #tag 5 would be theNVMTag, whatever that is #tag 6 would be the VMTag #now create a read property multiple to request all the names of these collected id's properties = [] if len(identifier_list) > 0: for id in identifier_list: properties.append([object_type,id.instance_number,77]) try: answer = read_property_multiple(device, properties) except BACnetError, e: # @fixme Remove after we figure out the error. print e.npdu raise e if len(answer) != len(identifier_list): raise BACnetException('Identifier list and answer list are different lengths') for i in range(len(identifier_list)): results.append([device,identifier_list[i].object_type, identifier_list[i].instance_number, answer[i][0].character_string]) if max_tags == 50: results = results.append(read_private_object_list(device, vendor, object_type, last_instance))