Beispiel #1
0
    def read_properties(self, target_address, point_map, max_per_request=None,
                        use_read_multiple=True):
        """Read a set of points and return the results"""

        if not use_read_multiple:
            return self.read_using_single_request(target_address, point_map)

        # Set max_per_request really high if not set.
        if max_per_request is None:
            max_per_request = self._max_per_request

        _log.debug("Reading {count} points on {target}, max per"
                   " scrape: {max}".format(count=len(point_map),
                                           target=target_address,
                                           max=max_per_request))
        # process point map and populate object_property_map and
        # reverse_point_map
        (object_property_map, reverse_point_map) = self._get_object_properties(
            point_map, target_address)

        result_dict = {}
        finished = False

        while not finished:
            read_access_spec_list = []
            count = 0
            for _ in xrange(max_per_request):
                try:
                    obj_data, properties = object_property_map.popitem()
                except KeyError:
                    finished = True
                    break
                (spec_list, spec_count) = self._get_access_spec(
                    obj_data, properties)
                count += spec_count
                read_access_spec_list.append(spec_list)

            if read_access_spec_list:
                _log.debug(("Requesting {count} properties from "
                           "{target}").format(count=count,
                                              target=target_address))
                request = ReadPropertyMultipleRequest(
                    listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address(target_address)

                iocb = self.iocb_class(request)
                self.this_application.submit_request(iocb)
                bacnet_results = iocb.ioResult.get(10)

                _log.debug(("Received read response from {target} count: "
                            "{count}").format(count=count,
                                              target=target_address))

                for prop_tuple, value in bacnet_results.iteritems():
                    name = reverse_point_map[prop_tuple]
                    result_dict[name] = value

        return result_dict
Beispiel #2
0
    def read_properties(self, target_address, point_map, max_per_request=None, use_read_multiple=True):
        """
        Read a set of points and return the results
        """

        if not use_read_multiple:
            return self.read_using_single_request(target_address, point_map)

        # Set max_per_request really high if not set.
        if max_per_request is None:
            max_per_request = self._max_per_request

        _log.debug("Reading {count} points on {target}, max per scrape: {max}".format(
            count=len(point_map), target=target_address, max=max_per_request))
        # process point map and populate object_property_map and
        # reverse_point_map
        (object_property_map, reverse_point_map) = self._get_object_properties(point_map, target_address)

        result_dict = {}
        finished = False

        while not finished:
            read_access_spec_list = []
            count = 0
            for _ in range(max_per_request):
                try:
                    obj_data, properties = object_property_map.popitem()
                except KeyError:
                    finished = True
                    break
                (spec_list, spec_count) = self._get_access_spec(obj_data, properties)
                count += spec_count
                read_access_spec_list.append(spec_list)

            if read_access_spec_list:
                _log.debug("Requesting {count} properties from {target}".format(count=count, target=target_address))
                request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address(target_address)

                iocb = self.iocb_class(request)
                self.bacnet_application.submit_request(iocb)
                bacnet_results = iocb.ioResult.get(10)

                _log.debug("Received read response from {target} count: {count}".format(
                    count=count, target=target_address))

                for prop_tuple, value in bacnet_results.items():
                    name = reverse_point_map[prop_tuple]
                    result_dict[name] = value

        return result_dict
Beispiel #3
0
    def simple_read(self,
                    target_address,
                    obj_inst,
                    propertylist,
                    obj_type="device",
                    index=0):

        try:
            reverse_point_map = {}
            result_dict = []
            read_access_spec_list = []
            count = 0
            prop_ref_list = []
            for prop in propertylist:
                prop_ref = PropertyReference(propertyIdentifier=prop)
                prop_ref_list.append(prop_ref)
                count += 1

            read_access_spec = ReadAccessSpecification(
                objectIdentifier=(obj_type, obj_inst),
                listOfPropertyReferences=prop_ref_list)

            read_access_spec_list.append(read_access_spec)
            if read_access_spec_list:
                if count == 1:
                    _log.debug(
                        "Requesting {property} properties from {target}".
                        format(property=prop, target=target_address))
                else:
                    _log.debug(
                        "Requesting {count} properties from {target}".format(
                            count=count, target=target_address))
                request = ReadPropertyMultipleRequest(
                    listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address(target_address)
                iocb = IOCB(request, self.async_call)
                self.this_application.submit_request(iocb)
                print "bacnet request sent"
                bacnet_results = tuple
                bacnet_results = iocb.ioResult.get(35)
                print "bacnet data fetched"
                for prop_tuple, value in bacnet_results.iteritems():

                    result_dict.append(value)
            print result_dict
            return result_dict

        except Exception as e:
            print e
            return None
Beispiel #4
0
async def discover_properties(app, device_id, addr):
    objects = await app.execute_request(
        ReadPropertyRequest(objectIdentifier=('device', device_id),
                            propertyIdentifier='objectList',
                            destination=Address(addr)))
    result = {}
    for object_identifier in objects:
        _logger.info(object_identifier)
        read_access_specs = [
            ReadAccessSpecification(
                objectIdentifier=object_identifier,
                listOfPropertyReferences=[
                    PropertyReference(propertyIdentifier='presentValue'),
                    PropertyReference(propertyIdentifier='objectName'),
                    PropertyReference(propertyIdentifier='objectType'),
                    PropertyReference(propertyIdentifier='description'),
                    PropertyReference(propertyIdentifier='units'),
                ],
            ),
        ]
        result.update(await app.execute_request(
            ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_specs,
                destination=Address(addr)), ))
    global properties
    properties = result
    asyncio.get_event_loop().stop()
Beispiel #5
0
        def read_properties(self,
                            target_address,
                            point_map,
                            max_per_request=None):
            """Read a set of points and return the results"""
            #This will be used to get the results mapped
            # back on the the names
            reverse_point_map = {}

            #Used to group properties together for the request.
            object_property_map = defaultdict(list)

            for name, properties in point_map.iteritems():
                object_type, instance_number, property_name = properties
                reverse_point_map[object_type, instance_number,
                                  property_name] = name

                object_property_map[object_type,
                                    instance_number].append(property_name)

            read_access_spec_list = []
            for obj_data, properties in object_property_map.iteritems():
                obj_type, obj_inst = obj_data
                prop_ref_list = []
                for prop in properties:
                    prop_ref = PropertyReference(propertyIdentifier=prop)
                    prop_ref_list.append(prop_ref)
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_ref_list)
                read_access_spec_list.append(read_access_spec)

            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list)
            request.pduDestination = Address(target_address)

            iocb = IOCB(request, self.async_call)
            self.this_application.submit_request(iocb)
            bacnet_results = iocb.ioResult.get(10)

            result_dict = {}

            for prop_tuple, value in bacnet_results.iteritems():
                name = reverse_point_map[prop_tuple]
                result_dict[name] = value

            return result_dict
