wlan_monitor.py
Go to the documentation of this file.
1 #!/usr/bin/env python
2 #
3 # Copyright 2017 Fraunhofer Institute for Manufacturing Engineering and Automation (IPA)
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16 
17 import getpass
18 import re
19 import os
20 import sys
21 from subprocess import Popen, PIPE
22 import paramiko
23 
24 import rospy
25 from diagnostic_msgs.msg import DiagnosticArray, DiagnosticStatus, KeyValue
26 
27 class IwConfigParser(object):
28  def _parse_info(self, info):
29  values = []
30  # split by either double-space or newline
31  for information in re.split(" |\n",info):
32  # split by either : or =
33  content = re.split(":|=", information)
34  if len(content) == 2:
35  try:
36  content[0] = content[0].decode() #python3
37  content[1] = content[1].decode() #python3
38  except (UnicodeDecodeError, AttributeError):
39  pass
40  values.append(KeyValue(content[0].lstrip(), content[1].rstrip()))
41  return values
42 
44  def __init__(self):
45  IwConfigParser.__init__(self)
46 
47  self.interfaces = []
48  self.stat = DiagnosticStatus()
49  self.stat.level = DiagnosticStatus.OK
50  self.stat.message = "OK"
51  self.stat.values = []
52  try:
53  p = Popen("iw dev | awk '$1==\"Interface\"{print $2}'", stdout=PIPE, stdin=PIPE, stderr=PIPE, shell=True)
54  res = p.wait()
55  (stdout,stderr) = p.communicate()
56  try:
57  stdout = stdout.decode() #python3
58  except (UnicodeDecodeError, AttributeError):
59  pass
60  self.interfaces = sorted(os.linesep.join([s for s in stdout.splitlines() if s]).split('\n'))
61  except Exception as e:
62  rospy.logerr("IwConfigLocal init exception: %s" %e)
63 
64  def update(self):
65  self.stat.level = DiagnosticStatus.OK
66  self.stat.message = "OK"
67  self.stat.values = []
68  for interface in self.interfaces:
69  self.stat.values.append(KeyValue(key = str(interface), value = "======================="))
70  try:
71  p = Popen(["iwconfig", interface], stdout=PIPE, stdin=PIPE, stderr=PIPE)
72  res = p.wait()
73  (stdout,stderr) = p.communicate()
74  try:
75  stdout = stdout.decode() #python3
76  except (UnicodeDecodeError, AttributeError):
77  pass
78 
79  if res != 0:
80  self.stat.values.append(KeyValue(key = 'iwconfig stderr', value = stderr))
81  self.stat.values.append(KeyValue(key = 'iwconfig stdout', value = stdout))
82  else:
83  self.stat.values += self._parse_info(stdout)
84  except Exception as e:
85  rospy.logerr("IwConfigLocal update exception: %s" %e)
86  self.stat.values.append(KeyValue(key = 'update exception', value = str(e)))
87 
89  def __init__(self, hostname, user, password):
90  IwConfigParser.__init__(self)
91  self.ssh = paramiko.SSHClient()
92  self.ssh.load_system_host_keys()
93  ssh_key_file = os.getenv("HOME")+'/.ssh/id_rsa.pub'
94  self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())# no known_hosts error
95  self.ssh.connect(str(hostname), username=user, key_filename=ssh_key_file) # no passwd needed
96  #self.ssh.connect(str(hostname), username=user, password=password)
97 
98  self.interfaces = []
99  self.stat = DiagnosticStatus()
100  self.stat.level = DiagnosticStatus.OK
101  self.stat.message = "OK"
102  self.stat.values = []
103  try:
104  (stdin, stdout, stderr) = self.ssh.exec_command("iw dev | awk '$1==\"Interface\"{print $2}'")
105  output = ''.join(stdout.readlines())
106  self.interfaces = sorted(os.linesep.join([s for s in output.splitlines() if s]).split('\n'))
107  except Exception as e:
108  rospy.logerr("IwConfigSSH init exception: %s" %e)
109 
110  def update(self):
111  self.stat.level = DiagnosticStatus.OK
112  self.stat.message = "OK"
113  self.stat.values = []
114  for interface in self.interfaces:
115  self.stat.values.append(KeyValue(key = str(interface), value = "======================="))
116  try:
117  (stdin, stdout, stderr) = self.ssh.exec_command("iwconfig %s"%interface)
118 
119  output = ''.join(stdout.readlines())
120  self.stat.values += self._parse_info(output)
121  except Exception as e:
122  rospy.logerr("IwConfigSSH update exception: %s" %e)
123  self.stat.values.append(KeyValue(key = 'update exception', value = str(e)))
124 
125 class WlanMonitor():
126  def __init__(self):
127  rospy.init_node("wlan_monitor")
128  self.get_params()
129 
130  self._wlan_stat = DiagnosticStatus()
131  self._wlan_stat.name = '%s WLAN Info' % self.diag_hostname
132  self._wlan_stat.hardware_id = self.diag_hostname
133  self._wlan_stat.level = DiagnosticStatus.OK
134  self._wlan_stat.message = 'No Data'
135  self._wlan_stat.values = []
136  self.msg = DiagnosticArray()
137  self.msg.header.stamp = rospy.get_rostime()
138  self.msg.status = [self._wlan_stat]
139 
140  self.diag_pub = rospy.Publisher("/diagnostics", DiagnosticArray, queue_size=1)
141  self.diag_timer = rospy.Timer(rospy.Duration(1.0), self.publish_diagnostics)
142 
143  if self.monitor_local:
145  else:
146  try:
147  self.iwconfig = IwConfigSSH(self.diag_hostname, self.user, self.password)
148  except Exception as e:
149  msg = "Cannot connect to router via ssh. Please check if ssh key of user '{}' is contained in the router configuration or password is provided. Error message: {}".format(getpass.getuser(), e)
150  rospy.logerr(msg)
151  self._wlan_stat.level = DiagnosticStatus.ERROR
152  self._wlan_stat.message = msg
153  self._wlan_stat.values = [ KeyValue(key = 'Exception', value = str(e)) ]
154  self.msg.status = [self._wlan_stat]
155  return
156 
157  self.monitor_timer = rospy.Timer(rospy.Duration(1.0), self.update_diagnostics)
158 
159  def update_diagnostics(self, event):
160  self.iwconfig.update()
161 
162  self.msg = DiagnosticArray()
163  self.msg.header.stamp = rospy.get_rostime()
164  self._wlan_stat.level = self.iwconfig.stat.level
165  self._wlan_stat.message = self.iwconfig.stat.message
166  self._wlan_stat.values = self.iwconfig.stat.values
167  self.msg.status = [self._wlan_stat]
168 
169  def publish_diagnostics(self, event):
170  self.diag_pub.publish(self.msg)
171 
172  def get_params(self):
173  self.diag_hostname = rospy.get_param('~diag_hostname', "localhost")
174  self.monitor_local = rospy.get_param("~monitor_local", True)
175  self.user = rospy.get_param('~user', "")
176  self.password = rospy.get_param('~password', "")
177 
178 if __name__ == "__main__":
179  monitor = WlanMonitor()
180  rospy.spin()
def update_diagnostics(self, event)
def _parse_info(self, info)
Definition: wlan_monitor.py:28
def publish_diagnostics(self, event)
def __init__(self, hostname, user, password)
Definition: wlan_monitor.py:89


cob_monitoring
Author(s): Florian Weisshardt , Felix Messmer
autogenerated on Wed Apr 7 2021 03:03:11