예제 #1
0
    def net_obj_id(self, obj, inst, prop, idx):
        self.obj = obj
        self.inst = inst
        self.prop = prop
        self.idx = idx

        deferred(self.read_prop_vendor)
def main():
    global this_application

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(ini=args.ini)
    if _debug: _log.debug("    - this_device: %r", this_device)

    # make a simple application
    this_application = BIPSimpleApplication(this_device, args.ini.address)

    # create a thread and
    read_thread = ReadPointListThread(point_list)
    if _debug: _log.debug("    - read_thread: %r", read_thread)

    # start it running when the core is running
    deferred(read_thread.start)

    _log.debug("running")

    run()

    # dump out the results
    for request, response in zip(point_list, read_thread.response_values):
        print(request, response)

    _log.debug("fini")
예제 #3
0
    def prop_vendor_ack(self, iocb):

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

        # decode results from bacnet_settings's read property
        self.response_bacset = net.dcode(apdu)

        # get actual proxy IP from Device
        actual_IP = self.response_bacset[1]

        # Check public IP
        public_IP = self.get_public_ip()
        print public_IP

        # check if IPs are real IPV4
        # If both IPs are different, do a write property to the correct object
        if self.validate_ip(actual_IP) and self.validate_ip(public_IP):
            if actual_IP != public_IP:
                self.proxyIP = public_IP
                deferred(self.write_bac_set)
                print actual_IP, public_IP
            else:
                print "IPs are the same"
                stop()
        else:
            print "IPs are not valid"
            stop()

        #deferred(self.write_bac_set)

        # do something for error/reject/abort
        if iocb.ioError:
            sys.stdout.write(str(iocb.ioError) + '\n')
예제 #4
0
    def complete_request(self, iocb):
        if _debug: ReadPropertyApplication._debug("complete_request %r", iocb)

        if iocb.ioResponse:
            apdu = iocb.ioResponse

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

            # special case for array parts, others are managed by cast_out
            value = apdu.propertyValue.cast_out(datatype)
            if _debug: ReadPropertyApplication._debug("    - value: %r", value)

            sys.stdout.write(self.property_identifier + " = " + str(value) + '\n')
            if hasattr(value, 'debug_contents'):
                value.debug_contents(stream=sys.stdout)
            sys.stdout.flush()

        if iocb.ioError:
            if _debug: ReadPropertyApplication._debug("    - error: %r", iocb.ioError)

            # if it is an unknown property, just skip to the next one
            if getattr(iocb.ioError, 'errorCode', '') != 'unknownProperty':
                sys.stdout.write(self.property_identifier + "! " + str(iocb.ioError) + '\n')
                sys.stdout.flush()

        # fire off another request
        deferred(self.next_request)
예제 #5
0
    def object_name_results(self, iocb):
        if _debug:
            ReadObjectListApplication._debug("object_name_results %r", iocb)

        # extract the context
        context = iocb.context

        # do something for error/reject/abort
        if iocb.ioError:
            context.completed(iocb.ioError)
            return

        # do something for success
        apdu = iocb.ioResponse

        # should be an ack
        if not isinstance(apdu, ReadPropertyACK):
            if _debug: ReadObjectListApplication._debug("    - not an ack")
            context.completed(RuntimeError("read property ack expected"))
            return

        # pull out the name
        object_name = apdu.propertyValue.cast_out(CharacterString)
        if _debug:
            ReadObjectListApplication._debug("    - object_name: %r",
                                             object_name)

        # store it in the context
        context.object_names.append(object_name)

        # read the next one
        deferred(self.read_next_object, context)
예제 #6
0
    def object_list_results(self, iocb):
        if _debug:
            ReadObjectListApplication._debug("object_list_results %r", iocb)

        # extract the context
        context = iocb.context

        # do something for error/reject/abort
        if iocb.ioError:
            context.completed(iocb.ioError)
            return

        # do something for success
        apdu = iocb.ioResponse

        # should be an ack
        if not isinstance(apdu, ReadPropertyACK):
            if _debug: ReadObjectListApplication._debug("    - not an ack")
            context.completed(RuntimeError("read property ack expected"))
            return

        # pull out the content
        object_list = apdu.propertyValue.cast_out(ArrayOfObjectIdentifier)
        if _debug:
            ReadObjectListApplication._debug("    - object_list: %r",
                                             object_list)

        # store it in the context
        context.object_list = object_list

        # make a queue of the identifiers to read, start reading them
        context._object_list_queue = deque(object_list)
        deferred(self.read_next_object, context)
예제 #7
0
def main():
    global this_application

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(
        objectName=args.ini.objectname,
        objectIdentifier=int(args.ini.objectidentifier),
        maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted),
        segmentationSupported=args.ini.segmentationsupported,
        vendorIdentifier=int(args.ini.vendoridentifier),
    )

    # make a simple application
    this_application = ReadPointListApplication(point_list, this_device,
                                                args.ini.address)

    # fire off a request when the core has a chance
    deferred(this_application.next_request)

    _log.debug("running")

    run()

    # dump out the results
    for request, response in zip(point_list, this_application.response_values):
        print(request, response)

    _log.debug("fini")
예제 #8
0
파일: io.py 프로젝트: DemandLogic/bacpypes
    def _trigger(self):
        """Called to launch the next request in the queue."""
        if _debug: IOQController._debug("_trigger")

        # if we are busy, do nothing
        if self.state != CTRL_IDLE:
            if _debug: IOQController._debug("    - not idle")
            return

        # if there is nothing to do, return
        if not self.ioQueue.queue:
            if _debug: IOQController._debug("    - empty queue")
            return

        # get the next iocb
        iocb = self.ioQueue.get()

        try:
            # hopefully there won't be an error
            err = None

            # let derived class figure out how to process this
            self.process_io(iocb)
        except:
            # extract the error
            err = sys.exc_info()[1]

        # if there was an error, abort the request
        if err:
            self.abort_io(iocb, err)

        # if we're idle, call again
        if self.state == CTRL_IDLE:
            deferred(IOQController._trigger, self)
예제 #9
0
    def indication(self, apdu):
        if _debug: WhoIsIAmApplication._debug("indication %r", apdu)

        if (isinstance(self._request, WhoIsRequest)) and (isinstance(
                apdu, IAmRequest)):
            device_type, device_instance = apdu.iAmDeviceIdentifier
            if device_type != 'device':
                raise DecodingError("invalid object type")

            if (self._request.deviceInstanceRangeLowLimit is not None) and \
                    (device_instance < self._request.deviceInstanceRangeLowLimit):
                pass
            elif (self._request.deviceInstanceRangeHighLimit is not None) and \
                    (device_instance > self._request.deviceInstanceRangeHighLimit):
                pass
            else:
                # Received I-am from target's Device instance
                dev_ObjID = apdu.iAmDeviceIdentifier
                dev_pdusource = apdu.pduSource

                point_list[0][0] = str(dev_pdusource)
                point_list[1][0] = str(dev_pdusource)
                point_list[0][2] = dev_ObjID[1]
                point_list[1][2] = dev_ObjID[1]

                #fire off request. read device properties model name and software version
                deferred(self.next_request)

        # forward it along
        BIPSimpleApplication.indication(self, apdu)
예제 #10
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
예제 #11
0
파일: test.py 프로젝트: riahtu/myems-bacnet
def main():

    # make a device object
    this_device = LocalDeviceObject(objectName=config.bacnet_device['object_name'],
                                    objectIdentifier=config.bacnet_device['object_identifier'],
                                    maxApduLengthAccepted=config.bacnet_device['max_apdu_length_accepted'],
                                    segmentationSupported=config.bacnet_device['segmentation_supported'],
                                    vendorIdentifier=config.bacnet_device['vendor_identifier'], )

    # point list, set according to your device
    point_list = [
        # point_id, addr, obj_type, obj_inst, prop_id, idx
        (1, '10.117.73.53', 'analogInput', 1, 'presentValue', None),
        (2, '10.117.73.53', 'analogInput', 2, 'presentValue', None),
        (3, '10.117.73.53', 'analogInput', 3, 'presentValue', None),
        (4, '10.117.73.53', 'analogInput', 4, 'presentValue', None),
        (5, '10.117.73.53', 'analogInput', 5, 'presentValue', None),
        (6, '10.117.73.53', 'analogInput', 6, 'presentValue', None),
    ]

    # make a simple application
    this_application = MyEMSApplication(point_list,
                                        this_device,
                                        config.bacnet_device['local_address'],
                                        Address(config.bacnet_device['foreignBBMD']),
                                        int(config.bacnet_device['foreignTTL']))

    # fire off a request when the core has a chance
    deferred(this_application.next_request)

    run()

    # dump out the results
    for request, response in zip(point_list, this_application.response_values):
        print(request, response)
예제 #12
0
def main():
    global this_application

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(ini=args.ini)
    if _debug: _log.debug("    - this_device: %r", this_device)

    # make a simple application
    this_application = SubscribeCOVApplication(this_device, args.ini.address)

    # make a subscription context
    context = SubscriptionContext(Address("10.0.1.31"), ('analogValue', 1), False, 60)

    # send the subscription when the stack is ready
    deferred(this_application.send_subscription, context)

    _log.debug("running")

    run()

    _log.debug("fini")
예제 #13
0
def main():
    global this_application

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(ini=args.ini)
    if _debug: _log.debug("    - this_device: %r", this_device)

    # make a simple application
    this_application = ReadPointListApplication(point_list, this_device,
                                                args.ini.address)

    # fire off a request when the core has a chance
    deferred(this_application.next_request)

    _log.debug("running")

    run()

    # dump out the results
    for request, response in zip(point_list, this_application.response_values):
        print(request, response)

    _log.debug("fini")
예제 #14
0
    def complete_request(self, iocb):
        if _debug: ReadPointListApplication._debug("complete_request %r", iocb)

        if iocb.ioResponse:
            apdu = iocb.ioResponse

            # find the datatype
            datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier)
            if _debug: ReadPointListApplication._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: ReadPointListApplication._debug("    - value: %r", value)

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

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

        # fire off another request
        deferred(self.next_request)
예제 #15
0
파일: Text.py 프로젝트: snuids/BAC0
    def write_text_value(self, request, timeout=10):
        try:
            iocb = IOCB(request)
            iocb.set_timeout(timeout)
            # 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 not isinstance(apdu, SimpleAckPDU):  # expect an ACK
                    self._log.error("Not an ack, see debug for more infos.")
                    return

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

        except WritePropertyException as error:
            # construction error
            self._log.error(("exception: {!r}".format(error)))
예제 #16
0
파일: io.py 프로젝트: yaztown/bacpypes
    def _trigger(self):
        """Called to launch the next request in the queue."""
        if _debug: IOQController._debug("_trigger")

        # if we are busy, do nothing
        if self.state != CTRL_IDLE:
            if _debug: IOQController._debug("    - not idle")
            return

        # if there is nothing to do, return
        if not self.ioQueue.queue:
            if _debug: IOQController._debug("    - empty queue")
            return

        # get the next iocb
        iocb = self.ioQueue.get()

        try:
            # hopefully there won't be an error
            err = None

            # let derived class figure out how to process this
            self.process_io(iocb)
        except:
            # extract the error
            err = sys.exc_info()[1]

        # if there was an error, abort the request
        if err:
            self.abort_io(iocb, err)

        # if we're idle, call again
        if self.state == CTRL_IDLE:
            deferred(IOQController._trigger, self)
예제 #17
0
    def confirmation(self, apdu):
        if _debug: PrairieDog._debug("confirmation %r", apdu)

        if isinstance(apdu, Error):
            if _debug: PrairieDog._debug("    - error: %r", apdu)
            self.response_values.append(apdu)

        elif isinstance(apdu, AbortPDU):
            if _debug: PrairieDog._debug("    - abort: %r", apdu)
            self.response_values.append(apdu)

        elif (isinstance(self._request, ReadPropertyRequest)) and (isinstance(apdu, ReadPropertyACK)):
            # find the datatype
            datatype = get_datatype(apdu.objectIdentifier[0], apdu.propertyIdentifier)
            if _debug: PrairieDog._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: PrairieDog._debug("    - value: %r", value)

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

        # fire off another request
        deferred(self.next_request)
예제 #18
0
    def complete_request(self, iocb):

        if iocb.ioResponse:
            apdu = iocb.ioResponse

            # find the datatype
            datatype = get_datatype(apdu.objectIdentifier[0],
                                    apdu.propertyIdentifier)
            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)

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

        if iocb.ioError:
            self.response_values.append(iocb.ioError)

        # fire off another request
        deferred(self.next_request)
예제 #19
0
def main():
    global vendor_id

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(ini=args.ini)
    if _debug:
        _log.debug("    - this_device: %r", this_device)

    # make a sample application
    this_application = BIPSimpleApplication(this_device, args.ini.address)

    # create the objects and add them to the application
    create_objects(this_application)

    # run this update when the stack is ready
    deferred(update_weather_data)

    if _debug:
        _log.debug("running")

    run()

    if _debug:
        _log.debug("fini")
예제 #20
0
    def property_change(self, old_value, new_value):
        if _debug:
            DetectionMonitor._debug("property_change %r %r", old_value,
                                    new_value)

        # set the parameter value
        setattr(self.algorithm, self.parameter, new_value)

        # if the algorithm is already triggered, don't bother checking for more
        if self.algorithm._triggered:
            if _debug: DetectionMonitor._debug("    - already triggered")
            return

        # if there is a special filter, use it, otherwise use !=
        if self.filter:
            trigger = self.filter(old_value, new_value)
        else:
            trigger = (old_value != new_value)
        if _debug: DetectionMonitor._debug("    - trigger: %r", trigger)

        # trigger it
        if trigger:
            deferred(self.algorithm._execute)
            if _debug:
                DetectionMonitor._debug("    - deferred: %r",
                                        self.algorithm._execute)

            self.algorithm._triggered = True
예제 #21
0
def getData(collection):
    global this_application, device_address, object_identifier, property_list
    # 清空数组
    global result, tag_list, tag_keys, count
    print collection
    result = []
    tag_list = []
    tag_keys = {}
    count = 0
    parser = ConfigArgumentParser(description=__doc__)
    args = parser.parse_args()

    tag_list = collection["bacnet_items"]
    try:
        this_device = LocalDeviceObject(ini=args.ini)
        this_application = ReadPropertyApplication(this_device,
                                                   args.ini.address)
        deferred(this_application.requests)
        run()
        this_application.close_socket()

    except Exception as e:
        print str(e)
        return {"data": "采集失败", "success": "false"}
    import datetime
    dt = datetime.datetime.now()
    timestamp = dt.strftime("%Y-%m-%d %H:%M:%S")
    for item in tag_keys:
        result.append({
            "timestamp": timestamp,
            "value": None,
            "item": tag_keys[item]['tag'],
            "quality": "Error"
        })
    return {"data": result, "success": "true"}
예제 #22
0
파일: io.py 프로젝트: DemandLogic/bacpypes
    def complete_io(self, iocb, msg):
        """Called by a handler to return data to the client."""
        if _debug: IOQController._debug("complete_io %r %r", iocb, msg)

        # check to see if it is completing the active one
        if iocb is not self.active_iocb:
            raise RuntimeError, "not the current iocb"

        # normal completion
        IOController.complete_io(self, iocb, msg)

        # no longer an active iocb
        self.active_iocb = None

        # check to see if we should wait a bit
        if self.wait_time:
            # change our state
            self.state = CTRL_WAITING

            # schedule a call in the future
            task = FunctionTask(IOQController._wait_trigger, self)
            task.install_task(_time() + self.wait_time)

        else:
            # change our state
            self.state = CTRL_IDLE

            # look for more to do
            deferred(IOQController._trigger, self)
예제 #23
0
    def what_is_network_number(self, args=""):
        """
        winn [ <addr> ]

        Send a What-Is-Network-Number message.  If the address is unspecified
        the message is locally broadcast.
        """
        args = args.split()

        # build a request
        try:
            request = WhatIsNetworkNumber()
            if len(args) > 0:
                request.pduDestination = Address(args[0])
            else:
                request.pduDestination = LocalBroadcast()
        except:
            self._log.error(
                "Cannot build request (invalid arguments) : {}".format(args))
            return

        iocb = IOCB((self.this_application.nsap.local_adapter,
                     request))  # make an IOCB
        iocb.set_timeout(2)
        deferred(self.this_application.nse.request_io, iocb)
        iocb.wait()
예제 #24
0
    def whois_router_to_network(self, args=None):
        # build a request
        try:
            request = WhoIsRouterToNetwork()
            if not args:
                request.pduDestination = LocalBroadcast()
            elif args[0].isdigit():
                request.pduDestination = LocalBroadcast()
                request.wirtnNetwork = int(args[0])
            else:
                request.pduDestination = Address(args[0])
                if len(args) > 1:
                    request.wirtnNetwork = int(args[1])
        except:
            self._log.error("WhoIsRouterToNetwork : invalid arguments")
            return
        iocb = IOCB((self.this_application.nsap.local_adapter,
                     request))  # make an IOCB
        iocb.set_timeout(2)
        deferred(self.this_application.nse.request_io, iocb)
        iocb.wait()

        try:
            self.init_routing_table(str(
                self.this_application.nse._iartn.pop()))
        except IndexError:
            pass
예제 #25
0
    def handle_read(self):
        if _debug: MSTPDirector._debug("handle_read")

        try:
            msg, addr = self.socket.recvfrom(512)
            if _debug: MSTPDirector._debug("    - received %d octets ", len(msg))
            pdu = PDU(msg,destination=int(str(self.address)))
            mstp_src = pdu.get()
            pdu.pduSource = Address(mstp_src)

            if _debug: MSTPDirector._debug("Received MSTP PDU={}".format(str(pdu)))

            # send the PDU up to the client
            deferred(self._response, pdu)

        except socket.timeout as err:
            if _debug: MSTPDirector._debug("    - socket timeout: %s", err)

        except socket.error as err:
            if err.args[0] == 11:
                pass
            else:
                if _debug: MSTPDirector._debug("    - socket error: %s", err)

                # pass along to a handler
                self.handle_error(err)

        except Exception as e:
            MSTPDirector._error('Exception in handle_read: {}'.format(e))
예제 #26
0
    def do_WhoIsRequest(self, apdu):
        """Respond to a Who-Is request."""
        self._log.debug("do_WhoIsRequest {!r}".format(apdu))

        # build a key from the source and parameters
        key = (
            str(apdu.pduSource),
            apdu.deviceInstanceRangeLowLimit,
            apdu.deviceInstanceRangeHighLimit,
        )
        low_limit = key[1]
        high_limit = key[2]

        # count the times this has been received
        self.who_is_counter[key] += 1

        if low_limit is not None:
            if self.localDevice.objectIdentifier[1] < low_limit:
                return
        if high_limit is not None:
            if self.localDevice.objectIdentifier[1] > high_limit:
                return
        # generate an I-Am
        self._log.debug("Responding to Who is by a Iam")
        self.iam_req.pduDestination = apdu.pduSource
        iocb = IOCB(self.iam_req)  # make an IOCB
        deferred(self.request_io, iocb)
예제 #27
0
def WriteValues(PointList):
    global this_application, this_ServerAdress
    # create a thread
    thread_list = []

    print(PointList)
    # loop through the address and point lists
    #for points in PointList:
    # create a thread
    #print(points)
    read_thread = WritePointListThread(this_ServerAdress, PointList)
    if _debug: _log.debug("	   - read_thread: %r", read_thread)
    thread_list.append(read_thread)

    # create a thread supervisor
    thread_supervisor = ReadWriteThreadSupervisor(thread_list)

    # start it running when the core is running
    deferred(thread_supervisor.start)

    _log.debug("running")

    run()

    # dump out the results
    for read_thread in thread_list:
        for request, response in zip(read_thread.point_list,
                                     read_thread.response_values):
            print(request, response)
예제 #28
0
파일: io.py 프로젝트: yaztown/bacpypes
    def complete_io(self, iocb, msg):
        """Called by a handler to return data to the client."""
        if _debug: IOQController._debug("complete_io %r %r", iocb, msg)

        # check to see if it is completing the active one
        if iocb is not self.active_iocb:
            raise RuntimeError, "not the current iocb"

        # normal completion
        IOController.complete_io(self, iocb, msg)

        # no longer an active iocb
        self.active_iocb = None

        # check to see if we should wait a bit
        if self.wait_time:
            # change our state
            self.state = CTRL_WAITING

            # schedule a call in the future
            task = FunctionTask(IOQController._wait_trigger, self)
            task.install_task(_time() + self.wait_time)

        else:
            # change our state
            self.state = CTRL_IDLE

            # look for more to do
            deferred(IOQController._trigger, self)
예제 #29
0
    def whois_router_to_network(self, network=None, *, destination=None):
        # build a request
        try:
            request = WhoIsRouterToNetwork()
            if network:
                request.wirtnNetwork = int(network)
            if destination:
                request.pduDestination = Address(destination)
                self._log.debug("WhoIsRouterToNetwork Destination : {}".format(
                    destination))
            else:
                request.pduDestination = LocalBroadcast()
        except:
            self._log.error("WhoIsRouterToNetwork : invalid arguments")
            return
        iocb = IOCB((self.this_application.nsap.local_adapter,
                     request))  # make an IOCB
        iocb.set_timeout(2)
        deferred(self.this_application.nse.request_io, iocb)
        iocb.wait()

        try:
            self.init_routing_table(str(
                self.this_application.nse._iartn.pop()))
        except IndexError:
            pass
예제 #30
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
 def do_write_property(self, device, callback=None):
     try:
         iocb = device if isinstance(device, IOCB) else self.form_iocb(device, request_type="writeProperty")
         deferred(self.request_io, iocb)
         self.requests_in_progress.update({iocb: {"callback": callback}})
         iocb.add_callback(self.__general_cb)
     except Exception as error:
         log.exception("exception: %r", error)
예제 #32
0
    def response(self, apdu):
        if _debug: TestApplication._debug("response %r", apdu)

        # check for loopback
        if apdu.pduDestination == self.localAddress:
            if _debug: TestApplication._debug("    - loopback")
            deferred(self.confirmation, apdu)
        else:
            BIPSimpleApplication.response(self, apdu)
예제 #33
0
def run_application(objectidentifier: int):
    global this_device
    global this_application

    # parse the command line arguments
    parser = ConfigArgumentParser(description=__doc__)

    # add an argument for interval
    parser.add_argument(
        'device_id',
        type=int,
        help='device identifier',
    )

    # add an argument for interval
    parser.add_argument(
        'device_addr',
        type=str,
        help='device address',
    )

    # make a device object
    this_device = LocalDeviceObject(
        objectName="objectpropertyreader",
        objectIdentifier=599,
        maxApduLengthAccepted=1024,
        segmentationSupported="segmentedBoth",
        vendorIdentifier=15,
    )

    import netifaces
    from ipaddress import IPv4Network

    wifi_ip = netifaces.ifaddresses('en0')[netifaces.AF_INET][0]
    #Addres of this device which will perform the querying.
    address = wifi_ip['addr'] + "/" + str(
        IPv4Network("0.0.0.0/" + wifi_ip['netmask']).prefixlen) + ":47809"

    # make a simple application
    this_application = ReadAllObjectPropertiesApplication(this_device, address)

    # build a device object identifier
    device_id = ('device', objectidentifier)

    # Address of device being queried.
    device_addr = Address(
        wifi_ip['addr'] + "/" +
        str(IPv4Network("0.0.0.0/" + wifi_ip['netmask']).prefixlen) + ":47808")

    # kick off the process after the core is up and running
    deferred(this_application.read_object_list, device_id, device_addr)

    _log.debug("running")

    run()

    _log.debug("fini")
예제 #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()
def main():
    global this_application

    # parse the command line arguments
    args = ConfigArgumentParser(description=__doc__).parse_args()

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

    # make a device object
    this_device = LocalDeviceObject(
        objectName=args.ini.objectname,
        objectIdentifier=int(args.ini.objectidentifier),
        maxApduLengthAccepted=int(args.ini.maxapdulengthaccepted),
        segmentationSupported=args.ini.segmentationsupported,
        vendorIdentifier=int(args.ini.vendoridentifier),
        )

    # make a simple application
    this_application = BIPSimpleApplication(this_device, args.ini.address)

    # get the services supported
    services_supported = this_application.get_services_supported()
    if _debug: _log.debug("    - services_supported: %r", services_supported)

    # let the device object know
    this_device.protocolServicesSupported = services_supported.value

    # create a thread and
    read_thread = ReadPointListThread(point_list)
    if _debug: _log.debug("    - read_thread: %r", read_thread)

    # start it running when the core is running
    deferred(read_thread.start)

    _log.debug("running")

    run()

    # dump out the results
    for request, response in zip(point_list, read_thread.response_values):
        print(request, response)

    _log.debug("fini")
