Beispiel #1
0
    def send_subscription(self, context):
        if _debug: SubscribeCOVApplication._debug("send_subscription %r", context)

        # build a request
        request = SubscribeCOVRequest(
            subscriberProcessIdentifier=context.subscriberProcessIdentifier,
            monitoredObjectIdentifier=context.monitoredObjectIdentifier,
            )
        request.pduDestination = context.address

        # optional parameters
        if context.issueConfirmedNotifications is not None:
            request.issueConfirmedNotifications = context.issueConfirmedNotifications
        if context.lifetime is not None:
            request.lifetime = context.lifetime

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

        # callback when it is acknowledged
        iocb.add_callback(self.subscription_acknowledged)

        # give it to the application
        this_application.request_io(iocb)
Beispiel #2
0
    def read_object_list(self, device_id, device_addr):
        if _debug:
            ReadAllObjectPropertiesApplication._debug("read_object_list %r %r",
                                                      device_id, device_addr)

        # create a context to hold the results
        context = ObjectPropertyContext(device_id, device_addr)

        # build a request for the object name
        request = ReadPropertyRequest(
            destination=context.device_addr,
            objectIdentifier=context.device_id,
            propertyIdentifier='objectList',
        )
        if _debug:
            ReadAllObjectPropertiesApplication._debug("    - request: %r",
                                                      request)

        # make an IOCB, reference the context
        iocb = IOCB(request)
        iocb.context = context
        if _debug:
            ReadAllObjectPropertiesApplication._debug("    - iocb: %r", iocb)

        # let us know when its complete
        iocb.add_callback(self.object_list_results)

        # give it to the application
        self.request_io(iocb)
Beispiel #3
0
    def next_request(self):
        if _debug: ReadPropertyApplication._debug("next_request")
        global device_address, object_identifier, property_list

        # check to see if we're done
        if not property_list:
            if _debug: ReadPropertyApplication._debug("    - done")
            stop()
            return

        # get the next request
        self.property_identifier = property_list.popleft()
        if _debug:
            ReadPropertyApplication._debug("    - property_identifier: %r",
                                           self.property_identifier)

        # build a request
        request = ReadPropertyRequest(
            destination=device_address,
            objectIdentifier=object_identifier,
            propertyIdentifier=self.property_identifier,
        )
        if _debug: ReadPropertyApplication._debug("    - request: %r", request)

        # make an IOCB
        iocb = IOCB(request)

        # set a callback for the response
        iocb.add_callback(self.complete_request)
        if _debug: ReadPropertyApplication._debug("    - iocb: %r", iocb)

        # send the request
        this_application.request_io(iocb)
Beispiel #4
0
    def _discovery(self):
        global device_address

        # build a request
        obj_type, prop_id = ('device', 'objectList')

        # build a request
        request = ReadPropertyRequest(
            objectIdentifier=(obj_type, self._device_id),
            propertyIdentifier=prop_id,
        )
        request.pduSource = Address(this_device._address)
        request.pduDestination = Address(int(self._addr))
        request.propertyArrayIndex = self._instance_list.pop(0)

        if _debug:
            BacnetClientConsoleCmd._debug("    - request: %r", request)

        # make an IOCB
        iocb = IOCB(request)

        # set a callback for the response
        iocb.add_callback(self._discovery_response)
        if _debug:
            BacnetClientConsoleCmd._debug("    - iocb: %r", iocb)

        # send the request
        this_application.request_io(iocb)
Beispiel #5
0
    def iam(self, destination=None):
        """
        Build an IAm response.  IAm are sent in response to a WhoIs request that;
        matches our device ID, whose device range includes us, or is a broadcast.
        Content is defined by the script (deviceId, vendor, etc...)

        :returns: bool

        Example::

            iam()
        """

        self._log.debug("do_iam")

        try:
            # build a response
            request = self._iam_request(destination=destination)
            iocb = IOCB(request)  # make an IOCB
            deferred(self.this_application.request_io, iocb)
            iocb.wait()
            return True

        except Exception as error:
            self._log.error("exception: {!r}".format(error))
            return False
Beispiel #6
0
    def next_request(self):
        if _debug: ReadPointListApplication._debug("next_request")

        # check to see if we're done
        if not self.point_queue:
            if _debug: ReadPointListApplication._debug("    - done")
            stop()
            return

        # get the next request
        addr, obj_type, obj_inst, prop_id = self.point_queue.popleft()

        # build a request
        request = ReadPropertyRequest(
            objectIdentifier=(obj_type, obj_inst),
            propertyIdentifier=prop_id,
        )
        request.pduDestination = Address(addr)
        if _debug:
            ReadPointListApplication._debug("    - request: %r", request)

        # make an IOCB
        iocb = IOCB(request)

        # set a callback for the response
        iocb.add_callback(self.complete_request)
        if _debug: ReadPointListApplication._debug("    - iocb: %r", iocb)

        # send the request
        this_application.request_io(iocb)
    def next_request(self):

        # check to see if we're done
        if not self.point_queue:
            stop()
            return

        # get the next request
        point_id, addr, obj_type, obj_inst, prop_id, idx = self.point_queue.popleft()

        # build a request
        request = ReadPropertyRequest(
            objectIdentifier=(obj_type, obj_inst),
            propertyIdentifier=prop_id,
            propertyArrayIndex=idx
            )
        request.pduDestination = Address(addr)

        # make an IOCB
        iocb = IOCB(request)

        # set a callback for the response
        iocb.add_callback(self.complete_request)

        # send the request
        self.request_io(iocb)
 def _get_value_for_prop(self, prop):
     request = ReadPropertyRequest(destination=self.device.source,
                                   objectIdentifier=self.object,
                                   propertyIdentifier=prop)
     iocb = IOCB(request)
     iocb.add_callback(self._got_prop, prop)
     self.bacnet_adapter.request_io(iocb)
    def next_request(self):
        if _debug: ReadPointListApplication._debug("next_request")

        # check to see if we're done
        if not self.point_queue:
            if _debug: ReadPointListApplication._debug("    - done")
            stop()
            return

        # get the next request
        addr, obj_type, obj_inst, prop_id = self.point_queue.popleft()

        # build a request
        request = ReadPropertyRequest(
            objectIdentifier=(obj_type, obj_inst),
            propertyIdentifier=prop_id,
            )
        request.pduDestination = Address(addr)
        if _debug: ReadPointListApplication._debug("    - request: %r", request)

        # make an IOCB
        iocb = IOCB(request)

        # set a callback for the response
        iocb.add_callback(self.complete_request)
        if _debug: ReadPointListApplication._debug("    - iocb: %r", iocb)

        # send the request
        this_application.request_io(iocb)
Beispiel #10
0
    def read_next_object(self, context):
        if _debug:
            ReadObjectListApplication._debug("read_next_object %r", context)

        # if there's nothing more to do, we're done
        if not context._object_list_queue:
            if _debug: ReadObjectListApplication._debug("    - all done")
            context.completed()
            return

        # pop off the next object identifier
        object_id = context._object_list_queue.popleft()
        if _debug:
            ReadObjectListApplication._debug("    - object_id: %r", object_id)

        # build a request for the object name
        request = ReadPropertyRequest(
            destination=context.device_addr,
            objectIdentifier=object_id,
            propertyIdentifier='objectName',
        )
        if _debug:
            ReadObjectListApplication._debug("    - request: %r", request)

        # make an IOCB, reference the context
        iocb = IOCB(request)
        iocb.context = context
        if _debug: ReadObjectListApplication._debug("    - iocb: %r", iocb)

        # let us know when its complete
        iocb.add_callback(self.object_name_results)

        # give it to the application
        self.request_io(iocb)
