예제 #1
0
파일: server.py 프로젝트: mcruse/monotone
def who_is_request_received(msg, network):
    if not the_devices: 
        if debug: print 'who is received but we have no device(s)'
        return

    if len(msg.data) == 0: #device limits tags len==0 means global request
        if debug: print 'who are'
        for the_device in the_devices.values():
            i_am(the_device, network)
    else:
        if debug: print 'check if we are who is'
        tags = tag.decode(msg.data).value
        if debug: 
            print tags
        
        if len(tags) == 2:
            if debug:
                print tags[0]
                print tags[1]
            lower_limit = data.decode_unsigned_integer(tags[0].data) #Device Instance Range Low Limit
            upper_limit = data.decode_unsigned_integer(tags[1].data)
            if debug: print 'is it between: %s and %s' % (lower_limit, upper_limit)

# From bacnet plugfest, we were filtering out anyone not on our network from test for
# address limits.  We were responding ok to global whoisall
#            if network == the_device.network:
            for the_device in the_devices.values():
                if the_device.instance_number >= lower_limit:
                    if the_device.instance_number <= upper_limit:
                        if debug: print 'i am the mo-fo'
                        i_am(the_device, network)
예제 #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)
예제 #3
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)
예제 #4
0
def read_property_multiple_g3(device, properties, timeout=3.0, no_fallback=0):
    # Some device's do not properly answer multiple properties to multiple
    # objects. This method first tries RPM, then RPM(singular) and finially RP
    # to retrieve a list of properties.
    # A readPropertyFallback attribute remembers which mode was successful and
    # that is used in subsequent reads.
    if (not (_device_table.has_key(device)) or \
        (_device_table[device].readPropertyFallback < BACNET_RPM_SINGLE_OK)):
        results = _read_property_multiple_g3(device,properties, timeout)
        if (results != None):
            if (len(results) == len(properties)): 
                _device_table[device].readPropertyFallback=1 # No fallback needed.
                return results
            elif no_fallback != 0:
                return results
            else:
                # Broken device?
                _device_table[device].readPropertyFallback=0

    results = []
    properties = copy.copy(properties)
    while properties:
        property = properties.pop(0)
        try:
            rp_result = read_property_g3(device, property)
            if (rp_result is not None): #remember this worked
                if (_device_table[device].readPropertyFallback == BACNET_RPM_UNKNOWN):
                    msglog.log('broadway', msglog.types.WARN,
                               'read_property fallback for device = ' +
                               str(device))
                    _device_table[device].readPropertyFallback = BACNET_RPM_NOT_SUPPORTED
                #convert result to RPM style
                result = sequence.ReadAccessResult()
                result.object_identifier = rp_result.object_identifier
                result.list_of_results = [
                    sequence._ReadPropertyMultipleResult(
                        property_identifier=rp_result.property_identifier,
                        property_array_index=rp_result.property_array_index,
                        property_value=rp_result.property_value)
                    ]
            else:
                # Place holder...
                result = ReadAccessResult()
        except BACnetError, e:
            # Simulate RPMs behaviour when a subset of reads fail.
            error = sequence.Error(decode=tag.decode(e.npdu.data).value)
            result = sequence.ReadAccessResult()
            result.object_identifier = data.BACnetObjectIdentifier(property[0],
                                                                   property[1])
            if len(property) > 3 and property[3] != -1:
                index = property[3]
            else:
                index = -1
            result.list_of_results = [
                sequence._ReadPropertyMultipleResult(
                    property_identifier=property[2],
                    property_array_index=index,
                    property_access_error=error)
                ]
        results.append(result)