예제 #36
0
파일: io.py 프로젝트: DemandLogic/bacpypes
    def abort_io(self, iocb, err):
        """Called by a handler or a client to abort a transaction."""
        if _debug: IOQController._debug("abort_io %r %r", iocb, err)

        # normal abort
        IOController.abort_io(self, iocb, err)

        # check to see if it is completing the active one
        if iocb is not self.active_iocb:
            if _debug: IOQController._debug("    - not current iocb")
            return

        # no longer an active iocb
        self.active_iocb = None

        # change our state
        self.state = CTRL_IDLE

        # look for more to do
        deferred(IOQController._trigger, self)
예제 #37
0
    def property_change(self, old_value, new_value):
        if _debug: DetectionMonitor._debug("property_change %r %r", old_value, new_value)

        # set the parameter value
        setattr(self.algorithm, self.parameter, new_value)

        # if the algorithm is already triggered, don't bother checking for more
        if self.algorithm._triggered:
            if _debug: DetectionMonitor._debug("    - already triggered")
            return

        # if there is a special filter, use it, otherwise use !=
        if self.filter:
            trigger = self.filter(old_value, new_value)
        else:
            trigger = (old_value != new_value)
        if _debug: DetectionMonitor._debug("    - trigger: %r", trigger)

        # trigger it
        if trigger:
            deferred(self.algorithm._execute)
            if _debug: DetectionMonitor._debug("    - deferred: %r", self.algorithm._execute)

            self.algorithm._triggered = True
예제 #38
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")
예제 #39
0
        segmentationSupported=args.ini.segmentationsupported,
        vendorIdentifier=int(args.ini.vendoridentifier),
    )

    # make a simple application
    this_application = ReadPointListApplication(point_list, this_device, args.ini.address)

    # get the services supported
    services_supported = this_application.get_services_supported()
    if _debug:
        _log.debug("    - services_supported: %r", services_supported)

    # let the device object know
    this_device.protocolServicesSupported = services_supported.value

    # fire off a request when the core has a chance
    deferred(this_application.next_request)

    _log.debug("running")

    run()

    # dump out the results
    for request, response in zip(point_list, this_application.response_values):
        print request, response

except Exception, e:
    _log.exception("an error has occurred: %s", e)
finally:
    _log.debug("finally")
예제 #40
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)
                    )
예제 #41
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
예제 #42
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")
예제 #43
0
def main():
    """
    Main function, called when run as an application.
    """
    global server_address

    # parse the command line arguments
    parser = ArgumentParser(description=__doc__)
    parser.add_argument(
        "host", nargs='?',
        help="address of host (default %r)" % (SERVER_HOST,),
        default=SERVER_HOST,
        )
    parser.add_argument(
        "port", nargs='?', type=int,
        help="server port (default %r)" % (SERVER_PORT,),
        default=SERVER_PORT,
        )
    parser.add_argument(
        "--hello", action="store_true",
        default=False,
        help="send a hello message",
        )
    args = parser.parse_args()

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

    # extract the server address and port
    host = args.host
    port = args.port
    server_address = (host, port)
    if _debug: _log.debug("    - server_address: %r", server_address)

    # build the stack
    this_console = ConsoleClient()
    if _debug: _log.debug("    - this_console: %r", this_console)

    this_middle_man = MiddleMan()
    if _debug: _log.debug("    - this_middle_man: %r", this_middle_man)

    this_director = TCPClientDirector()
    if _debug: _log.debug("    - this_director: %r", this_director)

    bind(this_console, this_middle_man, this_director)
    bind(MiddleManASE(), this_director)

    # create a task manager for scheduled functions
    task_manager = TaskManager()
    if _debug: _log.debug("    - task_manager: %r", task_manager)

    # don't wait to connect
    deferred(this_director.connect, server_address)

    # send hello maybe
    if args.hello:
        deferred(this_middle_man.indication, PDU(xtob('68656c6c6f0a')))

    if _debug: _log.debug("running")

    run()

    if _debug: _log.debug("fini")