Beispiel #11
0
    def do_request(self):
        if _debug:
            ReadPointListApplication._debug('do_request')

        request = SubscribeCOVRequest(subscriberProcessIdentifier=1234,
                                      monitoredObjectIdentifier=('analogInput',
                                                                 0),
                                      issueConfirmedNotifications=False,
                                      lifetime=100)
        request.pduDestination = Address('192.168.2.70')
        if _debug:
            ReadPointListApplication._debug('    - request: %r', request)
        # make an IOCB
        iocb = IOCB(request)
        # set a callback for the response
        # iocb.add_callback(self.complete_request)
        if _debug:
            ReadPointListApplication._debug("    - iocb: %r", iocb)
        # send the request
        this_application.request_io(iocb)
        iocb.wait()
        # do something for success
        if iocb.ioResponse:
            if _debug:
                ReadPointListApplication._debug("    - response: %r",
                                                iocb.ioResponse)

        # do something for error/reject/abort
        if iocb.ioError:
            if _debug:
                ReadPointListApplication._debug("    - error: %r",
                                                iocb.ioError)
Beispiel #12
0
 def _get_device_info(self):
     request = ReadPropertyRequest(destination=self.source,
                                   objectIdentifier=self.id,
                                   propertyIdentifier='objectName')
     iocb = IOCB(request)
     iocb.add_callback(self._got_object_name)
     self.bacnet_adapter.request_io(iocb)
 def _get_new_sensors_for_new_device(self, source, device_id):
     request = ReadPropertyRequest(destination=source,
                                   objectIdentifier=device_id,
                                   propertyIdentifier="objectList")
     iocb = IOCB(request)
     iocb.add_callback(self._got_sensors_for_device)
     self.bacnet_adapter.request_io(iocb)
Beispiel #14
0
    def do_save(self, args):
        """save <addr> <device instance>"""
        args = args.split()
        if _debug: SaveToFlashConsoleCmd._debug("do_save %r", args)

        try:
            addr, obj_inst = args[:2]

            # object type = 8 (device). property = 1151 (SaveToFlash)
            obj_type = 8
            obj_inst = int(obj_inst)
            prop_id = 1151

            # build a request
            request = WritePropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
            )
            request.pduDestination = Address(addr)

            if len(args) == 5:
                request.propertyArrayIndex = int(args[4])

            # send an Enumerated value of 1 means SaveToFlash
            tag_list = TagList([ApplicationTag(9, xtob('01'))])
            if _debug:
                SaveToFlashConsoleCmd._debug("    - tag_list: %r", tag_list)

            # stuff the tag list into an Any
            request.propertyValue = Any()
            request.propertyValue.decode(tag_list)

            if _debug:
                SaveToFlashConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: SaveToFlashConsoleCmd._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:
                # should be an ack
                if not isinstance(iocb.ioResponse, SimpleAckPDU):
                    if _debug: SaveToFlashConsoleCmd._debug("    - not an ack")
                    return

                sys.stdout.write("ack\n")

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

        except Exception as error:
            SaveToFlashConsoleCmd._exception("exception: %r", error)
Beispiel #15
0
    def __init__(self, *args):
        BIPSimpleApplication.__init__(Mock())
        self.elementService = Mock()
        #self.ResponseQueue = Mock()
        #self.ResponseQueue.get.return_value = ([21, 'degreesCelcius'], Event())
        iocb = IOCB()
        apdu = ReadPropertyMultipleACK(listOfReadAccessResults=[
            ReadAccessResult(
                objectIdentifier=('analogValue', 1),
                listOfResults=[
                    ReadAccessResultElement(
                        propertyIdentifier='presentValue',
                        readResult=ReadAccessResultElementChoice(
                            propertyValue=Any(Real(21.0)), )),
                    ReadAccessResultElement(
                        propertyIdentifier='units',
                        readResult=ReadAccessResultElementChoice(
                            propertyValue=Any(Enumerated(62)), )),
                ],
            )
        ])

        iocb.complete(apdu)
        self.request = Mock()
        self.request.return_value = iocb
Beispiel #16
0
 def _get_prop_for_obj(self, obj_id):
     request = ReadPropertyRequest(destination=self.device.source,
                                   objectIdentifier=obj_id,
                                   propertyIdentifier='propertyList')
     iocb = IOCB(request)
     iocb.add_callback(self._got_properties_for_object, obj_id)
     self.bacnet_adapter.request_io(iocb)
Beispiel #17
0
    def read_prop_vendor(self):
        #get bacnet source pdu from point_list array. point_list has been override by next_request method
        addr = point_list[0][0]

        obj_type = self.obj
        obj_inst = self.inst
        prop_id = self.prop

        # build a request
        request = ReadPropertyRequest(
            objectIdentifier=(obj_type, obj_inst),
            propertyIdentifier=int(prop_id),
        )
        request.pduDestination = Address(addr)

        request.propertyArrayIndex = self.idx
        #if _debug: ReadPropertyAnyConsoleCmd._debug("    - request: %r", request)

        # make an IOCB
        iocb = IOCB(request)

        #if _debug: ReadPropertyAnyConsoleCmd._debug("    - iocb: %r", iocb)

        # set a callback for the response
        iocb.add_callback(self.prop_vendor_ack)

        # give it to the application
        this_application.request_io(iocb)
Beispiel #18
0
    def whois(self, *args, global_broadcast=False):
        """
        Build a WhoIs request

        :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional**
        :returns: discoveredDevices as a defaultdict(int)

        Example::

            whois(global_broadcast=True) # WhoIs broadcast globally.  Every device will respond with an IAm
            whois('2:5')                 # WhoIs looking for the device at (Network 2, Address 5)
            whois('10 1000')             # WhoIs looking for devices in the ID range (10 - 1000)

        """
        if not self._started:
            raise ApplicationNotStarted(
                "BACnet stack not running - use startApp()")

        if args:
            args = args[0].split()
        msg = args if args else "any"

        self._log.debug("do_whois {!r}".format(msg))

        # build a request
        request = WhoIsRequest()
        if (len(args) == 1) or (len(args) == 3):
            request.pduDestination = Address(args[0])
            del args[0]
        else:
            if global_broadcast:
                request.pduDestination = GlobalBroadcast()
            else:
                request.pduDestination = LocalBroadcast()

        if len(args) == 2:
            try:
                request.deviceInstanceRangeLowLimit = int(args[0])
                request.deviceInstanceRangeHighLimit = int(args[1])
            except ValueError:
                pass
        self._log.debug("{:>12} {}".format("- request:", request))

        iocb = IOCB(request)  # make an IOCB
        self.this_application._last_i_am_received = []
        # pass to the BACnet stack
        deferred(self.this_application.request_io, iocb)

        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

        if iocb.ioError:  # unsuccessful: error/reject/abort
            pass

        time.sleep(3)
        self.discoveredDevices = self.this_application.i_am_counter
        return self.this_application._last_i_am_received
Beispiel #19
0
    def get_object_list(self):
        request = ReadPropertyRequest(destination=self.source,
                                      objectIdentifier=self.id,
                                      propertyIdentifier="objectList")

        iocb = IOCB(request)
        iocb.add_callback(self._got_object_list)
        self.bacnet_adapter.request_io(iocb)