예제 #5
0
def who_is_request_received(msg, network):
    if not the_devices:
        if debug: print 'who is received but we have no device(s)'
        return

    if len(msg.data) == 0:  #device limits tags len==0 means global request
        if debug: print 'who are'
        for the_device in the_devices.values():
            i_am(the_device, network)
    else:
        if debug: print 'check if we are who is'
        tags = tag.decode(msg.data).value
        if debug:
            print tags

        if len(tags) == 2:
            if debug:
                print tags[0]
                print tags[1]
            lower_limit = data.decode_unsigned_integer(
                tags[0].data)  #Device Instance Range Low Limit
            upper_limit = data.decode_unsigned_integer(tags[1].data)
            if debug:
                print 'is it between: %s and %s' % (lower_limit, upper_limit)

            # From bacnet plugfest, we were filtering out anyone not on our network from test for
            # address limits.  We were responding ok to global whoisall
            #            if network == the_device.network:
            for the_device in the_devices.values():
                if the_device.instance_number >= lower_limit:
                    if the_device.instance_number <= upper_limit:
                        if debug: print 'i am the mo-fo'
                        i_am(the_device, network)
예제 #6
0
def server_read_property(device, msg):
    s = None
    o = None
    ss = None
    p = None
    try:
        # device.time_rp.begin()
        request = tag.decode(msg.data)
        if DEBUG:
            print "SERVER READ PROPERTY request: ", request
        s = sequence.ReadPropertyRequest(decode=request.value)
        if DEBUG:
            print "SERVER READ PROPERTY sequence: ", s
        o = device.find_bacnet_object(s.object_identifier)
        if o is None:  # object not found
            raise ENotFound(
                "BACnet Server Read, Object not found, Type: %d Instance: %d propID: %d"
                % (s.object_identifier.object_type, s.object_identifier.instance_number, s.property_identifier)
            )
        if DEBUG:
            print "SERVER READ PROPERTY object: ", o
        ss = s.property_identifier
        if DEBUG:
            print "ss = ", ss
        p = o.find_property(ss)
        if o is None:  # object not found
            raise ENotFound(
                "BACnet Server Read, Prop not found, Type: %d Instance: %d propID: %d"
                % (s.object_identifier.object_type, s.object_identifier.instance_number, s.property_identifier)
            )
        if DEBUG:
            print "SERVER READ PROPERTY property: ", p
        i = None
        answer = sequence.ReadPropertyACK()
        if s.property_array_index != OPTIONAL:
            if DEBUG:
                print "_bacnet.serverreadproperty ", s.property_array_index
            i = s.property_array_index
            answer.property_array_index = i
            if DEBUG:
                print i
        answer.object_identifier = s.object_identifier
        answer.property_identifier = s.property_identifier
        answer.property_value = p.as_tags(i)  # this is where we retrieve the value from the node
        answer = complex_ack_pdu(msg, answer.encoding)
        # device.time_rp.end()
        return answer
    except:
        # @fixme use literals not numbers
        msglog.log("mpx:bacnet", msglog.types.ERR, str(msg))
        msglog.exception()
        if p:
            return error_pdu(msg, 2, 25)  # operational-problem
        if o:
            return error_pdu(msg, 2, 32)  # unknown-property
        if s:
            return error_pdu(msg, 1, 31)  # unknown-object
        return error_pdu(msg, 2, 0)  # other
예제 #7
0
def read_property_multiple_g3(device, properties, timeout=3.0, no_fallback=0):
    # Some device's do not properly answer multiple properties to multiple
    # objects. This method first tries RPM, then RPM(singular) and finially RP
    # to retrieve a list of properties.
    # A readPropertyFallback attribute remembers which mode was successful and
    # that is used in subsequent reads.
    if not (_device_table.has_key(device)) or (_device_table[device].readPropertyFallback < BACNET_RPM_SINGLE_OK):
        results = _read_property_multiple_g3(device, properties, timeout)
        if results != None:
            if len(results) == len(properties):
                _device_table[device].readPropertyFallback = 1  # No fallback needed.
                return results
            elif no_fallback != 0:
                return results
            else:
                # Broken device?
                _device_table[device].readPropertyFallback = 0

    results = []
    properties = copy.copy(properties)
    while properties:
        property = properties.pop(0)
        try:
            rp_result = read_property_g3(device, property)
            if rp_result is not None:  # remember this worked
                if _device_table[device].readPropertyFallback == BACNET_RPM_UNKNOWN:
                    msglog.log("broadway", msglog.types.WARN, "read_property fallback for device = " + str(device))
                    _device_table[device].readPropertyFallback = BACNET_RPM_NOT_SUPPORTED
                # convert result to RPM style
                result = sequence.ReadAccessResult()
                result.object_identifier = rp_result.object_identifier
                result.list_of_results = [
                    sequence._ReadPropertyMultipleResult(
                        property_identifier=rp_result.property_identifier,
                        property_array_index=rp_result.property_array_index,
                        property_value=rp_result.property_value,
                    )
                ]
            else:
                # Place holder...
                result = ReadAccessResult()
        except BACnetError, e:
            # Simulate RPMs behaviour when a subset of reads fail.
            error = sequence.Error(decode=tag.decode(e.npdu.data).value)
            result = sequence.ReadAccessResult()
            result.object_identifier = data.BACnetObjectIdentifier(property[0], property[1])
            if len(property) > 3 and property[3] != -1:
                index = property[3]
            else:
                index = -1
            result.list_of_results = [
                sequence._ReadPropertyMultipleResult(
                    property_identifier=property[2], property_array_index=index, property_access_error=error
                )
            ]
        results.append(result)
