blob: fa689f0ec0c065d7d11cc1eb3d00686371a8a51b [file] [log] [blame]
Norman James65a295a2015-09-26 22:21:10 -05001#!/usr/bin/env python
2
3import os
4import sys
5import gobject
6import dbus
7import dbus.service
8import dbus.mainloop.glib
9import cPickle
10import json
11
12if (len(sys.argv) < 2):
13 print "Usage: inventory_manager.py [system name]"
14 exit(1)
15System = __import__(sys.argv[1])
16import Openbmc
17
18DBUS_NAME = 'org.openbmc.managers.Inventory'
19OBJ_NAME = '/org/openbmc/managers/Inventory'
20FRUS = System.FRU_INSTANCES
21FRU_PATH = System.FRU_PATH
22
23## accessor class to FRU data structure
24class Fru:
25 def __init__(self,fru):
26 ## validation
27 if (FRUS.has_key(fru) == False):
28 # TODO: event log
29 raise Exception("Invalid FRU path: "+fru)
30
31 self.fru = fru
32
33 def getField(self,field):
34 if (FRUS[self.fru].has_key(field) == False):
35 # TODO: event log
36 raise Exception("Invalid field: "+field)
37
38 return FRUS[self.fru][field]
39
40 def isFru(self):
41 return FRUS[self.fru]['fru']
42
43 def update(self,data):
44 for k in data.keys():
45 FRUS[self.fru][k] = data[k]
46
47 def isCached(self):
48 return True
49
50 def getCacheFilename(self):
51 global FRU_PATH
52 filename = FRU_PATH+self.fru.replace('/','.')
53 return filename
54
55 def saveToCache(self):
56 if (self.isCached() == False):
57 return
58 print "Caching: "+self.fru
59 output = open(self.getCacheFilename(), 'wb')
60 ## just pickle dict not whole object
61 print FRUS[self.fru]
62 cPickle.dump(FRUS[self.fru],output)
63 output.close()
64
65 def loadFromCache(self):
66 if (self.isCached() == False):
67 return;
68 ## overlay with pickled data
69 filename=self.getCacheFilename()
70 if (os.path.isfile(filename)):
71 print "Loading from cache: "+filename
72 p = open(filename, 'rb')
73 data2 = cPickle.load(p)
74 for k in data2.keys():
75 FRUS[self.fru][k] = data2[k]
76
77 def __str__(self):
78 r = "Fru: "+str(self.fru_id)+"\n"
79 for f in self.data.keys():
80 r = r+f+" = "+str(self.data[f])+"\n"
81 return r
82
83
84
85class InventoryManager(dbus.service.Object):
86 def __init__(self,bus,name):
87 dbus.service.Object.__init__(self,bus,name)
88
89 bus.add_signal_receiver(self.UpdateFruHandler,
Norman Jamesdfdaca92015-09-27 22:11:15 -050090 dbus_interface = "org.openbmc.sensors.IpmiBt",
Norman James65a295a2015-09-26 22:21:10 -050091 signal_name = 'UpdateFru')
92
Norman Jamesdfdaca92015-09-27 22:11:15 -050093 bus.add_signal_receiver(self.SetSensorHandler,
94 dbus_interface = "org.openbmc.sensors.IpmiBt",
95 signal_name = "SetSensor")
96
Norman James65a295a2015-09-26 22:21:10 -050097 self.fru_db = {}
98 self.fru_id_lookup = {}
99 self.sensor_id_lookup = {}
100
101 for fru_path in FRUS.keys():
102 self.addFru(fru_path)
103 f = FRUS[fru_path]
104 if (f.has_key('fru_id')):
105 self.fru_id_lookup[f['fru_id']] = fru_path
106 if (f.has_key('sensor_id')):
107 self.sensor_id_lookup[f['sensor_id']] = fru_path
108
109
110 def UpdateFruHandler(self,fru_id,data):
Norman Jamesdfdaca92015-09-27 22:11:15 -0500111 self.updateFruFromId(fru_id,data)
Norman James65a295a2015-09-26 22:21:10 -0500112
Norman Jamesdfdaca92015-09-27 22:11:15 -0500113 def SetSensorHandler(self,sensor_id,data):
114 fru_path = self.getFruSensor(sensor_id)
115 if (fru_path != ""):
116 state = { 'state' : data }
117 self.updateFru(fru_path,state)
118
119
Norman James65a295a2015-09-26 22:21:10 -0500120 @dbus.service.method(DBUS_NAME,
121 in_signature='y', out_signature='s')
122 def getFruSensor(self,sensor_id):
123 if (self.sensor_id_lookup.has_key(sensor_id) == False):
124 return ""
125 return self.sensor_id_lookup[sensor_id]
126
127 def addFru(self,fru_path):
128 new_fru = Fru(fru_path)
129 new_fru.loadFromCache()
130 self.fru_db[fru_path] = new_fru
131
132 @dbus.service.method(DBUS_NAME,
133 in_signature='ia{sv}', out_signature='')
134 def updateFruFromId(self,fru_id,data):
135 iid = int(fru_id)
136 if (self.fru_id_lookup.has_key(iid) == False):
137 # TODO: event log
138 print "fru id "+str(iid)+" not found"
139 else:
140 self.updateFru(self.fru_id_lookup[iid],data)
141
142
143 @dbus.service.method(DBUS_NAME,
144 in_signature='sa{sv}', out_signature='')
145 def updateFru(self,fru_path,data):
146 ## translate dbus data into basic data types
147 clean_data = {}
148 for k in data.keys():
149 d = Openbmc.DbusProperty(k,data[k])
150 clean_data[str(k)] = d.getBaseValue()
151
152 if (self.fru_db.has_key(fru_path)):
153 ## update properties then save to cache
154 print "Updating FRU: "+fru_path
155 self.fru_db[fru_path].update(clean_data)
156 self.fru_db[fru_path].saveToCache()
157
158
159 @dbus.service.method(DBUS_NAME,
160 in_signature='', out_signature='a{sa{sv}}')
161 def getFrus(self):
162 return FRUS
163
164
165if __name__ == '__main__':
166 dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
167 bus = dbus.SessionBus()
168 name = dbus.service.BusName(DBUS_NAME,bus)
169 obj = InventoryManager(bus,OBJ_NAME)
170 mainloop = gobject.MainLoop()
171
172 print "Running Inventory Manager"
173 mainloop.run()
174