Beispiel #6
0
    def build_rpm_request_from_dict(self, request_dict, vendor_id):
        """
        Read property multiple allow to read a lot of properties with only one request
        The existing RPM function is made using a string that must be created using bacpypes 
        console style and is hard to automate.

        This new version will be an attempt to improve that::

            _rpm = {'address': '11:2',
                'objects': {'analogInput:1': ['presentValue', 'description', 'unit', 'objectList@idx:0'],
                            'analogInput:2': ['presentValue', 'description', 'unit', 'objectList@idx:0'],
                },
                vendor_id: 842
                }

        """
        vendor_id = 842
        addr = request_dict["address"]
        objects = request_dict["objects"]
        if "vendor_id" in request_dict.keys():
            vendor_id = int(request_dict["vendor_id"])

        read_access_spec_list = []

        for obj, list_of_properties in objects.items():
            obj_type, obj_instance = obj.split(":")
            obj_type = validate_object_type(obj_type, vendor_id=vendor_id)
            obj_instance = int(obj_instance)
            property_reference_list = build_property_reference_list(
                obj_type, list_of_properties
            )
            read_acces_spec = build_read_access_spec(
                obj_type, obj_instance, property_reference_list
            )
            read_access_spec_list.append(read_acces_spec)

        if not read_access_spec_list:
            raise RuntimeError("at least one read access specification required")

        # build the request
        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=read_access_spec_list
        )
        request.pduDestination = Address(addr)

        return request
Beispiel #7
0
    def request_values(
        self,
        device_address_str: str,
        objects: Sequence[Tuple[Union[int, str], int]],
        chunk_size: Optional[int] = None,
        request_timeout: Optional[Timedelta] = None,
    ):
        device_address = Address(device_address_str)
        device_info: DeviceInfo = self.deviceInfoCache.get_device_info(
            device_address)

        # we adjusted chunking for object property request, which requested 3 properties per object
        # here we request only 1 property so scale
        chunk_scale = 3

        if not chunk_size:
            chunk_size = 20 * chunk_scale
            if device_info and device_info.segmentationSupported == "noSegmentation":
                chunk_size = 4 * chunk_scale

        logger.debug(
            f"Chunking for device {device_address_str} is {chunk_size}")

        for objects_chunk in chunks(objects, chunk_size):
            prop_reference_list = [
                PropertyReference(propertyIdentifier="presentValue")
            ]

            read_access_specs = [
                ReadAccessSpecification(
                    objectIdentifier=ObjectIdentifier(object_identifier),
                    listOfPropertyReferences=prop_reference_list,
                ) for object_identifier in objects_chunk
            ]

            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_specs)
            request.pduDestination = device_address

            iocb = IOCB(request)
            iocb.add_callback(self._iocb_callback)
            if request_timeout:
                iocb.set_timeout(request_timeout.s)

            deferred(self.request_io, iocb)
Beispiel #8
0
 def read_properties(self, target_address, point_map, max_per_request=None):
     """Read a set of points and return the results"""
     #This will be used to get the results mapped
     # back on the the names
     reverse_point_map = {}
     
     #Used to group properties together for the request.
     object_property_map = defaultdict(list)
     
     for name, properties in point_map.iteritems():
         object_type, instance_number, property_name = properties
         reverse_point_map[object_type,
                           instance_number,
                           property_name] = name
                           
         object_property_map[object_type,
                             instance_number].append(property_name)
                             
     read_access_spec_list = []
     for obj_data, properties in object_property_map.iteritems():
         obj_type, obj_inst = obj_data
         prop_ref_list = []
         for prop in properties:
             prop_ref = PropertyReference(propertyIdentifier=prop)
             prop_ref_list.append(prop_ref)
         read_access_spec = ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst),
                                                    listOfPropertyReferences=prop_ref_list)
         read_access_spec_list.append(read_access_spec)    
         
     request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list)
     request.pduDestination = Address(target_address)
     
     iocb = IOCB(request, self.async_call)
     self.this_application.submit_request(iocb)   
     bacnet_results = iocb.ioResult.get(10)
     
     result_dict={}
 
     for prop_tuple, value in bacnet_results.iteritems():
         name = reverse_point_map[prop_tuple]
         result_dict[name] = value        
     
     return result_dict
Beispiel #9
0
 def scrape_all(self):
     read_access_spec_list = []
     for obj_data, properties in self.object_property_map.iteritems():
         obj_type, obj_inst = obj_data
         prop_ref_list = []
         for prop in properties:
             prop_ref = PropertyReference(propertyIdentifier=prop)
             prop_ref_list.append(prop_ref)
         read_access_spec = ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst),
                                                    listOfPropertyReferences=prop_ref_list)
         read_access_spec_list.append(read_access_spec) 
         
     request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list)
     
     request.pduDestination = self.target_address
     iocb = IOCB(request)
     this_application.submit_request(iocb)
     
     iocb.ioDefered.addCallback(self.scrape_all_callback)
     return iocb.ioDefered
Beispiel #10
0
 def scrape_all(self):
     read_access_spec_list = []
     for obj_data, properties in self.object_property_map.iteritems():
         obj_type, obj_inst = obj_data
         prop_ref_list = []
         for prop in properties:
             prop_ref = PropertyReference(propertyIdentifier=prop)
             prop_ref_list.append(prop_ref)
         read_access_spec = ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst),
                                                    listOfPropertyReferences=prop_ref_list)
         read_access_spec_list.append(read_access_spec) 
         
     request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list)
     
     request.pduDestination = self.target_address
     iocb = IOCB(request)
     self.this_application.request(iocb)
     
     iocb.ioDefered.addCallback(self.scrape_all_callback)
     return iocb.ioDefered
Beispiel #11
0
async def read_prop_values(app, addr):
    read_access_specs = []
    for i in range(40):
        read_access_specs.append(
            ReadAccessSpecification(
                objectIdentifier=('analogInput', i),
                listOfPropertyReferences=[
                    PropertyReference(propertyIdentifier='presentValue')
                ],
            ))
    return await app.execute_request(
        ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_specs,
                                    destination=Address(addr)), )
Beispiel #12
0
    def _get_prop_for_obj(self, obj_id):

        props_to_get = ['objectName', 'description', 'presentValue', 'units']

        prop_ref_list = []

        for prop in props_to_get:
            ref = PropertyReference(propertyIdentifier=prop)
            prop_ref_list.append(ref)

        read_access_spec = ReadAccessSpecification(
            objectIdentifier=obj_id,
            listOfPropertyReferences=prop_ref_list,
        )

        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=[read_access_spec],
            destination=self.device.source)

        iocb = IOCB(request)
        iocb.add_callback(self._got_properties_for_object, obj_id)
        self.bacnet_adapter.request_io(iocb)