예제 #8
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
예제 #9
0
def _read_property_multiple_callback(tsm):
    try:
        if tsm.exception:
            raise tsm.exception
        r = tsm.response
        recv_callback_helper(r)
        responses = tag.decode(r.data)
        return sequence.context_read_access_result_list(responses)
    except Exception, e:
        return e
예제 #10
0
def _read_property_multiple_callback(tsm):
    try:
        if tsm.exception:
            raise tsm.exception
        r = tsm.response
        recv_callback_helper(r)
        responses = tag.decode(r.data)
        return sequence.context_read_access_result_list(responses)
    except Exception, e:
        return e
예제 #11
0
def _read_property_callback(tsm):
    try:
        if tsm.exception:
            raise tsm.exception
        r = tsm.response
        recv_callback_helper(r)
        response = tag.decode(r.data)
        return sequence.ReadPropertyACK(decode=response.value)
    except Exception, e:
        return e
예제 #12
0
def _read_property_callback(tsm):
    try:
        if tsm.exception:
            raise tsm.exception
        r = tsm.response
        recv_callback_helper(r)
        response = tag.decode(r.data)
        return sequence.ReadPropertyACK(decode=response.value)
    except Exception, e:
        return e
예제 #13
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
예제 #14
0
def server_write_property_multiple(device, msg):
    request = tag.decode(msg.data)
    if DEBUG:
        print "SERVER WRITE PROPERTY MULTIPLE request: ", request
    results = None
    # convert request into a list of read access specifications
    ss = sequence.context_write_access_specification_list(request)
    o = None
    p = None
    if DEBUG:
        print "SERVER WRITE PROPERTY sequence: ", ss
    for s in ss:  # do each write access specification
        o = device.find_bacnet_object(s.object_identifier)
        if DEBUG:
            print "SERVER WRITE PROPERTY object: ", o
        for pv in s.list_of_properties:
            i = None
            if pv.property_array_index != OPTIONAL:
                i = pv.property_array_index
            priority = None
            if pv.priority != OPTIONAL:
                priority = pv.priority
            try:
                p = o.find_property(pv.property_identifier)
                p.write(pv.value, i, priority)  # index?
            except EPermission:
                if DEBUG:
                    print "SERVER WRITE PROPERTY EPERMISSION ERROR"
                result = sequence.WritePropertyMultipleError()
                result.error_type = sequence.Error(2, 40)  # write access denied
                bopr = BACnetObjectPropertyReference()
                bopr.object_identifier = s.object_identifier
                bopr.property_identifier = pv.property_identifier
                bopr.property_index = pv.property_array_index
                result.first_failed_write_attempt = bopr
                return complex_ack_pdu(result.encoding)
            except:
                if DEBUG:
                    print "SERVER WRITE PROPERTY ERROR"
                result = sequence.WritePropertyMultipleError()
                if p:
                    result.error_type = sequence.Error(2, 25)  # operational error
                elif o:
                    result.error_type = sequence.Error(2, 32)  # unknown property
                else:  # unkown object
                    result.error_type = sequence.Error(1, 31)  # unknown object
                bopr = BACnetObjectPropertyReference()
                bopr.object_identifier = s.object_identifier
                bopr.property_identifier = pv.property_identifier
                bopr.property_index = pv.property_array_index
                result.first_failed_write_attempt = bopr
                return complex_ack_pdu(result.encoding)
            if DEBUG:
                print "SERVER WRITE PROPERTY property: ", p
    return simple_ack_pdu(msg)
