Skip to content

Commit

Permalink
fix: improve communication with sleeping nodes when WakeUp CC is unsu…
Browse files Browse the repository at this point in the history
…pported or support not yet known (#1784)
  • Loading branch information
AlCalzone authored Feb 16, 2021
1 parent ce50e41 commit 5fe38da
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 7 deletions.
10 changes: 6 additions & 4 deletions packages/zwave-js/src/lib/driver/Driver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2059,10 +2059,12 @@ ${handlers.length} left`,
!!node &&
// Pings can be used to check if a node is really asleep, so they should be sent regardless
!messageIsPing(msg) &&
// Nodes that support the Wake Up CC should have their messages queued for wakeup
// If a sleeping node is currently awake, we should use the WakeUp priority so the message
// get handled immediately
node.supportsCC(CommandClasses["Wake Up"]) &&
// Nodes that can sleep and support the Wake Up CC should have their messages queued for wakeup
node.canSleep &&
(node.supportsCC(CommandClasses["Wake Up"]) ||
// If we don't know the Wake Up support yet, also change the priority or RequestNodeInfoRequests will get stuck
// in front of the queue
node.interviewStage < InterviewStage.NodeInfo) &&
// If we move multicasts to the wakeup queue, it is unlikely
// that there is ever a points where all targets are awake
!(msg instanceof SendDataMulticastRequest) &&
Expand Down
10 changes: 7 additions & 3 deletions packages/zwave-js/src/lib/driver/SendThreadMachine.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ZWaveError, ZWaveErrorCodes } from "@zwave-js/core";
import { CommandClasses, ZWaveError, ZWaveErrorCodes } from "@zwave-js/core";
import { SortedList } from "alcalzone-shared/sorted-list";
import {
Action,
Expand All @@ -23,7 +23,7 @@ import {
} from "../controller/SendDataMessages";
import { MessagePriority } from "../message/Constants";
import type { Message } from "../message/Message";
import { NodeStatus } from "../node/Types";
import { InterviewStage, NodeStatus } from "../node/Types";
import {
CommandQueueEvent,
CommandQueueInterpreter,
Expand Down Expand Up @@ -283,14 +283,18 @@ const guards: MachineOptions<SendThreadContext, SendThreadEvent>["guards"] = {
const targetNode = message.getNodeUnsafe();

// The send queue is sorted automatically. If the first message is for a sleeping node, all messages in the queue are.
// There are two exceptions:
// There are a few exceptions:
// 1. Pings may be used to determine whether a node is really asleep.
// 2. Responses to handshake requests must always be sent, because some sleeping nodes may try to send us encrypted messages.
// If we don't send them, they block the send queue
// 3. Nodes that can sleep but do not support wakeup: https://github.com/zwave-js/node-zwave-js/discussions/1537
// We need to try and send messages to them even if they are asleep, because we might never hear from them

return (
!targetNode ||
targetNode.status !== NodeStatus.Asleep ||
(!targetNode.supportsCC(CommandClasses["Wake Up"]) &&
targetNode.interviewStage >= InterviewStage.NodeInfo) ||
messageIsPing(message) ||
nextTransaction.priority === MessagePriority.Handshake
);
Expand Down

0 comments on commit 5fe38da

Please sign in to comment.