Skip to content

Commit

Permalink
Merge branch 'hotfix-stable7-7.1.004' into stable7
Browse files Browse the repository at this point in the history
  • Loading branch information
pipiche38 committed Oct 13, 2023
2 parents 25df339 + deda25e commit 052f2de
Show file tree
Hide file tree
Showing 75 changed files with 1,335 additions and 1,140 deletions.
2 changes: 1 addition & 1 deletion .hidden/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"branch": "stable7", "version": "7.1.003"}
{"branch": "stable7", "version": "7.1.004"}
2 changes: 0 additions & 2 deletions Classes/AdminWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,6 @@ def updateStatusWidget(self, Devices, statusType):
return

def updateNotificationWidget(self, Devices, notification):

deviceid_txt_widget = DEVICEID_TXT_WIDGET + "%02s" % self.HardwareID
unit = 0
for x in Devices:
Expand All @@ -186,5 +185,4 @@ def updateNotificationWidget(self, Devices, notification):
Devices[unit].Update(nValue=nValue, sValue=sValue)

def handleCommand(self, Command):

return
6 changes: 3 additions & 3 deletions Classes/GroupMgtv2/GrpDatabase.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
"Device Addr"]
"""
import os
import json
import os
import time

import Domoticz

from Modules.tools import setConfigItem, getConfigItem, is_domoticz_db_available
from Modules.domoticzAPI import getConfigItem, setConfigItem
from Modules.tools import is_domoticz_db_available


def write_groups_list(self):
Expand Down
8 changes: 7 additions & 1 deletion Classes/GroupMgtv2/GrpDomoticz.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ def best_group_widget(self, GroupId):
WidgetType = self.ListOfDevices[NwkId]["Ep"][devEp]["ClusterType"][DomoDeviceUnit]
self.logging("Debug", "------------ GroupWidget: %s WidgetType: %s" % (GroupWidgetType, WidgetType))

if WidgetType in ("VenetianInverted", "VanneInverted", "CurtainInverted"):
# Those widgets are commanded via cluster Level Control
GroupWidgetType = "LvlControl"
continue

if GroupWidgetType is None and WidgetType in WIDGET_STYLE:
GroupWidgetType = WidgetType
continue
Expand Down Expand Up @@ -240,7 +245,8 @@ def best_group_widget(self, GroupId):
GroupWidgetType = WidgetType
continue

if WidgetType in ("Venetian", "VenetianInverted", "WindowCovering", "BlindPercentInverted"):

if WidgetType in ("Venetian", "WindowCovering", "BlindPercentInverted"):
GroupWidgetType = WidgetType

if GroupWidgetType is None:
Expand Down
21 changes: 16 additions & 5 deletions Classes/GroupMgtv2/GrpResponses.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def add_group_member_ship_response(self, MsgData):
Status:
0x00: Ok
0x8a: The device does not have storage space to support the requested operation.
0x8b: The device is not in the proper state to support the requested operation.
0x8a: Duplicate entry ---> Already exists in the group
0x8b: Entry not found ---> Not in the group
"""

self.logging("Debug", "add_group_member_ship_response - MsgData: %s (%s)" % (MsgData, len(MsgData)))
Expand Down Expand Up @@ -79,7 +79,8 @@ def add_group_member_ship_response(self, MsgData):
)
return

if MsgStatus == "00":
# Status 8a is duplicate ---> Seen as success for update of data (if not exits that should not happen)
if MsgStatus == "00" or MsgStatus == "8a":
# Success
if "GroupMemberShip" not in self.ListOfDevices[MsgSrcAddr]:
self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"] = {}
Expand Down Expand Up @@ -140,8 +141,18 @@ def check_group_member_ship_response(self, MsgData):
self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"][MsgEP][MsgGroupID]["Status"] = "OK"
checkToCreateOrUpdateGroup(self, MsgSrcAddr, MsgEP, MsgGroupID)

