Example #1
0
 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'
Example #2
0
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)
Example #3
0
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
Example #4
0
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
Example #5
0
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
Example #6
0
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
Example #7
0
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)
Example #8
0
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))