Skip to content

Instantly share code, notes, and snippets.

@jamesabruce
Created February 21, 2025 17:13
Show Gist options
  • Save jamesabruce/264252414c794f3b41fab58752af227e to your computer and use it in GitHub Desktop.
Save jamesabruce/264252414c794f3b41fab58752af227e to your computer and use it in GitHub Desktop.
Matter.js PC/Mac remote suspend virtual device
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