Example #1
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)
Example #2
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)
Example #3
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)
Example #4
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)    
Example #5
0
def read_property_multiple(device, properties):

    # this hack is back in now because Trane's onsite bridge (device 11)
    # does not properly answer multiple properties
    # 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

    results = []
    if not (_device_table.has_key(device)) or (_device_table[device].readPropertyFallback < 2):
        results = read_property_multiple_real2(device, properties)
        if results != None:
            if len(results) == len(properties):
                _device_table[device].readPropertyFallback = 1  # No fallback needed.
                return results
    # we did not get the result we expected, try to fall back to a different
    # method this function breaks the read_property_multiple into groups of
    # GroupSize
    results = []
    Groupsize = 1
    while properties:
        group = properties[0:Groupsize]
        ilen = len(group)
        result = None

        if (_device_table[device].readPropertyFallback == 0) or (_device_table[device].readPropertyFallback == 2):

            result = read_property_multiple_real2(device, group)

            if result != None:  # remember this worked
                if _device_table[device].readPropertyFallback == 0:
                    msglog.log(
                        "broadway", msglog.types.WARN, "read_property_multiple fallback for device = " + str(device)
                    )
                _device_table[device].readPropertyFallback = 2  # Use single RPM.

        if (_device_table[device].readPropertyFallback == 0) or (_device_table[device].readPropertyFallback == 3):

            result = read_property(device, group[0])

            if result != None:  # remember this worked
                if _device_table[device].readPropertyFallback == 0:
                    msglog.log("broadway", msglog.types.WARN, "read_property fallback for device = " + str(device))
                _device_table[device].readPropertyFallback = 3

                rp_result = result  # convert result to RPM style
                result = ((None, None),)
                for p in rp_result.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
                        p_bacnet_value_type = p.value[0].number
                        result = ((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
                        result = ((p_value, p_bacnet_value_type),)
                    elif p.number == 5:
                        # error code
                        result = ((None, None),)
        properties = properties[Groupsize:]
        if result is None:
            if DEBUG:
                print "No results..."
            result = (None, None)
            for i in range(0, ilen):
                results.append(result)
        else:
            for i in range(0, ilen):
                if i < len(result):
                    results.append(result[i])
                else:
                    raise BACnetException("Too few results...")
    return results
Example #6
0
def read_property_multiple(device, properties):
    
    # this hack is back in now because Trane's onsite bridge (device 11)
    # does not properly answer multiple properties
    # 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

    results=[]
    if (not (_device_table.has_key(device)) or \
        (_device_table[device].readPropertyFallback < 2)):
        results = read_property_multiple_real2(device,properties)
        if (results != None):
            if (len(results) == len(properties)): 
                _device_table[device].readPropertyFallback=1 # No fallback needed.
                return results
    # we did not get the result we expected, try to fall back to a different
    # method this function breaks the read_property_multiple into groups of
    # GroupSize
    results=[]
    Groupsize = 1
    while properties:
        group = properties[0:Groupsize]
        ilen = len(group)
        result = None
        
        if (_device_table[device].readPropertyFallback == 0) or \
           (_device_table[device].readPropertyFallback == 2):

            result = read_property_multiple_real2(device, group)

            if (result != None): #remember this worked
                if (_device_table[device].readPropertyFallback == 0):
                    msglog.log('broadway', msglog.types.WARN,
                               'read_property_multiple fallback for device = ' +
                               str(device))
                _device_table[device].readPropertyFallback = 2 # Use single RPM.

        if (_device_table[device].readPropertyFallback == 0) or \
           (_device_table[device].readPropertyFallback == 3):

            result = read_property(device, group[0])

            if (result != None): #remember this worked
                if (_device_table[device].readPropertyFallback == 0):
                    msglog.log('broadway', msglog.types.WARN,
                               'read_property fallback for device = ' +
                               str(device))    
                _device_table[device].readPropertyFallback = 3

                rp_result = result  #convert result to RPM style
                result = ((None, None),)
                for p in rp_result.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
                        p_bacnet_value_type = p.value[0].number
                        result = ((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
                        result = ((p_value, p_bacnet_value_type),)
                    elif p.number == 5:
                        # error code
                        result = ((None, None),)
        properties = properties[Groupsize:]
        if result is None:
            if DEBUG: print 'No results...'
            result = (None,None)
            for i in range(0,ilen):
                results.append(result)
        else:
            for i in range(0,ilen):
                if i < len(result):
                    results.append(result[i])
                else:
                    raise BACnetException('Too few results...')
    return results