Beispiel #13
0
    def do_rpm(self, args):
        """
        rpm <devid> ( <objid> ( <prop> [ <indx> ] )... )...

        Send a Read-Property-Multiple request to a device identified by its
        device identifier.
        """
        args = args.split()
        if _debug: DiscoverConsoleCmd._debug("do_rpm %r", args)

        try:
            i = 0
            devid = int(args[i])
            if _debug: DiscoverConsoleCmd._debug("    - devid: %r", devid)
            i += 1

            # map the devid identifier to an address from the database
            addr = snapshot.get_value(devid, '-', 'address')
            if not addr:
                raise ValueError("unknown device")
            if _debug: DiscoverConsoleCmd._debug("    - addr: %r", addr)

            read_access_spec_list = []
            while i < len(args):
                obj_id = ObjectIdentifier(args[i]).value
                if _debug:
                    DiscoverConsoleCmd._debug("    - obj_id: %r", obj_id)
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if _debug:
                        DiscoverConsoleCmd._debug("    - prop_id: %r", prop_id)
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_id[0], prop_id)
                        if not datatype:
                            raise ValueError(
                                "invalid property for object type")

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id, )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=obj_id,
                    listOfPropertyReferences=prop_reference_list,
                )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError(
                    "at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list, )
            request.pduDestination = Address(addr)
            if _debug: DiscoverConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: DiscoverConsoleCmd._debug("    - iocb: %r", iocb)

            # give it to the application
            deferred(this_application.request_io, iocb)

            # wait for it to complete
            iocb.wait()

            # do something for success
            if iocb.ioResponse:
                apdu = iocb.ioResponse
                if _debug: DiscoverConsoleCmd._debug("    - apdu: %r", apdu)

                # should be an ack
                if not isinstance(apdu, ReadPropertyMultipleACK):
                    if _debug: DiscoverConsoleCmd._debug("    - not an ack")
                    return

                # loop through the results
                for result in apdu.listOfReadAccessResults:
                    # here is the object identifier
                    objectIdentifier = result.objectIdentifier
                    if _debug:
                        DiscoverConsoleCmd._debug("    - objectIdentifier: %r",
                                                  objectIdentifier)

                    # now come the property values per object
                    for element in result.listOfResults:
                        # get the property and array index
                        propertyIdentifier = element.propertyIdentifier
                        if _debug:
                            DiscoverConsoleCmd._debug(
                                "    - propertyIdentifier: %r",
                                propertyIdentifier)
                        propertyArrayIndex = element.propertyArrayIndex
                        if _debug:
                            DiscoverConsoleCmd._debug(
                                "    - propertyArrayIndex: %r",
                                propertyArrayIndex)

                        # here is the read result
                        readResult = element.readResult

                        property_label = str(propertyIdentifier)
                        if propertyArrayIndex is not None:
                            property_label += "[" + str(
                                propertyArrayIndex) + "]"

                        # check for an error
                        if readResult.propertyAccessError is not None:
                            if interactive:
                                print("{} ! {}".format(
                                    property_label,
                                    readResult.propertyAccessError))

                        else:
                            # here is the value
                            propertyValue = readResult.propertyValue

                            # find the datatype
                            datatype = get_datatype(objectIdentifier[0],
                                                    propertyIdentifier)
                            if _debug:
                                DiscoverConsoleCmd._debug(
                                    "    - datatype: %r", datatype)
                            if not datatype:
                                str_value = '?'
                            else:
                                # special case for array parts, others are managed by cast_out
                                if issubclass(datatype,
                                              Array) and (propertyArrayIndex
                                                          is not None):
                                    if propertyArrayIndex == 0:
                                        datatype = Unsigned
                                    else:
                                        datatype = datatype.subtype
                                    if _debug:
                                        DiscoverConsoleCmd._debug(
                                            "    - datatype: %r", datatype)

                                value = propertyValue.cast_out(datatype)
                                if _debug:
                                    DiscoverConsoleCmd._debug(
                                        "    - value: %r", value)

                                # convert the value to a string
                                if hasattr(value, 'dict_contents'):
                                    dict_contents = value.dict_contents(
                                        as_class=OrderedDict)
                                    str_value = json.dumps(dict_contents)
                                else:
                                    str_value = str(value)

                            if interactive:
                                print("{}: {}".format(property_label,
                                                      str_value))

                            # save it in the snapshot
                            snapshot.upsert(devid,
                                            '{}:{}'.format(*objectIdentifier),
                                            property_label, str_value)

            # do something for error/reject/abort
            if iocb.ioError:
                if interactive:
                    print(str(iocb.ioError))

        except Exception as error:
            DiscoverConsoleCmd._exception("exception: %r", error)
Beispiel #14
0
    def request_device_properties(
        self,
        device_address_str: str,
        properties=None,
        skip_when_cached=False,
        request_timeout: Optional[Timedelta] = None,
    ):
        if threading.current_thread() == threading.main_thread():
            logger.error(
                "request_device_properties called from main thread! Run it from an executor!",
                stack_info=True,
            )

        if properties is None:
            properties = ["objectName", "description"]

        device_address = Address(device_address_str)
        device_info: DeviceInfo = self.deviceInfoCache.get_device_info(
            device_address)

        if not device_info:
            for retry in range(self._retry_count):
                deferred(self.who_is, address=device_address)
                time.sleep(5 * (retry + 1))

                device_info: DeviceInfo = self.deviceInfoCache.get_device_info(
                    device_address)
                if device_info:
                    break
            else:
                device_info: DeviceInfo = self.deviceInfoCache.get_device_info(
                    device_address)

                if not device_info:
                    logger.error(
                        "Device with address {} is not in device cache!",
                        device_address_str,
                    )
                    return

        if skip_when_cached:
            cache_key = (device_address_str, "device",
                         device_info.deviceIdentifier)
            if cache_key in self._object_info_cache:
                cached_object_info = self._object_info_cache[cache_key]
                if all(property in cached_object_info
                       for property in properties):
                    logger.debug("Device info already in cache. Skipping!")
                    return

        prop_reference_list = [
            PropertyReference(propertyIdentifier=property)
            for property in properties
        ]

        device_object_identifier = ("device", device_info.deviceIdentifier)

        read_access_spec = ReadAccessSpecification(
            objectIdentifier=device_object_identifier,
            listOfPropertyReferences=prop_reference_list,
        )

        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=[read_access_spec])
        request.pduDestination = device_address

        iocb = IOCB(request)
        deferred(self.request_io, iocb)
        if request_timeout:
            iocb.set_timeout(request_timeout.s)

        iocb.wait()

        if iocb.ioResponse:
            result_values = self._unpack_iocb(iocb)
            if device_object_identifier in result_values:
                with self._object_info_cache_lock:
                    cache_key = (
                        device_address_str,
                        "device",
                        device_info.deviceIdentifier,
                    )
                    if cache_key not in self._object_info_cache:
                        self._object_info_cache[cache_key] = {}
                    self._object_info_cache[cache_key].update(
                        result_values[device_object_identifier])

            return result_values[device_object_identifier]

        # do something for error/reject/abort
        if iocb.ioError:
            logger.error(
                "IOCB returned with error for device properties request (device {}, objects {}, props {}) : {}",
                device_address_str,
                device_object_identifier,
                properties,
                iocb.ioError,
            )

        return None
