@apocaliss92/nodedreame 1.11.3 → 1.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -86,7 +86,7 @@ module.exports = __toCommonJS(index_exports);
86
86
 
87
87
  // src/support/version.ts
88
88
  var LIBRARY_NAME = "nodedreame";
89
- var LIBRARY_VERSION = "1.11.3";
89
+ var LIBRARY_VERSION = "1.11.5";
90
90
 
91
91
  // src/transport/errors.ts
92
92
  var DreameError = class extends Error {
@@ -2913,77 +2913,65 @@ function pose(x, y, angle, absent) {
2913
2913
  // src/models/vacuum/map/render.ts
2914
2914
  var import_pngjs = require("pngjs");
2915
2915
  var SCHEMES = {
2916
- "dreame-light": {
2917
- floor: [210, 222, 235, 255],
2918
- wall: [60, 60, 60, 255],
2919
- carpet: [180, 150, 120, 200],
2920
- segSat: 0.45,
2921
- segVal: 0.95,
2922
- path: [60, 110, 180, 235],
2923
- robotBody: [40, 70, 110, 255],
2916
+ // Flat-design: soft neutral floor, bright low-saturation segment fills, thin
2917
+ // mid-grey walls, a single vivid accent for the path.
2918
+ flat: {
2919
+ floor: [236, 239, 241, 255],
2920
+ wall: [120, 132, 145, 255],
2921
+ carpet: [205, 185, 160, 200],
2922
+ segSat: 0.28,
2923
+ segVal: 0.99,
2924
+ path: [255, 138, 101, 240],
2925
+ robotBody: [38, 50, 56, 255],
2924
2926
  robotHeading: [255, 255, 255, 255],
2925
- charger: [40, 160, 80, 255],
2926
- noGoFill: [220, 60, 60, 70],
2927
- noGoBorder: [200, 40, 40, 220],
2928
- noMopFill: [60, 120, 220, 60],
2929
- noMopBorder: [40, 90, 200, 200],
2930
- virtualWall: [200, 40, 40, 230],
2931
- obstacle: [230, 150, 30, 255],
2932
- label: [40, 40, 40, 255]
2933
- },
2934
- "dreame-dark": {
2935
- floor: [40, 46, 56, 255],
2936
- wall: [15, 15, 18, 255],
2937
- carpet: [80, 66, 52, 200],
2938
- segSat: 0.5,
2939
- segVal: 0.62,
2940
- path: [120, 170, 230, 235],
2941
- robotBody: [120, 170, 230, 255],
2942
- robotHeading: [20, 24, 30, 255],
2943
- charger: [60, 200, 110, 255],
2944
- noGoFill: [220, 70, 70, 80],
2945
- noGoBorder: [230, 70, 70, 220],
2946
- noMopFill: [70, 130, 230, 70],
2947
- noMopBorder: [80, 140, 235, 210],
2948
- virtualWall: [230, 70, 70, 235],
2949
- obstacle: [240, 180, 60, 255],
2950
- label: [225, 230, 240, 255]
2927
+ charger: [38, 166, 154, 255],
2928
+ noGoFill: [239, 83, 80, 60],
2929
+ noGoBorder: [229, 57, 53, 210],
2930
+ noMopFill: [66, 165, 245, 55],
2931
+ noMopBorder: [30, 136, 229, 200],
2932
+ virtualWall: [229, 57, 53, 225],
2933
+ obstacle: [255, 167, 38, 255],
2934
+ label: [55, 71, 79, 255]
2951
2935
  },
2952
- "mijia-light": {
2953
- floor: [225, 232, 240, 255],
2954
- wall: [70, 78, 92, 255],
2955
- carpet: [188, 162, 132, 200],
2956
- segSat: 0.35,
2957
- segVal: 0.98,
2958
- path: [80, 130, 200, 230],
2959
- robotBody: [30, 100, 200, 255],
2936
+ // Dark-neon: near-black floor with high-saturation glowing segment fills, a
2937
+ // bright cyan path and magenta robot.
2938
+ "dark-neon": {
2939
+ floor: [16, 18, 27, 255],
2940
+ wall: [5, 6, 10, 255],
2941
+ carpet: [60, 50, 80, 200],
2942
+ segSat: 0.85,
2943
+ segVal: 0.95,
2944
+ path: [0, 230, 255, 240],
2945
+ robotBody: [255, 45, 170, 255],
2960
2946
  robotHeading: [255, 255, 255, 255],
2961
- charger: [40, 170, 90, 255],
2962
- noGoFill: [225, 70, 70, 70],
2963
- noGoBorder: [205, 45, 45, 220],
2964
- noMopFill: [70, 130, 225, 60],
2965
- noMopBorder: [50, 100, 205, 200],
2966
- virtualWall: [205, 45, 45, 230],
2967
- obstacle: [235, 160, 35, 255],
2968
- label: [45, 52, 64, 255]
2947
+ charger: [0, 255, 150, 255],
2948
+ noGoFill: [255, 40, 90, 80],
2949
+ noGoBorder: [255, 40, 90, 235],
2950
+ noMopFill: [40, 130, 255, 75],
2951
+ noMopBorder: [40, 160, 255, 225],
2952
+ virtualWall: [255, 40, 90, 235],
2953
+ obstacle: [255, 220, 0, 255],
2954
+ label: [230, 240, 255, 255]
2969
2955
  },
2970
- tasshack: {
2971
- floor: [200, 210, 225, 255],
2972
- wall: [80, 80, 95, 255],
2973
- carpet: [176, 148, 118, 205],
2974
- segSat: 0.5,
2975
- segVal: 0.9,
2976
- path: [50, 100, 170, 235],
2977
- robotBody: [35, 60, 100, 255],
2956
+ // Materico (Material-design): light grey surface, Material-palette segment
2957
+ // fills, indigo/teal accents.
2958
+ materico: {
2959
+ floor: [245, 245, 245, 255],
2960
+ wall: [97, 97, 97, 255],
2961
+ carpet: [188, 170, 144, 205],
2962
+ segSat: 0.55,
2963
+ segVal: 0.93,
2964
+ path: [63, 81, 181, 235],
2965
+ robotBody: [48, 63, 159, 255],
2978
2966
  robotHeading: [255, 255, 255, 255],
2979
- charger: [35, 150, 75, 255],
2980
- noGoFill: [215, 55, 55, 75],
2981
- noGoBorder: [195, 35, 35, 220],
2982
- noMopFill: [55, 115, 215, 65],
2983
- noMopBorder: [35, 85, 195, 205],
2984
- virtualWall: [195, 35, 35, 230],
2985
- obstacle: [225, 145, 25, 255],
2986
- label: [35, 42, 54, 255]
2967
+ charger: [0, 150, 136, 255],
2968
+ noGoFill: [244, 67, 54, 65],
2969
+ noGoBorder: [211, 47, 47, 215],
2970
+ noMopFill: [33, 150, 243, 60],
2971
+ noMopBorder: [25, 118, 210, 205],
2972
+ virtualWall: [211, 47, 47, 225],
2973
+ obstacle: [255, 152, 0, 255],
2974
+ label: [33, 33, 33, 255]
2987
2975
  }
2988
2976
  };
2989
2977
  function hsvToRgba(h, s, v) {
@@ -3021,15 +3009,18 @@ function segmentColor(id, pal) {
3021
3009
  }
3022
3010
  function renderVacuumPng(map, opts = {}) {
3023
3011
  const scale = Math.max(1, Math.trunc(opts.scale ?? 1));
3024
- const pal = SCHEMES[opts.colorScheme ?? "dreame-light"];
3012
+ const pal = SCHEMES[opts.colorScheme ?? "flat"] ?? SCHEMES.flat;
3025
3013
  const w = Math.max(1, map.dimensions.width * scale);
3026
3014
  const h = Math.max(1, map.dimensions.height * scale);
3027
3015
  const png = new import_pngjs.PNG({ width: w, height: h });
3028
3016
  png.data.fill(0);
3017
+ const dim = map.dimensions;
3029
3018
  for (const layer of map.layers) {
3030
- paintLayer(png, layer, scale, pal);
3019
+ paintLayer(png, layer, dim.height, scale, pal);
3020
+ }
3021
+ if (opts.showCleanedArea === true && map.cleanedArea !== null) {
3022
+ paintCleanedArea(png, map.cleanedArea, dim, scale, pal.path);
3031
3023
  }
3032
- const dim = map.dimensions;
3033
3024
  if (opts.showNoGo !== false) {
3034
3025
  for (const area of map.restrictedAreas) {
3035
3026
  const fill = area.kind === "noMop" ? pal.noMopFill : pal.noGoFill;
@@ -3052,10 +3043,17 @@ function renderVacuumPng(map, opts = {}) {
3052
3043
  drawPolyline(png, path.points, dim, scale, pal.path, Math.max(1, scale));
3053
3044
  }
3054
3045
  }
3046
+ if (opts.showFurniture !== false) {
3047
+ for (const zone of map.lowLyingAreas) {
3048
+ paintFurnitureZone(png, zone.points, dim, scale);
3049
+ }
3050
+ }
3055
3051
  if (opts.showObstacles !== false) {
3052
+ const byType = opts.colorObstaclesByType !== false;
3056
3053
  for (const ob of map.obstacles) {
3057
3054
  const p = worldToPx(ob.x, ob.y, dim, scale);
3058
- drawDisk(png, p.x, p.y, Math.max(2, scale * 2), pal.obstacle);
3055
+ const color = byType ? obstacleColor(ob.type) : pal.obstacle;
3056
+ drawDiamond(png, p.x, p.y, Math.max(2, scale * 2), color);
3059
3057
  }
3060
3058
  }
3061
3059
  if (opts.showCharger !== false && map.dock !== null) {
@@ -3064,31 +3062,33 @@ function renderVacuumPng(map, opts = {}) {
3064
3062
  if (opts.showRobot !== false && map.robot !== null) {
3065
3063
  drawRobot(png, map.robot, dim, scale, pal);
3066
3064
  }
3067
- if (opts.showSegmentLabels === true) {
3065
+ if (opts.showSegmentNames === true || opts.showSegmentLabels === true) {
3068
3066
  for (const seg of map.segments) {
3069
3067
  const p = worldToPx(seg.centroid.x, seg.centroid.y, dim, scale);
3070
- drawLabel(png, p.x, p.y, String(seg.id), pal.label, Math.max(1, scale));
3068
+ const text = opts.showSegmentNames === true ? labelText(seg.name, seg.id) : String(seg.id);
3069
+ drawLabel(png, p.x, p.y, text, pal.label, Math.max(1, scale));
3071
3070
  }
3072
3071
  }
3073
3072
  return import_pngjs.PNG.sync.write(png);
3074
3073
  }
3075
3074
  function worldToPx(worldX, worldY, dim, scale) {
3075
+ const cellY = (worldY - dim.top) / dim.gridSize;
3076
3076
  return {
3077
3077
  x: Math.round((worldX - dim.left) / dim.gridSize * scale),
3078
- y: Math.round((worldY - dim.top) / dim.gridSize * scale)
3078
+ y: Math.round((dim.height - 1 - cellY) * scale)
3079
3079
  };
3080
3080
  }
3081
- function paintLayer(png, layer, scale, pal) {
3081
+ function paintLayer(png, layer, dimHeight, scale, pal) {
3082
3082
  const color = layer.type === "segment" ? segmentColor(layer.segmentId ?? 0, pal) : layer.type === "wall" ? pal.wall : layer.type === "carpet" ? pal.carpet : pal.floor;
3083
3083
  for (const run of layer.runs) {
3084
- paintRun(png, run, color, scale);
3084
+ paintRun(png, run, dimHeight, color, scale);
3085
3085
  }
3086
3086
  }
3087
- function paintRun(png, run, color, scale) {
3087
+ function paintRun(png, run, dimHeight, color, scale) {
3088
3088
  const [xPx, yPx, len] = run;
3089
+ const baseY = (dimHeight - 1 - yPx) * scale;
3089
3090
  for (let i = 0; i < len; i += 1) {
3090
3091
  const baseX = (xPx + i) * scale;
3091
- const baseY = yPx * scale;
3092
3092
  for (let dy = 0; dy < scale; dy += 1) {
3093
3093
  for (let dx = 0; dx < scale; dx += 1) {
3094
3094
  setPixel(png, baseX + dx, baseY + dy, color);
@@ -3194,7 +3194,7 @@ function drawRobot(png, robot, dim, scale, pal) {
3194
3194
  drawDisk(png, p.x, p.y, r, pal.robotBody);
3195
3195
  const rad = robot.angle * Math.PI / 180;
3196
3196
  const hx = Math.round(p.x + Math.cos(rad) * r);
3197
- const hy = Math.round(p.y + Math.sin(rad) * r);
3197
+ const hy = Math.round(p.y - Math.sin(rad) * r);
3198
3198
  drawLine(png, p.x, p.y, hx, hy, pal.robotHeading, Math.max(1, Math.trunc(scale / 2) + 1));
3199
3199
  }
3200
3200
  function drawCharger(png, dock, dim, scale, pal) {
@@ -3202,6 +3202,58 @@ function drawCharger(png, dock, dim, scale, pal) {
3202
3202
  const r = Math.max(2, scale * 2);
3203
3203
  fillRect(png, p.x - r, p.y - r, p.x + r, p.y + r, pal.charger);
3204
3204
  }
3205
+ function drawDiamond(png, cx, cy, r, color) {
3206
+ for (let dy = -r; dy <= r; dy += 1) {
3207
+ const w = r - Math.abs(dy);
3208
+ for (let dx = -w; dx <= w; dx += 1) {
3209
+ setPixel(png, cx + dx, cy + dy, color);
3210
+ }
3211
+ }
3212
+ }
3213
+ function obstacleColor(type) {
3214
+ const hue = Math.abs(Math.trunc(type)) * 47 % 360;
3215
+ return hsvToRgba(hue, 0.85, 0.95);
3216
+ }
3217
+ var FURNITURE_LINE = [150, 110, 200, 235];
3218
+ function paintFurnitureZone(png, points, dim, scale) {
3219
+ if (points.length < 2) return;
3220
+ for (let i = 0; i < points.length; i += 1) {
3221
+ const a = points[i];
3222
+ const b = points[(i + 1) % points.length];
3223
+ if (a === void 0 || b === void 0) continue;
3224
+ const pa = worldToPx(a.x, a.y, dim, scale);
3225
+ const pb = worldToPx(b.x, b.y, dim, scale);
3226
+ drawLine(png, pa.x, pa.y, pb.x, pb.y, FURNITURE_LINE, Math.max(1, scale));
3227
+ }
3228
+ }
3229
+ function paintCleanedArea(png, overlay, parentDim, scale, baseColor) {
3230
+ const tint = [baseColor[0], baseColor[1], baseColor[2], 55];
3231
+ const inner = overlay.dimensions;
3232
+ const block = Math.max(1, Math.round(inner.gridSize / parentDim.gridSize * scale));
3233
+ for (const [xPx, yPx, len] of overlay.cleaned) {
3234
+ for (let i = 0; i < len; i += 1) {
3235
+ const worldX = inner.left + (xPx + i) * inner.gridSize;
3236
+ const worldY = inner.top + yPx * inner.gridSize;
3237
+ const p = worldToPx(worldX, worldY, parentDim, scale);
3238
+ for (let dy = 0; dy < block; dy += 1) {
3239
+ for (let dx = 0; dx < block; dx += 1) {
3240
+ setPixel(png, p.x + dx, p.y + dy, tint);
3241
+ }
3242
+ }
3243
+ }
3244
+ }
3245
+ }
3246
+ function labelText(name, id) {
3247
+ const raw = (name ?? "").trim();
3248
+ const base = raw.length > 0 ? raw : `ROOM ${id}`;
3249
+ const upper = base.toUpperCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "");
3250
+ let out = "";
3251
+ for (const ch of upper) {
3252
+ if (GLYPHS[ch] !== void 0) out += ch;
3253
+ }
3254
+ const trimmed = out.trim().slice(0, 14);
3255
+ return trimmed.length > 0 ? trimmed : `ROOM ${id}`;
3256
+ }
3205
3257
  var GLYPHS = {
3206
3258
  "0": [7, 5, 5, 5, 7],
3207
3259
  "1": [2, 6, 2, 2, 7],
@@ -3213,7 +3265,34 @@ var GLYPHS = {
3213
3265
  "7": [7, 1, 2, 2, 2],
3214
3266
  "8": [7, 5, 7, 5, 7],
3215
3267
  "9": [7, 5, 7, 1, 7],
3216
- "-": [0, 0, 7, 0, 0]
3268
+ "-": [0, 0, 7, 0, 0],
3269
+ " ": [0, 0, 0, 0, 0],
3270
+ A: [2, 5, 7, 5, 5],
3271
+ B: [6, 5, 6, 5, 6],
3272
+ C: [3, 4, 4, 4, 3],
3273
+ D: [6, 5, 5, 5, 6],
3274
+ E: [7, 4, 6, 4, 7],
3275
+ F: [7, 4, 6, 4, 4],
3276
+ G: [3, 4, 5, 5, 3],
3277
+ H: [5, 5, 7, 5, 5],
3278
+ I: [7, 2, 2, 2, 7],
3279
+ J: [1, 1, 1, 5, 2],
3280
+ K: [5, 5, 6, 5, 5],
3281
+ L: [4, 4, 4, 4, 7],
3282
+ M: [5, 7, 7, 5, 5],
3283
+ N: [5, 7, 7, 7, 5],
3284
+ O: [2, 5, 5, 5, 2],
3285
+ P: [6, 5, 6, 4, 4],
3286
+ Q: [2, 5, 5, 6, 3],
3287
+ R: [6, 5, 6, 5, 5],
3288
+ S: [3, 4, 2, 1, 6],
3289
+ T: [7, 2, 2, 2, 2],
3290
+ U: [5, 5, 5, 5, 7],
3291
+ V: [5, 5, 5, 5, 2],
3292
+ W: [5, 5, 7, 7, 5],
3293
+ X: [5, 5, 2, 5, 5],
3294
+ Y: [5, 5, 2, 2, 2],
3295
+ Z: [7, 1, 2, 4, 7]
3217
3296
  };
3218
3297
  function drawLabel(png, cx, cy, text, color, px) {
3219
3298
  const glyphW = 3 * px;