예제 #15
0
def cov_notification_msg(server_device, msg, confirmed):
    notif = tag.decode(msg.data)
    if DEBUG:
        print "COV NOTIFICATION: ", notif
    # convert request into a list of cov specifications
    ss = sequence.CovNotification(decode=notif.value)
    if DEBUG:
        print "COV NOTIFICATION sequence: ", ss
    pid = ss.pid
    if DEBUG:
        print "COV NOTIFICATION pid: ", pid
    device_id = ss.device_identifier.instance_number
    if DEBUG:
        print "COV NOTIFICATION device_id: ", device_id
    time_remaining = ss.time_remaining
    if DEBUG:
        print "COV NOTIFICATION time_remaining: ", time_remaining

    if _device_table.has_key(device_id):
        device = _device_table[device_id]
    else:
        # Unknown device.
        return error_pdu(msg, 5, 25)

    try:
        if device.node is None:
            dnode = as_node("/services/network/BACnet/internetwork/Devices/" + str(device_id))
            device.node = dnode

        o = device.node.as_node(
            (str(ss.object_identifier.object_type)) + "/" + (str(ss.object_identifier.instance_number))
        )

    except:
        return error_pdu(msg, 5, 25)
    if DEBUG:
        print "COV NOTIFICATION object: ", o

    for pv in ss.list_of_property_values:
        try:
            p = o.get_child(str(pv.property_identifier), auto_discover=0)
        except ENoSuchName:
            if DEBUG:
                print "COV NOTIFICATION ENOSUCHNAME"
            # This can happen if the property we are refering to is
            # not instantiated (because it isn't polled/monitored/not-of-
            # interest. Example: We are only monitoring present-value
            # property, but not status-flags. Ignore for now.

        else:
            p.cov_notif_processing(pv.value, pid, time_remaining)

    return simple_ack_pdu(msg)
예제 #16
0
def server_read_property_multiple(device, msg):
    request = tag.decode(msg.data)
    if DEBUG:
        print "SERVER READ PROPERTY MULTIPLE request: ", request
    results = []
    # convert request into a list of read access specifications
    ss = sequence.context_read_access_specification_list(request)
    o = None
    p = None
    if DEBUG:
        print "SERVER READ PROPERTY sequence: ", ss
    # device.time_rpm.begin()
    for s in ss:
        o = device.find_bacnet_object(s.object_identifier)
        if DEBUG:
            print "SERVER READ PROPERTY object: ", o
        result = sequence.ReadAccessResult()
        result.object_identifier = s.object_identifier
        props = []
        for spec in s.list_of_specs:
            prop_result = sequence._ReadPropertyMultipleResult()
            prop_result.property_identifier = spec.property_identifier
            i = None
            if spec.property_index != OPTIONAL:
                i = spec.property_index
                prop_result.property_array_index = i
            try:
                p = o.find_property(spec.property_identifier)
                prop_result.property_value = p.as_tags(i)
            except:
                if p:
                    prop_result.property_access_error = sequence.Error(2, 25)  # operational error
                elif o:
                    prop_result.property_access_error = sequence.Error(2, 32)  # unknown property
                else:  # unkown object
                    prop_result.property_access_error = sequence.Error(1, 31)  # unknown object
                if DEBUG:
                    print "SERVER property_access_error: ", str(
                        prop_result.property_access_error
                    ), s.object_identifier.object_type, s.object_identifier.instance_number, str(
                        spec.property_identifier
                    )
            if DEBUG:
                print "SERVER READ PROPERTY property: ", p
            props.append(prop_result.encoding)
        result.list_of_results = props
        results.extend(result.encoding)
    if DEBUG:
        print "SERVER READ PROPERTY MULTIPLE request results: ", results
    answer = complex_ack_pdu(msg, results)
    # device.time_rpm.end()
    return answer
