Skip to content

Commit

Permalink
Tweak resending procedure
Browse files Browse the repository at this point in the history
  • Loading branch information
Jbithell committed Mar 1, 2024
1 parent b85dd13 commit eb76234
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 14 deletions.
79 changes: 66 additions & 13 deletions server/src/osc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ export class OSC {
static deviceStatus: {
[deviceId: number]: number | false;
} = {};
static deviceResendStatus: {
[deviceId: number]: {
deviceNewStatus: number | false;
deviceSendStatusInterval: NodeJS.Timeout;
};
} = {};
static devicePingChecks: {
[deviceId: number]: {
lastPingReceivedTimestamp: number;
Expand All @@ -44,20 +50,28 @@ export class OSC {
OSC.devicePingChecks[deviceId].lastPingReceivedTimestamp =
Date.now();
if (OSC.deviceStatus[deviceId] !== msg[1]) {
// Device status has changed! Updated
OSC.deviceStatus[deviceId] = msg[1];
OSC.messageDevice(
deviceId,
"/cueb/outstationState",
OSC.deviceStatus[deviceId]
); // Echo the state back to the device to confirm it was received
if (
OSC.deviceResendStatus[deviceId]["deviceNewStatus"] == msg[1]
) {
// Status has been set to what we wanted, and device replied to let us know, so we can stop pestering the device
OSC.deviceResendStatus[deviceId]["deviceNewStatus"] = false;
}
eventEmitter.emit("trpc.deviceStatus");
}
OSC.messageDevice(
deviceId,
"/cueb/outstationState",
OSC.deviceStatus[deviceId]
); // Echo the state back to the device to confirm it was received
}
} else if (msg[0] == "/cueb/pong" && msg.length === 2) {
const deviceId = OSC.ipsToDevices[rinfo.address];
if (deviceId) {
OSC.devicePingChecks[deviceId].lastPingReceivedTimestamp =
Date.now();
console.log("Pong from device", deviceId);
}
} else {
console.log("Unknown message", msg, rinfo);
Expand All @@ -77,28 +91,61 @@ export class OSC {
OSC.ipsToDevices[ip] = deviceId;
OSC.deviceStatus[deviceId] = false;
OSC.devices[deviceId] = createOSCClient(ip, port);

OSC.deviceResendStatus[deviceId] = {
deviceNewStatus: false,
deviceSendStatusInterval: setInterval(() => {
// Resend the device its status if it has not sent it back
if (
OSC.deviceResendStatus[deviceId]["deviceNewStatus"] !==
OSC.deviceStatus[deviceId] &&
OSC.deviceStatus[deviceId] !== false &&
OSC.deviceResendStatus[deviceId]["deviceNewStatus"] !== false
) {
console.log(
"Resending status to device",
OSC.deviceStatus[deviceId],
OSC.deviceResendStatus[deviceId]["deviceNewStatus"]
);
OSC.messageDevice(
deviceId,
"/cueb/outstationState",
OSC.deviceResendStatus[deviceId]["deviceNewStatus"]
);
}
}, 200),
};
OSC.devicePingChecks[deviceId] = {
sendInterval: setInterval(() => {
// Devices timeout after 5000ms of no pings received from a server
if (
Date.now() - OSC.devicePingChecks[deviceId].lastPingSentTimestamp >=
3500
3000 ||
Date.now() -
OSC.devicePingChecks[deviceId].lastPingReceivedTimestamp >=
3000
) {
OSC.messageDevice(deviceId, "/cueb/ping");
console.log("Pinging device", deviceId);
}
}, 500),
}, 200),
checkInterval: setInterval(() => {
// We should mark a device as timed out if we haven't heard from it for 4 seconds - it should be transmitting its state every 2 seconds
// We should mark a device as timed out if we haven't heard from it for 5 seconds
if (
Date.now() -
OSC.devicePingChecks[deviceId].lastPingReceivedTimestamp >
4000
5000
) {
OSC.deviceStatus[deviceId] = false;
eventEmitter.emit("trpc.deviceStatus");
if (OSC.deviceStatus[deviceId] != false) {
console.log("Device timed out", deviceId);
OSC.deviceStatus[deviceId] = false;
eventEmitter.emit("trpc.deviceStatus");
}
}
}, 500),
// Similarly, if we're not sure what a device's state is (it probably just joined the network) then we should ask it - it'll reply with it
if (OSC.deviceStatus[deviceId] === false) {
OSC.messageDevice(deviceId, "/cueb/outstationState");
}
}, 200),
lastPingReceivedTimestamp: 0,
lastPingSentTimestamp: 0,
};
Expand All @@ -116,6 +163,12 @@ export class OSC {
}
}
}
static setStatus(deviceId: number, status: number) {
if (status !== OSC.deviceStatus[deviceId]) {
OSC.deviceResendStatus[deviceId]["deviceNewStatus"] = status;
OSC.messageDevice(deviceId, "/cueb/outstationState", status);
}
}
static messageDevice(
deviceId: number,
message: string,
Expand Down
2 changes: 1 addition & 1 deletion server/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ const devicesRouter = router({
setState: publicProcedure
.input(z.object({ id: z.number(), newState: z.number() }))
.mutation(({ input }) => {
OSC.messageDevice(input.id, "/cueb/outstationState", input.newState);
OSC.setStatus(input.id, input.newState);
return {};
}),
scanForDevices: publicProcedure.mutation(() => {
Expand Down

0 comments on commit eb76234

Please sign in to comment.