[PATCH pyphosphor] Move sensors.py and propertycacher.py frm skeleton

OpenBMC Patches openbmc-patches at stwcx.xyz
Wed May 18 00:10:50 AEST 2016


From: Brad Bishop <bradleyb at fuzziesquirrel.com>

These skeleton module are somewhat general purpose so move them
here.
This is just a straight copy plus a pep8 run.

Signed-off-by: Brad Bishop <bradleyb at fuzziesquirrel.com>
---
 obmc/dbuslib/propertycacher.py |  64 ++++++++++
 obmc/sensors.py                | 281 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 345 insertions(+)
 create mode 100644 obmc/dbuslib/propertycacher.py
 create mode 100644 obmc/sensors.py

diff --git a/obmc/dbuslib/propertycacher.py b/obmc/dbuslib/propertycacher.py
new file mode 100644
index 0000000..701a413
--- /dev/null
+++ b/obmc/dbuslib/propertycacher.py
@@ -0,0 +1,64 @@
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+import os
+import cPickle
+import json
+
+CACHE_PATH = '/var/cache/obmc/'
+
+
+def getCacheFilename(obj_path, iface_name):
+    name = obj_path.replace('/', '.')
+    filename = CACHE_PATH+name[1:]+"@"+iface_name+".props"
+    return filename
+
+
+def save(obj_path, iface_name, properties):
+    print "Caching: "+obj_path
+    try:
+        filename = getCacheFilename(obj_path, iface_name)
+        output = open(filename, 'wb')
+        try:
+            ## use json module to convert dbus datatypes
+            props = json.dumps(properties[iface_name])
+            prop_obj = json.loads(props)
+            cPickle.dump(prop_obj, output)
+        except Exception as e:
+            print "ERROR: "+str(e)
+        finally:
+            output.close()
+    except:
+        print "ERROR opening cache file: "+filename
+
+
+def load(obj_path, iface_name, properties):
+    ## overlay with pickled data
+    filename = getCacheFilename(obj_path, iface_name)
+    if (os.path.isfile(filename)):
+        if iface_name in properties:
+            properties[iface_name] = {}
+        print "Loading from cache: "+filename
+        try:
+            p = open(filename, 'rb')
+            data = cPickle.load(p)
+            for prop in data.keys():
+                properties[iface_name][prop] = data[prop]
+
+        except Exception as e:
+            print "ERROR: Loading cache file: " + str(e)
+        finally:
+            p.close()
diff --git a/obmc/sensors.py b/obmc/sensors.py
new file mode 100644
index 0000000..e923859
--- /dev/null
+++ b/obmc/sensors.py
@@ -0,0 +1,281 @@
+# Contributors Listed Below - COPYRIGHT 2016
+# [+] International Business Machines Corp.
+#
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+import os
+import subprocess
+import dbus
+import dbus.service
+from obmc.dbuslib.bindings import DbusProperties
+
+
+## Abstract class, must subclass
+class SensorValue(DbusProperties):
+    IFACE_NAME = 'org.openbmc.SensorValue'
+
+    def __init__(self, bus, name):
+        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(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') is 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') is 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):
+        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):
+        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:
+            ## 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:
+            # Keep the val as integer. scale may be floating point
+            val = int(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, sysfs=None):
+        ## default path. can be override
+        if sysfs is None:
+            self.sysfs_attr = "/sys/class/i2c-adapter/i2c-3/3-0050/online"
+        else:
+            self.sysfs_attr = sysfs
+        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")
-- 
2.8.2




More information about the openbmc mailing list