Beispiel #15
0
    def read_properties(self, target_address, point_map, max_per_request=None):
        """Read a set of points and return the results"""

        # Set max_per_request really high if not set.
        if max_per_request is None:
            max_per_request = 1000000

        _log.debug(
            "Reading {count} points on {target}, max per scrape: {max}".format(
                count=len(point_map),
                target=target_address,
                max=max_per_request))

        # This will be used to get the results mapped
        # back on the the names
        reverse_point_map = {}

        # TODO Support rading an index of an Array.

        # Used to group properties together for the request.
        object_property_map = defaultdict(list)

        for name, properties in point_map.iteritems():
            object_type, instance_number, property_name = properties
            reverse_point_map[object_type, instance_number,
                              property_name] = name

            object_property_map[object_type,
                                instance_number].append(property_name)

        result_dict = {}
        finished = False

        while not finished:
            read_access_spec_list = []
            count = 0
            for _ in xrange(max_per_request):
                try:
                    obj_data, properties = object_property_map.popitem()
                except KeyError:
                    finished = True
                    break
                obj_type, obj_inst = obj_data
                prop_ref_list = []
                for prop in properties:
                    prop_ref = PropertyReference(propertyIdentifier=prop)
                    prop_ref_list.append(prop_ref)
                    count += 1
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_ref_list)
                read_access_spec_list.append(read_access_spec)

            if read_access_spec_list:
                _log.debug(
                    "Requesting {count} properties from {target}".format(
                        count=count, target=target_address))
                request = ReadPropertyMultipleRequest(
                    listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address(target_address)

                iocb = IOCB(request, self.async_call)
                self.this_application.submit_request(iocb)

                bacnet_results = iocb.ioResult.get(10)

                _log.debug("Received read response from {target}".format(
                    count=count, target=target_address))

                for prop_tuple, value in bacnet_results.iteritems():
                    name = reverse_point_map[prop_tuple]
                    result_dict[name] = value

        return result_dict
Beispiel #16
0
    def readMultiple(self, args):
        """ This function build a readMultiple request wait for the answer and 
        return the value
        
        :param args: String with <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...
        :returns: data read from device (str representing data like 10 or True)
        
        *Example*::
            
            import BAC0
            myIPAddr = '192.168.1.10'
            bacnet = BAC0.ReadWriteScript(localIPAddr = myIPAddr)          
            bacnet.readMultiple('2:5 analogInput 1 presentValue units')
        
        will read controller with a MAC address of 5 in the network 2
        Will ask for the present Value and the units of analog input 1 (AI:1)
        """        
        args = args.split()
        print_debug("readMultiple %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError("unknown object type")

                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError("invalid property for object type : %s | %s" % (obj_type, prop_id))

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id,
                        )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                    )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError("at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list,
                )
            request.pduDestination = Address(addr)
            print_debug("    - request: %r", request)

            # give it to the application
            self.this_application.request(request)

        except ReadPropertyMultipleException as error:
            ReadProperty._exception("exception: %r", error)

        data = None
        while True:
            try:
                data, evt = self.this_application.ResponseQueue.get(timeout=self._TIMEOUT)
                evt.set()
                return data
            except Empty:
                print('No response from controller')
                return None
Beispiel #17
0
    def do_read(self, args):
        """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )..."""
        args = args.split()
        if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError, "unknown object type"

                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError, "invalid property for object type"

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id, )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError, "provide at least one property"

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError, "at least one read access specification required"

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list, )
            request.pduDestination = Address(addr)
            if _debug:
                ReadPropertyMultipleConsoleCmd._debug("    - request: %r",
                                                      request)

            # give it to the application
            this_application.request(request)

        except Exception, e:
            ReadPropertyMultipleConsoleCmd._exception("exception: %r", e)