Beispiel #20
0
    def prepare(self):
        if _debug: SomethingToDo._debug("prepare(%d)", self.args[0])

        # build an IOCB and add the completion callback
        iocb = IOCB(*self.args, **self.kwargs)
        iocb.add_callback(self.complete)
        if _debug: SomethingToDo._debug("    - iocb: %r", iocb)

        return iocb
Beispiel #21
0
    def do_saverl(self, args):
        """saverl <addr> <inst>"""
        args = args.split()
        if _debug: EventNotificationConsoleCmd._debug("do_saverl %r", args)
        global saved_recipent_list

        try:
            addr, obj_inst = args
            obj_inst = int(obj_inst)

            # build a request
            request = ReadPropertyRequest(
                objectIdentifier=('notificationClass', obj_inst),
                propertyIdentifier='recipientList',
            )
            request.pduDestination = Address(addr)

            # make an IOCB
            iocb = IOCB(request)
            if _debug:
                EventNotificationConsoleCmd._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 error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + '\n')

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

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

                # turn the property tag list blob into a list of destinations
                saved_recipent_list = apdu.propertyValue.cast_out(
                    ListOfDestination)

                for destination in saved_recipent_list:
                    destination.debug_contents(file=sys.stdout)

            # do something with nothing?
            else:
                if _debug:
                    EventNotificationConsoleCmd._debug(
                        "    - ioError or ioResponse expected")

        except Exception as error:
            EventNotificationConsoleCmd._exception("exception: %r", error)
Beispiel #22
0
    def run(self):
        if _debug: ReadPointListThread._debug("run")
        global this_application

        # loop through the points
        for obj_id, prop_id in self.point_list:
            obj_id = ObjectIdentifier(obj_id).value

            # build a request
            request = ReadPropertyRequest(
                destination=self.device_address,
                objectIdentifier=obj_id,
                propertyIdentifier=prop_id,
            )
            if _debug: ReadPointListThread._debug("    - request: %r", request)

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

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

            # wait for the response
            iocb.wait()

            if iocb.ioResponse:
                apdu = iocb.ioResponse

                # find the datatype
                datatype = get_datatype(apdu.objectIdentifier[0],
                                        apdu.propertyIdentifier)
                if _debug:
                    ReadPointListThread._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 (apdu.propertyArrayIndex
                                                    is not None):
                    if apdu.propertyArrayIndex == 0:
                        value = apdu.propertyValue.cast_out(Unsigned)
                    else:
                        value = apdu.propertyValue.cast_out(datatype.subtype)
                else:
                    value = apdu.propertyValue.cast_out(datatype)
                if _debug: ReadPointListThread._debug("    - value: %r", value)

                # save the value
                self.response_values.append(value)

            if iocb.ioError:
                if _debug:
                    ReadPointListThread._debug("    - error: %r", iocb.ioError)
                self.response_values.append(iocb.ioError)

        if _debug: ReadPointListThread._debug("    - fini")
Beispiel #23
0
    def send_cov_subscription(self, request):
        self._log.debug("Request : {}".format(request))
        iocb = IOCB(request)
        self._log.debug("IOCB : {}".format(iocb))

        iocb.add_callback(self.subscription_acknowledged)

        # pass to the BACnet stack
        deferred(self.this_application.request_io, iocb)
Beispiel #24
0
    def do_dcc(self, args):
        """dcc <addr> [ <duration> ] <enable> [ <password> ]"""
        args = args.split()
        if _debug: DCCConsoleCmd._debug("do_dcc %r", args)

        try:
            addr = args[0]

            if len(args) == 2:
                enable_disable = args[1]
                time_duration = password = None

            elif len(args) == 3:
                if args[1].isdigit():
                    time_duration = int(args[1])
                    enable_disable = args[2]
                    password = None
                else:
                    time_duration = None
                    enable_disable = args[1]
                    password = args[2]
            else:
                time_duration = int(args[1])
                enable_disable = args[2]
                password = args[3]

            # build a request
            request = DeviceCommunicationControlRequest(
                enableDisable=enable_disable,
                )
            request.pduDestination = Address(addr)

            if time_duration is not None:
                request.timeDuration = time_duration
            if password is not None:
                request.password = password
            if _debug: DCCConsoleCmd._debug("    - request: %r", request)

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

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

            # wait for it to complete
            iocb.wait()

            # do something for error/reject/abort
            if iocb.ioError:
                sys.stdout.write(str(iocb.ioError) + '\n')
            else:
                if _debug: DCCConsoleCmd._debug("    - ack")

        except Exception as error:
            DCCConsoleCmd._exception("exception: %r", error)
Beispiel #25
0
def main():
    # parse the command line arguments
    args = ArgumentParser(description=__doc__).parse_args()

    if _debug: _log.debug("initialization")
    if _debug: _log.debug("    - args: %r", args)

    # create a controller
    some_controller = SomeController()
    if _debug: _log.debug("    - some_controller: %r", some_controller)

    # test set
    tests = [
        ((
            1,
            2,
        ), {
            'a': 3
        }),
        ((
            4,
            5,
        ), {}),
        ((6, ), {
            'a': 7
        }),
    ]

    for test_args, test_kwargs in tests:
        print("test_args, test_kwargs: %r, %r" % (test_args, test_kwargs))

        # create a request with some args and kwargs
        iocb = IOCB(*test_args, **test_kwargs)

        # add a callback function , called when the request has been processed
        iocb.add_callback(call_me)

        # give the request to the controller
        some_controller.request_io(iocb)

        # wait for the request to be processed
        iocb.ioComplete.wait()
        if _debug: _log.debug("    - iocb: %r", iocb)

        # dump the contents
        print("iocb completion event set: %r" % (iocb.ioComplete.is_set(), ))
        print("")

        print("iocb successful: %r" % (iocb.ioState == COMPLETED, ))
        print("iocb response: %r" % (iocb.ioResponse, ))
        print("")

        print("iocb aborted: %r" % (iocb.ioState == ABORTED, ))
        print("iocb error: %r" % (iocb.ioError, ))
        print("")
Beispiel #26
0
    def read_next_object_properties(self, context):
        if _debug:
            ReadAllObjectPropertiesApplication._debug("read_next_object %r",
                                                      context)

        # if there's nothing more to do, we're done

        if all([
                len(context.properties_dict_queue[element]) == 0
                for element in context.properties_dict_queue
        ]):
            if _debug:
                ReadAllObjectPropertiesApplication._debug("    - all done")
            context.completed()
            return

        # pop off the next object identifier
        if context.current_object_id is None or len(
                context.properties_dict_queue[context.current_object_id]) == 0:
            context.current_object_id = context._object_list_queue.popleft()
            context.property_result_dict.update({
                context.current_object_id[0] + str(context.current_object_id[1]):
                dict()
            })

        context.current_property = context.properties_dict_queue[
            context.current_object_id].popleft()

        if _debug:
            ReadAllObjectPropertiesApplication._debug(
                "    - object_id: %r", context.current_object_id)

        # build a request for the object name
        request = ReadPropertyRequest(
            destination=context.device_addr,
            objectIdentifier=context.current_object_id,
            propertyIdentifier=context.current_property[0],
        )
        if _debug:
            ReadAllObjectPropertiesApplication._debug("    - request: %r",
                                                      request)

        # make an IOCB, reference the context
        iocb = IOCB(request)
        iocb.context = context
        if _debug:
            ReadAllObjectPropertiesApplication._debug("    - iocb: %r", iocb)

        # let us know when its complete
        iocb.add_callback(self.object_properties_results)

        # give it to the application
        self.request_io(iocb)
    def do_IAmRequest(self, apdu):
        """Do something with incoming I-Am requests."""
        if _debug: DiscoveryApplication._debug("do_IAmRequest %r", apdu)

        # check for required parameters
        if apdu.iAmDeviceIdentifier is None:
            raise MissingRequiredParameter("iAmDeviceIdentifier required")
        if apdu.maxAPDULengthAccepted is None:
            raise MissingRequiredParameter("maxAPDULengthAccepted required")
        if apdu.segmentationSupported is None:
            raise MissingRequiredParameter("segmentationSupported required")
        if apdu.vendorID is None:
            raise MissingRequiredParameter("vendorID required")

        # extract the device instance number
        device_instance = apdu.iAmDeviceIdentifier[1]
        if _debug:
            DiscoveryApplication._debug("    - device_instance: %r",
                                        device_instance)

        # extract the source address
        device_address = apdu.pduSource
        if _debug:
            DiscoveryApplication._debug("    - device_address: %r",
                                        device_address)

        # we didn't request anything yet
        if not self.who_is_request:
            return

        if (self.who_is_request.deviceInstanceRangeLowLimit is not None) and \
                (device_instance < self.who_is_request.deviceInstanceRangeLowLimit):
            pass
        elif (self.who_is_request.deviceInstanceRangeHighLimit is not None) and \
                (device_instance > self.who_is_request.deviceInstanceRangeHighLimit):
            pass
        else:
            # build a request for the object name
            request = ReadPropertyRequest(
                destination=apdu.pduSource,
                objectIdentifier=apdu.iAmDeviceIdentifier,
                propertyIdentifier='objectName',
            )

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

            # let us know when its complete
            iocb.add_callback(self.device_discovered)

            # give it to the application
            self.request_io(iocb)
    def dcc(self, address=None, duration=None, password=None, state=None):
        """
        Will send DeviceCommunicationControl request
        """
        if not self._started:
            raise ApplicationNotStarted(
                "BACnet stack not running - use startApp()")

        if not address:
            raise ValueError("Provide address for request")

        if not state:
            raise ValueError(
                "Provide state ('enable', 'disable', 'disableInitiation'")

        # build a request
        request = DeviceCommunicationControlRequest()
        request.enableDisable = DeviceCommunicationControlRequestEnableDisable.enumerations[
            state]
        request.pduDestination = Address(address)
        if duration:
            request.duration = Unsigned16(duration)

        request.password = CharacterString(password)

        self._log.debug("{:>12} {}".format("- request:", request))

        iocb = IOCB(request)  # make an IOCB

        # pass to the BACnet stack
        deferred(self.this_application.request_io, iocb)

        # Unconfirmed request...so wait until complete
        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

            if not isinstance(apdu, SimpleAckPDU):  # expect an ACK
                self._log.warning("Not an ack, see debug for more infos.")
                self._log.debug("Not an ack. | APDU : {} / {}".format(
                    (apdu, type(apdu))))
                return

        if iocb.ioError:  # unsuccessful: error/reject/abort
            apdu = iocb.ioError
            reason = find_reason(apdu)
            raise NoResponseFromController(
                "APDU Abort Reason : {}".format(reason))

        self._log.info(
            "DeviceCommunicationControl request sent to device : {}".format(
                address))
    def run(self):
        if _debug: ReadPointListThread._debug("run")
        global this_application

        # loop through the points
        for addr, obj_type, obj_inst, prop_id in self.point_queue:
            # build a request
            request = ReadPropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
                )
            request.pduDestination = Address(addr)
            if _debug: ReadPointListThread._debug("    - request: %r", request)

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

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

            # wait for the response
            iocb.wait()

            if iocb.ioResponse:
                apdu = iocb.ioResponse

                # find the datatype
                datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier)
                if _debug: ReadPointListThread._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 (apdu.propertyArrayIndex is not None):
                    if apdu.propertyArrayIndex == 0:
                        value = apdu.propertyValue.cast_out(Unsigned)
                    else:
                        value = apdu.propertyValue.cast_out(datatype.subtype)
                else:
                    value = apdu.propertyValue.cast_out(datatype)
                if _debug: ReadPointListThread._debug("    - value: %r", value)

                # save the value
                self.response_values.append(value)

            if iocb.ioError:
                if _debug: ReadPointListThread._debug("    - error: %r", iocb.ioError)
                self.response_values.append(iocb.ioError)

        # done
        stop()
Beispiel #30
0
Datei: br.py Projekt: navkal/bg
def send_request( target_args, app ):

    # build a request
    request = ReadPropertyRequest(
        objectIdentifier=( target_args['type'], target_args['instance'] ),
        propertyIdentifier=target_args['property']
    )
    request.pduDestination = Address( target_args['address'] )

    # make an IOCB
    iocb = IOCB( request )

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

    # wait for it to complete
    iocb.wait()

    # Handle completion: error, success, neither
    if iocb.ioError:
        # Error
        success = False
        message = str( iocb.ioError )
        result = ''

    elif iocb.ioResponse:
        # Success
        success = True
        message = ''

        # Get the response PDU
        apdu = iocb.ioResponse

        # Extract the returned value
        datatype = get_datatype( apdu.objectIdentifier[0], apdu.propertyIdentifier )
        if issubclass( datatype, Array ) and (apdu.propertyArrayIndex is not None):
            if apdu.propertyArrayIndex == 0:
                result = apdu.propertyValue.cast_out( Unsigned )
            else:
                result = apdu.propertyValue.cast_out( datatype.subtype )
        else:
            result = apdu.propertyValue.cast_out( datatype )

    else:
        # Neither
        success = False
        message = 'Request terminated unexpectedly'
        result = ''

    rsp = { target_args['property']: result }

    return success, message, rsp
Beispiel #31
0
    def whois(self, *args):
        """
        Build a WhoIs request

        :param args: string built as [ <addr>] [ <lolimit> <hilimit> ] **optional**
        :returns: discoveredDevices as a defaultdict(int)

        Example::

            whois()             # WhoIs broadcast globally.  Every device will respond with an IAm
            whois('2:5')        # WhoIs looking for the device at (Network 2, Address 5)
            whois('10 1000')    # WhoIs looking for devices in the ID range (10 - 1000) 

        """
        if not self._started:
            raise ApplicationNotStarted("BACnet stack not running - use startApp()")

        if args:
            args = args[0].split()
        msg = args if args else "any"

        self._log.debug("do_whois {!r}".format(msg))

        # build a request
        request = WhoIsRequest()
        if (len(args) == 1) or (len(args) == 3):
            request.pduDestination = Address(args[0])
            del args[0]
        else:
            request.pduDestination = GlobalBroadcast()

        if len(args) == 2:
            request.deviceInstanceRangeLowLimit = int(args[0])
            request.deviceInstanceRangeHighLimit = int(args[1])
        self._log.debug("{:>12} {}".format("- request:", request))

        iocb = IOCB(request)  # make an IOCB

        # pass to the BACnet stack
        self.this_application.request_io(iocb)

        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

        if iocb.ioError:  # unsuccessful: error/reject/abort
            pass

        self.discoveredDevices = self.this_application.i_am_counter
        return self.discoveredDevices
 def got_new_device_who_is_response(self, apdu):
     # first check that this new device is one we actually care about (some times we get whois responses from other devices, even though the request was targeted to a specific ip rather than a global address)
     if not str(apdu.pduSource) in self.devices:
         print "got who is response from a device we don't care about"
         return
     # now we need to get the device name using the identifier we just got
     request = ReadPropertyRequest(
         destination=apdu.pduSource,
         objectIdentifier=apdu.iAmDeviceIdentifier,
         propertyIdentifier='objectName')
     iocb = IOCB(request)
     iocb.add_callback(self._got_device_object_name,
                       apdu.iAmDeviceIdentifier)
     self.bacnet_adapter.request_io(iocb)
