UNPKG

iobroker.roborock

Version:
111 lines (97 loc) 3.36 kB
import { loadImage } from "@napi-rs/canvas"; import * as zlib from "node:zlib"; import * as Images from "../../common/images"; export interface Point { x: number; y: number; } export const VISUAL_BLOCK_SIZE = 3; // Standard Roborock Palette (Dark Mode style) export const ROBOROCK_PALETTE = [ "#DFDFDFff", // 0: Default (background/no color) "#50A4FF", // 1: Blue "#FF744D", // 2: Orange "#008FA8", // 3: Cyan "#F5AF10", // 4: Yellow "#E9E9E9ff", // 5: Reserve/Fallback ]; // Legacy Colors used in V1 map (can be deprecated if we fully switch to Palette) export const LEGACY_COLORS = { floor: "#23465e", obstacle: "#2b2e30", path: "#FFFFFF", }; export const ALGORITHM_COLORS = { // Colors for the adjacency algorithm visualization if needed // Usually mapped to ROBOROCK_PALETTE indices }; export async function loadSharedImages(robotType?: string) { let robotImgSource = Images.IMG_ROBOT_ORIGINAL; switch (robotType) { case "robot": robotImgSource = Images.IMG_ROBOT_DEFAULT; break; case "robot1": robotImgSource = Images.IMG_ROBOT1; break; case "tank": robotImgSource = Images.IMG_TANK; break; case "spaceship": robotImgSource = Images.IMG_SPACESHIP; break; case "robot2": robotImgSource = Images.IMG_ROBOT_2; break; } return Promise.all([loadImage(robotImgSource), loadImage(Images.IMG_CHARGER), loadImage(Images.IMG_GO_TO_PIN)]); } export function robotXtoCanvasX(x: number, left: number): number { return (x - left) * VISUAL_BLOCK_SIZE + VISUAL_BLOCK_SIZE / 2; } export function robotYtoCanvasY(y: number, top: number, height: number): number { return (height / VISUAL_BLOCK_SIZE + top - y) * VISUAL_BLOCK_SIZE - VISUAL_BLOCK_SIZE / 2; } // Convert room ID to Hex Color using standard palette export function getRoomColor(colorId: number): string { if (colorId > 0 && colorId < ROBOROCK_PALETTE.length) { return ROBOROCK_PALETTE[colorId]; } // Wrap around format for IDs larger than palette return ROBOROCK_PALETTE[1 + ((colorId - 1) % (ROBOROCK_PALETTE.length - 2))]; // -2 because index 0 is bg, index 5 is fallback? Algorithm usually uses 4 colors (1-4). // Let's stick to 4 main colors. } export function hexToRgba(hex: string, alpha = 255): [number, number, number, number] { const r = parseInt(hex.slice(1, 3), 16); const g = parseInt(hex.slice(3, 5), 16); const b = parseInt(hex.slice(5, 7), 16); return [r, g, b, alpha]; } /** * B01 and V1: compression is always ZLIB (0x78) or GZIP (0x1f 0x8b) at offset 0. No scan, no raw deflate. */ export function decompress(compressed: Buffer): Buffer { if (isSignatureMatch(compressed)) return compressed; if (compressed.length < 2) return compressed; if (compressed[0] === 0x78) { return zlib.inflateSync(compressed); } if (compressed[0] === 0x1f && compressed[1] === 0x8b) { return zlib.gunzipSync(compressed); } return compressed; } export function isSignatureMatch(buf: Buffer): boolean { if (buf.length < 2) return false; // V1: "rr" if (buf[0] === 0x72 && buf[1] === 0x72) return true; // B01: "B01" if (buf.length > 3 && buf.toString("ascii", 0, 3) === "B01") return true; // Protobuf: 0x08, 0x0a, 0x12 return isLikelyProtobuf(buf); } export function isLikelyProtobuf(buf: Buffer): boolean { if (buf.length < 1) return false; return buf[0] === 0x08 || buf[0] === 0x0a || buf[0] === 0x12; }