Robot Web Services
3HAC050973-001 Revision:L, Application Manual - Robot Web Services
RWPanelSubscriber.py

Temporary This example program subscribes on RobotWare Panel resources and displays the changes in Controller State, Speed Ratio and the Operation Mode. The application sets-up a websocket connection and retrieve panel resource events. The Authorization header is retrieved from the initial HTTP request to subscribe which is then passed in web socket upgrade request.* The inbound events received on the websocket is parsed and the event data is displayed.

The output will look like:

Initial Events :
Controller State : motoron
Operation Mode : MANR
Speed Ratio : 25
Web Sockect connection established
Events :
        Speed Ratio : 50
Events :
        Controller State : motoroff
Events :
        Operation Mode : AUTO
Events :
        Speed Ratio : 100

Program:

1 # Web socket client using https://ws4py.readthedocs.org/en/latest/
2 import sys, argparse
3 import xml.etree.ElementTree as ET
4 from ws4py.client.threadedclient import WebSocketClient
5 import requests
6 from requests.auth import HTTPDigestAuth
7 
8 namespace = '{http://www.w3.org/1999/xhtml}'
9 
10 def print_event(evt):
11  root = ET.fromstring(evt)
12  if root.findall(".//{0}li[@class='pnl-ctrlstate-ev']".format(namespace)):
13  print ("\tController State : " + root.find(".//{0}li[@class='pnl-ctrlstate-ev']/{0}span".format(namespace)).text)
14  if root.findall(".//{0}li[@class='pnl-opmode-ev']".format(namespace)):
15  print ("\tOperation Mode : " + root.find(".//{0}li[@class='pnl-opmode-ev']/{0}span".format(namespace)).text)
16  if root.findall(".//{0}li[@class='pnl-speedratio-ev']".format(namespace)):
17  print ("\tSpeed Ratio : " + root.find(".//{0}li[@class='pnl-speedratio-ev']/{0}span".format(namespace)).text)
18 
19 
20 
21 # This class encapsulates the Web Socket Callbacks functions.
22 class RobWebSocketClient(WebSocketClient):
23  def opened(self):
24  print ("Web Sockect connection established")
25 
26  def closed(self, code, reason=None):
27  print ("Closed down", code, reason)
28 
29  def received_message(self, event_xml):
30  if event_xml.is_text:
31  print ("Events : ")
32  print_event(event_xml.data.decode("utf-8"))
33  else:
34  print ("Received Illegal Event " + str(event_xml))
35 
36 
37 # The main RobotWare Panel class
38 class RWPanel:
39 
40  def __init__(self, host, username, password):
41  self.host = host
42  self.username = username
43  self.password = password
44  self.digest_auth = HTTPDigestAuth(self.username,self.password)
45  self.subscription_url = 'http://{0}/subscription'.format(self.host)
46  self.session = requests.Session()
47 
48 
49  def subscribe(self):
50  # Create a payload to subscribe on RobotWare Panel Resources with high priority
51  payload = {'resources':['1','2','3'],
52  '1':'/rw/panel/speedratio',
53  '1-p':'1',
54  '2':'/rw/panel/ctrlstate',
55  '2-p':'1',
56  '3':'/rw/panel/opmode',
57  '3-p':'1'}
58 
59  resp = self.session.post(self.subscription_url , auth=self.digest_auth, data=payload)
60  print ("Initial Events : ")
61  print_event(resp.text)
62  if resp.status_code == 201:
63  self.location = resp.headers['Location']
64  self.cookie = '-http-session-={0}; ABBCX={1}'.format(resp.cookies['-http-session-'], resp.cookies['ABBCX'])
65  return True
66  else:
67  print ('Error subscribing ' + str(resp.status_code))
68  return False
69 
70  def start_recv_events(self):
71  self.header = [('Cookie',self.cookie)]
72  self.ws = RobWebSocketClient(self.location,
73  protocols=['robapi2_subscription'],
74  headers=self.header)
75  self.ws.connect()
76  self.ws.run_forever()
77 
78  def close(self):
79  self.ws.close()
80 
81 
82 def enable_http_debug():
83  import logging
84  import httplib
85  httplib.HTTPConnection.debuglevel = 1
86  logging.basicConfig() # Initialize logging
87  logging.getLogger().setLevel(logging.DEBUG)
88  requests_log = logging.getLogger("requests.packages.urllib3")
89  requests_log.setLevel(logging.DEBUG)
90  requests_log.propagate = True
91 
92 def main(argv):
93  try:
94  parser = argparse.ArgumentParser()
95  parser.add_argument("-host",help="The host to connect. Defaults to localhost on port 80", default='localhost:80')
96  parser.add_argument("-user",help="The login user name. Defaults to default user name", default='Default User')
97  parser.add_argument("-passcode",help="The login password. Defaults to default password", default='robotics')
98  parser.add_argument("-debug",help="Enable HTTP level debugging.", action='store_true')
99  args = parser.parse_args()
100 
101  if args.debug:
102  enable_http_debug()
103 
104  rwpanel = RWPanel(args.host, args.user, args.passcode)
105  if rwpanel.subscribe():
106  rwpanel.start_recv_events()
107  except KeyboardInterrupt:
108  rwpanel.close()
109 
110 
111 if __name__ == "__main__":
112  main(sys.argv[1:])
113 
114 
115 
116 
117 
118 
119 
120