Beispiel #18
0
    def do_read(self, addr, properties):
        """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )..."""
        read_access_spec_list = []
        try:
            for obj_type, obj_inst, props in properties:
                if type(obj_type) is int:
                    pass
                elif obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError("unknown object type")

                prop_reference_list = []
                for prop_id, idx in props:
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError(
                                "invalid property for object type")

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id, )

                    # check for an array index
                    if idx is not None:
                        prop_reference.propertyArrayIndex = int(idx)

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")
                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                )
                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError(
                    "at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list, )
            request.pduDestination = Address(addr)
            if _debug: logger.debug("    - request: %r", request)
            self._request = request
            # make an IOCB
            iocb = IOCB(request)
            if _debug: logger.debug("    - iocb: %r", iocb)

            # give it to the application
            self.request_io(iocb)

            # do something for error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + '\n')

        except Exception as error:
            logger.debug("exception: %r", error)
def create_ReadPropertyMultipleRequest(args):
    """
    Create a request to compare with called arg
    """
    args = args.split()

    i = 0
    addr = args[i]
    i += 1

    read_access_spec_list = []
    while i < len(args):
        obj_type = args[i]
        i += 1

        if obj_type.isdigit():
            obj_type = int(obj_type)
        elif not get_object_class(obj_type):
            raise ValueError("unknown object type")

        obj_inst = int(args[i])
        i += 1

        prop_reference_list = []
        while i < len(args):
            prop_id = args[i]
            if prop_id not in PropertyIdentifier.enumerations:
                break

            i += 1
            if prop_id in ('all', 'required', 'optional'):
                pass
            else:
                datatype = get_datatype(obj_type, prop_id)
                if not datatype:
                    raise ValueError(
                        "invalid property for object type : %s | %s" %
                        (obj_type, prop_id))

            # build a property reference
            prop_reference = PropertyReference(
                propertyIdentifier=prop_id,
            )

            # check for an array index
            if (i < len(args)) and args[i].isdigit():
                prop_reference.propertyArrayIndex = int(args[i])
                i += 1

            # add it to the list
            prop_reference_list.append(prop_reference)

        # check for at least one property
        if not prop_reference_list:
            raise ValueError("provide at least one property")

        # build a read access specification
        read_access_spec = ReadAccessSpecification(
            objectIdentifier=(obj_type, obj_inst),
            listOfPropertyReferences=prop_reference_list,
        )

        # add it to the list
        read_access_spec_list.append(read_access_spec)

    # check for at least one
    if not read_access_spec_list:
        raise RuntimeError(
            "at least one read access specification required")

    # build the request
    request = ReadPropertyMultipleRequest(
        listOfReadAccessSpecs=read_access_spec_list,
    )
    request.pduDestination = Address(addr)
    return request
Beispiel #20
0
    def simpleread(self):
        try:
            reverse_point_map = {}
            result_dict = []
            read_access_spec_list = []
            count = 0
            prop_ref_list = []
            propertylist = ["units"]
            for prop in propertylist:
                prop_ref = PropertyReference(propertyIdentifier=prop)
                print("prop_ref: {} of property: {}", prop_ref, prop)
                print
                prop_ref_list.append(prop_ref)
                count += 1
                print("prop_ref_list:{} of property: {}", prop_ref_list, prop)
                print
            read_access_spec = ReadAccessSpecification(
                objectIdentifier=("analogOutput", 2),
                listOfPropertyReferences=prop_ref_list)

            read_access_spec_list.append(read_access_spec)
            print("read_access_spec_list is:{} of property: {}",
                  read_access_spec_list, read_access_spec)
            if read_access_spec_list:

                _log.debug(
                    "Requesting {count} properties from {target}".format(
                        count=count, target="2001:127"))
                print "what!!"
                request = ReadPropertyMultipleRequest(
                    listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address("2001:127")
                print "request addressed"
                iocb = IOCB(request, self.async_call)
                print "request made"
                self.simple = True
                self.this_application.submit_request(iocb)
                print "request sent"
                bacnet_results = tuple
                bacnet_results = (iocb.ioResult.get(35))
                print "request received"
                print bacnet_results
                print result_dict
                return result_dict
        except Exception as e:
            print e

        try:
            print "g"
            request = WhoIsRequest()
            address = list()
            deviceidentifier = list()
            request.pduDestination = GlobalBroadcast()
            self.this_application.request(request)
            thread = threading.Thread(target=10)
            thread.start()
            self.this_application.request(request)
            self.this_application.release = True
            self.this_application.update = False
            print "run started"
            #run()
            print "done"
            addresslist = self.this_application.found_address
            addresslist = list(set(addresslist))
            for a, b in addresslist:
                address.append(a)
                deviceidentifier.append(b)
            todelete = list()
            print address
            print deviceidentifier
            print "destination address list is ", address
            print "object instance of that address", deviceidentifier
            return address, deviceidentifier
        except Exception as e:
            _log.exception("an error has occurred: %s", e)
            return None
Beispiel #21
0
 def read_properties(self, target_address, point_map, max_per_request=None):
     """Read a set of points and return the results"""
     
     #Set max_per_request really high if not set.
     if max_per_request is None:
         max_per_request = 1000000
         
     _log.debug("Reading {count} points on {target}, max per scrape: {max}".format(count=len(point_map),
                                                                                   target=target_address,
                                                                                   max=max_per_request))
     
     #This will be used to get the results mapped
     # back on the the names
     reverse_point_map = {}
     
     #Used to group properties together for the request.
     object_property_map = defaultdict(list)
     
     for name, properties in point_map.iteritems():
         if len(properties) == 3:
             object_type, instance_number, property_name = properties
             property_index = None
         elif len(properties) == 4:
             object_type, instance_number, property_name, property_index = properties
         else:
             _log.error("skipping {} in request to {}: incorrect number of parameters".format(name, target_address))
         reverse_point_map[object_type,
                           instance_number,
                           property_name,
                           property_index] = name
                           
         object_property_map[object_type,
                             instance_number].append((property_name, property_index))
                             
     result_dict={}
     finished = False
                     
     while not finished:        
         read_access_spec_list = []
         count = 0
         for _ in xrange(max_per_request):
             try:
                 obj_data, properties = object_property_map.popitem()
             except KeyError:
                 finished = True
                 break
             obj_type, obj_inst = obj_data
             prop_ref_list = []
             for prop, prop_index in properties:
                 prop_ref = PropertyReference(propertyIdentifier=prop)
                 if prop_index is not None:
                     prop_ref.propertyArrayIndex = prop_index
                 prop_ref_list.append(prop_ref)
                 count += 1
             read_access_spec = ReadAccessSpecification(objectIdentifier=(obj_type, obj_inst),
                                                        listOfPropertyReferences=prop_ref_list)
             read_access_spec_list.append(read_access_spec)    
             
         if read_access_spec_list:
             _log.debug("Requesting {count} properties from {target}".format(count=count,
                                                                             target=target_address))
             request = ReadPropertyMultipleRequest(listOfReadAccessSpecs=read_access_spec_list)
             request.pduDestination = Address(target_address)
             
             iocb = self.iocb_class(request)
             self.this_application.submit_request(iocb)   
             bacnet_results = iocb.ioResult.get(10)
             
             _log.debug("Received read response from {target}".format(count=count,
                                                                      target=target_address))
         
             for prop_tuple, value in bacnet_results.iteritems():
                 name = reverse_point_map[prop_tuple]
                 result_dict[name] = value        
     
     return result_dict
Beispiel #22
0
    def request_object_properties(
        self,
        device_address_str: str,
        objects: Sequence[Tuple[Union[int, str], int]],
        properties=None,
        skip_when_cached=False,
        chunk_size: Optional[int] = None,
        request_timeout: Optional[Timedelta] = None,
    ):
        if threading.current_thread() == threading.main_thread():
            logger.error(
                "request_object_properties called from main thread! Run it from an executor!",
                stack_info=True,
            )

        if properties is None:
            properties = ["objectName", "description", "units"]

        device_address = Address(device_address_str)
        device_info: DeviceInfo = self.deviceInfoCache.get_device_info(
            device_address)

        if skip_when_cached:
            object_to_request = []
            for object_type, object_instance in objects:
                cache_key = (device_address_str, object_type, object_instance)
                if cache_key in self._object_info_cache:
                    cached_object_info = self._object_info_cache[cache_key]
                    if all(property in cached_object_info
                           for property in properties):
                        logger.debug(
                            "Object info for {} already in cache. Skipping!",
                            (object_type, object_instance),
                        )
                        continue

                object_to_request.append((object_type, object_instance))

            if not object_to_request:
                logger.debug("All objects already in cache")
                return

            objects = object_to_request

        result_values = {}

        if not chunk_size:
            chunk_size = 20
            if device_info and device_info.segmentationSupported == "noSegmentation":
                chunk_size = 4

        for objects_chunk in chunks(objects, chunk_size):
            prop_reference_list = [
                PropertyReference(propertyIdentifier=property)
                for property in properties
            ]

            read_access_specs = [
                ReadAccessSpecification(
                    objectIdentifier=ObjectIdentifier(object_identifier),
                    listOfPropertyReferences=prop_reference_list,
                ) for object_identifier in objects_chunk
            ]

            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_specs)
            request.pduDestination = device_address

            iocb = IOCB(request)
            deferred(self.request_io, iocb)
            if request_timeout:
                iocb.set_timeout(request_timeout.s)

            iocb.wait()

            if iocb.ioResponse:
                chunk_result_values = self._unpack_iocb(iocb)
                for object_identifier in chunk_result_values:
                    object_type, object_instance = object_identifier
                    with self._object_info_cache_lock:
                        cache_key = (device_address_str, object_type,
                                     object_instance)
                        if cache_key not in self._object_info_cache:
                            self._object_info_cache[cache_key] = {}
                        self._object_info_cache[cache_key].update(
                            chunk_result_values[object_identifier])

                result_values.update(chunk_result_values)

            # do something for error/reject/abort
            if iocb.ioError:
                logger.error(
                    "IOCB returned with error for object properties request (device {}, objects {}, props {}): {}",
                    device_address_str,
                    objects,
                    properties,
                    iocb.ioError,
                )
                # TODO: maybe raise error here

        return result_values
def create_ReadPropertyMultipleRequest(args):
    """
    Create a request to compare with called arg
    """
    args = args.split()

    i = 0
    addr = args[i]
    i += 1

    read_access_spec_list = []
    while i < len(args):
        obj_type = args[i]
        i += 1

        if obj_type.isdigit():
            obj_type = int(obj_type)
        elif not get_object_class(obj_type):
            raise ValueError("unknown object type")

        obj_inst = int(args[i])
        i += 1

        prop_reference_list = []
        while i < len(args):
            prop_id = args[i]
            if prop_id not in PropertyIdentifier.enumerations:
                break

            i += 1
            if prop_id in ('all', 'required', 'optional'):
                pass
            else:
                datatype = get_datatype(obj_type, prop_id)
                if not datatype:
                    raise ValueError(
                        "invalid property for object type : %s | %s" %
                        (obj_type, prop_id))

            # build a property reference
            prop_reference = PropertyReference(propertyIdentifier=prop_id, )

            # check for an array index
            if (i < len(args)) and args[i].isdigit():
                prop_reference.propertyArrayIndex = int(args[i])
                i += 1

            # add it to the list
            prop_reference_list.append(prop_reference)

        # check for at least one property
        if not prop_reference_list:
            raise ValueError("provide at least one property")

        # build a read access specification
        read_access_spec = ReadAccessSpecification(
            objectIdentifier=(obj_type, obj_inst),
            listOfPropertyReferences=prop_reference_list,
        )

        # add it to the list
        read_access_spec_list.append(read_access_spec)

    # check for at least one
    if not read_access_spec_list:
        raise RuntimeError("at least one read access specification required")

    # build the request
    request = ReadPropertyMultipleRequest(
        listOfReadAccessSpecs=read_access_spec_list, )
    request.pduDestination = Address(addr)
    return request
    def do_read(self, args):
        """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )..."""
        args = args.split()
        if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError, "unknown object type"
                
                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError, "invalid property for object type"

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id,
                        )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError, "provide at least one property"

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                    )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError, "at least one read access specification required"

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list,
                )
            request.pduDestination = Address(addr)
            if _debug: ReadPropertyMultipleConsoleCmd._debug("    - request: %r", request)

            # give it to the application
            this_application.request(request)

        except Exception, e:
            ReadPropertyMultipleConsoleCmd._exception("exception: %r", e)