# If we have receive a MsgStatus error, we cannot conclude, so we consider the membership to that group, not existing

# Status 8b NetId not in GrpId ---> Must delete group data (should not happen)
elif MsgStatus == "8b" and "GroupMemberShip" in self.ListOfDevices[MsgSrcAddr]:
if MsgGroupID in self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"][MsgEP]:
del self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"][MsgEP][MsgGroupID]

if len(self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"][MsgEP]) == 0:
del self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"][MsgEP]

if len(self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"]) == 0:
del self.ListOfDevices[MsgSrcAddr]["GroupMemberShip"]

checkToRemoveGroup(self,MsgSrcAddr,MsgEP,MsgGroupID)

def look_for_group_member_ship_response(self, MsgData):
"""
Expand Down
16 changes: 6 additions & 10 deletions Classes/IAS.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,20 @@
"""


import time
import struct
import time

import Domoticz
from Modules.basicOutputs import write_attribute
from Modules.bindings import bindDevice
from Modules.tools import getEpForCluster
from Modules.sendZigateCommand import raw_APS_request
from Modules.tools import get_and_inc_ZCL_SQN, getEpForCluster
from Modules.zigateConsts import ZIGATE_EP
from Zigbee.zclCommands import (zcl_ias_wd_command_squawk,
zcl_ias_wd_command_start_warning,
zcl_ias_zone_enroll_response,
zcl_read_attribute, zcl_write_attribute)
from Zigbee.zdpCommands import zdp_simple_descriptor_request

from Modules.basicOutputs import write_attribute
from Modules.sendZigateCommand import raw_APS_request
from Modules.tools import get_and_inc_ZCL_SQN


# Synopsys
#

Expand Down Expand Up @@ -294,7 +290,7 @@ def write_IAS_WD_Squawk(self, NwkId, ep, SquawkMode):
SQUAWKMODE = {"disarmed": 0b00000000, "armed": 0b00000001}

if SquawkMode not in SQUAWKMODE:
Domoticz.Error("_write_IAS_WD_Squawk - %s/%s Unknown Squawk Mode: %s" % (NwkId, ep, SquawkMode))
self.logging("Error", "_write_IAS_WD_Squawk - %s/%s Unknown Squawk Mode: %s" % (NwkId, ep, SquawkMode))

self.logging(
"Debug",
Expand Down Expand Up @@ -485,7 +481,7 @@ def retreive_attributes(self, MsgData):
idx += size
elif len(MsgData[idx:]) == 6:
# crap, lets finish it
# Domoticz.Log("Crap Data: %s len: %s" %(MsgData[idx:], len(MsgData[idx:])))
self.logging("Debug", "Crap Data: %s len: %s" %(MsgData[idx:], len(MsgData[idx:])))
idx += 6

return attributes
Expand Down
1 change: 0 additions & 1 deletion Classes/LoggingManagement.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@
import logging
import os
import os.path

import threading
import time
from logging.handlers import RotatingFileHandler, TimedRotatingFileHandler
Expand Down
42 changes: 18 additions & 24 deletions Classes/NetworkEnergy.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
from pathlib import Path
from time import time

import Domoticz
from Modules.basicOutputs import maskChannel
from Zigbee.zdpCommands import zdp_management_network_update_request

Expand Down Expand Up @@ -88,7 +87,7 @@ def isRouter(nwkid):
if nwkid == r:
continue
if "Health" in self.ListOfDevices[nwkid]:
Domoticz.Log("_initNwkEnrgy %s - >%s<" % (nwkid, self.ListOfDevices[nwkid]["Health"]))
self.logging("Debug", "_initNwkEnrgy %s - >%s<" % (nwkid, self.ListOfDevices[nwkid]["Health"]))
if self.ListOfDevices[nwkid]["Health"] == "Not Reachable":
self.logging("Log", "_initNwkEnrgy - skiping device %s which is Not Reachable" % nwkid)
continue
Expand Down Expand Up @@ -128,13 +127,13 @@ def prettyPrintNwkEnrgy(self):

for r in self.EnergyLevel:
for i in self.EnergyLevel[r]:
Domoticz.Log("%s <-> %s : %s" % (r, i, self.EnergyLevel[r][i]["Status"]))
self.logging("Log", "%s <-> %s : %s" % (r, i, self.EnergyLevel[r][i]["Status"]))
if self.EnergyLevel[i]["Status"] == "Completed":
Domoticz.Log("---> Tx: %s" % (self.EnergyLevel[r][i]["Tx"]))
Domoticz.Log("---> Failure: %s" % (self.EnergyLevel[r][i]["Failure"]))
self.logging("Log","---> Tx: %s" % (self.EnergyLevel[r][i]["Tx"]))
self.logging("Log","---> Failure: %s" % (self.EnergyLevel[r][i]["Failure"]))
for c in self.EnergyLevel[r][i]["Channels"]:
Domoticz.Log("---> %s: %s" % (c, self.EnergyLevel[r][i]["Channels"][c]))
self.logging("Debug", "")
self.logging("Log", "---> %s: %s" % (c, self.EnergyLevel[r][i]["Channels"][c]))
self.logging("Log", "")

def NwkScanReq(self, root, target, channels):

Expand Down Expand Up @@ -162,7 +161,7 @@ def start_scan(self, root=None, target=None, channels=None):

self.logging("Debug", "start_scan")
if self.ScanInProgress:
Domoticz.Log("a Scan is already in progress")
self.logging("Log", "a Scan is already in progress")
return
self.ScanInProgress = True

Expand Down Expand Up @@ -213,7 +212,7 @@ def _next_scan(self):
if len(self.nwkidInQueue) > 0:
root, entry = self.nwkidInQueue.pop()
if r != root and i != entry:
Domoticz.Error("Mismatch %s versus %s" % (i, entry))
self.logging("Error", "Mismatch %s versus %s" % (i, entry))
continue
elif self.EnergyLevel[r][i]["Status"] == "ScanRequired":
_channels = []
Expand Down Expand Up @@ -241,12 +240,10 @@ def finish_scan(self):
storeEnergy = {}
storeEnergy[stamp] = []
for r in self.EnergyLevel:
Domoticz.Status("Network Energy Level Report: %s" % r)
Domoticz.Status("-----------------------------------------------")
Domoticz.Status(
"%6s <- %5s %6s %8s %4s %4s %4s %4s %4s %4s"
% ("router", "nwkid", "Tx", "Failure", "11", "15", "19", "20", "25", "26")
)
self.logging("Status", "Network Energy Level Report: %s" % r)
self.logging("Status", "-----------------------------------------------")
self.logging("Status", "%6s <- %5s %6s %8s %4s %4s %4s %4s %4s %4s" % (
"router", "nwkid", "Tx", "Failure", "11", "15", "19", "20", "25", "26"))
router = {}
router["_NwkId"] = r
router["MeshRouters"] = []
Expand Down Expand Up @@ -296,7 +293,7 @@ def finish_scan(self):
entry["Channels"].append(channels)
toprint += " %4s" % self.EnergyLevel[r][nwkid]["Channels"][c]
router["MeshRouters"].append(entry)
Domoticz.Status(toprint)
self.logging("Status", toprint)
storeEnergy[stamp].append(router)

self.logging("Debug", "Network Energly Level Report: %s" % storeEnergy)
Expand Down Expand Up @@ -324,10 +321,8 @@ def finish_scan(self):
fout.write("\n")
json.dump(storeEnergy, fout)
else:
Domoticz.Error(
"Unable to get access to directory %s, please check PluginConf.txt"
% (self.pluginconf.pluginConf["pluginReports"])
)
self.logging("Error", "Unable to get access to directory %s, please check PluginConf.txt" % (
self.pluginconf.pluginConf["pluginReports"]) )

def NwkScanResponse(self, MsgData):

Expand Down Expand Up @@ -374,7 +369,7 @@ def NwkScanResponse(self, MsgData):
}

if MsgDataStatus != "00":
Domoticz.Error("NwkScanResponse - Status: %s with Data: %s" % (MsgDataStatus, MsgData))
self.logging("Error", "NwkScanResponse - Status: %s with Data: %s" % (MsgDataStatus, MsgData))
return

if len(self.nwkidInQueue) == 0 and MsgSrc:
Expand All @@ -389,9 +384,8 @@ def NwkScanResponse(self, MsgData):
root, entry = self.nwkidInQueue.pop()
self.logging("Debug", "NwkScanResponse - Root: %s, Entry: %s, MsgSrc: %s" % (root, entry, MsgSrc))
if entry != MsgSrc:
Domoticz.Log(
"NwkScanResponse - Unexpected message >%s< from %s, expecting %s" % (MsgData, MsgSrc, entry)
)
self.logging("Log", "NwkScanResponse - Unexpected message >%s< from %s, expecting %s" % (
MsgData, MsgSrc, entry) )

elif len(self.nwkidInQueue) > 0:
root, entry = self.nwkidInQueue.pop()
Expand Down
33 changes: 16 additions & 17 deletions Classes/OTA.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,11 @@
import time
from datetime import datetime
from os import listdir
from os.path import isfile, join, exists
from os.path import exists, isfile, join
from pathlib import Path

import Domoticz
from Classes.AdminWidgets import AdminWidgets
from Classes.LoggingManagement import LoggingManagement
from Modules.sendZigateCommand import sendZigateCmd
from Modules.tools import get_device_nickname
from Modules.zigateConsts import ADDRESS_MODE, ZIGATE_EP
Expand All @@ -44,9 +45,6 @@
zcl_raw_ota_query_next_image_response,
zcl_raw_ota_upgrade_end_response)

from Classes.AdminWidgets import AdminWidgets
from Classes.LoggingManagement import LoggingManagement

# This file is hosted on @koenkk repository.
# This file is maintained from the community, so make sure what you do.

Expand Down Expand Up @@ -509,11 +507,11 @@ def ota_send_block(self, dest_addr, dest_ep, image_type, msg_image_version, bloc

logging(self, "Debug", "ota_send_block - Addr: %s/%s Type: 0x%X" % (dest_addr, dest_ep, image_type))
if image_type not in self.ListOfImages["ImageType"]:
Domoticz.Error("ota_send_block - unknown image_type %s" % image_type)
logging(self, "Error", "ota_send_block - unknown image_type %s" % image_type)
return False

if image_type != int(self.ListInUpdate["ImageType"], 16):
Domoticz.Error("ota_send_block - inconsistent ImageType Received: %s Expecting: %s" % (image_type, self.ListInUpdate["ImageType"]))
logging(self, "Error", "ota_send_block - inconsistent ImageType Received: %s Expecting: %s" % (image_type, self.ListInUpdate["ImageType"]))
return False

_status = 0x00
Expand Down Expand Up @@ -742,19 +740,19 @@ def firmware_update(self, brand, file_name, target_nwkid, target_ep, force_updat
return False

if brand not in self.ListOfImages["Brands"]:
Domoticz.Error("restapi_firmware_update Brands %s unknown" % brand)
logging(self, "Error", "restapi_firmware_update Brands %s unknown" % brand)
return False

if file_name not in self.ListOfImages["Brands"][brand]:
Domoticz.Error("restapi_firmware_update FileName %s unknown in this Brand %s" % (file_name, brand))
logging(self, "Error", "restapi_firmware_update FileName %s unknown in this Brand %s" % (file_name, brand))
return False

if target_nwkid not in self.ListOfDevices:
Domoticz.Error("restapi_firmware_update NwkId: %s unknown" % target_nwkid)
logging(self, "Error", "restapi_firmware_update NwkId: %s unknown" % target_nwkid)
return False

if target_ep not in self.ListOfDevices[target_nwkid]["Ep"]:
Domoticz.Error("restapi_firmware_update NwkId: %s Ep: %s unknown" % (target_nwkid, target_ep))
logging(self, "Error", "restapi_firmware_update NwkId: %s Ep: %s unknown" % (target_nwkid, target_ep))
return False

image_type = self.ListOfImages["Brands"][brand][file_name]["ImageType"]
Expand Down Expand Up @@ -929,7 +927,7 @@ def ota_extract_image_headers(self, subfolder, image): # OK 13/10

logging(self, "Debug", "ota_extract_image_headers - offset:%s ..." % offset)
ota_image = ota_image[offset:]
headers = unpack_headers(ota_image)
headers = unpack_headers(self, ota_image)
_logging_headers(self, headers)

logging(
Expand Down Expand Up @@ -961,12 +959,12 @@ def offset_start_firmware(ota_image): # OK 13/10
return i
return None

def unpack_headers(ota_image): # OK 13/10
def unpack_headers(self, ota_image): # OK 13/10

try:
header_data = list(struct.unpack("<LHHHHHLH32BLBQHH", ota_image[:69]))
except struct.error:
Domoticz.Error("ota_extract_image_headers - Error when unpacking: %s" % ota_image[:69])
logging(self, "Error", "ota_extract_image_headers - Error when unpacking: %s" % ota_image[:69])
return None

for i in range(8, 40):
Expand Down Expand Up @@ -1334,9 +1332,10 @@ def start_upgrade_infos(self, MsgSrcAddr, intMsgImageType, intMsgManufCode, MsgF
def loading_zigbee_ota_index( self ):

self.zigbee_ota_index = []
self.zigbee_ota_index = _load_json_from_url( self, self.pluginconf.pluginConf["ZigbeeOTA_Repository"] )
self.zigbee_ota_index.extend( convert_ikea_format_to_list( _load_json_from_url( self, self.pluginconf.pluginConf["IkeaTradfri_Repository"] )) )
self.zigbee_ota_index.extend( convert_sonoff_format_to_list( _load_json_from_url( self, self.pluginconf.pluginConf["Sonoff_Repository"] )) )
if self.pluginconf.pluginConf["internetAccess"]:
self.zigbee_ota_index = _load_json_from_url( self, self.pluginconf.pluginConf["ZigbeeOTA_Repository"] )
self.zigbee_ota_index.extend( convert_ikea_format_to_list( _load_json_from_url( self, self.pluginconf.pluginConf["IkeaTradfri_Repository"] )) )
self.zigbee_ota_index.extend( convert_sonoff_format_to_list( _load_json_from_url( self, self.pluginconf.pluginConf["Sonoff_Repository"] )) )


def convert_sonoff_format_to_list( _zigbee_sonoff_index ):
Expand Down
14 changes: 11 additions & 3 deletions Classes/PluginConf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@

import json
import os.path
from pathlib import Path
import time
from pathlib import Path

import Domoticz
from Modules.tools import (getConfigItem, is_domoticz_db_available, is_hex,
setConfigItem)
from Modules.domoticzAPI import getConfigItem, setConfigItem
from Modules.tools import is_domoticz_db_available, is_hex

SETTINGS = {
"Services": {
Expand Down Expand Up @@ -293,8 +293,16 @@
"Tuya0601": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Profalux": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Schneider": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"AbstractDz": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"CasaIA": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Philips": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Enki": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Gledopto": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Orvibo": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"PiZigate": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"Pluzzy": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"PollControl": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"PluginTools": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"PDM": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"inRawAPS": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
"outRawAPS": {"type": "bool","default": 0,"current": None,"restart": 0,"hidden": False,"Advanced": True,},
Expand Down
Loading

0 comments on commit 052f2de

Please sign in to comment.