45 from dbus.exceptions
import DBusException
54 NaoqiNode.__init__(self,
'nao_diagnostic_updater')
60 self.
sleep = 1.0/rospy.get_param(
'~update_rate', 0.5)
71 self.jointTempPathsList.append(
"Device/SubDeviceList/%s/Temperature/Sensor/Value" % self.
jointNamesList[i])
72 self.jointStiffPathsList.append(
"Device/SubDeviceList/%s/Hardness/Actuator/Value" % self.
jointNamesList[i])
76 "Device/SubDeviceList/Battery/Charge/Sensor/Status",
77 "Device/SubDeviceList/Battery/Current/Sensor/Value"]
81 if(len(deviceInfoData) > 1
and isinstance(deviceInfoData[1], list)):
82 deviceInfoData = deviceInfoData[1]
83 if(deviceInfoData[0]
is None or deviceInfoData[0] == 0):
86 if(self.pip.startswith(
"127.")
or self.
pip ==
"localhost"):
88 f = open(
"/etc/hostname")
100 rospy.loginfo(
"nao_diagnostic_updater initialized")
104 """ Connects to NaoQi and gets proxies to ALMotion and ALMemory. """ 105 rospy.loginfo(
"Connecting to NaoQi at %s:%d", self.
pip, self.
pport)
112 """ Diagnostic thread code - collects and sends out diagnostic data. """ 119 if isinstance(jointsTempData[1], list):
123 jointsTempData = jointsTempData[1]
124 jointsStiffData = jointsStiffData[1]
125 batteryData = batteryData[1]
126 except RuntimeError,e:
127 print "Error accessing ALMemory, exiting...\n" 129 rospy.signal_shutdown(
"No NaoQI available anymore")
131 diagnosticArray = DiagnosticArray()
135 status = DiagnosticStatus()
139 kv.key =
"Temperature" 140 temperature = jointsTempData[i]
141 kv.value = str(temperature)
142 status.values.append(kv)
149 kv.value = str(jointsStiffData[i])
150 status.values.append(kv)
151 if (type(temperature) != float
and type(temperature) != int)
or self.
jointNamesList[i] ==
"RHipYawPitch":
152 status.level = DiagnosticStatus.OK
153 status.message =
"No temperature sensor" 155 status.level = DiagnosticStatus.OK
156 status.message =
"Normal: %3.1f C" % temperature
158 status.level = DiagnosticStatus.WARN
159 status.message =
"Hot: %3.1f C" % temperature
161 status.level = DiagnosticStatus.ERROR
162 status.message =
"Too hot: %3.1f C" % temperature
163 diagnosticArray.status.append(status)
166 status = DiagnosticStatus()
167 status.hardware_id =
"%s#%s"%(self.
hardwareID,
"battery")
168 status.name =
"nao_power: Battery" 170 kv.key =
"Percentage" 171 if batteryData[0]
is None:
174 kv.value = str(batteryData[0] * 100)
175 status.values.append(kv)
179 statuskeys = [
"End off Discharge flag",
"Near End Off Discharge flag",
"Charge FET on",
"Discharge FET on",
"Accu learn flag",
"Discharging flag",
"Full Charge Flag",
"Charge Flag",
"Charge Temperature Alarm",
"Over Charge Alarm",
"Discharge Alarm",
"Charge Over Current Alarm",
"Discharge Over Current Alarm (14A)",
"Discharge Over Current Alarm (6A)",
"Discharge Temperature Alarm",
"Power-Supply present" ]
181 for j
in range(0, 16):
183 kv.key = statuskeys[j]
184 if batteryData[1]
is None:
186 elif int(batteryData[1]) & 1<<j:
190 status.values.append(kv)
194 if batteryData[1]
is None:
197 kv.value = bin(int(batteryData[1]))
198 status.values.append(kv)
201 if batteryData[0]
is None:
202 status.level = DiagnosticStatus.OK
203 status.message =
"Battery status unknown, assuming simulation" 204 elif int(batteryData[1]) & 1<<6:
205 status.level = DiagnosticStatus.OK
206 status.message =
"Battery fully charged" 207 elif int(batteryData[1]) & 1<<7:
208 status.level = DiagnosticStatus.OK
209 status.message =
"Charging (%3.1f%%)" % (batteryData[0] * 100)
210 elif batteryData[0] > 0.60:
211 status.level = DiagnosticStatus.OK
212 status.message =
"Battery OK (%3.1f%% left)" % (batteryData[0] * 100)
213 elif batteryData[0] > 0.30:
214 status.level = DiagnosticStatus.WARN
215 status.message =
"Battery discharging (%3.1f%% left)" % (batteryData[0] * 100)
217 status.level = DiagnosticStatus.ERROR
218 status.message =
"Battery almost empty (%3.1f%% left)" % (batteryData[0] * 100)
219 diagnosticArray.status.append(status)
222 status = DiagnosticStatus()
223 status.hardware_id =
"%s#%s"%(self.
hardwareID,
"power")
224 status.name =
"nao_power: Current" 226 if batteryData[2]
is None:
227 status.level = DiagnosticStatus.OK
228 status.message =
"Total Current: unknown" 232 kv.value = str(batteryData[2])
233 status.values.append(kv)
234 status.level = DiagnosticStatus.OK
235 if batteryData[2] > 0:
236 currentStatus =
"charging" 238 currentStatus =
"discharging" 239 status.message =
"Total Current: %3.2f Ampere (%s)" % (batteryData[2], currentStatus)
240 diagnosticArray.status.append(status)
243 status = DiagnosticStatus()
244 status.hardware_id =
"%s#%s"%(self.
hardwareID,
"cpu")
245 status.name =
"nao_cpu: Head Temperature" 248 kv.key =
"CPU Temperature" 249 kv.value = str(temp[
'HeadSilicium'])
250 status.values.append(kv)
252 kv.key =
"Board Temperature" 253 kv.value = str(temp[
'HeadBoard'])
254 status.values.append(kv)
255 if(temp[
'HeadSilicium'] ==
"invalid"):
256 status.level = DiagnosticStatus.OK
257 status.message =
"unknown, assuming simulation" 259 status.message =
"%3.2f deg C" % (temp[
'HeadSilicium'])
260 if temp[
'HeadSilicium'] < 100:
261 status.level = DiagnosticStatus.OK
262 elif temp[
'HeadSilicium'] < 105:
263 status.level = DiagnosticStatus.WARN
265 status.level = DiagnosticStatus.ERROR
266 diagnosticArray.status.append(status)
269 statusWifi = DiagnosticStatus()
270 statusWifi.hardware_id =
"%s#%s"%(self.
hardwareID,
"wlan")
271 statusWifi.name =
"nao_wlan: Status" 273 statusLan = DiagnosticStatus()
274 statusLan.hardware_id =
"%s#%s"%(self.
hardwareID,
"ethernet")
275 statusLan.name =
"nao_ethernet: Status" 278 statusLan.level = DiagnosticStatus.ERROR
279 statusLan.message =
"offline" 280 statusWifi.level = DiagnosticStatus.ERROR
281 statusWifi.message =
"offline" 282 systemBus = dbus.SystemBus()
284 manager = dbus.Interface(systemBus.get_object(
"org.moblin.connman",
"/"),
"org.moblin.connman.Manager")
285 except DBusException
as e:
288 properties = manager.GetProperties()
289 for property
in properties[
"Services"]:
290 service = dbus.Interface(systemBus.get_object(
"org.moblin.connman", property),
"org.moblin.connman.Service")
292 props = service.GetProperties()
293 except DBusException
as e:
296 state = str(props.get(
"State",
"None"))
300 nettype = str(props.get(
"Type",
"<unknown>"))
301 if(nettype ==
"wifi"):
307 kv.value = str(props.get(
"Name",
"<unknown>"))
308 status.values.append(kv)
309 if nettype ==
"wifi":
310 strength = int(props.get(
"Strength",
"<unknown>"))
313 kv.value =
"%d%%"%strength
314 status.values.append(kv)
320 status.values.append(kv)
322 status.message = state
324 status.message =
"%s (%d%%)"%(state, strength)
326 if state
in [
"online",
"ready"]:
327 status.level = DiagnosticStatus.OK
328 elif state
in [
"configuration",
"association"]:
329 status.level = DiagnosticStatus.WARN
331 status.message = str(
"%s (%s)"%(state, props.get(
"Error")))
332 status.level = DiagnosticStatus.ERROR
334 statusWifi.level = DiagnosticStatus.OK
335 statusWifi.message =
"nao_diagnostic_updater not running on robot, cannot determine WLAN status" 337 statusLan.level = DiagnosticStatus.OK
338 statusLan.message =
"nao_diagnostic_updater not running on robot, cannot determine Ethernet status" 340 diagnosticArray.status.append(statusWifi)
341 diagnosticArray.status.append(statusLan)
344 diagnosticArray.header.stamp = rospy.Time.now()
345 self.diagnosticPub.publish(diagnosticArray)
346 rospy.sleep(self.
sleep)
349 """Read the CPU and head temperature from the system devices. 351 Returns {'HeadSilicium': <temperature>, 'HeadBoard': <temperature>} 353 Temperatures are returned as float values in degrees Celsius, or 354 as the string 'invalid' if the sensors are not accessible. 356 temp = {
'HeadSilicium':
'invalid',
'HeadBoard':
'invalid'}
359 f = open(
"/sys/class/i2c-adapter/i2c-1/1-004c/temp2_input")
360 temp[
'HeadSilicium'] = float(f.readline()) / 1000.
366 temp[
'HeadSilicium'] =
"invalid" 368 f = open(
"/sys/class/i2c-adapter/i2c-1/1-004c/temp1_input")
369 temp[
'HeadBoard'] = float(f.readline()) / 1000.
375 temp[
'HeadBoard'] =
"invalid" 379 if __name__ ==
'__main__':
def get_proxy(self, name, warn=True)