Beispiel #33
0
 def read(self,pduSource,obj_id,key,device,read=None):
     #function.log('request',pduSource,obj_id,key,device)
     if isinstance(obj_id,str):
         obj_id=obj_id.split(':')
         obj_id[1]=int(obj_id[1])
     request=ReadPropertyRequest(
         objectIdentifier=tuple(obj_id),
         propertyIdentifier=key,
         destination=RemoteStation(pduSource[0] or 0,bytearray(pduSource[1]))
     ) 
   
     iocb = IOCB(request)            
     iocb.context=device,key
     iocb.add_callback(read or self.readBack)
     self.request_io(iocb)
Beispiel #34
0
    def write(self, args, vendor_id=0):
        """ Build a WriteProperty request, wait for an answer, and return status [True if ok, False if not].

        :param args: String with <addr> <type> <inst> <prop> <value> [ <indx> ] [ <priority> ]
        :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.write('2:5 analogValue 1 presentValue 100')

        Direct the controller at (Network 2, address 5) to write 100 to the presentValues of
        its analogValue 1 (AV:1)
        """
        if not self._started:
            raise ApplicationNotStarted("BACnet stack not running - use startApp()")
        args = args.split()
        self.log_title("Write property", args)

        try:
            # build a WriteProperty request
            iocb = IOCB(self.build_wp_request(args, vendor_id=vendor_id))
            # pass to the BACnet stack
            deferred(self.this_application.request_io, iocb)
            self._log.debug("{:<20} {!r}".format("iocb", iocb))

        except WritePropertyException as error:
            # construction error
            self._log.exception("exception: {!r}".format(error))

        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

            if not isinstance(iocb.ioResponse, SimpleAckPDU):  # expect an ACK
                self._log.warning("Not an ack, see debug for more infos.")
                self._log.debug(
                    "Not an ack. | APDU : {} / {}".format((apdu, type(apdu)))
                )
                return

        if iocb.ioError:  # unsuccessful: error/reject/abort
            raise NoResponseFromController()
Beispiel #35
0
    def do_write(self, args):
        """write <addr> <unitID> <register> <value>

        :param addr: IP address of the MODBUS/TCP device or gateway
        :param unitID: unit identifier
        :param register: register in 5-digit or 6-digit format
        :param value: value to write

        This command generates a :class:`WriteSingleCoil`,
        or :class:`WriteSingleRegisterRequest` depending on the address
        prefix; 0 or 4.
        """
        args = args.split()
        if _debug: ConsoleClient._debug("do_write %r", args)

        if (len(args) < 3):
            print("address, unit and register required")
            return

        # get the address and unit
        addr, unitID, register, value = args

        # address might have a port
        if ':' in addr:
            addr, port = addr.split(':')
            server_address = (addr, int(port))
        else:
            server_address = (addr, 502)

        # unit identifier
        unitID = int(unitID)
        if _debug: ConsoleClient._debug("    - addr, unitID: %r, %r", server_address, unitID)

        # get the register and count
        register = int(register)
        if _debug: ConsoleClient._debug("    - register: %r", register)

        # decode the register into a type
        digits = int(math.log10(register)) + 1
        if digits <= 4:
            # must be a coil
            registerType = 0
        elif digits == 5:
            registerType = register // 10000
            register = register % 10000
        elif digits == 6:
            registerType = register // 100000
            register = register % 100000
        else:
            print("5 or 6 digit addresses please")
            return
        if _debug: ConsoleClient._debug("    - registerType, register: %r, %r", registerType, register)

        # value
        value = int(value)
        if _debug: ConsoleClient._debug("    - value: %r", value)

        # build a request
        if registerType == 0:
            # coil
            req = WriteSingleCoilRequest(register - 1, value)
        elif registerType == 4:
            # holding register
            req = WriteSingleRegisterRequest(register - 1, value)
        else:
            print("unsupported register type")
            return

        # set the destination
        req.pduDestination = server_address
        req.mpduUnitID = unitID
        if _debug: ConsoleClient._debug("    - req: %r", req)

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

        # submit the request via the main thread
        deferred(self.controller.request_io, iocb)

        # wait for the response
        iocb.wait()

        # exceptions
        if iocb.ioError:
            print("error: %r" % (iocb.ioError,))
            return

        # extract the response
        resp = iocb.ioResponse
        if _debug: ConsoleClient._debug("    - resp: %r", resp)

        # write responses
        if isinstance(iocb.ioResponse, WriteSingleCoilResponse):
            print("  ::= " + str(iocb.ioResponse.value))

        elif isinstance(iocb.ioResponse, WriteSingleRegisterResponse):
            print("  ::= " + str(iocb.ioResponse.value))

        else:
            raise TypeError("unsupported response")
Beispiel #36
0
    def do_read(self, args):
        """read <addr> <unitID> <register> [ <count> ]

        :param addr: IP address of the MODBUS/TCP device or gateway
        :param unitID: unit identifier
        :param register: register in 5-digit or 6-digit format
        :param count: number of registers to read, defaults to one

        This command generates a :class:`ReadCoilsRequest`,
        :class:`ReadDiscreteInputsRequest`, :class:`ReadInputRegistersRequest`,
        or :class:`ReadMultipleRegistersRequest` depending on the address
        prefix; 0, 1, 3, or 4.
        """
        args = args.split()
        if _debug: ConsoleClient._debug("do_read %r", args)

        if (len(args) < 3):
            print("address, unit and register required")
            return

        # get the address and unit, and register
        addr, unitID, register = args[:3]

        # address might have a port
        if ':' in addr:
            addr, port = addr.split(':')
            server_address = (addr, int(port))
        else:
            server_address = (addr, 502)

        # unit identifier
        unitID = int(unitID)
        if _debug: ConsoleClient._debug("    - addr, unitID: %r, %r", addr, unitID)

        # get the register and count
        register = int(register)
        if len(args) == 4:
            rcount = int(args[3])
        else:
            rcount = 1
        if _debug: ConsoleClient._debug("    - register, rcount: %r, %r", register, rcount)

        # decode the register into a type
        digits = int(math.log10(register)) + 1
        if digits <= 4:
            # must be a coil
            registerType = 0
        elif digits == 5:
            registerType = register // 10000
            register = register % 10000
        elif digits == 6:
            registerType = register // 100000
            register = register % 100000
        else:
            print("5 or 6 digit addresses please")
            return
        if _debug: ConsoleClient._debug("    - registerType, register: %r, %r", registerType, register)

        # build a request
        if registerType == 0:
            # coil
            req = ReadCoilsRequest(register - 1, rcount)
        elif registerType == 1:
            # discrete inputs
            req = ReadDiscreteInputsRequest(register - 1, rcount)
        elif registerType == 3:
            # input register
            req = ReadInputRegistersRequest(register - 1, rcount)
        elif registerType == 4:
            # holding register
            req = ReadMultipleRegistersRequest(register - 1, rcount)
        else:
            print("unsupported register type")
            return

        # set the destination
        req.pduDestination = server_address
        req.mpduUnitID = unitID
        if _debug: ConsoleClient._debug("    - req: %r", req)

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

        # submit the request via the main thread
        deferred(self.controller.request_io, iocb)

        # wait for the response
        iocb.wait()

        # exceptions
        if iocb.ioError:
            print("error: %r" % (iocb.ioError,))
            return

        # extract the response
        resp = iocb.ioResponse
        if _debug: ConsoleClient._debug("    - resp: %r", resp)

        # read responses
        if isinstance(resp, ExceptionResponse):
            print("  ::= " + str(resp))

        elif isinstance(resp, ReadCoilsResponse):
            print("  ::= " + str(resp.bits))

        elif isinstance(resp, ReadDiscreteInputsResponse):
            print("  ::= " + str(resp.bits))

        elif isinstance(resp, ReadInputRegistersResponse):
            print("  ::= " + str(resp.registers))

            for dtype, codec in ModbusStruct.items():
                try:
                    value = codec.unpack(resp.registers)
                    print("   " + dtype + " ::= " + str(value))
                except Exception as err:
                    if _debug: ConsoleClient._debug("unpack exception %r: %r", codec, err)

        elif isinstance(resp, ReadMultipleRegistersResponse):
            print("  ::= " + str(resp.registers))

            for dtype, codec in ModbusStruct.items():
                try:
                    value = codec.unpack(resp.registers)
                    print("   " + dtype + " ::= " + str(value))
                except Exception as err:
                    if _debug: ConsoleClient._debug("unpack exception %r: %r", codec, err)
        else:
            raise TypeError("unsupported response")
    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 #38
0
    def do_read(self, args):
        """read <addr> <type> <inst> <prop> [ <indx> ]"""
        args = args.split()
        if _debug: ReadPropertyConsoleCmd._debug("do_read %r", args)

        try:
            addr, obj_type, obj_inst, prop_id = args[:4]

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

            obj_inst = int(obj_inst)

            datatype = get_datatype(obj_type, prop_id)
            if not datatype:
                raise ValueError("invalid property for object type")

            # build a request
            request = ReadPropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
                )
            request.pduDestination = Address(addr)

            if len(args) == 5:
                request.propertyArrayIndex = int(args[4])
            if _debug: ReadPropertyConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: ReadPropertyConsoleCmd._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, ReadPropertyACK):
                    if _debug: ReadPropertyConsoleCmd._debug("    - not an ack")
                    return

                # find the datatype
                datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier)
                if _debug: ReadPropertyConsoleCmd._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 (apdu.propertyArrayIndex is not None):
                    if apdu.propertyArrayIndex == 0:
                        value = apdu.propertyValue.cast_out(Unsigned)
                    else:
                        value = apdu.propertyValue.cast_out(datatype.subtype)
                else:
                    value = apdu.propertyValue.cast_out(datatype)
                if _debug: ReadPropertyConsoleCmd._debug("    - value: %r", value)

                sys.stdout.write(str(value) + '\n')
                if hasattr(value, 'debug_contents'):
                    value.debug_contents(file=sys.stdout)
                sys.stdout.flush()

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

        except Exception, error:
            ReadPropertyConsoleCmd._exception("exception: %r", error)
Beispiel #39
0
    def read(self, args, arr_index=None, vendor_id=0, bacoid=None):
        """
        Build a ReadProperty 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/24'
            bacnet = BAC0.connect(ip = myIPAddr)
            bacnet.read('2:5 analogInput 1 presentValue')

        Requests the controller at (Network 2, address 5) for the presentValue of
        its analog input 1 (AI:1).
        """
        if not self._started:
            raise ApplicationNotStarted("BACnet stack not running - use startApp()")

        args_split = args.split()

        self.log_title("Read property", args_split)

        vendor_id = vendor_id
        bacoid = bacoid

        try:
            # build ReadProperty request
            iocb = IOCB(
                self.build_rp_request(
                    args_split, arr_index=arr_index, vendor_id=vendor_id, bacoid=bacoid
                )
            )
            # pass to the BACnet stack
            deferred(self.this_application.request_io, iocb)
            self._log.debug("{:<20} {!r}".format("iocb", iocb))

        except ReadPropertyException as error:
            # construction error
            self._log.exception("exception: {!r}".format(error))

        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

            if not isinstance(apdu, ReadPropertyACK):  # expecting an ACK
                self._log.warning("Not an ack, see debug for more infos.")
                self._log.debug(
                    "Not an ack. | APDU : {} / {}".format((apdu, type(apdu)))
                )
                return

            # find the datatype
            datatype = get_datatype(
                apdu.objectIdentifier[0], apdu.propertyIdentifier, vendor_id=vendor_id
            )
            if not datatype:
                raise TypeError("unknown datatype")

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

            self._log.debug("{:<20} {:<20}".format("value", "datatype"))
            self._log.debug("{!r:<20} {!r:<20}".format(value, datatype))
            return value

        if iocb.ioError:  # unsuccessful: error/reject/abort
            apdu = iocb.ioError
            reason = find_reason(apdu)
            if reason == "segmentationNotSupported":
                self._log.warning(
                    "Segmentation not supported... will read properties one by one..."
                )
                self._log.debug("The Request was : {}".format(args_split))
                value = self._split_the_read_request(args, arr_index)
                return value
            else:
                if reason == "unknownProperty":
                    # if "priorityArray" in args:
                    #    self._log.debug("Unknown property {}".format(args))
                    # else:
                    #    self._log.warning("Unknown property {}".format(args))
                    if "description" in args:
                        return "Not Implemented"
                    elif "inactiveText" in args:
                        return "Off"
                    elif "activeText" in args:
                        return "On"
                    else:
                        raise UnknownPropertyError("Unknown property {}".format(args))
                elif reason == "unknownObject":
                    self._log.warning("Unknown object {}".format(args))
                    raise UnknownObjectError("Unknown object {}".format(args))
                else:
                    # Other error... consider NoResponseFromController (65)
                    # even if the realy reason is another one
                    raise NoResponseFromController(
                        "APDU Abort Reason : {}".format(reason)
                    )
Beispiel #40
0
    def do_write(self, args):
        """write <addr> <type> <inst> <prop> [ <indx> ]"""
        args = args.split()
        if _debug: WriteSomethingConsoleCmd._debug("do_write %r", args)

        try:
            addr, obj_type, obj_inst, prop_id = args[:4]

            obj_type = int(obj_type)
            obj_inst = int(obj_inst)
            prop_id = int(prop_id)

            # build a request
            request = WritePropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
                )
            request.pduDestination = Address(addr)

            if len(args) == 5:
                request.propertyArrayIndex = int(args[4])

            # build a custom datastructure
            tag_list = TagList([
                OpeningTag(1),
                ContextTag(0, xtob('9c40')),
                ContextTag(1, xtob('02')),
                ContextTag(2, xtob('02')),
                ClosingTag(1)
                ])
            if _debug: WriteSomethingConsoleCmd._debug("    - tag_list: %r", tag_list)

            # stuff the tag list into an Any
            request.propertyValue = Any()
            request.propertyValue.decode(tag_list)

            if _debug: WriteSomethingConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: WriteSomethingConsoleCmd._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:
                # should be an ack
                if not isinstance(iocb.ioResponse, SimpleAckPDU):
                    if _debug: WriteSomethingConsoleCmd._debug("    - not an ack")
                    return

                sys.stdout.write("ack\n")

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

        except Exception as error:
            WriteSomethingConsoleCmd._exception("exception: %r", error)