예제 #17
0
def server_read_property(device, msg):
    s = None
    o = None
    ss = None
    p = None
    try:
        #device.time_rp.begin()
        request = tag.decode(msg.data)
        if DEBUG: print 'SERVER READ PROPERTY request: ', request
        s = sequence.ReadPropertyRequest(decode=request.value)
        if DEBUG: print 'SERVER READ PROPERTY sequence: ', s
        o = device.find_bacnet_object(s.object_identifier)
        if o is None: # object not found
            raise ENotFound('BACnet Server Read, Object not found, Type: %d Instance: %d propID: %d' % \
                            (s.object_identifier.object_type, 
                             s.object_identifier.instance_number,
                             s.property_identifier))
        if DEBUG: print 'SERVER READ PROPERTY object: ', o
        ss = s.property_identifier
        if DEBUG: print 'ss = ', ss
        p = o.find_property(ss)
        if o is None: # object not found
            raise ENotFound('BACnet Server Read, Prop not found, Type: %d Instance: %d propID: %d' % \
                            (s.object_identifier.object_type, 
                             s.object_identifier.instance_number,
                             s.property_identifier))
        if DEBUG: print 'SERVER READ PROPERTY property: ', p
        i = None
        answer = sequence.ReadPropertyACK()
        if s.property_array_index != OPTIONAL:
            if DEBUG: print '_bacnet.serverreadproperty ', s.property_array_index
            i = s.property_array_index
            answer.property_array_index = i
            if DEBUG: print i
        answer.object_identifier = s.object_identifier
        answer.property_identifier = s.property_identifier
        answer.property_value = p.as_tags(i)  #this is where we retrieve the value from the node
        answer = complex_ack_pdu(msg, answer.encoding)
        #device.time_rp.end()
        return answer
    except:
        #@fixme use literals not numbers
        msglog.log('mpx:bacnet',msglog.types.ERR,str(msg))
        msglog.exception()
        if p:
            return error_pdu(msg, 2, 25) # operational-problem
        if o:
            return error_pdu(msg, 2, 32) # unknown-property 
        if s:
            return error_pdu(msg, 1, 31) # unknown-object 
        return error_pdu(msg, 2, 0) # other
예제 #18
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)
예제 #19
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)
예제 #20
0
def server_write_property_multiple(device, msg):
    request = tag.decode(msg.data)
    if DEBUG: print 'SERVER WRITE PROPERTY MULTIPLE request: ', request
    results = None
    #convert request into a list of read access specifications
    ss = sequence.context_write_access_specification_list(request)
    o = None
    p = None
    if DEBUG: print 'SERVER WRITE PROPERTY sequence: ', ss
    for s in ss: #do each write access specification
        o = device.find_bacnet_object(s.object_identifier)
        if DEBUG: print 'SERVER WRITE PROPERTY object: ', o
        for pv in s.list_of_properties:
            i = None
            if pv.property_array_index != OPTIONAL:
                i = pv.property_array_index
            priority = None
            if pv.priority != OPTIONAL:
                priority = pv.priority
            try:
                p = o.find_property(pv.property_identifier)
                p.write(pv.value, i, priority)  #index?
            except EPermission:
                if DEBUG: print 'SERVER WRITE PROPERTY EPERMISSION ERROR'
                result = sequence.WritePropertyMultipleError()
                result.error_type = sequence.Error(2,40) #write access denied
                bopr = BACnetObjectPropertyReference()
                bopr.object_identifier = s.object_identifier
                bopr.property_identifier = pv.property_identifier
                bopr.property_index = pv.property_array_index
                result.first_failed_write_attempt = bopr
                return complex_ack_pdu(result.encoding)
            except:
                if DEBUG: print 'SERVER WRITE PROPERTY ERROR'
                result = sequence.WritePropertyMultipleError()
                if p:
                    result.error_type = sequence.Error(2,25) #operational error
                elif o:
                    result.error_type = sequence.Error(2,32) #unknown property
                else: #unkown object
                    result.error_type = sequence.Error(1,31) #unknown object
                bopr = BACnetObjectPropertyReference()
                bopr.object_identifier = s.object_identifier
                bopr.property_identifier = pv.property_identifier
                bopr.property_index = pv.property_array_index
                result.first_failed_write_attempt = bopr
                return complex_ack_pdu(result.encoding)
            if DEBUG: print 'SERVER WRITE PROPERTY property: ', p
    return simple_ack_pdu(msg)
