Skip to content

Commit

Permalink
[jsk_network_tools] add wifi_status.py
Browse files Browse the repository at this point in the history
  • Loading branch information
furushchev committed Aug 27, 2016
1 parent cab9af1 commit 8672057
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 0 deletions.
1 change: 1 addition & 0 deletions jsk_network_tools/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ add_message_files(
OpenNISample.msg
AllTypeTest.msg
SilverhammerInternalBuffer.msg
WifiStatus.msg
)
add_service_files(
FILES
Expand Down
12 changes: 12 additions & 0 deletions jsk_network_tools/launch/wifi_status.launch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<launch>
<arg name="network_interface" default="wlan0" />
<arg name="warning_quality" default="0.4" />
<arg name="update_rate" default="1.0" />

<node name="wifi_status"
pkg="jsk_network_tools" type="wifi_status.py">
<param name="network_interface" value="$(arg network_interface)" />
<param name="warning_quality" value="$(arg warning_quality)" />
<param name="update_rate" value="$(arg update_rate)" />
</node>
</launch>
11 changes: 11 additions & 0 deletions jsk_network_tools/msg/WifiStatus.msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
Header header
string interface
bool enabled
bool connected
string ssid
string frequency
string access_point
string bitrate
string tx_power
string link_quality
string signal_level
109 changes: 109 additions & 0 deletions jsk_network_tools/scripts/wifi_status.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: Yuki Furuta <[email protected]>

import re
import subprocess
import traceback

import rospy
from diagnostic_msgs.msg import DiagnosticStatus, KeyValue, DiagnosticArray
from jsk_network_tools.msg import WifiStatus

class Iwconfig(object):
def __init__(self, dev):
self.dev = dev
self.status = {}
def fetch(self):
try:
output = subprocess.check_output(["iwconfig", self.dev],
stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
rospy.logdebug("iwconfig command return non-zero code: %s" % str(e.returncode))
output = e.output
for entity in re.split('\s{2,}', output.replace('=',':').replace('"','')):
splitted = entity.split(':')
if len(splitted) >= 2:
key = entity.split(':')[0].strip()
value = "".join(entity.split(':')[1:]).strip()
if "Quality" in key:
q1, q2 = value.split('/')
value = str(float(q1) / float(q2))
self.status[key] = value
def is_enabled(self):
if "ESSID" not in self.status:
return False
else:
return True
def is_connected(self):
if not self.is_enabled():
return False
elif "off" in self.status["ESSID"]:
return False
else:
return True

class WifiStatusPublisherNode(object):
def __init__(self):
self.ifname = rospy.get_param("~network_interface", "wlan0")
self.rate = rospy.get_param("~update_rate", 1.0)
self.warn_quality = rospy.get_param("~warning_quality", 0.4)
self.iwconfig = Iwconfig(self.ifname)
self.status_pub = rospy.Publisher("~status", WifiStatus, queue_size=1)
self.diagnostic_pub = rospy.Publisher("/diagnostics", DiagnosticArray, queue_size=1)
self.poll_timer = rospy.Timer(rospy.Rate(self.rate).sleep_dur, self.poll)
def poll(self, event=None):
self.iwconfig.fetch()
self.publish_status()
self.diagnostic()
def publish_status(self):
try:
msg = WifiStatus()
msg.header.stamp = rospy.Time.now()
msg.interface = self.ifname
msg.enabled = self.iwconfig.is_enabled()
msg.connected = self.iwconfig.is_connected()
if self.iwconfig.is_connected():
msg.ssid = self.iwconfig.status["ESSID"]
msg.frequency = self.iwconfig.status["Frequency"]
msg.access_point = self.iwconfig.status["Access Point"]
msg.bitrate = self.iwconfig.status["Bit Rate"]
msg.tx_power = self.iwconfig.status["Tx-Power"]
msg.link_quality = str(self.iwconfig.status["Link Quality"])
msg.signal_level = self.iwconfig.status["Signal level"]
self.status_pub.publish(msg)
except Exception as e:
rospy.logerr("Failed to publish status: %s" % str(e))
rospy.logerr(traceback.format_exc())
def diagnostic(self):
try:
da = DiagnosticArray()
ds = DiagnosticStatus()
ds.name = rospy.get_caller_id().lstrip('/') + ': Status'
ds.hardware_id = self.ifname
if not self.iwconfig.is_enabled():
ds.level = DiagnosticStatus.STALE
ds.message = "Device not found"
elif not self.iwconfig.is_connected():
ds.level = DiagnosticStatus.ERROR
ds.message = "No connection"
else:
if float(self.iwconfig.status["Link Quality"]) < self.warn_quality:
ds.level = DiagnosticStatus.WARN
ds.message = "Connected, but bad quality"
else:
ds.level = DiagnosticStatus.OK
ds.message = "Connected"
for key, val in self.iwconfig.status.items():
ds.values.append(KeyValue(key, val))
da.status.append(ds)
da.header.stamp = rospy.Time.now()
self.diagnostic_pub.publish(da)
except Exception as e:
rospy.logerr('Failed to publish diagnostic: %s' % str(e))
rospy.logerr(traceback.format_exc())

if __name__ == '__main__':
rospy.init_node("wifi_status")
n = WifiStatusPublisherNode()
rospy.spin()

0 comments on commit 8672057

Please sign in to comment.