Beispiel #41
0
    def do_subscribe(self, args):
        """subscribe addr proc_id obj_type obj_inst [ confirmed ] [ lifetime ]

        Generate a SubscribeCOVRequest and wait for the response.
        """
        args = args.split()
        if _debug: SubscribeCOVConsoleCmd._debug("do_subscribe %r", args)

        try:
            addr, proc_id, obj_type, obj_inst = args[:4]

            proc_id = int(proc_id)

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

            if len(args) >= 5:
                issue_confirmed = args[4]
                if issue_confirmed == '-':
                    issue_confirmed = None
                else:
                    issue_confirmed = issue_confirmed.lower() == 'true'
                if _debug: SubscribeCOVConsoleCmd._debug("    - issue_confirmed: %r", issue_confirmed)
            else:
                issue_confirmed = None

            if len(args) >= 6:
                lifetime = args[5]
                if lifetime == '-':
                    lifetime = None
                else:
                    lifetime = int(lifetime)
                if _debug: SubscribeCOVConsoleCmd._debug("    - lifetime: %r", lifetime)
            else:
                lifetime = None

            # build a request
            request = SubscribeCOVRequest(
                subscriberProcessIdentifier=proc_id,
                monitoredObjectIdentifier=(obj_type, obj_inst),
                )
            request.pduDestination = Address(addr)

            # optional parameters
            if issue_confirmed is not None:
                request.issueConfirmedNotifications = issue_confirmed
            if lifetime is not None:
                request.lifetime = lifetime

            if _debug: SubscribeCOVConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: SubscribeCOVConsoleCmd._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:
                if _debug: SubscribeCOVConsoleCmd._debug("    - response: %r", iocb.ioResponse)

            # do something for error/reject/abort
            if iocb.ioError:
                if _debug: SubscribeCOVConsoleCmd._debug("    - error: %r", iocb.ioError)

        except Exception as e:
            SubscribeCOVConsoleCmd._exception("exception: %r", e)