Beispiel #25
0
    def build_rpm_request(self, args):
        """
        Build request from args
        """
        i = 0
        addr = args[i]
        i += 1

        read_access_spec_list = []
        while i < len(args):
            obj_type = args[i]
            i += 1

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif not get_object_class(obj_type):
                raise ValueError("unknown object type")

            obj_inst = int(args[i])
            i += 1

            prop_reference_list = []
            while i < len(args):
                prop_id = args[i]
                if prop_id not in PropertyIdentifier.enumerations:
                    break

                i += 1
                if prop_id in ("all", "required", "optional"):
                    pass
                else:
                    datatype = get_datatype(obj_type, prop_id)
                    if not datatype:
                        raise ValueError(
                            "invalid property for object type : {} | {}".format(
                                (obj_type, prop_id)
                            )
                        )

                # build a property reference
                prop_reference = PropertyReference(propertyIdentifier=prop_id)

                # check for an array index
                if (i < len(args)) and args[i].isdigit():
                    prop_reference.propertyArrayIndex = int(args[i])
                    i += 1

                prop_reference_list.append(prop_reference)

            if not prop_reference_list:
                raise ValueError("provide at least one property")

            # build a read access specification
            read_access_spec = ReadAccessSpecification(
                objectIdentifier=(obj_type, obj_inst),
                listOfPropertyReferences=prop_reference_list,
            )

            read_access_spec_list.append(read_access_spec)

        if not read_access_spec_list:
            raise RuntimeError("at least one read access specification required")

        # build the request
        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=read_access_spec_list
        )
        request.pduDestination = Address(addr)
        self._log.debug("{:<20} {!r}".format("REQUEST", request))
        return request
