Module:rci
From Digi Developer
This module allows you to attach a callback to handle RCI Requests. It also provides functionality allowing an RCI request to be processed in the gateway, and the response to be returned.
Note: there are limitations on the XML data which may be passed through an RCI callback on many Digi devices (e.g. the ConnectPort X2, X4, and X8). These limits are:
- Max attribute length (e.g. <tag attribute="this field length" />): 50 characters
- Max number of attributes (per element): 10 attributes
- Max element tag length: 50 characters
Contents |
API
add_rci_callback(name, callback) return None
Function callback is called when name is sent as a rci do_command target.
callback will be called with a string representing the xml contained within the do_command. callback returns a string which will be returned to the caller as the result of the request. The returned string must e valid xml. Returning invalid xml will result in invalid xml being returned to the requester. Note, plain text is valid xml. Binary data must be base64 encoded. If no reply is expected, an empty string ("") must be returned
This is a blocking call. callback will be called from the thread that calls this function.
There are no limitations on what the callback function does, However, device processing waits for a response so it is recommended to keep processing to a minimum. Best practice is to respond immediately and then perform processing in another thread. If no response is returned from callback within 45 seconds, the device will stop waiting and return a warning to the RCI requester.
stop_rci_callback(name) return None
Stops the previously called add_rci_callback with the specified name.
process_request(request) return response
Processes an RCI request and returns the response.
Examples
Example #1
This example will print out any data sent to it and then send the data back as the reply
import rci def rci_callback(xml): print xml return "received: %s" % (xml) rci.add_rci_callback("rci_callback_example", rci_callback)
Running this, send a RCI request as follows to the device
<rci_request version="1.1"> <do_command target="rci_callback_example"> ping </do_command> </rci_request>
In reply the device will send:
<rci_reply version="1.1"><do_command target="rci_callback_example"> received:ping </do_command></rci_reply>
Example #2
This example will use the producer/consumer design pattern to have asynchronous RCI calls. The work in the consumer thread in this case will just write the messages to standard out. This design pattern is good to use if you are using the RCI mechanism to do some action that can take awhile to process instead of using it as a mechanism to retrieve prepared data from the device.
import rci import thread from Queue import Queue # queue to hold messages between producer and consumer threads q = Queue(10) def rci_callback(xml): # Stop listening if the message contains the string "STOP" if xml.find("STOP")>-1: rci.stop_rci_callback("rci_callback_example") return "Stopped" # Because we have limited time and are blocking the response in the # callback thread we will act as a producer, adding incomming messages # to a Queue to be processed by a consumer thread q.put(xml) return "Ok" def producer_thread(): print "listening for RCI callbacks" #Start listening for RCI messages, block until unregistered or an exception occurs rci.add_rci_callback("rci_callback_example", rci_callback) print "STOP received, no longer listening" # start a thread to handle RCI requests thread.start_new_thread(producer_thread, ()) # Main thread will now become a consumer of the queue while True: data = q.get() print data
Example #3
This example shows how you would make use of the process_request method to retrieve the uptime of the Digi device. This does NOT require a callback be installed. The response is generated by the core services within the Digi product.
# import the rci module to get access to the process_request method import rci # This is the rci request that will return device statistics request = '<rci_request version="1.1"><query_state><device_stats/></query_state></rci_request>' # Response will store the response from the rci request response = rci.process_request(request)
The contents of response will be similar to:
<rci_reply version="1.1"> <query_state> <device_stats> <cpu>9</cpu> <uptime>341961</uptime> <datetime>Mon May 11 10:24:47 2009</datetime> <totalmem>16777216</totalmem> <usedmem>13243060</usedmem> <freemem>3534156</freemem> </device_stats> </query_state> </rci_reply>
