blob: f951eeba45d2f133cd4b9495d98b6f69357824e3 [file] [log] [blame]
#!/usr/bin/python -u
import sys
import subprocess
#from gi.repository import GObject
import gobject
import dbus
import dbus.service
import dbus.mainloop.glib
import os
import Openbmc
## Abstract class, must subclass
class SensorValue(Openbmc.DbusProperties):
IFACE_NAME = 'org.openbmc.SensorValue'
def __init__(self,bus,name):
#Openbmc.DbusProperties.__init__(self)
self.Set(SensorValue.IFACE_NAME,'units',"")
self.Set(SensorValue.IFACE_NAME,'error',False)
@dbus.service.method(IFACE_NAME,
in_signature='v', out_signature='')
def setValue(self,value):
self.Set(SensorValue.IFACE_NAME,'value',value)
@dbus.service.method(IFACE_NAME,
in_signature='', out_signature='v')
def getValue(self):
return self.Get(SensorValue.IFACE_NAME,'value')
class SensorThresholds(Openbmc.DbusProperties):
IFACE_NAME = 'org.openbmc.SensorThresholds'
def __init__(self,bus,name):
self.Set(SensorThresholds.IFACE_NAME,'thresholds_enabled',False)
self.Set(SensorThresholds.IFACE_NAME,'emergency_enabled',False)
self.Set(SensorThresholds.IFACE_NAME,'warning_upper',0)
self.Set(SensorThresholds.IFACE_NAME,'warning_lower',0)
self.Set(SensorThresholds.IFACE_NAME,'critical_upper',0)
self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
self.Set(SensorThresholds.IFACE_NAME,'critical_lower',0)
self.Set(SensorThresholds.IFACE_NAME,'threshold_state',"NORMAL")
self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
@dbus.service.method(IFACE_NAME,
in_signature='', out_signature='')
def resetThresholdState(self):
self.Set(SensorThresholds.IFACE_NAME,'worst_threshold_state',"NORMAL")
def check_thresholds(self,value):
iface = SensorThresholds.IFACE_NAME
if (self.Get(iface,'thresholds_enabled') == False):
return False
rtn = False
current_state = "NORMAL"
if (value >= self.properties[iface]['critical_upper']):
current_state = "CRITICAL"
rtn = True
elif (value <= self.properties[iface]['critical_lower']):
current_state = "CRITICAL"
rtn = True
elif (value >= self.properties[iface]['warning_upper']):
current_state = "WARNING"
rtn = True
elif (value <= self.properties[iface]['warning_lower']):
current_state = "WARNING"
rtn = True
if (self.Get(iface,'threshold_state') != current_state and
current_state == "CRITICAL" and
self.Get(iface,'emergency_enabled') == True):
self.Emergency()
self.Set(iface,'threshold_state',current_state)
worst = self.properties[iface]['worst_threshold_state']
if (current_state == "CRITICAL" or
(current_state == "WARNING" and worst != "CRITICAL")):
self.Set(iface,'worst_threshold_state',current_state)
return rtn
@dbus.service.signal(IFACE_NAME,signature='')
def Emergency(self):
pass
class VirtualSensor(SensorValue):
def __init__(self,bus,name):
Openbmc.DbusProperties.__init__(self)
SensorValue.__init__(self,bus,name)
dbus.service.Object.__init__(self,bus,name)
class HwmonSensor(SensorValue,SensorThresholds):
IFACE_NAME = 'org.openbmc.HwmonSensor'
def __init__(self,bus,name):
Openbmc.DbusProperties.__init__(self)
SensorValue.__init__(self,bus,name)
SensorThresholds.__init__(self,bus,name)
self.Set(HwmonSensor.IFACE_NAME,'scale',1)
self.Set(HwmonSensor.IFACE_NAME,'offset',0)
self.Set(HwmonSensor.IFACE_NAME,'filename','')
self.value_dirty = False
# need to cache value to know if changed
self.value = None
dbus.service.Object.__init__(self,bus,name)
@dbus.service.method(SensorValue.IFACE_NAME,
in_signature='v', out_signature='')
def setValue(self,value):
self.value_dirty = True
SensorValue.setValue(self,value)
## Called by sensor process to update value from polling
## if returns not None, then sensor process will update hwmon value
@dbus.service.method(IFACE_NAME,
in_signature='v', out_signature='(bv)')
def setByPoll(self,value):
scale = self.properties[HwmonSensor.IFACE_NAME]['scale']
offset = self.properties[HwmonSensor.IFACE_NAME]['offset']
if (self.value_dirty == True):
## new value externally set, so just return to hwmon
## process to write value
self.value_dirty = False
val = (self.properties[SensorValue.IFACE_NAME]['value']-offset) * scale
return [True,val]
else:
val = (value/scale) + offset
if (val != self.value):
SensorValue.setValue(self,val)
self.check_thresholds(val)
self.value = val
return [False,0]
CONTROL_IFACE = 'org.openbmc.Control'
class PowerCap(VirtualSensor):
def __init__(self, bus, name):
VirtualSensor.__init__(self, bus, name)
SensorValue.setValue(self, 0)
self.sysfs_attr = "/sys/class/hwmon/hwmon3/user_powercap"
##override setValue method
@dbus.service.method(SensorValue.IFACE_NAME,
in_signature='v', out_signature='')
def setValue(self, value):
try:
cmd_str = "echo "+str(value)+" > "+self.sysfs_attr
ret = subprocess.check_output(cmd_str, shell=True)
except subprocess.CalledProcessError as powerexc:
print "Set PowerCap Error", powerexc.returncode,
powerexc.output
return
print "Set PowerCap: ", value
SensorValue.setValue(self, value)
class BootProgressSensor(VirtualSensor):
def __init__(self,bus,name):
VirtualSensor.__init__(self,bus,name)
self.setValue("Off")
bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
def SystemStateHandler(self,state):
if (state == "HOST_POWERED_OFF"):
self.setValue("Off")
##override setValue method
@dbus.service.method(SensorValue.IFACE_NAME,
in_signature='v', out_signature='')
def setValue(self,value):
SensorValue.setValue(self,value)
if (value == "FW Progress, Starting OS"):
self.GotoSystemState("HOST_BOOTED")
@dbus.service.signal(CONTROL_IFACE,signature='s')
def GotoSystemState(self,state):
pass
class OccStatusSensor(VirtualSensor):
def __init__(self,bus,name):
## default path. can be override
self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
VirtualSensor.__init__(self,bus,name)
self.setValue("Disabled")
bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
def SystemStateHandler(self,state):
if (state == "HOST_POWERED_OFF"):
self.setValue("Disabled")
##override setValue method
@dbus.service.method(SensorValue.IFACE_NAME,
in_signature='v', out_signature='')
def setValue(self,value):
if (value == "Enabled"):
print "Installing OCC device"
os.system("echo 1 > " + self.sysfs_attr)
else:
print "Deleting OCC device"
os.system("echo 0 > " + self.sysfs_attr)
SensorValue.setValue(self,value)
@dbus.service.signal(CONTROL_IFACE,signature='s')
def GotoSystemState(self,state):
pass
class BootCountSensor(VirtualSensor):
def __init__(self,bus,name):
VirtualSensor.__init__(self,bus,name)
self.setValue(2)
class OperatingSystemStatusSensor(VirtualSensor):
def __init__(self,bus,name):
VirtualSensor.__init__(self,bus,name)
self.setValue("Off")
bus.add_signal_receiver(self.SystemStateHandler,signal_name = "GotoSystemState")
def SystemStateHandler(self,state):
if (state == "HOST_POWERED_OFF"):
self.setValue("Off")