Skip to content

Instantly share code, notes, and snippets.

@bpmct
Last active May 6, 2025 08:38
Show Gist options
  • Select an option

  • Save bpmct/1f7ca6387b3b34ccafdec31a5c88359c to your computer and use it in GitHub Desktop.

Select an option

Save bpmct/1f7ca6387b3b34ccafdec31a5c88359c to your computer and use it in GitHub Desktop.
#!/usr/bin/env bun
const fs = require("fs");
const axios = require("axios");
// Command code for getting events
const COMMAND_GET_EVENTS = 7;
// Load JSON file utility
const loadJson = (path) => {
try {
return fs.existsSync(path) ? JSON.parse(fs.readFileSync(path, "utf8")) : null;
} catch (error) {
console.error(`Error loading ${path}:`, error.message);
return null;
}
};
// Format timestamp to human-readable form (e.g., "5 seconds ago")
const formatTimestamp = (timestamp) => {
if (!timestamp) return "Never seen";
const lastSeen = new Date(timestamp);
const now = new Date();
const diffSec = Math.floor((now - lastSeen) / 1000);
if (diffSec < 60) return `${diffSec} second${diffSec !== 1 ? 's' : ''} ago`;
if (diffSec < 3600) return `${Math.floor(diffSec / 60)} minute${Math.floor(diffSec / 60) !== 1 ? 's' : ''} ago`;
if (diffSec < 86400) return `${Math.floor(diffSec / 3600)} hour${Math.floor(diffSec / 3600) !== 1 ? 's' : ''} ago`;
return `${Math.floor(diffSec / 86400)} day${Math.floor(diffSec / 86400) !== 1 ? 's' : ''} ago`;
};
// Main function
async function main() {
// Load configuration files
const config = loadJson(`${process.env.HOME}/.config/artemis/config`);
const fleetJson = loadJson("fleet.json");
const devicesJson = loadJson("devices.json") || {};
// Exit if required files are missing
if (!config || !fleetJson) {
console.error("Error: Required configuration files missing");
process.exit(1);
}
// Get authentication token
const accessToken = config.auths?.Artemis?.access_token || config.access_token || config.token;
if (!accessToken) {
console.error("Error: No valid authentication token found");
process.exit(1);
}
// Get Supabase info
const supabaseUrl = "https://voisfafsfolxhqpkudzd.supabase.co";
const anonKey = fleetJson.servers?.Artemis?.anon;
const organizationId = config.organization?.default;
try {
// Get device IDs from devices.json
const deviceIds = Object.keys(devicesJson);
if (deviceIds.length === 0) {
console.error("No devices found in devices.json");
process.exit(1);
}
// Call Supabase binary endpoint for events
const url = `${supabaseUrl}/functions/v1/b`;
const params = {
"_device_ids": deviceIds.map(id => String(id)),
"_limit": 1,
"_types": null
};
// Create binary payload
const commandBuffer = Buffer.alloc(1);
commandBuffer.writeUint8(COMMAND_GET_EVENTS);
const paramsBuffer = Buffer.from(JSON.stringify(params));
const payload = Buffer.concat([commandBuffer, paramsBuffer]);
// Make API request
const response = await axios.post(url, payload, {
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/octet-stream",
apikey: anonKey
},
responseType: "arraybuffer"
});
// Parse response
const jsonString = Buffer.from(response.data).toString("utf-8");
const data = JSON.parse(jsonString);
// Process events for each device
const devices = deviceIds.map(deviceId => {
// Extract events for this device
let lastEvent = null;
if (Array.isArray(data)) {
// If response is an array, find events for this device
lastEvent = data.find(event => event.device_id === deviceId);
} else if (data && data[deviceId] && Array.isArray(data[deviceId]) && data[deviceId].length > 0) {
// If response is organized by device ID
lastEvent = data[deviceId][0];
}
// Get last seen timestamp
const timestamp = lastEvent?.timestamp || lastEvent?.ts || lastEvent?.created_at;
// Pod information
const podVersion = fleetJson.groups?.default?.pod || "my-pod@latest";
return {
device_id: deviceId,
name: devicesJson[deviceId]?.name || "unknown",
last_seen: timestamp || null,
last_seen_human: timestamp ? formatTimestamp(timestamp) : "Never seen",
never_seen: !timestamp,
pod: {
name: "my-pod",
version: podVersion.includes('@') ? podVersion.split('@')[1] : "latest"
}
};
});
// Sort by device name
devices.sort((a, b) => (a.name || "").localeCompare(b.name || ""));
// Output the results
console.log(JSON.stringify({
organization_id: organizationId,
fleet_id: fleetJson.id,
device_count: devices.length,
devices
}, null, 2));
} catch (error) {
console.error('Error getting fleet status:', error.message);
process.exit(1);
}
}
main();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment