660 likes | 833 Views
WFE603. Programming in Python. Rob Faludi Collaborative Strategy Leader. Session Overview. Problem Statement Python Programming Language (v. 2.4 ) Python on Digi devices Digi ESP. The Problem. Putting application intelligence in the right places Writing simply
E N D
WFE603 Programming in Python Rob Faludi Collaborative Strategy Leader
Session Overview • Problem Statement • Python Programming Language (v. 2.4) • Python on Digi devices • Digi ESP
The Problem • Putting application intelligence in the right places • Writing simply • Writing experimentally • Writing powerfully
Open-source, flexible language that puts decision-making smarts on a gateway • Very simply to write basic code • Easy to experiment interactively • Powerful extensions • Broad support
High-level • Readable • Dynamically typed • Automatic memory management • Scripting, OOP, functions • Extensible • Powerful • Portable • Free
Zen of Python • Beautiful is better than ugly. • Explicit is better than implicit. • Simple is better than complex. • Complex is better than complicated. • Flat is better than nested. • Sparse is better than dense. • Readability counts. • Special cases aren't special enough to break the rules. • Although practicality beats purity. • Errors should never pass silently. • Unless explicitly silenced. • In the face of ambiguity, refuse the temptation to guess. • There should be one-- and preferably only one --obvious way to do it. • Although that way may not be obvious at first unless you're Dutch. • Now is better than never. • Although never is often better than *right* now. • If the implementation is hard to explain, it's a bad idea. • If the implementation is easy to explain, it may be a good idea. • Namespaces are one honking great idea -- let's do more of those!
Less is more • Less to type • Less to debug • Less to maintain • Productivity
Lots of Resources • Online • Python.org (http://docs.python.org) • Dive Into Python (http://diveintopython.org) • Python Challenge (http://www.pythonchallenge.com) • Books • Learning Python by Mark Lutz • Programming Python by Mark Lutz • Python Cookbook by Alex Martelli, Anna Martelli Ravenscroft, David Ascher
A basic program def hello(): """Prints a salutation to the user""" # Say hello print "Hello World!" if __name__ == "__main__": hello() Note that indentation dictates structure, not keywords or special tokens.
Really basic print "Hello World!"
Python is about getting work done print "Hello World!" print 2+2 foo="bar" print foo
Indentation Matters if 1+1==2: print "answer correct!" print "you did math!" if 1+1==3: print "answer correct" print "you did math!"
Core Data Types • Numbers • Strings • Lists • Dictionaries • Tuples • Files
Data types – Scalars • Numbers • Three types (int, float and long) • Varying representations (10, 0xa, 012) • Don't worry too much about type (except division) • 5 /2 = 2 • 5.0 / 2 = 2.5 • from __future__ import division • bool • Values ( True and False ) • None
Container Objects • Sequences • Strings: mystring ="abcdefg" • Lists: foo=[1, 'a', None] • Tuples: bar=(1, 'a', None) (immutable) • Mapping • Dictionaries: moof={"a": True, 42: 7}
Strings • Normal – "Hello\nThere" (allows escapes) • Triple-quoted (preserves entered text) """Hello There""" • Raw – r"Hello\nThere" (escapes ignored) • Unicode – u"\u0496"(inserts Җ) • Allows unicode escapes, creates unicode strings, a different type • Many native operations plus normal immutable sequence operations
dir shows available attributes >>> f= 37.1 >>> g="hello" >>> dir(f) ['__abs__', '__add__', '__class__', '__coerce__', '__delattr__', '__div__', '__divmod__', '__doc__', '__eq__', '__float__', '__floordiv__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__int__', '__le__', '__long__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__nonzero__', '__pos__', '__pow__', '__radd__', '__rdiv__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rmod__', '__rmul__', '__rpow__', '__rsub__', '__rtruediv__', '__setattr__', '__str__', '__sub__', '__truediv__'] >>> dir(g) ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__str__', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'replace', 'rfind', 'rindex', 'rjust', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill’]
Conditional Execution if <expr>: <…> elif <expr>: <…> else <expr>: <…> There is no goto or case statement in Python
Loops for <var> in <sequence>: <…> while <expr>: <…> • Variations: • break and continue affect looping • passcan act as a placeholder • (x)range(i[, j[, k]]) is extremely useful for for statements
Functions defarg_info(arg=42, *pos_args, **kw_args): """Doc-string""" if (arg == 42): print "arg has default value" # Print positional arguments for i in len(pos_args): # Use string formatting operator print "Positional argument %d is %v" % (i, pos_args[i]) print "Keyword arguments" for key in kw_args.keys(): print "\t", key, ": ", kw_args[key] return len(pos_args) + len(kw_args)
Modules • We already have seen one # hello.py def hello(): """Prints a salutation to the user""" # Say hello print "Hello World!" if __name__ == "__main__": hello() import hello hello.hello()
Importing • Styles • from <module> import <name> • import <module> as <alias> • Uses sys.path to find
Exceptions and Error Handling class ItCantWork(Exception): pass def no_work(): raise ValueError try: no_work() except ValueError, e: # handle exception does_work() else: raise ItCantWork
Homework • Classes • Generators • Iterators • List comprehensions • The standard library • Lots of other useful things…
Using Digi Python • Where do I configure Python on the Digi device? • Applications -> Python in the WebUI • Manage scripts and module files on the device • Configure Python scripts to run automatically on boot • Python in iDigi Manager Pro • Manage scripts and module files on the device • Configure Python scripts to run automatically on boot • Python command line tools • set python – Configure automatic start with added options • python – Run scripts manually, or enter an interactive session
Putting Files on the Device • Plain Text Files • use .py extension • upload files • iDigi • web UI • command line interface
Launching a Program • Check the Box • iDigi • web UI • command line interface • Command Line Launch • from CLI: set python • or from within Python: import <filename>
set python • Purpose: Configures Python programs to execute on device boot. • Syntax: set python [range=1-4] [state={on|off}] • [command=filename,args] • Options: • range=1-4 • Range specifies the index or indices to view or modify with the command. • state={on|off}When the state is set to on, the specified command is run when the device boots. • command=filename,argsThe program filename to execute and any arguments to pass with the program, similar to the arguments for the python command. The command option allows for programs to be run from a TFTP server; however, this usage is not recommended. If there are spaces to provide arguments, make sure to wrap the entire command in quotation marks.
Running Interpreter • terminal% telnet 192.168.1.200 • Trying 192.168.1.200... • Connected to 192.168.1.200 • Escape character is '^]'. • #> python • >>>
Monitoring the System Management -> Connections • For monitoring only, can't disconnect Python activity • Equivalent functionality in the CLI is the who command
Checking Resources (Memory) • The memory of the system is all the memory there is (no virtual memory), use it wisely. • The rest of the system uses memory as well, leave some for it (~400-500k at least)
Checking Resources (Sockets) 128 max in the entire system
Garbage Collection • Simplest: • Run gc.collect() as often as "you find necessary". • Tune thresholds (gc.set_threshold) • "correct" values vary widely per application • Don't use __del__ methods • If you must, break cycles manually by examining gc.garbage periodically and using your object knowledge to resolve the cycle
Viewing Debug Output #> set trace state=on mask=printf:* All sys.stdout and sys.stderr output from your script will be redirected to the console that ran trace.
XBee® Sockets Creation: from socket import * s = socket(AF_XBEE, SOCK_DGRAM, XBS_PROT_TRANSPORT) • XBee sockets are datagram sockets like UDP • Maximum packet length depends on radio technology and configuration Address format: (address_string, endpoint, profile_id, cluster_id) zigbee/zb_ex1_hello.py, zb_ex2_rw.py
XBee Module ddo_command(addr_extended, id[, param, timeout, order=False, apply=True) ddo_set_param(…) ddo_get_param(…) – No param argument Get/set DDO parameters on XBee modules • addr_extended– Address of node to configure • id – Two letter string identifying parameter • param – New value to set for ddo_command or ddo_set_param • timeout – Max time to wait for response • order – Force this request not to run concurrently • apply – Make changes active (Same as "AC" id) Returns: ddo_commandandddo_get_paramreturn binary string configuration value. ddo_set_param returns boolean success. All versions throw an exception if they cannot reach the radio.
XBee(cont…) get_node_list(<refresh>) -> list of node objects • Performs device discovery • refresh • False: returns the gateways cache of nodes. • True: Blocks to perform fresh discovery • Node object attributes • type: One of coordinator, router or end • addr_extended, addr_short: Address representations • addr_parent: Parent's short address • profile_id, manufacturer_id: Identifying characteristics • label: Nodes 'NI' parameter • device_type: Nodes 'DD' parameter zigbee/zb_ex4_disc.py
File system • Path structure is <VOLUME>/<path> • System volume is WEB • Python modules go in WEB/python • Directory listing/traversal may be limited • listdir, mkdir will be available in FW version 2.9 • USB volumes progress A, B, ... • Not guaranteed to enumerate the same each boot • Python file objects work completely.
DigicliModule import digicli digicli.digicli(<cmd>) -> (status, output) Run a CLI command • cmd – Command to run Returns • status – False if command failed • output – list of output lines from execution
Perform a Network Node Discovery # Perform a node discovery and print out # the list of discovered nodes to stdio. # import the zigbee module into its own namespace import zigbee # Perform a node discovery: node_list= zigbee.getnodelist() # Print the table: print "%12s %12s %8s %24s" % \ ("Label", "Type", "Short", "Extended") print "%12s %12s %8s %24s" % \ ("-" * 12, "-" * 12, "-" * 8, "-" * 24) for node in node_list: print "%12s %12s %8s %12s" % \ (node.label, node.type, node.addr_short, node.addr_extended)
Use DDO to Read Temperature from XBee Sensor # Collect a sample from a known XBee Sensor adapter # and parse it into a temperature. # import zigbee and xbee_sensor modules: import zigbee import xbee_sensor # configure known destination: DESTINATION="[00:13:a2:00:40:0a:07:8d]!" # ensure sensor is powered from adapter: zigbee.ddo_set_param(DESTINATION, 'D2', 5) zigbee.ddo_set_param(DESTINATION, 'AC', '') # get and parse sample: sample = zigbee.ddo_get_param(DESTINATION, '1S') xbee_temp = xbee_sensor.XBeeWatchportT() xbee_temp.parse_sample(sample) print "Temperature is: %f degrees Celsius" % (xbee_temp.temperature)
DigicliExample import digicli status, output = digicli.digicli('show net') if status: for line in output: if line.find('MAC Address') >= 0: l = line.split(':') print "".join(l[1:]).strip()import digicli digicli.digicli(<cmd>) -> (status, output)
The Digi ESP • An IDE used across several product lines, built on top of Eclipse • Facilitates development with Digi products • Distributed as a built-in product (not as plug-ins) • Powerful editing capabilities (syntax highlight, auto completion, syntax verification, …); Code builders and checkers; Integrated symbolic debugger • Example/Project wizards • Configuration tools • Extended through custom plug-ins to provide a better integration with our products • Bundled with other components needed like JVM, Python interpreters, etc • Multiplatform (runs on MS Windows, Linux and Mac)