From 9ec89dbf11fc498abcfb195ecdf48648dcc1e2ea Mon Sep 17 00:00:00 2001 From: Richard Littauer Date: Tue, 28 Apr 2020 18:13:47 -0400 Subject: [PATCH] refactor: Remove tutorials/WhoIsIAm.py This removes the Tutorial code and updates the old samples/WhoIsIAm.py to match it. --- .../gettingstarted/gettingstarted001.rst | 192 +++++++++--------- .../gettingstarted/gettingstarted002.rst | 82 ++++---- samples/Tutorial/WhoIsIAm.py | 181 ----------------- samples/WhoIsIAm.py | 83 +++----- 4 files changed, 168 insertions(+), 370 deletions(-) delete mode 100644 samples/Tutorial/WhoIsIAm.py mode change 100755 => 100644 samples/WhoIsIAm.py diff --git a/doc/source/gettingstarted/gettingstarted001.rst b/doc/source/gettingstarted/gettingstarted001.rst index b48997b..b799d93 100644 --- a/doc/source/gettingstarted/gettingstarted001.rst +++ b/doc/source/gettingstarted/gettingstarted001.rst @@ -3,25 +3,25 @@ Getting Started =============== -Ah, so you are interested in getting started with BACnet and Python. Welcome -to BACpypes, I hope you enjoy your journey. This tutorial starts with -just enough of the basics of BACnet to get a workstation communicating with -another device. We will cover installing the library, downloading and +Ah, so you are interested in getting started with BACnet and Python. Welcome +to BACpypes, I hope you enjoy your journey. This tutorial starts with +just enough of the basics of BACnet to get a workstation communicating with +another device. We will cover installing the library, downloading and configuring the samples applications. Basic Assumptions ----------------- -I will assume you are a software developer and it is your job to communicate -with a device from another company that uses BACnet. Your employer has -given you a test device and purchased a copy of the BACnet standard. I will +I will assume you are a software developer and it is your job to communicate +with a device from another company that uses BACnet. Your employer has +given you a test device and purchased a copy of the BACnet standard. I will need... -- a development workstation running some flavor of Linux or Windows, complete with +- a development workstation running some flavor of Linux or Windows, complete with the latest version of Python (2.7 or >3.4) and `setup tools `_. -- a small Ethernet hub into which you can plug both your workstation and your +- a small Ethernet hub into which you can plug both your workstation and your mysterious BACnet device, so you won't be distracted by lots of other network traffic. - a BACnetIP/BACnet-MSTP Router if your mysterious device is an MSTP device (BACpypes is @@ -33,7 +33,7 @@ need... `Anaconda `_ or Enthought `Canopy `_. -Before getting this test environment set up and while you are still connected +Before getting this test environment set up and while you are still connected to the internet, install the BACpypes library:: $ sudo easy_install bacpypes @@ -42,7 +42,7 @@ or:: $ sudo pip install bacpypes -And while you are at it, get a copy of the BACpypes project from GitHub. It +And while you are at it, get a copy of the BACpypes project from GitHub. It contains the library source code, sample code, and this documentation. Install the `Git `_ software from `here `_, then make a local copy of the @@ -50,11 +50,11 @@ repository by cloning it:: $ git clone https://github.com/JoelBender/bacpypes.git -No protocol analysis workbench would be complete without an installed +No protocol analysis workbench would be complete without an installed copy of `Wireshark `_:: $ sudo apt-get install wireshark - + or if you use Windows, `download it here `_. .. caution:: @@ -67,15 +67,15 @@ or if you use Windows, `download it here `_, and sequentially - higher numbers are used in many applications (i.e. 47809, 47810,...). + The BACnet protocol has been assigned port 47808 (hex 0xBAC0) by + by the `Internet Assigned Numbers Authority `_, and sequentially + higher numbers are used in many applications (i.e. 47809, 47810,...). There are some BACnet routing and networking issues related to using these higher unoffical ports, but that is a topic for another tutorial. @@ -213,38 +213,38 @@ Starting An Application ----------------------- The simplest BACpypes sample application is the **WhoIsIAm.py** -application. It sends out Who-Is and I-Am messages and +application. It sends out Who-Is and I-Am messages and displays the results it receives. What are these things? -As mentioned before, BACnet has unique device identifiers and -most applications use these identifiers in their configuration +As mentioned before, BACnet has unique device identifiers and +most applications use these identifiers in their configuration to know who their peers are. Once these identifiers are given to a device they typically do not change, even as the network topology changes. -BACnet devices use the Who-Is request to translate device -identifiers into network addresses. This is very similar to -a decentralized DNS service, but the names are unsigned -integers. The request is broadcast on the network and the +BACnet devices use the Who-Is request to translate device +identifiers into network addresses. This is very similar to +a decentralized DNS service, but the names are unsigned +integers. The request is broadcast on the network and the client waits around to listen for I-Am messages. The source -address of the I-Am response is "bound" to the device identifier +address of the I-Am response is "bound" to the device identifier and most communications are unicast thereafter. -First, start up Wireshark on your workstation and a capture +First, start up Wireshark on your workstation and a capture session with a BACnet capture filter:: udp and port 47808 -You might start seeing BACnet traffic from your test device, -and if you wait to power it on after starting your capture -you should see at least a broadcast I-Am message. By looking -in the I-Am packet decoding you will see some of its -configuration parameters that should match what you expected +You might start seeing BACnet traffic from your test device, +and if you wait to power it on after starting your capture +you should see at least a broadcast I-Am message. By looking +in the I-Am packet decoding you will see some of its +configuration parameters that should match what you expected them to be. Now start the simplest tutorial application:: - $ python samples/Tutorial/WhoIsIAm.py + $ python samples/WhoIsIAm.py .. note:: @@ -272,7 +272,7 @@ BACnet communications traffic. Generate the basic I-Am message:: > iam -You should see Wireshark capture your I-Am message containing your configuration +You should see Wireshark capture your I-Am message containing your configuration parameters. This is a "global broadcast" message. Your test device will see it but since your test device probably isn't looking for you, it will not respond to the message. @@ -281,27 +281,27 @@ respond to the message. Binding to the Test Device -------------------------- -Next we want to confirm that your workstation can receive the -messages the test device sends out. We do this by generating a -generic Who-Is request. The request will be "unconstrained", meaning +Next we want to confirm that your workstation can receive the +messages the test device sends out. We do this by generating a +generic Who-Is request. The request will be "unconstrained", meaning every device that hears the message will respond with their corresponding -I-Am messages. +I-Am messages. -.. caution:: +.. caution:: - Generating **unconstrained** Who-Is requests on a large network will create - a LOT of traffic, which can lead to network problems caused by the resulting + Generating **unconstrained** Who-Is requests on a large network will create + a LOT of traffic, which can lead to network problems caused by the resulting flood of messages. - + To generate the Who-Is request:: > whois -You should see the Who-Is request captured in Wireshark along with the I-Am -response from your test device, and then the details of the response displayed +You should see the Who-Is request captured in Wireshark along with the I-Am +response from your test device, and then the details of the response displayed on the workstation console.:: - > whois + > whois > pduSource = iAmDeviceIdentifier = ('device', 1000) maxAPDULengthAccepted = 480 @@ -309,13 +309,13 @@ on the workstation console.:: vendorID = 8 -There are a few different forms of the *whois* command supported by this +There are a few different forms of the *whois* command supported by this simple application. You can see these with the help command:: > help whois whois [ ] [ ] -This is like a BNF syntax, the **whois** command is optionally +This is like a BNF syntax, the **whois** command is optionally followed by a BACnet device address, and then optionally followed by a low (address) limit and high (address) limit. The most common use of the Who-Is request is to look for a specific device given its device @@ -329,9 +329,9 @@ building as a group:: > whois 203000 203099 -Every once in a while a contractor might install a BACnet +Every once in a while a contractor might install a BACnet device that hasn't been properly configured. Assuming that -it has an IP address, you can send an **unconstrained Who-Is** request +it has an IP address, you can send an **unconstrained Who-Is** request to the specific device and hope that it responds:: > whois 192.168.0.10 @@ -349,9 +349,9 @@ but that is a subject of an other tutorial. What's Next ----------- -The next tutorial describes the different ways this +The next tutorial describes the different ways this application can be run, and what the commands can tell you -about how it is working. All of the "console" applications -(i.e. those that prompt for commands) use the same basic +about how it is working. All of the "console" applications +(i.e. those that prompt for commands) use the same basic commands and work the same way. diff --git a/doc/source/gettingstarted/gettingstarted002.rst b/doc/source/gettingstarted/gettingstarted002.rst index 4d22180..a9084b9 100644 --- a/doc/source/gettingstarted/gettingstarted002.rst +++ b/doc/source/gettingstarted/gettingstarted002.rst @@ -3,9 +3,9 @@ Running BACpypes Applications ============================= -All BACpypes sample applications have the same basic set of command line -options so it is easy to move between applications, turn debugging on and -and use different configurations. There may be additional options and +All BACpypes sample applications have the same basic set of command line +options so it is easy to move between applications, turn debugging on and +and use different configurations. There may be additional options and command parameters than just the ones described in this section. Getting Help @@ -14,7 +14,7 @@ Getting Help Whatever the command line parameters and additional options might be for an application, you can start with help:: - $ python Tutorial/WhoIsIAm.py --help + $ python samples/WhoIsIAm.py --help usage: WhoIsIAm.py [-h] [--buggers] [--debug [DEBUG [DEBUG ...]]] [--color] [--ini INI] This application presents a 'console' prompt to the user asking for Who-Is and @@ -33,22 +33,22 @@ an application, you can start with help:: Listing Debugging Loggers ------------------------- -The BACpypes library and sample applications make extensive use of the -built-in *logging* module in Python. Every module in the library, along -with every class and exported function, has a logging object associated -with it. By attaching a log handler to a logger, the log handler is given +The BACpypes library and sample applications make extensive use of the +built-in *logging* module in Python. Every module in the library, along +with every class and exported function, has a logging object associated +with it. By attaching a log handler to a logger, the log handler is given a chance to output the progress of the application. -Because BACpypes modules are deeply interconnected, dumping a complete list -of all of the logger names is a long list. Start out focusing on the +Because BACpypes modules are deeply interconnected, dumping a complete list +of all of the logger names is a long list. Start out focusing on the components of the WhoIsIAm.py application:: - $ python Tutorial/WhoIsIAm.py --buggers | grep __main__ + $ python samples/WhoIsIAm.py --buggers | grep __main__ __main__ __main__.WhoIsIAmApplication __main__.WhoIsIAmConsoleCmd -In this sample, the entire application is called __main__ and it defines +In this sample, the entire application is called __main__ and it defines two classes. Debugging a Module @@ -61,12 +61,12 @@ Telling the application to debug a module is simple:: DEBUG:__main__: - args: Namespace(buggers=False, debug=['__main__'], ini=) DEBUG:__main__.WhoIsIAmApplication:__init__ (, '128.253.109.40/24:47808') DEBUG:__main__:running - > + > -The output is the severity code of the logger (almost always DEBUG), the name -of the module, class, or function, then some message about the progress of the -application. From the output above you can see the application initializing, -setting the args variable, creating an instance of the WhoIsIAmApplication class +The output is the severity code of the logger (almost always DEBUG), the name +of the module, class, or function, then some message about the progress of the +application. From the output above you can see the application initializing, +setting the args variable, creating an instance of the WhoIsIAmApplication class (with some parameters), and then declaring itself - running. @@ -76,52 +76,52 @@ Debugging a Class Debugging all of the classes and functions can generate a lot of output, so it is useful to focus on a specific function or class:: - $ python Tutorial/WhoIsIAm.py --debug __main__.WhoIsIAmApplication + $ python samples/WhoIsIAm.py --debug __main__.WhoIsIAmApplication DEBUG:__main__.WhoIsIAmApplication:__init__ (, '128.253.109.40/24:47808') - > + > -The same method is used to debug the activity of a BACpypes module, for +The same method is used to debug the activity of a BACpypes module, for example, there is a class called UDPActor in the UDP module:: - $ python Tutorial/WhoIsIAm.py --ini BAC0.ini --debug bacpypes.udp.UDPActor + $ python samples/WhoIsIAm.py --ini BAC0.ini --debug bacpypes.udp.UDPActor > DEBUG:bacpypes.udp.UDPActor:__init__ ('128.253.109.254', 47808) DEBUG:bacpypes.udp.UDPActor:response pduSource = ('128.253.109.254', 47808) pduData = x'81.04.00.37.0A.10.6D.45.BA.C0.01.28.FF.FF.00.00.B6.01.05.FD...' -In this sample, an instance of a UDPActor is created and then its response -function is called with an instance of a PDU as a parameter. Following +In this sample, an instance of a UDPActor is created and then its response +function is called with an instance of a PDU as a parameter. Following the function invocation description, the debugging output continues with the -contents of the PDU. Notice, the protocol data is printed as a hex +contents of the PDU. Notice, the protocol data is printed as a hex encoded string (and restricted to just the first 20 bytes of the message). -You can debug a function just as easily. Specify as many different -combinations of logger names as necessary. Note, you cannot debug a +You can debug a function just as easily. Specify as many different +combinations of logger names as necessary. Note, you cannot debug a specific function within a class. Sending Debug Log to a file ---------------------------- -The current --debug command line option takes a list of named debugging access -points and attaches a StreamHandler which sends the output to sys.stderr. -There is a way to send the debugging output to a -RotatingFileHandler by providing a file name, and optionally maxBytes and -backupCount. For example, this invocation sends the main application debugging -to standard error and the debugging output of the bacpypes.udp module to the +The current --debug command line option takes a list of named debugging access +points and attaches a StreamHandler which sends the output to sys.stderr. +There is a way to send the debugging output to a +RotatingFileHandler by providing a file name, and optionally maxBytes and +backupCount. For example, this invocation sends the main application debugging +to standard error and the debugging output of the bacpypes.udp module to the traffic.txt file:: - $ python Tutorial/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt + $ python samples/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt -By default the `maxBytes` is zero so there is no rotating file, but it can be +By default the `maxBytes` is zero so there is no rotating file, but it can be provided, for example this limits the file size to 1MB:: - $ python Tutorial/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt:1048576 + $ python samples/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt:1048576 -If `maxBytes` is provided, then by default the `backupCount` is 10, but it can also +If `maxBytes` is provided, then by default the `backupCount` is 10, but it can also be specified, so this limits the output to one hundred files:: - $ python Tutorial/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt:1048576:100 + $ python samples/WhoIsIAm.py --debug __main__ bacpypes.udp:traffic.txt:1048576:100 .. caution:: @@ -136,18 +136,18 @@ The definition of debug:: Changing INI Files ------------------ -It is not unusual to have a variety of different INI files specifying +It is not unusual to have a variety of different INI files specifying different port numbers or other BACnet communications paramters. Rather than swapping INI files, you can simply provide the INI file on the -command line, overriding the default BACpypes.ini file. For example, I +command line, overriding the default BACpypes.ini file. For example, I have an INI file for port 47808:: - $ python Tutorial/WhoIsIAm.py --ini BAC0.ini + $ python samples/WhoIsIAm.py --ini BAC0.ini And another one for port 47809:: - $ python Tutorial/WhoIsIAm.py --ini BAC1.ini + $ python samples/WhoIsIAm.py --ini BAC1.ini And I switch back and forth between them. diff --git a/samples/Tutorial/WhoIsIAm.py b/samples/Tutorial/WhoIsIAm.py deleted file mode 100644 index d58455c..0000000 --- a/samples/Tutorial/WhoIsIAm.py +++ /dev/null @@ -1,181 +0,0 @@ -#!/usr/bin/env python - -""" -This application presents a 'console' prompt to the user asking for Who-Is and I-Am -commands which create the related APDUs, then lines up the corresponding I-Am -for incoming traffic and prints out the contents. -""" - -import sys - -from bacpypes.debugging import bacpypes_debugging, ModuleLogger -from bacpypes.consolelogging import ConfigArgumentParser -from bacpypes.consolecmd import ConsoleCmd - -from bacpypes.core import run, enable_sleeping - -from bacpypes.pdu import Address, GlobalBroadcast -from bacpypes.apdu import WhoIsRequest, IAmRequest -from bacpypes.errors import DecodingError - -from bacpypes.app import BIPSimpleApplication -from bacpypes.local.device import LocalDeviceObject - -# some debugging -_debug = 1 -_log = ModuleLogger(globals()) - -# globals -this_device = None -this_application = None - -# -# WhoIsIAmApplication -# - -@bacpypes_debugging -class WhoIsIAmApplication(BIPSimpleApplication): - - def __init__(self, *args): - if _debug: WhoIsIAmApplication._debug("__init__ %r", args) - BIPSimpleApplication.__init__(self, *args) - - # keep track of requests to line up responses - self._request = None - - def request(self, apdu): - if _debug: WhoIsIAmApplication._debug("request %r", apdu) - - # save a copy of the request - self._request = apdu - - # forward it along - BIPSimpleApplication.request(self, apdu) - - def confirmation(self, apdu): - if _debug: WhoIsIAmApplication._debug("confirmation %r", apdu) - - # forward it along - BIPSimpleApplication.confirmation(self, apdu) - - 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: - # print out the contents - sys.stdout.write('pduSource = ' + repr(apdu.pduSource) + '\n') - sys.stdout.write('iAmDeviceIdentifier = ' + str(apdu.iAmDeviceIdentifier) + '\n') - sys.stdout.write('maxAPDULengthAccepted = ' + str(apdu.maxAPDULengthAccepted) + '\n') - sys.stdout.write('segmentationSupported = ' + str(apdu.segmentationSupported) + '\n') - sys.stdout.write('vendorID = ' + str(apdu.vendorID) + '\n') - sys.stdout.flush() - - # forward it along - BIPSimpleApplication.indication(self, apdu) - - -# -# WhoIsIAmConsoleCmd -# - -@bacpypes_debugging -class WhoIsIAmConsoleCmd(ConsoleCmd): - - def do_whois(self, args): - """whois [ ] [ ]""" - args = args.split() - if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) - - try: - # gather the parameters - if (len(args) == 1) or (len(args) == 3): - addr = Address(args[0]) - del args[0] - else: - addr = GlobalBroadcast() - - if len(args) == 2: - lolimit = int(args[0]) - hilimit = int(args[1]) - else: - lolimit = hilimit = None - - # code lives in the device service - this_application.who_is(lolimit, hilimit, addr) - - except Exception as error: - WhoIsIAmConsoleCmd._exception("exception: %r", error) - - def do_iam(self, args): - """iam""" - args = args.split() - if _debug: WhoIsIAmConsoleCmd._debug("do_iam %r", args) - - # code lives in the device service - this_application.i_am() - - def do_rtn(self, args): - """rtn ... """ - args = args.split() - if _debug: WhoIsIAmConsoleCmd._debug("do_rtn %r", args) - - # provide the address and a list of network numbers - router_address = Address(args[0]) - network_list = [int(arg) for arg in args[1:]] - - # pass along to the service access point - this_application.nsap.update_router_references(None, router_address, network_list) - - -# -# __main__ -# - -def main(): - global this_device - 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 = WhoIsIAmApplication(this_device, args.ini.address) - - # make a console - this_console = WhoIsIAmConsoleCmd() - if _debug: _log.debug(" - this_console: %r", this_console) - - # enable sleeping will help with threads - enable_sleeping() - - _log.debug("running") - - run() - - _log.debug("fini") - -if __name__ == "__main__": - main() diff --git a/samples/WhoIsIAm.py b/samples/WhoIsIAm.py old mode 100755 new mode 100644 index 8e6132c..d58455c --- a/samples/WhoIsIAm.py +++ b/samples/WhoIsIAm.py @@ -2,7 +2,7 @@ """ This application presents a 'console' prompt to the user asking for Who-Is and I-Am -commands which create the related APDUs, then lines up the coorresponding I-Am +commands which create the related APDUs, then lines up the corresponding I-Am for incoming traffic and prints out the contents. """ @@ -12,8 +12,7 @@ from bacpypes.debugging import bacpypes_debugging, ModuleLogger from bacpypes.consolelogging import ConfigArgumentParser from bacpypes.consolecmd import ConsoleCmd -from bacpypes.core import run, deferred, enable_sleeping -from bacpypes.iocb import IOCB +from bacpypes.core import run, enable_sleeping from bacpypes.pdu import Address, GlobalBroadcast from bacpypes.apdu import WhoIsRequest, IAmRequest @@ -23,7 +22,7 @@ from bacpypes.app import BIPSimpleApplication from bacpypes.local.device import LocalDeviceObject # some debugging -_debug = 0 +_debug = 1 _log = ModuleLogger(globals()) # globals @@ -68,10 +67,10 @@ class WhoIsIAmApplication(BIPSimpleApplication): raise DecodingError("invalid object type") if (self._request.deviceInstanceRangeLowLimit is not None) and \ - (device_instance < self._request.deviceInstanceRangeLowLimit): + (device_instance < self._request.deviceInstanceRangeLowLimit): pass elif (self._request.deviceInstanceRangeHighLimit is not None) and \ - (device_instance > self._request.deviceInstanceRangeHighLimit): + (device_instance > self._request.deviceInstanceRangeHighLimit): pass else: # print out the contents @@ -85,6 +84,7 @@ class WhoIsIAmApplication(BIPSimpleApplication): # forward it along BIPSimpleApplication.indication(self, apdu) + # # WhoIsIAmConsoleCmd # @@ -93,60 +93,37 @@ class WhoIsIAmApplication(BIPSimpleApplication): class WhoIsIAmConsoleCmd(ConsoleCmd): def do_whois(self, args): - """whois [ ] [ ]""" + """whois [ ] [ ]""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_whois %r", args) try: - # build a request - request = WhoIsRequest() + # gather the parameters if (len(args) == 1) or (len(args) == 3): - request.pduDestination = Address(args[0]) + addr = Address(args[0]) del args[0] else: - request.pduDestination = GlobalBroadcast() + addr = GlobalBroadcast() if len(args) == 2: - request.deviceInstanceRangeLowLimit = int(args[0]) - request.deviceInstanceRangeHighLimit = int(args[1]) - if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) + lolimit = int(args[0]) + hilimit = int(args[1]) + else: + lolimit = hilimit = None - # make an IOCB - iocb = IOCB(request) - if _debug: WhoIsIAmConsoleCmd._debug(" - iocb: %r", iocb) + # code lives in the device service + this_application.who_is(lolimit, hilimit, addr) - # give it to the application - this_application.request_io(iocb) - - except Exception as err: - WhoIsIAmConsoleCmd._exception("exception: %r", err) + except Exception as error: + WhoIsIAmConsoleCmd._exception("exception: %r", error) def do_iam(self, args): """iam""" args = args.split() if _debug: WhoIsIAmConsoleCmd._debug("do_iam %r", args) - try: - # build a request - request = IAmRequest() - request.pduDestination = GlobalBroadcast() - - # set the parameters from the device object - request.iAmDeviceIdentifier = this_device.objectIdentifier - request.maxAPDULengthAccepted = this_device.maxApduLengthAccepted - request.segmentationSupported = this_device.segmentationSupported - request.vendorID = this_device.vendorIdentifier - if _debug: WhoIsIAmConsoleCmd._debug(" - request: %r", request) - - # make an IOCB - iocb = IOCB(request) - if _debug: WhoIsIAmConsoleCmd._debug(" - iocb: %r", iocb) - - # give it to the application - this_application.request_io(iocb) - - except Exception as err: - WhoIsIAmConsoleCmd._exception("exception: %r", err) + # code lives in the device service + this_application.i_am() def do_rtn(self, args): """rtn ... """ @@ -162,11 +139,12 @@ class WhoIsIAmConsoleCmd(ConsoleCmd): # -# main +# __main__ # def main(): - global this_device, this_application + global this_device + global this_application # parse the command line arguments args = ConfigArgumentParser(description=__doc__).parse_args() @@ -175,14 +153,16 @@ def main(): 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) + 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 = WhoIsIAmApplication( - this_device, args.ini.address, - ) - if _debug: _log.debug(" - this_application: %r", this_application) + this_application = WhoIsIAmApplication(this_device, args.ini.address) # make a console this_console = WhoIsIAmConsoleCmd() @@ -197,6 +177,5 @@ def main(): _log.debug("fini") - if __name__ == "__main__": main()