diff --git a/insteon_mqtt/handler/BroadcastCmdResponse.py b/insteon_mqtt/handler/BroadcastCmdResponse.py index ef0e412c..dd91ea55 100644 --- a/insteon_mqtt/handler/BroadcastCmdResponse.py +++ b/insteon_mqtt/handler/BroadcastCmdResponse.py @@ -82,9 +82,17 @@ def msg_received(self, protocol, msg): return Msg.CONTINUE elif msg.flags.type == Msg.Flags.Type.DIRECT_NAK: - LOG.error("%s device NAK error: %s", msg.from_addr, msg) - self.on_done(False, "Device command NAK", None) - return Msg.FINISHED + if msg.cmd2 == 0xFC: + # This is a "Pre NAK in case database search takes + # too long". This happens when the device database is + # large. Just ignore it, add more wait time and wait. + LOG.warning("%s Pre-NAK: %s, Message: %s", msg.from_addr, + msg.nak_str(), msg) + return Msg.CONTINUE + else: + LOG.error("%s device NAK error: %s", msg.from_addr, msg) + self.on_done(False, "Device command NAK", None) + return Msg.FINISHED else: LOG.warning("%s device unexpected msg: %s", msg.from_addr, msg) diff --git a/insteon_mqtt/handler/DeviceDbGet.py b/insteon_mqtt/handler/DeviceDbGet.py index 507d46bf..93b28bbf 100644 --- a/insteon_mqtt/handler/DeviceDbGet.py +++ b/insteon_mqtt/handler/DeviceDbGet.py @@ -103,11 +103,19 @@ def msg_received(self, protocol, msg): return Msg.CONTINUE elif msg.flags.type == Msg.Flags.Type.DIRECT_NAK: - LOG.error("%s device NAK error: %s, Message: %s", - msg.from_addr, msg.nak_str(), msg) - self.on_done(False, "Database command NAK. " + msg.nak_str(), - None) - return Msg.FINISHED + if msg.cmd2 == 0xFC: + # This is a "Pre NAK in case database search takes + # too long". This happens when the device database is + # large. Just ignore it, add more wait time and wait. + LOG.warning("%s Pre-NAK: %s, Message: %s", msg.from_addr, + msg.nak_str(), msg) + return Msg.CONTINUE + else: + LOG.error("%s device NAK error: %s, Message: %s", + msg.from_addr, msg.nak_str(), msg) + self.on_done(False, "Database command NAK. " + + msg.nak_str(), None) + return Msg.FINISHED else: LOG.warning("%s device unexpected msg: %s", msg.from_addr, msg) diff --git a/insteon_mqtt/handler/DeviceDbModify.py b/insteon_mqtt/handler/DeviceDbModify.py index 60ef8979..5c530167 100644 --- a/insteon_mqtt/handler/DeviceDbModify.py +++ b/insteon_mqtt/handler/DeviceDbModify.py @@ -78,10 +78,18 @@ def msg_received(self, protocol, msg): self.entry) elif msg.flags.type == Msg.Flags.Type.DIRECT_NAK: - LOG.error("%s db mod NAK: %s, Message: %s", self.db.addr, - msg.nak_str(), msg) - self.on_done(False, "Device database update failed. " + - msg.nak_str(), None) + if msg.cmd2 == 0xFC: + # This is a "Pre NAK in case database search takes + # too long". This happens when the device database is + # large. Just ignore it, add more wait time and wait. + LOG.warning("%s Pre-NAK: %s, Message: %s", + self.db.addr, msg.nak_str(), msg) + return Msg.CONTINUE + else: + LOG.error("%s db mod NAK: %s, Message: %s", + self.db.addr, msg.nak_str(), msg) + self.on_done(False, "Device database update failed. " + + msg.nak_str(), None) else: LOG.error("%s db mod unexpected msg type: %s", diff --git a/insteon_mqtt/handler/ExtendedCmdResponse.py b/insteon_mqtt/handler/ExtendedCmdResponse.py index 1f064e40..39e6edb0 100644 --- a/insteon_mqtt/handler/ExtendedCmdResponse.py +++ b/insteon_mqtt/handler/ExtendedCmdResponse.py @@ -88,11 +88,19 @@ def msg_received(self, protocol, msg): return Msg.CONTINUE elif msg.flags.type == Msg.Flags.Type.DIRECT_NAK: - LOG.error("%s device NAK error: %s, Message: %s", - msg.from_addr, msg.nak_str(), msg) - self.on_done(False, "Device command NAK. " + msg.nak_str(), - None) - return Msg.FINISHED + if msg.cmd2 == 0xFC: + # This is a "Pre NAK in case database search takes + # too long". This happens when the device database is + # large. Just ignore it, add more wait time and wait. + LOG.warning("%s Pre-NAK: %s, Message: %s", msg.from_addr, + msg.nak_str(), msg) + return Msg.CONTINUE + else: + LOG.error("%s device NAK error: %s, Message: %s", + msg.from_addr, msg.nak_str(), msg) + self.on_done(False, "Device command NAK. " + msg.nak_str(), + None) + return Msg.FINISHED else: LOG.warning("%s device unexpected msg: %s", msg.from_addr, msg) diff --git a/tests/handler/test_BroadcastCmdResponse.py b/tests/handler/test_BroadcastCmdResponse.py index 3a58f537..7d7f708a 100644 --- a/tests/handler/test_BroadcastCmdResponse.py +++ b/tests/handler/test_BroadcastCmdResponse.py @@ -67,6 +67,12 @@ def callback(msg, on_done=None): r = handler.msg_received(proto, msg) assert r == Msg.FINISHED + # direct Pre NAK + flags = Msg.Flags(Msg.Flags.Type.DIRECT_NAK, False) + msg = Msg.InpStandard(addr, addr, flags, 0x10, 0xFC) + r = handler.msg_received(proto, msg) + assert r == Msg.CONTINUE + # unexpected flags = Msg.Flags(Msg.Flags.Type.ALL_LINK_BROADCAST, False) msg = Msg.InpStandard(addr, addr, flags, 0x10, 0x00) diff --git a/tests/handler/test_DeviceDbGet.py b/tests/handler/test_DeviceDbGet.py index 0441b5ed..f6b4810e 100644 --- a/tests/handler/test_DeviceDbGet.py +++ b/tests/handler/test_DeviceDbGet.py @@ -36,6 +36,12 @@ def callback(success, msg, value): r = handler.msg_received(proto, std_ack) assert r == Msg.UNKNOWN + # direct Pre NAK + flags = Msg.Flags(Msg.Flags.Type.DIRECT_NAK, False) + msg = Msg.InpStandard(addr, addr, flags, 0x2f, 0xFC) + r = handler.msg_received(proto, msg) + assert r == Msg.CONTINUE + # Try w/ an extended msg. ext_data = bytes(14) ext_ack = Msg.OutExtended.direct(addr, 0x2f, 0x00, ext_data) diff --git a/tests/handler/test_ExtendedCmdResponse.py b/tests/handler/test_ExtendedCmdResponse.py index 56ddc283..1e76a421 100644 --- a/tests/handler/test_ExtendedCmdResponse.py +++ b/tests/handler/test_ExtendedCmdResponse.py @@ -69,6 +69,12 @@ def callback(msg, on_done=None): r = handler.msg_received(proto, msg) assert r == Msg.FINISHED + # direct Pre NAK + flags = Msg.Flags(Msg.Flags.Type.DIRECT_NAK, False) + msg = Msg.InpStandard(addr, addr, flags, 0x2e, 0xFC) + r = handler.msg_received(proto, msg) + assert r == Msg.CONTINUE + # unexpected flags = Msg.Flags(Msg.Flags.Type.BROADCAST, False) msg = Msg.InpStandard(addr, addr, flags, 0x2e, 0x00)