Beispiel #42
0
    def do_readrecord(self, args):
        """readrecord <addr> <inst> <start> <count>"""
        args = args.split()
        if _debug: TestConsoleCmd._debug("do_readrecord %r", args)

        try:
            addr, obj_inst, start_record, record_count = args

            obj_type = 'file'
            obj_inst = int(obj_inst)
            start_record = int(start_record)
            record_count = int(record_count)

            # build a request
            request = AtomicReadFileRequest(
                fileIdentifier=(obj_type, obj_inst),
                accessMethod=AtomicReadFileRequestAccessMethodChoice(
                    recordAccess=AtomicReadFileRequestAccessMethodChoiceRecordAccess(
                        fileStartRecord=start_record,
                        requestedRecordCount=record_count,
                        ),
                    ),
                )
            request.pduDestination = Address(addr)
            if _debug: TestConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: TestConsoleCmd._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, AtomicReadFileACK):
                    if _debug: TestConsoleCmd._debug("    - not an ack")
                    return

                # suck out the record data
                if apdu.accessMethod.recordAccess:
                    value = apdu.accessMethod.recordAccess.fileRecordData
                elif apdu.accessMethod.streamAccess:
                    value = apdu.accessMethod.streamAccess.fileData
                if _debug: TestConsoleCmd._debug("    - value: %r", value)

                sys.stdout.write(repr(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:
            TestConsoleCmd._exception("exception: %r", error)
    def do_write(self, args):
        """write <addr> <type> <inst> <prop> <value> [ <indx> ] [ <priority> ]"""
        args = args.split()
        ReadWritePropertyConsoleCmd._debug("do_write %r", args)

        try:
            addr, obj_type, obj_inst, prop_id = args[:4]

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif not get_object_class(obj_type, VendorAVObject.vendor_id):
                raise ValueError("unknown object type")
            if _debug: ReadWritePropertyConsoleCmd._debug("    - obj_type: %r", obj_type)

            obj_inst = int(obj_inst)
            if _debug: ReadWritePropertyConsoleCmd._debug("    - obj_inst: %r", obj_inst)

            if prop_id.isdigit():
                prop_id = int(prop_id)
            if _debug: ReadWritePropertyConsoleCmd._debug("    - prop_id: %r", prop_id)

            value = args[4]

            indx = None
            if len(args) >= 6:
                if args[5] != "-":
                    indx = int(args[5])
            if _debug: ReadWritePropertyConsoleCmd._debug("    - indx: %r", indx)

            priority = None
            if len(args) >= 7:
                priority = int(args[6])
            if _debug: ReadWritePropertyConsoleCmd._debug("    - priority: %r", priority)

            # get the datatype
            datatype = get_datatype(obj_type, prop_id, VendorAVObject.vendor_id)
            if _debug: ReadWritePropertyConsoleCmd._debug("    - datatype: %r", datatype)

            # change atomic values into something encodeable, null is a special case
            if (value == 'null'):
                value = Null()
            elif issubclass(datatype, Atomic):
                if datatype is Integer:
                    value = int(value)
                elif datatype is Real:
                    value = float(value)
                elif datatype is Unsigned:
                    value = int(value)
                value = datatype(value)
            elif issubclass(datatype, Array) and (indx is not None):
                if indx == 0:
                    value = Integer(value)
                elif issubclass(datatype.subtype, Atomic):
                    value = datatype.subtype(value)
                elif not isinstance(value, datatype.subtype):
                    raise TypeError("invalid result datatype, expecting %s" % (datatype.subtype.__name__,))
            elif not isinstance(value, datatype):
                raise TypeError("invalid result datatype, expecting %s" % (datatype.__name__,))
            if _debug: ReadWritePropertyConsoleCmd._debug("    - encodeable value: %r %s", value, type(value))

            # build a request
            request = WritePropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id
                )
            request.pduDestination = Address(addr)

            # save the value
            request.propertyValue = Any()
            try:
                request.propertyValue.cast_in(value)
            except Exception as error:
                ReadWritePropertyConsoleCmd._exception("WriteProperty cast error: %r", error)

            # optional array index
            if indx is not None:
                request.propertyArrayIndex = indx

            # optional priority
            if priority is not None:
                request.priority = priority

            if _debug: ReadWritePropertyConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: ReadWritePropertyConsoleCmd._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:
                sys.stdout.write("ack\n")

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

        except Exception as error:
            ReadWritePropertyConsoleCmd._exception("exception: %r", error)
Beispiel #44
0
    def do_writestream(self, args):
        """writestream <addr> <inst> <start> <data>"""
        args = args.split()
        if _debug: TestConsoleCmd._debug("do_writestream %r", args)

        try:
            addr, obj_inst, start_position, data = args

            obj_type = 'file'
            obj_inst = int(obj_inst)
            start_position = int(start_position)
            data = data.encode('utf-8')

            # build a request
            request = AtomicWriteFileRequest(
                fileIdentifier=(obj_type, obj_inst),
                accessMethod=AtomicWriteFileRequestAccessMethodChoice(
                    streamAccess=AtomicWriteFileRequestAccessMethodChoiceStreamAccess(
                        fileStartPosition=start_position,
                        fileData=data,
                        ),
                    ),
                )
            request.pduDestination = Address(addr)
            if _debug: TestConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: TestConsoleCmd._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, AtomicWriteFileACK):
                    if _debug: TestConsoleCmd._debug("    - not an ack")
                    return

                # suck out the record data
                if apdu.fileStartPosition is not None:
                    value = apdu.fileStartPosition
                elif apdu.fileStartRecord is not None:
                    value = apdu.fileStartRecord
                TestConsoleCmd._debug("    - value: %r", value)

                sys.stdout.write(repr(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:
            TestConsoleCmd._exception("exception: %r", error)
The IOController processes the IOCBs it is given and returns the 
IOCB back to the caller.
"""

import bacpypes
from bacpypes.iocb import IOCB, IOController


class SomeController(IOController):
    def process_io(self, iocb):
        self.complete_io(iocb, iocb.args[0] + iocb.args[1] * iocb.kwargs['a'])
        
def call_me(iocb):
    """
    When a controller completes the processing of a request, 
    the IOCB can contain one or more functions to be called. 
    """
    print("call me, %r or %r" % (iocb.ioResponse, iocb.ioError))        
        
if __name__ == '__main__':
    iocb = IOCB(1, 2, a=3)
    iocb.add_callback(call_me)
    some_controller = SomeController()
    some_controller.request_io(iocb)
    iocb.ioComplete.wait()
    
    print(iocb.ioComplete)
    print(iocb.ioComplete.is_set())
    print(iocb.ioState == bacpypes.iocb.COMPLETED)
    print(iocb.ioState == bacpypes.iocb.ABORTED)
    print(iocb.ioResponse)
    def do_read(self, args):
        """read <addr> <type> <inst> <prop> [ <indx> ]"""
        args = args.split()
        if _debug: ReadWritePropertyConsoleCmd._debug("do_read %r", args)

        try:
            addr, obj_type, obj_inst, prop_id = args[:4]

            if obj_type.isdigit():
                obj_type = int(obj_type)
            elif not get_object_class(obj_type, VendorAVObject.vendor_id):
                raise ValueError("unknown object type")
            if _debug: ReadWritePropertyConsoleCmd._debug("    - obj_type: %r", obj_type)

            obj_inst = int(obj_inst)
            if _debug: ReadWritePropertyConsoleCmd._debug("    - obj_inst: %r", obj_inst)

            if prop_id.isdigit():
                prop_id = int(prop_id)
            if _debug: ReadWritePropertyConsoleCmd._debug("    - prop_id: %r", prop_id)

            datatype = get_datatype(obj_type, prop_id, VendorAVObject.vendor_id)
            if not datatype:
                raise ValueError("invalid property for object type")

            # build a request
            request = ReadPropertyRequest(
                objectIdentifier=(obj_type, obj_inst),
                propertyIdentifier=prop_id,
                )
            request.pduDestination = Address(addr)

            if len(args) == 5:
                request.propertyArrayIndex = int(args[4])
            if _debug: ReadWritePropertyConsoleCmd._debug("    - request: %r", request)

            # make an IOCB
            iocb = IOCB(request)
            if _debug: ReadWritePropertyConsoleCmd._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

                # peek at the value tag
                value_tag = apdu.propertyValue.tagList.Peek()
                if _debug: ReadWritePropertyConsoleCmd._debug("    - value_tag: %r", value_tag)

                # make sure that it is application tagged
                if value_tag.tagClass != Tag.applicationTagClass:
                    sys.stdout.write("value is not application encoded\n")

                else:
                    # find the datatype
                    datatype = Tag._app_tag_class[value_tag.tagNumber]
                    if _debug: ReadWritePropertyConsoleCmd._debug("    - datatype: %r", datatype)
                    if not datatype:
                        raise TypeError("unknown datatype")

                    # cast out the value
                    value = apdu.propertyValue.cast_out(datatype)
                    if _debug: ReadWritePropertyConsoleCmd._debug("    - value: %r", value)

                    sys.stdout.write("%s (%s)\n" % (value, datatype))

                sys.stdout.flush()

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

        except Exception as error:
            ReadWritePropertyConsoleCmd._exception("exception: %r", error)
Beispiel #47
0
    def readMultiple(self, args):
        """ Build a ReadPropertyMultiple request, wait for the answer and return the values

        :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/24'
            bacnet = BAC0.connect(ip = myIPAddr)
            bacnet.readMultiple('2:5 analogInput 1 presentValue units')

        Requests the controller at (Network 2, address 5) for the (presentValue and units) of
        its analog input 1 (AI:1).
        """
        if not self._started:
            raise ApplicationNotStarted("BACnet stack not running - use startApp()")

        args = args.split()
        values = []

        self.log_title("Read Multiple", args)

        try:
            # build an ReadPropertyMultiple request
            iocb = IOCB(self.build_rpm_request(args))
            # pass to the BACnet stack
            deferred(self.this_application.request_io, iocb)
            self._log.debug("{:<20} {!r}".format("iocb", iocb))

        except ReadPropertyMultipleException as error:
            # construction error
            self._log.exception("exception: {!r}".format(error))

        iocb.wait()  # Wait for BACnet response

        if iocb.ioResponse:  # successful response
            apdu = iocb.ioResponse

            if not isinstance(apdu, ReadPropertyMultipleACK):  # expecting an ACK
                self._log.debug("{:<20}".format("not an ack"))
                self._log.warning(
                    "Not an Ack. | APDU : {} / {}".format((apdu, type(apdu)))
                )
                return

            # loop through the results
            for result in apdu.listOfReadAccessResults:
                # here is the object identifier
                objectIdentifier = result.objectIdentifier

                self.log_subtitle(
                    "{!r} : {!r}".format(objectIdentifier[0], objectIdentifier[1]),
                    width=114,
                )
                self._log.debug(
                    "{:<20} {:<20} {:<30} {:<20}".format(
                        "propertyIdentifier", "propertyArrayIndex", "value", "datatype"
                    )
                )
                self._log.debug("-" * 114)

                # now come the property values per object
                for element in result.listOfResults:
                    # get the property and array index
                    propertyIdentifier = element.propertyIdentifier
                    propertyArrayIndex = element.propertyArrayIndex

                    readResult = element.readResult

                    if readResult.propertyAccessError is not None:
                        self._log.debug(
                            "Property Access Error for {}".format(
                                readResult.propertyAccessError
                            )
                        )
                        values.append(None)
                    else:
                        # here is the value
                        propertyValue = readResult.propertyValue

                        # find the datatype
                        datatype = get_datatype(objectIdentifier[0], propertyIdentifier)

                        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)

                        self._log.debug(
                            "{!r:<20} {!r:<20} {!r:<30} {!r:<20}".format(
                                propertyIdentifier, propertyArrayIndex, value, datatype
                            )
                        )
                        values.append(value)

            return values

        if iocb.ioError:  # unsuccessful: error/reject/abort
            apdu = iocb.ioError
            reason = find_reason(apdu)
            self._log.warning("APDU Abort Reject Reason : {}".format(reason))
            self._log.debug("The Request was : {}".format(args))
            if reason == "unrecognizedService":
                raise UnrecognizedService()
            elif reason == "segmentationNotSupported":
                raise SegmentationNotSupported()
            elif reason == "unknownObject":
                self._log.warning("Unknown object {}".format(args))
                raise UnknownObjectError("Unknown object {}".format(args))
            elif reason == "unknownProperty":
                self._log.warning("325 Unknown property {}".format(args))

                values.append("")
                return values
            else:
                self._log.warning("No response from controller")
                values.append("")
                return values