@apocaliss92/nodedreame 1.12.3 → 1.12.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 +144 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +77 -15
- package/dist/index.d.ts +77 -15
- package/dist/index.js +144 -45
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -134,7 +134,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
134
134
|
|
|
135
135
|
// src/support/version.ts
|
|
136
136
|
var LIBRARY_NAME = "nodedreame";
|
|
137
|
-
var LIBRARY_VERSION = "1.12.
|
|
137
|
+
var LIBRARY_VERSION = "1.12.5";
|
|
138
138
|
|
|
139
139
|
// src/transport/errors.ts
|
|
140
140
|
var DreameError = class extends Error {
|
|
@@ -1980,50 +1980,93 @@ var VACUUM_CONSUMABLES = [
|
|
|
1980
1980
|
key: "main-brush",
|
|
1981
1981
|
label: "Main Brush",
|
|
1982
1982
|
life: { siid: 9, piid: 2 },
|
|
1983
|
+
timeLeft: { siid: 9, piid: 1, unit: "hours" },
|
|
1983
1984
|
reset: { siid: 9, aiid: 1 }
|
|
1984
1985
|
},
|
|
1985
1986
|
{
|
|
1986
1987
|
key: "side-brush",
|
|
1987
1988
|
label: "Side Brush",
|
|
1988
1989
|
life: { siid: 10, piid: 2 },
|
|
1990
|
+
timeLeft: { siid: 10, piid: 1, unit: "hours" },
|
|
1989
1991
|
reset: { siid: 10, aiid: 1 }
|
|
1990
1992
|
},
|
|
1991
|
-
{
|
|
1992
|
-
|
|
1993
|
+
{
|
|
1994
|
+
key: "filter",
|
|
1995
|
+
label: "Filter",
|
|
1996
|
+
life: { siid: 11, piid: 1 },
|
|
1997
|
+
timeLeft: { siid: 11, piid: 2, unit: "hours" },
|
|
1998
|
+
reset: { siid: 11, aiid: 1 }
|
|
1999
|
+
},
|
|
2000
|
+
{
|
|
2001
|
+
key: "sensor",
|
|
2002
|
+
label: "Sensor Dirty",
|
|
2003
|
+
life: { siid: 16, piid: 1 },
|
|
2004
|
+
timeLeft: { siid: 16, piid: 2, unit: "hours" },
|
|
2005
|
+
reset: { siid: 16, aiid: 1 }
|
|
2006
|
+
},
|
|
1993
2007
|
{
|
|
1994
2008
|
key: "tank-filter",
|
|
1995
2009
|
label: "Tank Filter",
|
|
1996
2010
|
life: { siid: 17, piid: 1 },
|
|
2011
|
+
timeLeft: { siid: 17, piid: 2, unit: "hours" },
|
|
1997
2012
|
reset: { siid: 17, aiid: 1 }
|
|
1998
2013
|
},
|
|
1999
|
-
{
|
|
2014
|
+
{
|
|
2015
|
+
key: "mop-pad",
|
|
2016
|
+
label: "Mop Pad",
|
|
2017
|
+
life: { siid: 18, piid: 1 },
|
|
2018
|
+
timeLeft: { siid: 18, piid: 2, unit: "hours" },
|
|
2019
|
+
reset: { siid: 18, aiid: 1 }
|
|
2020
|
+
},
|
|
2000
2021
|
{
|
|
2001
2022
|
key: "silver-ion",
|
|
2002
2023
|
label: "Silver-ion",
|
|
2003
2024
|
life: { siid: 19, piid: 2 },
|
|
2025
|
+
timeLeft: { siid: 19, piid: 1, unit: "days" },
|
|
2004
2026
|
reset: { siid: 19, aiid: 1 }
|
|
2005
2027
|
},
|
|
2006
2028
|
{
|
|
2007
2029
|
key: "detergent",
|
|
2008
2030
|
label: "Detergent",
|
|
2009
2031
|
life: { siid: 20, piid: 1 },
|
|
2032
|
+
timeLeft: { siid: 20, piid: 2, unit: "days" },
|
|
2010
2033
|
reset: { siid: 20, aiid: 1 }
|
|
2011
2034
|
},
|
|
2012
|
-
{
|
|
2035
|
+
{
|
|
2036
|
+
key: "squeegee",
|
|
2037
|
+
label: "Squeegee",
|
|
2038
|
+
life: { siid: 24, piid: 1 },
|
|
2039
|
+
timeLeft: { siid: 24, piid: 2, unit: "days" },
|
|
2040
|
+
reset: { siid: 24, aiid: 1 }
|
|
2041
|
+
},
|
|
2013
2042
|
{
|
|
2014
2043
|
key: "deodorizer",
|
|
2015
2044
|
label: "Deodorizer",
|
|
2016
2045
|
life: { siid: 29, piid: 2 },
|
|
2046
|
+
timeLeft: { siid: 29, piid: 1, unit: "days" },
|
|
2017
2047
|
reset: { siid: 29, aiid: 1 }
|
|
2018
2048
|
},
|
|
2019
|
-
{
|
|
2049
|
+
{
|
|
2050
|
+
key: "wheel",
|
|
2051
|
+
label: "Wheel Dirty",
|
|
2052
|
+
life: { siid: 30, piid: 2 },
|
|
2053
|
+
timeLeft: { siid: 30, piid: 1, unit: "days" },
|
|
2054
|
+
reset: { siid: 30, aiid: 1 }
|
|
2055
|
+
},
|
|
2020
2056
|
{
|
|
2021
2057
|
key: "scale-inhibitor",
|
|
2022
2058
|
label: "Scale Inhibitor",
|
|
2023
2059
|
life: { siid: 31, piid: 2 },
|
|
2060
|
+
timeLeft: { siid: 31, piid: 1, unit: "days" },
|
|
2024
2061
|
reset: { siid: 31, aiid: 1 }
|
|
2025
2062
|
},
|
|
2026
|
-
{
|
|
2063
|
+
{
|
|
2064
|
+
key: "dust-bag",
|
|
2065
|
+
label: "Dust Bag",
|
|
2066
|
+
life: { siid: 27, piid: 17 },
|
|
2067
|
+
timeLeft: null,
|
|
2068
|
+
reset: null
|
|
2069
|
+
}
|
|
2027
2070
|
];
|
|
2028
2071
|
function consumableSpec(key2) {
|
|
2029
2072
|
return VACUUM_CONSUMABLES.find((c) => c.key === key2);
|
|
@@ -2885,34 +2928,6 @@ var VACUUM_ACTIONS = {
|
|
|
2885
2928
|
autoEmpty: { siid: 15, aiid: 1 }
|
|
2886
2929
|
};
|
|
2887
2930
|
|
|
2888
|
-
// src/video/monitor/vendor.ts
|
|
2889
|
-
function videoVendorSwitchParams(vendor) {
|
|
2890
|
-
return { vendor };
|
|
2891
|
-
}
|
|
2892
|
-
function parseVideoVendorStatus(raw) {
|
|
2893
|
-
const text = typeof raw === "string" ? raw : typeof raw === "object" && raw !== null ? null : null;
|
|
2894
|
-
const source = text === null ? raw : safeJson(text);
|
|
2895
|
-
if (typeof source !== "object" || source === null) {
|
|
2896
|
-
return { vendor: null, initStatus: null };
|
|
2897
|
-
}
|
|
2898
|
-
const v = Reflect.get(source, "vendor");
|
|
2899
|
-
const s = Reflect.get(source, "initStatus");
|
|
2900
|
-
return {
|
|
2901
|
-
vendor: v === "ali" || v === "tx" ? v : null,
|
|
2902
|
-
initStatus: typeof s === "number" ? s : null
|
|
2903
|
-
};
|
|
2904
|
-
}
|
|
2905
|
-
function safeJson(text) {
|
|
2906
|
-
try {
|
|
2907
|
-
return JSON.parse(text);
|
|
2908
|
-
} catch {
|
|
2909
|
-
return null;
|
|
2910
|
-
}
|
|
2911
|
-
}
|
|
2912
|
-
function vendorSwitchSettled(status, wanted) {
|
|
2913
|
-
return status.vendor === wanted && status.initStatus === 1;
|
|
2914
|
-
}
|
|
2915
|
-
|
|
2916
2931
|
// src/video/monitor/protocol.ts
|
|
2917
2932
|
var import_node_crypto4 = require("crypto");
|
|
2918
2933
|
function makeMonitorSession(accountId, now = Date.now()) {
|
|
@@ -2989,6 +3004,34 @@ function firstOutValue(res) {
|
|
|
2989
3004
|
return Array.isArray(out) && out.length > 0 ? out[0]?.value : void 0;
|
|
2990
3005
|
}
|
|
2991
3006
|
|
|
3007
|
+
// src/video/monitor/vendor.ts
|
|
3008
|
+
function videoVendorSwitchParams(vendor) {
|
|
3009
|
+
return { vendor };
|
|
3010
|
+
}
|
|
3011
|
+
function parseVideoVendorStatus(raw) {
|
|
3012
|
+
const text = typeof raw === "string" ? raw : typeof raw === "object" && raw !== null ? null : null;
|
|
3013
|
+
const source = text === null ? raw : safeJson(text);
|
|
3014
|
+
if (typeof source !== "object" || source === null) {
|
|
3015
|
+
return { vendor: null, initStatus: null };
|
|
3016
|
+
}
|
|
3017
|
+
const v = Reflect.get(source, "vendor");
|
|
3018
|
+
const s = Reflect.get(source, "initStatus");
|
|
3019
|
+
return {
|
|
3020
|
+
vendor: v === "ali" || v === "tx" ? v : null,
|
|
3021
|
+
initStatus: typeof s === "number" ? s : null
|
|
3022
|
+
};
|
|
3023
|
+
}
|
|
3024
|
+
function safeJson(text) {
|
|
3025
|
+
try {
|
|
3026
|
+
return JSON.parse(text);
|
|
3027
|
+
} catch {
|
|
3028
|
+
return null;
|
|
3029
|
+
}
|
|
3030
|
+
}
|
|
3031
|
+
function vendorSwitchSettled(status, wanted) {
|
|
3032
|
+
return status.vendor === wanted && status.initStatus === 1;
|
|
3033
|
+
}
|
|
3034
|
+
|
|
2992
3035
|
// src/video/monitor/controller.ts
|
|
2993
3036
|
var DEFAULT_KEEP_ALIVE_MS = 1e4;
|
|
2994
3037
|
var DEFAULT_AREA = "4";
|
|
@@ -4895,6 +4938,12 @@ var OssFetcher = class {
|
|
|
4895
4938
|
};
|
|
4896
4939
|
|
|
4897
4940
|
// src/models/vacuum/vacuum-device.ts
|
|
4941
|
+
function consumableProps(spec) {
|
|
4942
|
+
return spec.timeLeft === null ? [spec.life] : [spec.life, { siid: spec.timeLeft.siid, piid: spec.timeLeft.piid }];
|
|
4943
|
+
}
|
|
4944
|
+
function asError(err) {
|
|
4945
|
+
return err instanceof Error ? err : new Error(String(err));
|
|
4946
|
+
}
|
|
4898
4947
|
var SUCTION = enumLookup([
|
|
4899
4948
|
0 /* Quiet */,
|
|
4900
4949
|
1 /* Standard */,
|
|
@@ -5052,25 +5101,72 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
|
|
|
5052
5101
|
});
|
|
5053
5102
|
}
|
|
5054
5103
|
/**
|
|
5055
|
-
*
|
|
5056
|
-
* {@link
|
|
5057
|
-
*
|
|
5058
|
-
|
|
5104
|
+
* Time left before a consumable needs attention, in the unit the robot counts
|
|
5105
|
+
* it in (see {@link ConsumableSpec.timeLeft}), or `null` when the model does
|
|
5106
|
+
* not report it or the key has no time-left twin.
|
|
5107
|
+
*/
|
|
5108
|
+
consumableTimeLeft(key2) {
|
|
5109
|
+
const spec = consumableSpec(key2);
|
|
5110
|
+
if (spec === void 0 || spec.timeLeft === null) return null;
|
|
5111
|
+
const value = this.#num(spec.timeLeft.siid, spec.timeLeft.piid);
|
|
5112
|
+
return value === null ? null : { value, unit: spec.timeLeft.unit };
|
|
5113
|
+
}
|
|
5114
|
+
/**
|
|
5115
|
+
* Seed EVERY consumable life property AND its time-left twin from the cloud
|
|
5116
|
+
* shadow (no robot wake), in one call, so {@link supportedConsumables} and
|
|
5117
|
+
* {@link consumableTimeLeft} reflect the full set on a docked robot. The
|
|
5118
|
+
* robot rarely re-pushes these over MQTT, so a consumer that wants them fresh
|
|
5119
|
+
* must call this again — the library does not poll them.
|
|
5059
5120
|
*/
|
|
5060
5121
|
async refreshConsumables() {
|
|
5061
|
-
await this.refreshCachedProperties(VACUUM_CONSUMABLES.
|
|
5122
|
+
await this.refreshCachedProperties(VACUUM_CONSUMABLES.flatMap(consumableProps));
|
|
5062
5123
|
}
|
|
5063
5124
|
/**
|
|
5064
5125
|
* Reset (mark replaced → life back to 100%) one consumable via its MIoT reset
|
|
5065
|
-
* action
|
|
5066
|
-
*
|
|
5126
|
+
* action, then re-read that consumable's life % and time left ONCE so the
|
|
5127
|
+
* cache — and every getter after this resolves — reflects the reset. The
|
|
5128
|
+
* re-read is live; if the robot does not answer it falls back to the cloud
|
|
5129
|
+
* shadow (which may still hold the pre-reset value until the robot reports),
|
|
5130
|
+
* and `refreshedFrom` says which one answered.
|
|
5131
|
+
*
|
|
5132
|
+
* Rejects when the model exposes no reset action for the key (e.g.
|
|
5133
|
+
* `dust-bag`), the key is unknown, or the action itself fails. A failed
|
|
5134
|
+
* RE-READ does not reject: the reset happened, and the result says the values
|
|
5135
|
+
* are unknown (`refreshedFrom: null`).
|
|
5067
5136
|
*/
|
|
5068
5137
|
async resetConsumable(key2) {
|
|
5069
5138
|
const spec = consumableSpec(key2);
|
|
5070
5139
|
if (spec === void 0 || spec.reset === null) {
|
|
5071
5140
|
throw new DreameError(`resetConsumable: no reset action for consumable "${key2}"`);
|
|
5072
5141
|
}
|
|
5073
|
-
|
|
5142
|
+
const actionResult = await this.callAction(spec.reset.siid, spec.reset.aiid, []);
|
|
5143
|
+
const refresh2 = await this.#rereadConsumable(spec);
|
|
5144
|
+
const fresh = refresh2.refreshedFrom !== null;
|
|
5145
|
+
return {
|
|
5146
|
+
key: key2,
|
|
5147
|
+
actionResult,
|
|
5148
|
+
refreshedFrom: refresh2.refreshedFrom,
|
|
5149
|
+
leftPct: fresh ? this.consumableLeftPct(key2) : null,
|
|
5150
|
+
timeLeft: fresh ? this.consumableTimeLeft(key2) : null,
|
|
5151
|
+
refreshError: refresh2.error
|
|
5152
|
+
};
|
|
5153
|
+
}
|
|
5154
|
+
/** One targeted re-read of a consumable's properties: live, else the cloud shadow. */
|
|
5155
|
+
async #rereadConsumable(spec) {
|
|
5156
|
+
const props = consumableProps(spec);
|
|
5157
|
+
let liveError;
|
|
5158
|
+
try {
|
|
5159
|
+
await this.refreshProperties(props);
|
|
5160
|
+
return { refreshedFrom: "device", error: null };
|
|
5161
|
+
} catch (err) {
|
|
5162
|
+
liveError = asError(err);
|
|
5163
|
+
}
|
|
5164
|
+
try {
|
|
5165
|
+
await this.refreshCachedProperties(props);
|
|
5166
|
+
return { refreshedFrom: "cloud-shadow", error: liveError };
|
|
5167
|
+
} catch (err) {
|
|
5168
|
+
return { refreshedFrom: null, error: asError(err) };
|
|
5169
|
+
}
|
|
5074
5170
|
}
|
|
5075
5171
|
// -- AI obstacle-detection ----------------------------------------------
|
|
5076
5172
|
/**
|
|
@@ -5438,7 +5534,9 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
|
|
|
5438
5534
|
break;
|
|
5439
5535
|
}
|
|
5440
5536
|
if (Date.now() + pollMs >= deadline) {
|
|
5441
|
-
throw new DreameError(
|
|
5537
|
+
throw new DreameError(
|
|
5538
|
+
"wifi signal map not available (none stored yet, or request timed out)"
|
|
5539
|
+
);
|
|
5442
5540
|
}
|
|
5443
5541
|
await new Promise((r) => setTimeout(r, pollMs));
|
|
5444
5542
|
}
|
|
@@ -5605,8 +5703,9 @@ var VacuumDevice = class _VacuumDevice extends BaseDevice {
|
|
|
5605
5703
|
if (vendorSwitchSettled(already, vendor)) {
|
|
5606
5704
|
return already;
|
|
5607
5705
|
}
|
|
5706
|
+
const session = makeMonitorSession(this.currentSession().uid);
|
|
5608
5707
|
await this.callAction(MONITOR_SIID, MONITOR_AIID.VIDEO_VENDOR, [
|
|
5609
|
-
|
|
5708
|
+
buildActionInput(MONITOR_PIID.VIDEO_VENDOR_STATUS, videoVendorSwitchParams(vendor), session)
|
|
5610
5709
|
]);
|
|
5611
5710
|
const every = opts?.pollIntervalMs ?? 5e3;
|
|
5612
5711
|
const deadline = Date.now() + (opts?.timeoutMs ?? every * 10);
|