Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store plugin databases in domoticz #1789

Merged
merged 15 commits into from
Dec 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 33 additions & 34 deletions Classes/GroupMgtv2/GrpDatabase.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,13 @@ def write_groups_list(self):
"""
self.logging("Debug", "Dumping: %s" % self.GroupListFileName)

self.logging("Status", f"+ Saving Group List into {self.GroupListFileName}")
with open(self.GroupListFileName, "wt") as handle:
json.dump(self.ListOfGroups, handle, sort_keys=True, indent=2)

if is_domoticz_db_available(self) and self.pluginconf.pluginConf["useDomoticzDatabase"]:
self.log.logging("Database", "Debug", "Save Plugin Group Db to Domoticz")
setConfigItem(Key="ListOfGroups", Value={"TimeStamp": time.time(), "b64Groups": self.ListOfGroups})
self.logging("Status", "+ Saving Group List into Domoticz")
setConfigItem(Key="ListOfGroups", Attribute="b64encoded", Value={"TimeStamp": time.time(), "b64encoded": self.ListOfGroups})


def load_groups_list_from_json(self):
Expand All @@ -48,39 +49,37 @@ def load_groups_list_from_json(self):
if self.GroupListFileName is None:
return

if is_domoticz_db_available(self) and self.pluginconf.pluginConf["useDomoticzDatabase"]:
_domoticz_grouplist = getConfigItem(Key="ListOfGroups")

dz_timestamp = 0
if "TimeStamp" in _domoticz_grouplist:
dz_timestamp = _domoticz_grouplist["TimeStamp"]
_domoticz_grouplist = _domoticz_grouplist["b64Groups"]
self.logging(
"Debug",
"Groups data loaded where saved on %s"
% (time.strftime("%A, %Y-%m-%d %H:%M:%S", time.localtime(dz_timestamp))),
)

txt_timestamp = 0
if os.path.isfile(self.GroupListFileName):
# Load from Domoticz
if self.pluginconf.pluginConf["useDomoticzDatabase"] or self.pluginconf.pluginConf["storeDomoticzDatabase"]:
_domoticz_grouplist = getConfigItem(Key="ListOfGroups", Attribute="b64encoded")
dz_timestamp = _domoticz_grouplist.get("TimeStamp",0)
_domoticz_grouplist = _domoticz_grouplist.get("b64encoded", {})
self.logging( "Debug", "Groups data loaded where saved on %s"% (time.strftime("%A, %Y-%m-%d %H:%M:%S", time.localtime(dz_timestamp))),)

# Load from Json
txt_timestamp = 0
if os.path.isfile(self.GroupListFileName):
_json_grouplist = {}
with open(self.GroupListFileName, "rt") as handle:
_json_grouplist = json.load(handle)
txt_timestamp = os.path.getmtime(self.GroupListFileName)
domoticz_log_api("%s timestamp is %s" % (self.GroupListFileName, txt_timestamp))
if dz_timestamp < txt_timestamp:
domoticz_log_api("Dz Group is older than Json Dz: %s Json: %s" % (dz_timestamp, txt_timestamp))
# We should load the json file

if not isinstance(_domoticz_grouplist, dict):
_domoticz_grouplist = {}

if not os.path.isfile(self.GroupListFileName):
self.logging("Debug", "GroupMgt - Nothing to import from %s" % self.GroupListFileName)
return

with open(self.GroupListFileName, "rt") as handle:
self.ListOfGroups = json.load(handle)

if is_domoticz_db_available(self) and self.pluginconf.pluginConf["useDomoticzDatabase"]:
domoticz_log_api("GroupList Loaded from Dz: %s from Json: %s" % (len(_domoticz_grouplist), len(self.ListOfGroups)))
self.logging( "Debug", "%s timestamp is %s" % (self.GroupListFileName, txt_timestamp))

# Check Loads
if _domoticz_grouplist and _json_grouplist :
self.logging( "Debug", "==> Sanity check : GroupList Loaded. %s entries from Domoticz, %s from Json, result: %s" % (
len(_domoticz_grouplist), len(_json_grouplist), _domoticz_grouplist == _json_grouplist ))

if self.pluginconf.pluginConf["useDomoticzDatabase"] and dz_timestamp > txt_timestamp:
# We should load the Domoticz file
self.ListOfGroups = _domoticz_grouplist
loaded_from = "Domoticz"
else:
# We should use Json
loaded_from = self.GroupListFileName
self.ListOfGroups = _json_grouplist

self.logging("Status", "Z4D loads %s config entries from %s" % (len(self.ListOfGroups), loaded_from))


def build_group_list_from_list_of_devices(self):
Expand Down
74 changes: 41 additions & 33 deletions Classes/PluginConf.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@
"Order": 12,
"param": {
"PosixPathUpdate": {"type": "bool","default": 1,"current": None,"restart": 0,"hidden": True,"Advanced": True,},
"storeDomoticzDatabase": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"storeDomoticzDatabase": {"type": "bool","default": 1,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"useDomoticzDatabase": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"PluginLogMode": {"type": "list","list": { "system default": 0, "0600": 0o600, "0640": 0o640, "0644": 0o644},"default": 0,"current": None,"restart": 1,"hidden": False,"Advanced": True,},
"numDeviceListVersion": {"type": "int","default": 12,"current": None,"restart": 0,"hidden": False,"Advanced": False,},
Expand Down Expand Up @@ -523,12 +523,13 @@ def write_Settings(self):
else:
write_pluginConf[param] = self.pluginConf[param]

Domoticz.Status( f"+ Saving Plugin Configuration into {pluginConfFile}")
with open(pluginConfFile, "wt") as handle:
json.dump(write_pluginConf, handle, sort_keys=True, indent=2)


if is_domoticz_db_available(self) and (self.pluginConf["useDomoticzDatabase"] or self.pluginConf["storeDomoticzDatabase"]):
setConfigItem(Key="PluginConf", Value={"TimeStamp": time.time(), "b64Settings": write_pluginConf})
Domoticz.Status("+ Saving Plugin Configuration into Domoticz")
setConfigItem(Key="PluginConf", Attribute="b64encoded", Value={"TimeStamp": time.time(), "b64encoded": write_pluginConf})


def _load_Settings(self):
Expand All @@ -537,55 +538,62 @@ def _load_Settings(self):

dz_timestamp = 0
if is_domoticz_db_available(self):
_domoticz_pluginConf = getConfigItem(Key="PluginConf")
_domoticz_pluginConf = getConfigItem(Key="PluginConf", Attribute="b64encoded")
if "TimeStamp" in _domoticz_pluginConf:
dz_timestamp = _domoticz_pluginConf["TimeStamp"]
_domoticz_pluginConf = _domoticz_pluginConf["b64Settings"]
Domoticz.Log(
"Plugin data loaded where saved on %s"
% (time.strftime("%A, %Y-%m-%d %H:%M:%S", time.localtime(dz_timestamp)))
)
_domoticz_pluginConf = _domoticz_pluginConf["b64encoded"]
Domoticz.Log( "Plugin data loaded where saved on %s" % (time.strftime("%A, %Y-%m-%d %H:%M:%S", time.localtime(dz_timestamp))) )
if not isinstance(_domoticz_pluginConf, dict):
_domoticz_pluginConf = {}

txt_timestamp = 0
if os.path.isfile(self.pluginConf["filename"]):
txt_timestamp = os.path.getmtime(self.pluginConf["filename"])
Domoticz.Log("%s timestamp is %s" % (self.pluginConf["filename"], txt_timestamp))

if dz_timestamp < txt_timestamp:
Domoticz.Log("Dz PluginConf is older than Json Dz: %s Json: %s" % (dz_timestamp, txt_timestamp))
# We should load the json file
Domoticz.Log("%s timestamp is %s" % (self.pluginConf["filename"], txt_timestamp))

with open(self.pluginConf["filename"], "rt") as handle:
_pluginConf = {}
try:
_pluginConf = json.load(handle)
with open(self.pluginConf["filename"], "rt") as handle:
_pluginConf = {}
try:
_pluginConf = json.load(handle)

except json.decoder.JSONDecodeError as e:
Domoticz.Error("poorly-formed %s, not JSON: %s" % (self.pluginConf["filename"], e))
return
except json.decoder.JSONDecodeError as e:
Domoticz.Error("poorly-formed %s, not JSON: %s" % (self.pluginConf["filename"], e))
return

for param in _pluginConf:
self.pluginConf[param] = _pluginConf[param]
loaded_from = "Domoticz"

# Check Load
if is_domoticz_db_available(self) and self.pluginConf["useDomoticzDatabase"]:
Domoticz.Log("PluginConf Loaded from Dz: %s from Json: %s" % (len(_domoticz_pluginConf), len(_pluginConf)))
if _domoticz_pluginConf:
for x in _pluginConf:
if x not in _domoticz_pluginConf:
Domoticz.Error("-- %s is missing in Dz" % x)
elif _pluginConf[x] != _domoticz_pluginConf[x]:
Domoticz.Error(
"++ %s is different in Dz: %s from Json: %s" % (x, _domoticz_pluginConf[x], _pluginConf[x])
)
if is_domoticz_db_available(self) and _pluginConf:
Domoticz.Log("==> Sanity check : PluginConf Loaded. %s entries from Domoticz, %s from Json" % (
len(_domoticz_pluginConf), len(_pluginConf)))

if is_domoticz_db_available(self) and self.pluginConf["useDomoticzDatabase"] and _domoticz_pluginConf:
for x in _pluginConf:
if x not in _domoticz_pluginConf:
Domoticz.Error("-- %s is missing in Dz" % x)

elif _pluginConf[x] != _domoticz_pluginConf[x]:
Domoticz.Error( "++ %s is different in Dz: %s from Json: %s" % (x, _domoticz_pluginConf[x], _pluginConf[x]) )

if self.pluginconf.pluginConf["useDomoticzDatabase"] and dz_timestamp > txt_timestamp:
# We should load the Domoticz file
load_plugin_conf = _domoticz_pluginConf
loaded_from = "Domoticz"
else:
# We should use Json
load_plugin_conf = _pluginConf

for param in load_plugin_conf:
self.pluginConf[param] = load_plugin_conf[param]

Domoticz.Status("Z4D loads %s config entries from %s" % (len(_domoticz_pluginConf), loaded_from))

# Overwrite Zigpy parameters if we are running native Zigate
if self.zigbee_communication != "zigpy":
# Force to 0 as this parameter is only relevant to Zigpy
self.pluginConf["ZigpyTopologyReport"] = False


def _load_oldfashon(self, homedir, hardwareid):
# Import PluginConf.txt
# Migration
Expand Down
Loading
Loading