Created
February 21, 2025 17:13
-
-
Save jamesabruce/264252414c794f3b41fab58752af227e to your computer and use it in GitHub Desktop.
Matter.js PC/Mac remote suspend virtual device
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
DeviceTypeId, | |
Endpoint, | |
EndpointServer, | |
Environment, | |
ServerNode, | |
StorageService, | |
Time, | |
VendorId, | |
} from "@matter/main"; | |
import { OnOffLightDevice, OnOffPlugInUnitDevice } from "@matter/main/devices"; | |
import { logEndpoint } from "@matter/main/protocol"; | |
import { execSync } from "node:child_process"; | |
// Create the "node". In Matter a "node" is a standalone device | |
const node = await ServerNode.create(); | |
// Create the endpoint properly with an ID | |
const endpoint = new Endpoint(OnOffLightDevice, { id: "onoff" }); | |
const light = await node.add(endpoint); | |
// Enable logging to debug connection issues | |
logEndpoint(EndpointServer.forEndpoint(node)); | |
// Run our server first to establish connections | |
await node.start(); | |
// Wait longer for session establishment before accepting commands | |
await new Promise(resolve => setTimeout(resolve, 5000)); | |
// Force a state update after connection established | |
await endpoint.set({ | |
onOff: { | |
onOff: true | |
} | |
}); | |
// Debug current state | |
console.log('Initial OnOff state:', endpoint.state.onOff); | |
// Add an event handler to log the light's current status | |
endpoint.events.onOff.onOff$Changed.on(value => { | |
console.log(`Light is now ${value}`); | |
if (!value) { // When turned off | |
console.log(`Suspending now`); | |
const platform = process.platform; | |
const suspendCommand = platform === 'win32' | |
? 'rundll32.exe powrprof.dll,SetSuspendState 0,1,0' // Windows | |
: platform === 'darwin' | |
? 'pmset sleepnow' // macOS | |
: 'sudo systemctl suspend'; // Linux | |
try { | |
execSync(suspendCommand); | |
} catch (error) { | |
console.error('Failed to execute suspend command:', error); | |
} | |
} | |
}); | |
/** Defined a shell command from an environment variable and execute it and log the response. */ | |
//Taken from deviceNode.ts in the full examples | |
function executeCommand(scriptParamName: string) { | |
const script = Environment.default.vars.string(scriptParamName); | |
if (script === undefined) return undefined; | |
console.log(`${scriptParamName}: ${execSync(script).toString().slice(0, -1)}`); | |
} | |
// Function to set state to ON once machine has resumed | |
async function setStateToOn() { | |
await endpoint.set({ | |
onOff: { | |
onOff: true | |
} | |
}); | |
console.log('State set to ON after wake'); | |
} | |
// Listen for resume events | |
process.on('SIGCONT', setStateToOn); // Unix/Linux/Mac resume signal | |
// Periodically check if we're awake (as backup) | |
setInterval(async () => { | |
if (endpoint.state.onOff.onOff === false) { | |
await setStateToOn(); | |
} | |
}, 5000); // Check every 5 seconds |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment