# -*- coding: utf-8 -*- # ***************************************************************************** # # This program is free software; you can redistribute it and/or modify it under # the terms of the GNU General Public License as published by the Free Software # Foundation; either version 2 of the License, or (at your option) any later # version. # # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more # details. # # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Module authors: # Markus Zolliker # # ***************************************************************************** """Define base classes for real Modules implemented in the server""" import os import json from secop.errors import BadValueError, ConfigError, InternalError, \ ProgrammingError, SECoPError, SilentError, secop_error class PersistentMixin: def __init__(*args, **kwds): super().__init__(*args, **kwds) # self.persistentFile = None # self.persistentData = {} self.writeDict.update(self.loadParameters()) def writeInitParams(self, started_callback=None): super().writeInitParams() self.saveParameters() if started_callback: started_callback() def loadParameters(self): """load persistent parameters :return: persistent parameters which have to be written is called upon startup and may be called from a module when a hardware powerdown is detected """ persistentdir = os.path.join(getGeneralConfig()['logdir'], 'persistent') self.persistentFile = os.path.join(persistentdir, '%s.%s.json' % (self.DISPATCHER.equipment_id, self.name)) try: with open(self.persistentFile, 'r') as f: self.persistentData = json.load(f) except FileNotFoundError: self.persistentData = {} writeDict = {} for pname, pobj in self.parameters.items(): if pobj.persistent and pname in self.persistentData: value = pobj.datatype.import_value(self.persistentData[pname]) try: pobj.value = value if not pobj.readonly: writeDict[pname] = value except Exception as e: self.log.warning('can not restore %r to %r (%r)' % (pname, value, e)) return writeDict def saveParameters(self): """save persistent parameters to be called regularely explicitly by the module """ data = {k: v.export_value() for k, v in self.parameters.items() if v.persistent} if data != self.persistentData: self.persistentData = data persistentdir = os.path.basename(self.persistentFile) tmpfile = self.persistentFile + '.tmp' if not os.path.isdir(persistentdir): os.makedirs(persistentdir, exist_ok=True) try: with open(tmpfile, 'w') as f: json.dump(self.persistentData, f, indent=2) f.write('\n') os.rename(tmpfile, self.persistentFile) finally: try: os.remove(tmpfile) except FileNotFoundError: pass