Beispiel #26
0
    def read_properties(self,
                        target_address,
                        point_map,
                        max_per_request=None,
                        use_read_multiple=True):
        """Read a set of points and return the results"""

        if not use_read_multiple:
            return self.read_using_single_request(target_address, point_map)

        #Set max_per_request really high if not set.
        if max_per_request is None:
            max_per_request = self._max_per_request

        _log.debug("Reading {count} points on {target}, max per"
                   " scrape: {max}".format(count=len(point_map),
                                           target=target_address,
                                           max=max_per_request))

        # This will be used to get the results mapped
        # back on the the names
        reverse_point_map = {}

        #Used to group properties together for the request.
        object_property_map = defaultdict(list)

        for name, properties in point_map.iteritems():
            if len(properties) == 3:
                object_type, instance_number, property_name = properties
                property_index = None
            elif len(properties) == 4:
                object_type, instance_number, property_name, property_index = properties
            else:
                _log.error(
                    "skipping {} in request to {}: incorrect number of parameters"
                    .format(name, target_address))
            reverse_point_map[object_type, instance_number, property_name,
                              property_index] = name

            object_property_map[object_type, instance_number].append(
                (property_name, property_index))

        result_dict = {}
        finished = False

        while not finished:
            read_access_spec_list = []
            count = 0
            for _ in xrange(max_per_request):
                try:
                    obj_data, properties = object_property_map.popitem()
                except KeyError:
                    finished = True
                    break
                obj_type, obj_inst = obj_data
                prop_ref_list = []
                for prop, prop_index in properties:
                    prop_ref = PropertyReference(propertyIdentifier=prop)
                    if prop_index is not None:
                        prop_ref.propertyArrayIndex = prop_index
                    prop_ref_list.append(prop_ref)
                    count += 1
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_ref_list)
                read_access_spec_list.append(read_access_spec)

            if read_access_spec_list:
                _log.debug(
                    "Requesting {count} properties from {target}".format(
                        count=count, target=target_address))
                request = ReadPropertyMultipleRequest(
                    listOfReadAccessSpecs=read_access_spec_list)
                request.pduDestination = Address(target_address)

                iocb = self.iocb_class(request)
                self.this_application.submit_request(iocb)
                bacnet_results = iocb.ioResult.get(10)

                _log.debug(
                    "Received read response from {target} count: {count}".
                    format(count=count, target=target_address))

                for prop_tuple, value in bacnet_results.iteritems():
                    name = reverse_point_map[prop_tuple]
                    result_dict[name] = value

        return result_dict
    def do_read(self, args):
        """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )..."""
        args = args.split()
        if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError("unknown object type")

                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError(
                                "invalid property for object type")

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id, )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError(
                    "at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list, )
            request.pduDestination = Address(addr)
            if _debug:
                ReadPropertyMultipleConsoleCmd._debug("    - request: %r",
                                                      request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug:
                ReadPropertyMultipleConsoleCmd._debug("    - iocb: %r", iocb)

            # give it to the application
            this_application.request_io(iocb)

            # wait for it to complete
            iocb.wait()

            # do something for success
            if iocb.ioResponse:
                apdu = iocb.ioResponse

                # should be an ack
                if not isinstance(apdu, ReadPropertyMultipleACK):
                    if _debug:
                        ReadPropertyMultipleConsoleCmd._debug(
                            "    - not an ack")
                    return

                # loop through the results
                for result in apdu.listOfReadAccessResults:
                    # here is the object identifier
                    objectIdentifier = result.objectIdentifier
                    if _debug:
                        ReadPropertyMultipleConsoleCmd._debug(
                            "    - objectIdentifier: %r", objectIdentifier)

                    # now come the property values per object
                    for element in result.listOfResults:
                        # get the property and array index
                        propertyIdentifier = element.propertyIdentifier
                        if _debug:
                            ReadPropertyMultipleConsoleCmd._debug(
                                "    - propertyIdentifier: %r",
                                propertyIdentifier)
                        propertyArrayIndex = element.propertyArrayIndex
                        if _debug:
                            ReadPropertyMultipleConsoleCmd._debug(
                                "    - propertyArrayIndex: %r",
                                propertyArrayIndex)

                        # here is the read result
                        readResult = element.readResult

                        sys.stdout.write(propertyIdentifier)
                        if propertyArrayIndex is not None:
                            sys.stdout.write("[" + str(propertyArrayIndex) +
                                             "]")

                        # check for an error
                        if readResult.propertyAccessError is not None:
                            sys.stdout.write(
                                " ! " + str(readResult.propertyAccessError) +
                                '\n')

                        else:
                            # here is the value
                            propertyValue = readResult.propertyValue

                            # find the datatype
                            datatype = get_datatype(objectIdentifier[0],
                                                    propertyIdentifier)
                            if _debug:
                                ReadPropertyMultipleConsoleCmd._debug(
                                    "    - datatype: %r", datatype)
                            if not datatype:
                                raise TypeError("unknown datatype")

                            # special case for array parts, others are managed by cast_out
                            if issubclass(datatype,
                                          Array) and (propertyArrayIndex
                                                      is not None):
                                if propertyArrayIndex == 0:
                                    value = propertyValue.cast_out(Unsigned)
                                else:
                                    value = propertyValue.cast_out(
                                        datatype.subtype)
                            else:
                                value = propertyValue.cast_out(datatype)
                            if _debug:
                                ReadPropertyMultipleConsoleCmd._debug(
                                    "    - value: %r", value)

                            sys.stdout.write(" = " + str(value) + '\n')
                        sys.stdout.flush()

            # do something for error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + '\n')

        except Exception, error:
            ReadPropertyMultipleConsoleCmd._exception("exception: %r", error)
Beispiel #28
0
    def readMultiple(self, args):
        """ This function build a readMultiple request wait for the answer and 
        return the value
        
        :param args: String with <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )...
        :returns: data read from device (str representing data like 10 or True)
        
        *Example*::
            
            import BAC0
            myIPAddr = '192.168.1.10'
            bacnet = BAC0.ReadWriteScript(localIPAddr = myIPAddr)          
            bacnet.readMultiple('2:5 analogInput 1 presentValue units')
        
        will read controller with a MAC address of 5 in the network 2
        Will ask for the present Value and the units of analog input 1 (AI:1)
        """
        args = args.split()
        print_debug("readMultiple %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError("unknown object type")

                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError(
                                "invalid property for object type : %s | %s" %
                                (obj_type, prop_id))

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id, )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError(
                    "at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list, )
            request.pduDestination = Address(addr)
            print_debug("    - request: %r", request)

            # give it to the application
            self.this_application.request(request)

        except ReadPropertyMultipleException as error:
            ReadProperty._exception("exception: %r", error)

        data = None
        while True:
            try:
                data, evt = self.this_application.ResponseQueue.get(
                    timeout=self._TIMEOUT)
                evt.set()
                return data
            except Empty:
                print('No response from controller')
                return None
Beispiel #29
0
    def build_rpm_request(self, args, vendor_id=0):
        """
        Build request from args
        """
        self._log.debug(args)
        i = 0
        addr = args[i]
        i += 1
        vendor_id = vendor_id

        read_access_spec_list = []
        while i < len(args):
            obj_type = args[i]
            i += 1

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif "@obj_" in obj_type:
                obj_type = int(obj_type.split("_")[1])
            elif not get_object_class(obj_type, vendor_id=vendor_id):
                raise ValueError("Unknown object type : {}".format(obj_type))

            obj_inst = int(args[i])
            i += 1

            prop_reference_list = []
            while i < len(args):
                prop_id = args[i]
                if "@obj_" in prop_id:
                    break
                if prop_id not in PropertyIdentifier.enumerations:
                    try:
                        if "@prop_" in prop_id:
                            prop_id = int(prop_id.split("_")[1])
                            self._log.debug(
                                "Proprietary property : {} | {} -> Vendor : {}"
                                .format(obj_type, prop_id, vendor_id))
                        else:
                            break
                    except:
                        break

                elif prop_id in (
                        "all",
                        "required",
                        "optional",
                        "objectName",
                        "objectType",
                        "objectIdentifier",
                        "polarity",
                ):
                    pass
                else:
                    datatype = get_datatype(obj_type,
                                            prop_id,
                                            vendor_id=vendor_id)
                    if not datatype:
                        raise ValueError(
                            "invalid property for object type : {} | {}".
                            format(obj_type, prop_id))
                i += 1

                # build a property reference
                prop_reference = PropertyReference(propertyIdentifier=prop_id)

                # check for an array index
                if (i < len(args)) and args[i].isdigit():
                    prop_reference.propertyArrayIndex = int(args[i])
                    i += 1

                prop_reference_list.append(prop_reference)

            if not prop_reference_list:
                raise ValueError("provide at least one property")

            # build a read access specification
            read_access_spec = ReadAccessSpecification(
                objectIdentifier=(obj_type, obj_inst),
                listOfPropertyReferences=prop_reference_list,
            )

            read_access_spec_list.append(read_access_spec)

        if not read_access_spec_list:
            raise RuntimeError(
                "at least one read access specification required")

        # build the request
        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=read_access_spec_list)
        request.pduDestination = Address(addr)
        return request
    def do_read(self, args):
        """read <addr> ( <type> <inst> ( <prop> [ <indx> ] )... )..."""
        args = args.split()
        if _debug: ReadPropertyMultipleConsoleCmd._debug("do_read %r", args)

        try:
            i = 0
            addr = args[i]
            i += 1

            read_access_spec_list = []
            while i < len(args):
                obj_type = args[i]
                i += 1

                if obj_type.isdigit():
                    obj_type = int(obj_type)
                elif not get_object_class(obj_type):
                    raise ValueError("unknown object type")

                obj_inst = int(args[i])
                i += 1

                prop_reference_list = []
                while i < len(args):
                    prop_id = args[i]
                    if prop_id not in PropertyIdentifier.enumerations:
                        break

                    i += 1
                    if prop_id in ('all', 'required', 'optional'):
                        pass
                    else:
                        datatype = get_datatype(obj_type, prop_id)
                        if not datatype:
                            raise ValueError("invalid property for object type")

                    # build a property reference
                    prop_reference = PropertyReference(
                        propertyIdentifier=prop_id,
                        )

                    # check for an array index
                    if (i < len(args)) and args[i].isdigit():
                        prop_reference.propertyArrayIndex = int(args[i])
                        i += 1

                    # add it to the list
                    prop_reference_list.append(prop_reference)

                # check for at least one property
                if not prop_reference_list:
                    raise ValueError("provide at least one property")

                # build a read access specification
                read_access_spec = ReadAccessSpecification(
                    objectIdentifier=(obj_type, obj_inst),
                    listOfPropertyReferences=prop_reference_list,
                    )

                # add it to the list
                read_access_spec_list.append(read_access_spec)

            # check for at least one
            if not read_access_spec_list:
                raise RuntimeError("at least one read access specification required")

            # build the request
            request = ReadPropertyMultipleRequest(
                listOfReadAccessSpecs=read_access_spec_list,
                )
            request.pduDestination = Address(addr)
            if _debug: ReadPropertyMultipleConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: ReadPropertyMultipleConsoleCmd._debug("    - iocb: %r", iocb)

            # give it to the application
            this_application.request_io(iocb)

            # wait for it to complete
            iocb.wait()

            # do something for success
            if iocb.ioResponse:
                apdu = iocb.ioResponse

                # should be an ack
                if not isinstance(apdu, ReadPropertyMultipleACK):
                    if _debug: ReadPropertyMultipleConsoleCmd._debug("    - not an ack")
                    return

                # loop through the results
                for result in apdu.listOfReadAccessResults:
                    # here is the object identifier
                    objectIdentifier = result.objectIdentifier
                    if _debug: ReadPropertyMultipleConsoleCmd._debug("    - objectIdentifier: %r", objectIdentifier)

                    # now come the property values per object
                    for element in result.listOfResults:
                        # get the property and array index
                        propertyIdentifier = element.propertyIdentifier
                        if _debug: ReadPropertyMultipleConsoleCmd._debug("    - propertyIdentifier: %r", propertyIdentifier)
                        propertyArrayIndex = element.propertyArrayIndex
                        if _debug: ReadPropertyMultipleConsoleCmd._debug("    - propertyArrayIndex: %r", propertyArrayIndex)

                        # here is the read result
                        readResult = element.readResult

                        sys.stdout.write(propertyIdentifier)
                        if propertyArrayIndex is not None:
                            sys.stdout.write("[" + str(propertyArrayIndex) + "]")

                        # check for an error
                        if readResult.propertyAccessError is not None:
                            sys.stdout.write(" ! " + str(readResult.propertyAccessError) + '\n')

                        else:
                            # here is the value
                            propertyValue = readResult.propertyValue

                            # find the datatype
                            datatype = get_datatype(objectIdentifier[0], propertyIdentifier)
                            if _debug: ReadPropertyMultipleConsoleCmd._debug("    - datatype: %r", datatype)
                            if not datatype:
                                raise TypeError("unknown datatype")

                            # special case for array parts, others are managed by cast_out
                            if issubclass(datatype, Array) and (propertyArrayIndex is not None):
                                if propertyArrayIndex == 0:
                                    value = propertyValue.cast_out(Unsigned)
                                else:
                                    value = propertyValue.cast_out(datatype.subtype)
                            else:
                                value = propertyValue.cast_out(datatype)
                            if _debug: ReadPropertyMultipleConsoleCmd._debug("    - value: %r", value)

                            sys.stdout.write(" = " + str(value) + '\n')
                        sys.stdout.flush()

            # do something for error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + '\n')

        except Exception as error:
            ReadPropertyMultipleConsoleCmd._exception("exception: %r", error)
Beispiel #31
0
    def build_rpm_request(self, args):
        """
        Build request from args
        """
        i = 0
        addr = args[i]
        i += 1

        read_access_spec_list = []
        while i < len(args):
            obj_type = args[i]
            i += 1

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif not get_object_class(obj_type):
                raise ValueError("unknown object type")

            obj_inst = int(args[i])
            i += 1

            prop_reference_list = []
            while i < len(args):
                prop_id = args[i]
                if prop_id not in PropertyIdentifier.enumerations:
                    break

                i += 1
                if prop_id in ('all', 'required', 'optional'):
                    pass
                else:
                    datatype = get_datatype(obj_type, prop_id)
                    if not datatype:
                        raise ValueError(
                            "invalid property for object type : {} | {}".format(
                                (obj_type, prop_id)))

                # build a property reference
                prop_reference = PropertyReference(propertyIdentifier=prop_id)

                # check for an array index
                if (i < len(args)) and args[i].isdigit():
                    prop_reference.propertyArrayIndex = int(args[i])
                    i += 1

                prop_reference_list.append(prop_reference)

            if not prop_reference_list:
                raise ValueError("provide at least one property")

            # build a read access specification
            read_access_spec = ReadAccessSpecification(
                objectIdentifier=(obj_type, obj_inst),
                listOfPropertyReferences=prop_reference_list)

            read_access_spec_list.append(read_access_spec)

        if not read_access_spec_list:
            raise RuntimeError(
                "at least one read access specification required")

        # build the request
        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=read_access_spec_list)
        request.pduDestination = Address(addr)
        self._log.debug("{:<20} {!r}".format(
            'REQUEST', request))
        return request
Beispiel #32
0
    def _form_ReadPropertyMultiple_request(self, args, body_json):
        """
        Example Read
        http://localhost/read/adderss/analogValue:1
        http://localhost/read/<address>/<object type>:<object instance number>
        http://localhost/read/<address>/<object type>:<object instance number>/<property>
        http://localhost:8081/read/192.168.1.100/analogValue:0/presentValue

        Example WhoIs
        http://localhost/whois/<address>

        Example ReadPropertyMultiple
        http://localhost:8081/readpropertymultiple/<address>/

        body_json = {'address':'192.168.1.100',
                'bacnet_objects': [{'object': 'analogValue:1',
                                    'property': 'presentValue'},
                                   {'object': 'analogValue:2',
                                    'property': 'presentValue'},
                                   {'object': 'analogValue:3',
                                    'property': 'presentValue'}]}
        """
        # Error check request
        if body_json['bacnet_objects'].__len__() == 0:
            # No objects defined in list
            msg = ('No BACnet object specifiers were passed. '+
                   'Must include specifiers like {"object":"analogValue:1",' +
                   '"property":"presentValue"}'
                   )
            if _debug:
                HTTPRequestHandler._debug("    - body_json: %r", msg)
            self.send_header('Content-Type','text/plain')
            self.end_headers()
            self.wfile.write(bytes(msg, 'utf-8'))
            raise ValueError(msg)

        if not 'bacnet_objects' in body_json.keys():
            # Improperty structured JSON request
            msg = ('Bad request format. "bacnet_objects" must be a key '+
                   'in the request body JSON oject. Got {}'.format(str(body_json.keys()))
                   )
            if _debug:
                HTTPRequestHandler._debug("    - body_json: %r", msg)
            self.send_header('Content-Type','text/plain')
            self.end_headers()
            self.wfile.write(bytes(msg, 'utf-8'))
            raise ValueError(msg)

        # Build Read Access Spec List
        read_access_spec_list = []
        """Formatted like
        results = {'analogValue:1' : {'presentValue':'1',
                                      'objectName':'some_name',
                                      'arrayResult':[1,2,3]},
                   'analogValue:2' : {'presentValue':'4'}
                   }"""

        for bacnet_object in body_json['bacnet_objects']:

            # Property reference list (for EACH object being requested)
            prop_reference_list = []
            try:
                # What is the object identifier?
                obj_id = ObjectIdentifier(bacnet_object['object']).value
                # Get the object type
                if not get_object_class(obj_id[0]):
                    # The passed value is not a valid BACnet object type
                    msg = ('The requested Object Identifier is not a valid BACnet '+
                           'object type. Got {}'.format(str(obj_id))
                           )
                    if _debug:
                        HTTPRequestHandler._debug("    - obj_id: %r", msg)
                    self.send_header('Content-Type','text/plain')
                    self.end_headers()
                    self.wfile.write(bytes(msg, 'utf-8'))
                    raise ValueError(msg)
            except ValueError:
                # The passed value is not a valid BACnet object type
                msg = ('The requested Object Identifier is not a valid BACnet '+
                       'object type. Got {}'.format(str(obj_id))
                       )
                if _debug:
                    HTTPRequestHandler._debug("    - objectID: %r", msg)
                self.send_header('Content-Type','text/plain')
                self.end_headers()
                self.wfile.write(bytes(msg, 'utf-8'))
                raise ValueError(msg)

            # Property ID
            prop_id = bacnet_object['property']
            if prop_id not in PropertyIdentifier.enumerations:
                # Invalid property identifier - usually 'presentValue' or 'all'
                msg = ('Invalid BACnet property. Valid propery must be one of '+
                       '{}'.format(str(PropertyIdentifier.enumerations.keys()))
                       )
                if _debug:
                    HTTPRequestHandler._debug("    - bac property: %r", msg)
                self.send_header('Content-Type','text/plain')
                self.end_headers()
                self.wfile.write(bytes(msg, 'utf-8'))
                raise ValueError(msg)

            # Object datatype
            datatype = get_datatype(obj_id[0], prop_id)
            if (datatype is None) and (prop_id != 'all'):
                # For converting between BACnet data types and pyton types
                msg = ('Invalid combination of BACnet object type and property ID '+
                       'Got {}, {}'.format(str(obj_id), str(prop_id))
                       )
                if _debug:
                    HTTPRequestHandler._debug("    - datatype: %r", msg)
                self.send_header('Content-Type','text/plain')
                self.end_headers()
                self.wfile.write(bytes(msg, 'utf-8'))
                raise ValueError(msg)

            # Build property reference
            # Not sure what this is - check ASHRAE standard lol
            prop_reference = PropertyReference(propertyIdentifier=prop_id)
            # Array index for BACnet objects with multiple values
            # Array index not supported for this API - just get the whole array
            prop_reference_list.append(prop_reference)

            # Build read access specification
            read_access_spec = ReadAccessSpecification(
                objectIdentifier=obj_id,
                listOfPropertyReferences=prop_reference_list
                )
            read_access_spec_list.append(read_access_spec)

        # Build request
        request = ReadPropertyMultipleRequest(
            listOfReadAccessSpecs=read_access_spec_list,
            )
        request.pduDestination = Address(body_json['address'])
        return request