예제 #21
0
def server_write_property(device, msg):
    try:
        # device.time_wp.begin()
        request = tag.decode(msg.data)
        if DEBUG:
            print "SERVER WRITE PROPERTY request: ", request
        s = sequence.WritePropertyRequest(decode=request.value)
        if DEBUG:
            print "SERVER WRITE PROPERTY sequence: ", s
        o = device.find_bacnet_object(s.object_identifier)
        if o is None:  # object not found
            raise ENotFound(
                "BACnet Server Write, Object not found, Type: %d Instance: %d propID: %d"
                % (s.object_identifier.object_type, s.object_identifier.instance_number, s.property_identifier)
            )
        if DEBUG:
            print "SERVER WRITE PROPERTY object: ", o
        p = o.find_property(s.property_identifier)
        if p is None:  # object not found
            raise ENotFound(
                "BACnet Server Write Prop not found, Type: %d Instance: %d propID: %d"
                % (s.object_identifier.object_type, s.object_identifier.instance_number, s.property_identifier)
            )
        if DEBUG:
            print "SERVER WRITE PROPERTY property: ", p
        priority = None
        if s.priority != OPTIONAL:
            priority = s.priority
        i = None
        if s.property_array_index != OPTIONAL:
            i = s.property_array_index
        if DEBUG:
            print "SERVER WRITE PROPERTY value: ", s.property_value[0].value, priority
        p.write(s.property_value, i, priority)
        answer = simple_ack_pdu(msg)
        # device.time_wp.end()
        return answer
    except EPermission:
        if DEBUG:
            print "Permission error on write propety"
        return error_pdu(msg, 2, 40)
    except:
        msglog.exception()
        if DEBUG:
            print "ERROR on Write Property"
            print "device: ", str(device)
        return error_pdu(msg, 2, 0)
예제 #22
0
def cov_notification_msg(server_device, msg, confirmed):
    notif = tag.decode(msg.data)
    if DEBUG: print 'COV NOTIFICATION: ', notif 
    #convert request into a list of cov specifications
    ss = sequence.CovNotification(decode=notif.value)
    if DEBUG: print 'COV NOTIFICATION sequence: ', ss
    pid = ss.pid 
    if DEBUG: print 'COV NOTIFICATION pid: ', pid 
    device_id = ss.device_identifier.instance_number
    if DEBUG: print 'COV NOTIFICATION device_id: ', device_id
    time_remaining = ss.time_remaining 
    if DEBUG: print 'COV NOTIFICATION time_remaining: ', time_remaining 

    if _device_table.has_key(device_id):
        device = _device_table[device_id]
    else:
        # Unknown device.
        return error_pdu(msg, 5, 25)

    try: 
        if device.node is None:
            dnode = as_node('/services/network/BACnet/internetwork/Devices/' + str(device_id))
            device.node = dnode

        o = device.node.as_node((str(ss.object_identifier.object_type)) \
            + '/'+ (str(ss.object_identifier.instance_number)))

    except:
        return error_pdu(msg, 5, 25) 
    if DEBUG: print 'COV NOTIFICATION object: ', o

    for pv in ss.list_of_property_values:
        try:
            p = o.get_child(str(pv.property_identifier), auto_discover=0)
        except ENoSuchName:
            if DEBUG: print 'COV NOTIFICATION ENOSUCHNAME'
            # This can happen if the property we are refering to is
            # not instantiated (because it isn't polled/monitored/not-of-
            # interest. Example: We are only monitoring present-value
            # property, but not status-flags. Ignore for now.

        else:
            p.cov_notif_processing(pv.value, pid, time_remaining)

    return simple_ack_pdu(msg)    
예제 #23
0
def server_read_property_multiple(device, msg):
    request = tag.decode(msg.data)
    if DEBUG: print 'SERVER READ PROPERTY MULTIPLE request: ', request
    results = []
    #convert request into a list of read access specifications
    ss = sequence.context_read_access_specification_list(request)
    o = None
    p = None
    if DEBUG: print 'SERVER READ PROPERTY sequence: ', ss
    #device.time_rpm.begin()
    for s in ss:
        o = device.find_bacnet_object(s.object_identifier)
        if DEBUG: print 'SERVER READ PROPERTY object: ', o
        result = sequence.ReadAccessResult()
        result.object_identifier = s.object_identifier
        props = []
        for spec in s.list_of_specs:
            prop_result = sequence._ReadPropertyMultipleResult()
            prop_result.property_identifier = spec.property_identifier
            i = None
            if spec.property_index != OPTIONAL:
                i = spec.property_index
                prop_result.property_array_index = i
            try:
                p = o.find_property(spec.property_identifier)
                prop_result.property_value = p.as_tags(i)
            except:
                if p:
                    prop_result.property_access_error = sequence.Error(2,25) #operational error
                elif o:
                    prop_result.property_access_error = sequence.Error(2,32) #unknown property
                else: #unkown object
                    prop_result.property_access_error = sequence.Error(1,31) #unknown object
                if DEBUG: print 'SERVER property_access_error: ', str(prop_result.property_access_error), \
                      s.object_identifier.object_type,  s.object_identifier.instance_number, \
                      str(spec.property_identifier)
            if DEBUG: print 'SERVER READ PROPERTY property: ', p
            props.append(prop_result.encoding)
        result.list_of_results = props
        results.extend(result.encoding)
    if DEBUG: print 'SERVER READ PROPERTY MULTIPLE request results: ', results
    answer = complex_ack_pdu(msg, results)
    #device.time_rpm.end()
    return answer
예제 #24
0
def server_write_property(device, msg):
    try:
        #device.time_wp.begin()
        request = tag.decode(msg.data)
        if DEBUG: print 'SERVER WRITE PROPERTY request: ', request
        s = sequence.WritePropertyRequest(decode=request.value)
        if DEBUG: print 'SERVER WRITE PROPERTY sequence: ', s
        o = device.find_bacnet_object(s.object_identifier)
        if o is None: # object not found
            raise ENotFound('BACnet Server Write, Object not found, Type: %d Instance: %d propID: %d' % \
                            (s.object_identifier.object_type, 
                             s.object_identifier.instance_number,
                             s.property_identifier))
        if DEBUG: print 'SERVER WRITE PROPERTY object: ', o
        p = o.find_property(s.property_identifier)
        if p is None: # object not found
            raise ENotFound('BACnet Server Write Prop not found, Type: %d Instance: %d propID: %d' % \
                            (s.object_identifier.object_type, 
                             s.object_identifier.instance_number,
                             s.property_identifier))
        if DEBUG: print 'SERVER WRITE PROPERTY property: ', p
        priority = None
        if s.priority != OPTIONAL:
            priority = s.priority
        i = None
        if s.property_array_index != OPTIONAL:
            i = s.property_array_index
        if DEBUG: print 'SERVER WRITE PROPERTY value: ', s.property_value[0].value, priority
        p.write(s.property_value, i, priority)
        answer = simple_ack_pdu(msg)
        #device.time_wp.end()
        return answer
    except EPermission:
        if DEBUG:
            print 'Permission error on write propety'
        return error_pdu(msg, 2, 40)
    except:
        msglog.exception()
        if DEBUG:
            print 'ERROR on Write Property'
            print 'device: ', str(device)
        return error_pdu(msg, 2, 0)
예제 #25
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
예제 #26
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
예제 #27
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))
예제 #28
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))