@robotical/webapp-types 3.25.11 → 3.25.13
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-types/package.json +2 -2
- package/dist-types/src/application/RAFTs/Marty/PublishedDataAnalyser.js +2 -1
- package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.d.ts +13 -0
- package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.js +6 -0
- package/dist-types/src/utils/colour-classifier.d.ts +1 -1
- package/dist-types/src/utils/colour-profile-eeprom.d.ts +36 -0
- package/dist-types/src/utils/colour-profile-eeprom.js +88 -0
- package/dist-types/src/utils/colour-sensor-diagnostics.d.ts +4 -2
- package/dist-types/src/utils/colour-sensor-diagnostics.js +34 -18
- package/dist-types/src/utils/colour-sensor-profile.d.ts +10 -4
- package/dist-types/src/utils/colour-sensor-profile.js +145 -59
- package/dist-types/src/utils/colour-sensor-registers.d.ts +1 -1
- package/dist-types/src/utils/colour-sensor-registers.js +1 -1
- package/package.json +1 -1
package/dist-types/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "marty-web-app",
|
|
3
|
-
"version": "3.25.
|
|
3
|
+
"version": "3.25.13",
|
|
4
4
|
"private": true,
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"@robotical/martyblocks": "^4.0.77",
|
|
19
19
|
"@robotical/martyblocksjr": "^4.5.6",
|
|
20
20
|
"@robotical/maze": "^0.1.22",
|
|
21
|
-
"@robotical/rc-sequencer": "^1.1.
|
|
21
|
+
"@robotical/rc-sequencer": "^1.1.16",
|
|
22
22
|
"@robotical/ricjs-robotical-addons": "^1.2.8",
|
|
23
23
|
"@robotical/robofly-game": "^0.1.25",
|
|
24
24
|
"@robotical/roboticaljs": "^1.1.28",
|
|
@@ -117,7 +117,8 @@ var PublishedDataAnalyser = /** @class */ (function (_super) {
|
|
|
117
117
|
}
|
|
118
118
|
else {
|
|
119
119
|
var profile = getAddonColourSensorProfile(this.marty, colourSensor);
|
|
120
|
-
var
|
|
120
|
+
var profileSignal = profile === null || profile === void 0 ? void 0 : profile.signal;
|
|
121
|
+
var context = JSON.stringify([colourSensor.id, colourSensor.name, profile === null || profile === void 0 ? void 0 : profile.serialNumber, profile === null || profile === void 0 ? void 0 : profile.offsetsHex, profile === null || profile === void 0 ? void 0 : profile.whiteCalibrationHex, profile === null || profile === void 0 ? void 0 : profile.capturedAtMs, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.airMax.red, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.airMax.green, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.airMax.blue, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.margin.red, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.margin.green, profileSignal === null || profileSignal === void 0 ? void 0 : profileSignal.margin.blue]);
|
|
121
122
|
if (context !== this.colourContext) {
|
|
122
123
|
this.resetColourDetection();
|
|
123
124
|
this.colourContext = context;
|
package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.d.ts
CHANGED
|
@@ -22,6 +22,19 @@ declare const colourDiagnosticsEnglish: {
|
|
|
22
22
|
confidenceHelp: string;
|
|
23
23
|
withoutAir: string;
|
|
24
24
|
firmwareAir: string;
|
|
25
|
+
profileSource: string;
|
|
26
|
+
eepromStatus: string;
|
|
27
|
+
eeprom: string;
|
|
28
|
+
local: string;
|
|
29
|
+
firebase: string;
|
|
30
|
+
defaultRules: string;
|
|
31
|
+
verified: string;
|
|
32
|
+
empty: string;
|
|
33
|
+
invalid: string;
|
|
34
|
+
readFailed: string;
|
|
35
|
+
writeFailed: string;
|
|
36
|
+
firmwareNotAudited: string;
|
|
37
|
+
notChecked: string;
|
|
25
38
|
waiting: string;
|
|
26
39
|
capture: string;
|
|
27
40
|
captureAir: string;
|
package/dist-types/src/screens/configuration/marty/Diagnostics/ColourSensorDiagnostics/messages.js
CHANGED
|
@@ -17,6 +17,12 @@ var colourDiagnosticsEnglish = {
|
|
|
17
17
|
confidenceHelp: "Rule strength, not probability. Higher scores mean more room before a colour or air cutoff. Air needs a saved calibration to score.",
|
|
18
18
|
withoutAir: "Firmware reports air; the RGB signal matches {{result}}.",
|
|
19
19
|
firmwareAir: "Firmware Air",
|
|
20
|
+
profileSource: "Profile: {{source}}",
|
|
21
|
+
eepromStatus: "EEPROM: {{status}}",
|
|
22
|
+
eeprom: "sensor memory", local: "local backup", firebase: "database backup", defaultRules: "default rules",
|
|
23
|
+
verified: "verified", empty: "no profile saved", invalid: "invalid or outdated profile",
|
|
24
|
+
readFailed: "read failed", writeFailed: "save failed", firmwareNotAudited: "not enabled for this firmware",
|
|
25
|
+
notChecked: "not checked yet",
|
|
20
26
|
waiting: "Select a sensor and wait for fresh readings.",
|
|
21
27
|
capture: "Take {{colour}} snapshot",
|
|
22
28
|
captureAir: "Take air snapshot",
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { ColourSignalProfile } from "./colour-classifier";
|
|
2
|
+
export declare const COLOUR_PROFILE_EEPROM_ADDRESS: "401c";
|
|
3
|
+
export declare const COLOUR_PROFILE_EEPROM_FORMAT = 1;
|
|
4
|
+
export type ColourProfileIdentity = {
|
|
5
|
+
serialNumber: string;
|
|
6
|
+
typeCode: string;
|
|
7
|
+
firmwareVersion: string;
|
|
8
|
+
offsetsHex: string;
|
|
9
|
+
whiteCalibrationHex: string;
|
|
10
|
+
};
|
|
11
|
+
export type ColourProfileStorageEvidence = {
|
|
12
|
+
source: "eeprom" | "local" | "firebase" | "defaultRules";
|
|
13
|
+
eeprom: {
|
|
14
|
+
status: "verified" | "empty" | "invalid" | "readFailed" | "writeFailed" | "firmwareNotAudited" | "notChecked";
|
|
15
|
+
address: typeof COLOUR_PROFILE_EEPROM_ADDRESS;
|
|
16
|
+
formatVersion: number;
|
|
17
|
+
hex?: string;
|
|
18
|
+
reason?: string;
|
|
19
|
+
checkedAtMs?: number;
|
|
20
|
+
writeAttempted?: boolean;
|
|
21
|
+
readbackMatches?: boolean;
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
export declare const supportsColourProfileEEPROM: (hardware: {
|
|
25
|
+
typeCode: string | null;
|
|
26
|
+
firmwareVersion: string | null;
|
|
27
|
+
}) => boolean;
|
|
28
|
+
/** Format 1: version(2), R/G/B air excursions(6 each), coordinate checksum(12). Big endian. */
|
|
29
|
+
export declare const encodeColourProfileEEPROM: (identity: ColourProfileIdentity, signal: ColourSignalProfile) => string;
|
|
30
|
+
export declare const decodeColourProfileEEPROM: (hex: string, identity: ColourProfileIdentity) => {
|
|
31
|
+
status: "verified";
|
|
32
|
+
signal: ColourSignalProfile;
|
|
33
|
+
} | {
|
|
34
|
+
status: "empty" | "invalid";
|
|
35
|
+
reason: string;
|
|
36
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
2
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
3
|
+
if (ar || !(i in from)) {
|
|
4
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
5
|
+
ar[i] = from[i];
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
9
|
+
};
|
|
10
|
+
// The documented four-byte gap between air offsets and the white reference.
|
|
11
|
+
export var COLOUR_PROFILE_EEPROM_ADDRESS = "401c";
|
|
12
|
+
export var COLOUR_PROFILE_EEPROM_FORMAT = 1;
|
|
13
|
+
var RAW_NOISE_MARGIN = 3;
|
|
14
|
+
var CHANNELS = ["red", "green", "blue"];
|
|
15
|
+
// 1.4.1 retains its existing calibration path, but its source has not been audited for this new allocation.
|
|
16
|
+
export var supportsColourProfileEEPROM = function (hardware) {
|
|
17
|
+
return (hardware.typeCode === "97" && hardware.firmwareVersion === "1.3.1") ||
|
|
18
|
+
(hardware.typeCode === "98" && hardware.firmwareVersion === "1.4.0");
|
|
19
|
+
};
|
|
20
|
+
var coordinates = function (identity) {
|
|
21
|
+
if (!supportsColourProfileEEPROM(identity) || !/^[a-zA-Z0-9_-]{1,128}$/.test(identity.serialNumber) ||
|
|
22
|
+
!/^[a-f0-9]{8}$/i.test(identity.offsetsHex) || !/^[a-f0-9]{16}$/i.test(identity.whiteCalibrationHex)) {
|
|
23
|
+
throw new Error("unsupportedProfileCoordinates");
|
|
24
|
+
}
|
|
25
|
+
var offsets = CHANNELS.map(function (_, i) { return parseInt(identity.offsetsHex.slice((i + 1) * 2, (i + 2) * 2), 16); });
|
|
26
|
+
var white = CHANNELS.map(function (_, i) { return parseInt(identity.whiteCalibrationHex.slice((i + 1) * 4, (i + 2) * 4), 16); });
|
|
27
|
+
if (white.some(function (value) { return value < 10 || value > 255; }))
|
|
28
|
+
throw new Error("invalidWhiteReference");
|
|
29
|
+
return { offsets: offsets, white: white };
|
|
30
|
+
};
|
|
31
|
+
// CRC-12 polynomial 0x80f, MSB-first, initial value zero, no reflection or final XOR.
|
|
32
|
+
var checksum = function (payload, identity) {
|
|
33
|
+
var bytes = __spreadArray(__spreadArray(__spreadArray(__spreadArray([payload >>> 16, (payload >>> 8) & 255, payload & 255], Array.from((identity.offsetsHex + identity.whiteCalibrationHex).match(/../g), function (byte) { return parseInt(byte, 16); }), true), [Number(identity.typeCode)], false), identity.firmwareVersion.split(".").map(Number), true), Array.from(identity.serialNumber, function (character) { return character.charCodeAt(0); }), true);
|
|
34
|
+
var crc = 0;
|
|
35
|
+
for (var _i = 0, bytes_1 = bytes; _i < bytes_1.length; _i++) {
|
|
36
|
+
var byte = bytes_1[_i];
|
|
37
|
+
for (var bit = 7; bit >= 0; bit--) {
|
|
38
|
+
var feedback = ((crc >>> 11) ^ (byte >>> bit)) & 1;
|
|
39
|
+
crc = ((crc << 1) & 0xfff) ^ (feedback ? 0x80f : 0);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return crc;
|
|
43
|
+
};
|
|
44
|
+
/** Format 1: version(2), R/G/B air excursions(6 each), coordinate checksum(12). Big endian. */
|
|
45
|
+
export var encodeColourProfileEEPROM = function (identity, signal) {
|
|
46
|
+
var _a = coordinates(identity), offsets = _a.offsets, white = _a.white;
|
|
47
|
+
var excursions = CHANNELS.map(function (channel, i) {
|
|
48
|
+
var rawMax = signal.airMax[channel] * white[i] / 255;
|
|
49
|
+
var margin = signal.margin[channel] * white[i] / 255;
|
|
50
|
+
var excursion = Math.round(rawMax) - (identity.typeCode === "97" ? offsets[i] : 0);
|
|
51
|
+
// Calibration's steadiness check guarantees this range; never silently quantise arbitrary legacy profiles.
|
|
52
|
+
if (!Number.isFinite(rawMax) || Math.abs(rawMax - Math.round(rawMax)) > 1e-7 ||
|
|
53
|
+
!Number.isFinite(margin) || Math.abs(margin - RAW_NOISE_MARGIN) > 1e-7 ||
|
|
54
|
+
excursion < 0 || excursion > 63 || excursion + offsets[i] >= 255 || excursion > Math.max(4, offsets[i] * 0.15)) {
|
|
55
|
+
throw new Error("profileNotRepresentable");
|
|
56
|
+
}
|
|
57
|
+
return excursion;
|
|
58
|
+
});
|
|
59
|
+
var payload = COLOUR_PROFILE_EEPROM_FORMAT * Math.pow(2, 18) + excursions[0] * Math.pow(2, 12) + excursions[1] * Math.pow(2, 6) + excursions[2];
|
|
60
|
+
return (payload * Math.pow(2, 12) + checksum(payload, identity)).toString(16).padStart(8, "0");
|
|
61
|
+
};
|
|
62
|
+
export var decodeColourProfileEEPROM = function (hex, identity) {
|
|
63
|
+
if (!/^[a-f0-9]{8}$/i.test(hex))
|
|
64
|
+
return { status: "invalid", reason: "invalidLength" };
|
|
65
|
+
if (["00000000", "ffffffff"].includes(hex.toLowerCase()))
|
|
66
|
+
return { status: "empty", reason: "noProfile" };
|
|
67
|
+
try {
|
|
68
|
+
var _a = coordinates(identity), offsets_1 = _a.offsets, white_1 = _a.white;
|
|
69
|
+
var word = parseInt(hex, 16);
|
|
70
|
+
var payload = Math.floor(word / Math.pow(2, 12));
|
|
71
|
+
if (Math.floor(payload / Math.pow(2, 18)) !== COLOUR_PROFILE_EEPROM_FORMAT)
|
|
72
|
+
return { status: "invalid", reason: "unknownFormat" };
|
|
73
|
+
if (word % Math.pow(2, 12) !== checksum(payload, identity))
|
|
74
|
+
return { status: "invalid", reason: "checksumOrCalibrationMismatch" };
|
|
75
|
+
var excursions_1 = [Math.floor(payload / Math.pow(2, 12)) % 64, Math.floor(payload / Math.pow(2, 6)) % 64, payload % 64];
|
|
76
|
+
if (excursions_1.some(function (value, i) { return value + offsets_1[i] >= 255 || value > Math.max(4, offsets_1[i] * 0.15); }))
|
|
77
|
+
return { status: "invalid", reason: "invalidAirExcursion" };
|
|
78
|
+
var airMax = Object.fromEntries(CHANNELS.map(function (channel, i) {
|
|
79
|
+
return [channel, (excursions_1[i] + (identity.typeCode === "97" ? offsets_1[i] : 0)) * 255 / white_1[i]];
|
|
80
|
+
}));
|
|
81
|
+
var margin = Object.fromEntries(CHANNELS.map(function (channel, i) { return [channel, RAW_NOISE_MARGIN * 255 / white_1[i]]; }));
|
|
82
|
+
// Measured air minima and capture history remain in diagnostics; classification needs only max + margin.
|
|
83
|
+
return { status: "verified", signal: { airMax: airMax, margin: margin } };
|
|
84
|
+
}
|
|
85
|
+
catch (_b) {
|
|
86
|
+
return { status: "invalid", reason: "invalidCoordinates" };
|
|
87
|
+
}
|
|
88
|
+
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import colourPolicy from "./marty-colour-policy.json";
|
|
2
2
|
import { ColourConfidenceFactors, ColourSignalProfile } from "./colour-classifier";
|
|
3
|
-
import {
|
|
3
|
+
import { ActiveColourSensorProfile } from "./colour-sensor-profile";
|
|
4
|
+
import { ColourProfileStorageEvidence } from "./colour-profile-eeprom";
|
|
4
5
|
import type { RaftObserver } from "../application/RAFTs/RaftObserver";
|
|
5
6
|
import type { RestMessageOptions } from "../types/communication-between-apps/wrapper-communication";
|
|
6
7
|
import { SensorRead, RawColourFrame, ColourSensorSetup } from "./colour-sensor-registers";
|
|
@@ -94,7 +95,8 @@ export type ColourSnapshot = {
|
|
|
94
95
|
airFlagTakesPrecedence: boolean;
|
|
95
96
|
boundaries: typeof BLOCKS_COLOUR_BOUNDARIES;
|
|
96
97
|
signal?: typeof colourPolicy.signal;
|
|
97
|
-
profile?:
|
|
98
|
+
profile?: ActiveColourSensorProfile;
|
|
99
|
+
profileStorage?: ColourProfileStorageEvidence;
|
|
98
100
|
clearBoundsUsedForClassification?: boolean;
|
|
99
101
|
confidence?: typeof colourPolicy.confidence;
|
|
100
102
|
};
|
|
@@ -72,7 +72,8 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
|
72
72
|
import packageInfo from "../../package.json";
|
|
73
73
|
import colourPolicy from "./marty-colour-policy.json";
|
|
74
74
|
import { classifyColour, colourChannelsFromValues } from "./colour-classifier";
|
|
75
|
-
import { getActiveColourSensorProfile } from "./colour-sensor-profile";
|
|
75
|
+
import { getActiveColourSensorProfile, hydrateColourSensorProfile, clearActiveColourSensorProfile } from "./colour-sensor-profile";
|
|
76
|
+
import { COLOUR_PROFILE_EEPROM_ADDRESS, COLOUR_PROFILE_EEPROM_FORMAT } from "./colour-profile-eeprom";
|
|
76
77
|
import { lockColourSensorOperation, waitForColourProfileRead } from "./colour-sensor-operation";
|
|
77
78
|
import { getPendingColourCalibration } from "./colour-calibration-reconnect";
|
|
78
79
|
import { collectColourSensorSetup, readRawColourSensor } from "./colour-sensor-registers";
|
|
@@ -165,7 +166,7 @@ var delay = function (ms, signal) { return new Promise(function (resolve, reject
|
|
|
165
166
|
abort();
|
|
166
167
|
}); };
|
|
167
168
|
var captureUnlocked = function (sensor, expectedColour, session, signal) { return __awaiter(void 0, void 0, void 0, function () {
|
|
168
|
-
var startedAtMs, checkActive, sensorSetup, sampleWindowStartedAtMs, samples, rawSamples, rawController, abortRaw, rawFailure, collectRaw, rawCapture, index, reading;
|
|
169
|
+
var startedAtMs, checkActive, sensorSetup, profileStorage, hardware, sampleWindowStartedAtMs, samples, rawSamples, rawController, abortRaw, rawFailure, collectRaw, rawCapture, index, reading;
|
|
169
170
|
var _a, _b, _c, _d, _e, _f;
|
|
170
171
|
return __generator(this, function (_g) {
|
|
171
172
|
switch (_g.label) {
|
|
@@ -187,6 +188,21 @@ var captureUnlocked = function (sensor, expectedColour, session, signal) { retur
|
|
|
187
188
|
throw new ColourDiagnosticError("sensorPowerFailed");
|
|
188
189
|
if (sensorSetup.hardware.status === "ok" && sensorSetup.hardware.value.commsOk === 0)
|
|
189
190
|
throw new ColourDiagnosticError("sensorOffline");
|
|
191
|
+
profileStorage = { source: "defaultRules", eeprom: {
|
|
192
|
+
status: "notChecked", address: COLOUR_PROFILE_EEPROM_ADDRESS, formatVersion: COLOUR_PROFILE_EEPROM_FORMAT,
|
|
193
|
+
reason: "sensorDetailsUnavailable",
|
|
194
|
+
} };
|
|
195
|
+
clearActiveColourSensorProfile(sensor);
|
|
196
|
+
if (!(sensorSetup.hardware.status === "ok" && sensorSetup.offsets.status === "ok" && sensorSetup.whiteCalibration.status === "ok")) return [3 /*break*/, 3];
|
|
197
|
+
hardware = sensorSetup.hardware.value;
|
|
198
|
+
if (!(hardware.serialNumber && hardware.typeCode && hardware.firmwareVersion)) return [3 /*break*/, 3];
|
|
199
|
+
return [4 /*yield*/, hydrateColourSensorProfile(sensor, { serialNumber: hardware.serialNumber,
|
|
200
|
+
typeCode: hardware.typeCode, firmwareVersion: hardware.firmwareVersion,
|
|
201
|
+
offsetsHex: sensorSetup.offsets.value.hexRd, whiteCalibrationHex: sensorSetup.whiteCalibration.value.hexRd }, signal, checkActive)];
|
|
202
|
+
case 2:
|
|
203
|
+
profileStorage = _g.sent();
|
|
204
|
+
_g.label = 3;
|
|
205
|
+
case 3:
|
|
190
206
|
readColourSensor(sensor);
|
|
191
207
|
sampleWindowStartedAtMs = Date.now();
|
|
192
208
|
samples = [];
|
|
@@ -228,42 +244,42 @@ var captureUnlocked = function (sensor, expectedColour, session, signal) { retur
|
|
|
228
244
|
});
|
|
229
245
|
}); };
|
|
230
246
|
rawCapture = collectRaw();
|
|
231
|
-
_g.label =
|
|
232
|
-
case
|
|
233
|
-
_g.trys.push([
|
|
247
|
+
_g.label = 4;
|
|
248
|
+
case 4:
|
|
249
|
+
_g.trys.push([4, , 9, 11]);
|
|
234
250
|
index = 0;
|
|
235
|
-
_g.label =
|
|
236
|
-
case
|
|
237
|
-
if (!(index <= CAPTURE_DURATION_MS / CAPTURE_INTERVAL_MS)) return [3 /*break*/,
|
|
251
|
+
_g.label = 5;
|
|
252
|
+
case 5:
|
|
253
|
+
if (!(index <= CAPTURE_DURATION_MS / CAPTURE_INTERVAL_MS)) return [3 /*break*/, 8];
|
|
238
254
|
checkActive();
|
|
239
255
|
if (rawFailure)
|
|
240
256
|
throw rawFailure;
|
|
241
257
|
reading = readColourSensor(sensor);
|
|
242
258
|
if (!samples.length || samples[samples.length - 1].receivedAtMs !== reading.receivedAtMs)
|
|
243
259
|
samples.push(reading);
|
|
244
|
-
if (!(index < CAPTURE_DURATION_MS / CAPTURE_INTERVAL_MS)) return [3 /*break*/,
|
|
260
|
+
if (!(index < CAPTURE_DURATION_MS / CAPTURE_INTERVAL_MS)) return [3 /*break*/, 7];
|
|
245
261
|
return [4 /*yield*/, delay(CAPTURE_INTERVAL_MS, signal)];
|
|
246
|
-
case
|
|
262
|
+
case 6:
|
|
247
263
|
_g.sent();
|
|
248
|
-
_g.label =
|
|
249
|
-
case 5:
|
|
250
|
-
index++;
|
|
251
|
-
return [3 /*break*/, 3];
|
|
252
|
-
case 6: return [3 /*break*/, 9];
|
|
264
|
+
_g.label = 7;
|
|
253
265
|
case 7:
|
|
266
|
+
index++;
|
|
267
|
+
return [3 /*break*/, 5];
|
|
268
|
+
case 8: return [3 /*break*/, 11];
|
|
269
|
+
case 9:
|
|
254
270
|
rawController.abort();
|
|
255
271
|
signal.removeEventListener("abort", abortRaw);
|
|
256
272
|
return [4 /*yield*/, rawCapture];
|
|
257
|
-
case
|
|
273
|
+
case 10:
|
|
258
274
|
_g.sent();
|
|
259
275
|
return [7 /*endfinally*/];
|
|
260
|
-
case
|
|
276
|
+
case 11:
|
|
261
277
|
if (rawFailure)
|
|
262
278
|
throw rawFailure;
|
|
263
279
|
if (samples.length < 2)
|
|
264
280
|
throw new ColourDiagnosticError("staleReading");
|
|
265
281
|
return [2 /*return*/, __assign(__assign({ schemaVersion: 2, sessionId: session.sessionId, sessionStartedAtMs: session.startedAtMs, captureId: createId(), expectedColour: expectedColour, startedAtMs: startedAtMs, finishedAtMs: Date.now(), appVersion: packageInfo.version, classifier: { source: colourPolicy.source, airFlagTakesPrecedence: false, boundaries: BLOCKS_COLOUR_BOUNDARIES,
|
|
266
|
-
signal: colourPolicy.signal, profile: getActiveColourSensorProfile(sensor), clearBoundsUsedForClassification: false,
|
|
282
|
+
signal: colourPolicy.signal, profile: getActiveColourSensorProfile(sensor), profileStorage: profileStorage, clearBoundsUsedForClassification: false,
|
|
267
283
|
confidence: colourPolicy.confidence }, device: {
|
|
268
284
|
id: sensor.raftId, type: sensor.raft.type, name: ((_c = (_b = sensor.raft).getFriendlyName) === null || _c === void 0 ? void 0 : _c.call(_b)) || sensor.raftId,
|
|
269
285
|
firmwareVersion: ((_d = sensor.raft.systemInfo) === null || _d === void 0 ? void 0 : _d.SystemVersion) || null, connectionMethod: sensor.raft.connectionMethod || null,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ColourSensor } from "./colour-sensor-diagnostics";
|
|
2
2
|
import { ColourSignalProfile } from "./colour-classifier";
|
|
3
|
+
import { ColourProfileIdentity, ColourProfileStorageEvidence } from "./colour-profile-eeprom";
|
|
3
4
|
export type ColourSensorProfile = {
|
|
4
5
|
schemaVersion: 1;
|
|
5
6
|
serialNumber: string;
|
|
@@ -12,21 +13,26 @@ export type ColourSensorProfile = {
|
|
|
12
13
|
purpleIncluded: boolean;
|
|
13
14
|
groundDetection: "clearThreshold" | "rgbFallback" | "purpleSkipped";
|
|
14
15
|
};
|
|
16
|
+
export type ActiveColourSensorProfile = Omit<ColourSensorProfile, "capturedAtMs" | "purpleIncluded" | "groundDetection"> & Partial<Pick<ColourSensorProfile, "capturedAtMs" | "purpleIncluded" | "groundDetection">>;
|
|
15
17
|
export declare const validColourSensorProfile: (value: unknown) => value is ColourSensorProfile;
|
|
16
18
|
export declare const cacheColourSensorProfile: (profile: ColourSensorProfile) => void;
|
|
17
19
|
export declare const colourSensorProfilePath: (profile: ColourSensorProfile) => string;
|
|
18
|
-
export declare const bindColourSensorProfile: (sensor: ColourSensor, profile:
|
|
19
|
-
export declare const getActiveColourSensorProfile: (sensor: Pick<ColourSensor, "raft" | "key">) =>
|
|
20
|
+
export declare const bindColourSensorProfile: (sensor: ColourSensor, profile: ActiveColourSensorProfile) => void;
|
|
21
|
+
export declare const getActiveColourSensorProfile: (sensor: Pick<ColourSensor, "raft" | "key">) => ActiveColourSensorProfile | undefined;
|
|
20
22
|
export declare const getAddonColourSensorProfile: (raft: object, addon: {
|
|
21
23
|
id: number;
|
|
22
24
|
name: string;
|
|
23
|
-
}) =>
|
|
24
|
-
export declare const
|
|
25
|
+
}) => ActiveColourSensorProfile | undefined;
|
|
26
|
+
export declare const getColourProfileStorage: (sensor: Pick<ColourSensor, "raft" | "key">) => ColourProfileStorageEvidence | undefined;
|
|
27
|
+
export declare const setColourProfileStorage: (sensor: Pick<ColourSensor, "raft" | "key">, evidence: ColourProfileStorageEvidence) => void;
|
|
28
|
+
export declare const clearActiveColourSensorProfile: (sensor: Pick<ColourSensor, "raft" | "key">) => void;
|
|
25
29
|
export declare const classifyColourAddon: (addon: {
|
|
26
30
|
id: number;
|
|
27
31
|
name: string;
|
|
28
32
|
vals: Record<string, number | boolean>;
|
|
29
33
|
}) => import("./colour-classifier").ColourName;
|
|
34
|
+
/** Caller owns the raw-command lock and has freshly read hardware, offsets and white references. */
|
|
35
|
+
export declare const hydrateColourSensorProfile: (sensor: ColourSensor, identity: ColourProfileIdentity, signal: AbortSignal, check: () => void) => Promise<ColourProfileStorageEvidence>;
|
|
30
36
|
export declare const loadColourSensorProfile: (sensor: ColourSensor, signal: AbortSignal) => Promise<void>;
|
|
31
37
|
/** Read-only browser/WebView hydration. Never wakes sleeping sensors or modifies their registers. */
|
|
32
38
|
export declare const startColourSensorProfileSync: () => () => void;
|
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
1
12
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
13
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
14
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -39,9 +50,11 @@ import { classifyColour, colourChannelsFromValues } from "./colour-classifier";
|
|
|
39
50
|
import { lockColourSensorOperation } from "./colour-sensor-operation";
|
|
40
51
|
import { readColourSensorHardware, readColourSensorReadiness, readColourSensorRegister } from "./colour-sensor-registers";
|
|
41
52
|
import { getPendingColourCalibration } from "./colour-calibration-reconnect";
|
|
53
|
+
import { COLOUR_PROFILE_EEPROM_ADDRESS, COLOUR_PROFILE_EEPROM_FORMAT, decodeColourProfileEEPROM, supportsColourProfileEEPROM } from "./colour-profile-eeprom";
|
|
42
54
|
var PREFIX = "marty-colour-signal-profile:";
|
|
43
55
|
var memory = new Map();
|
|
44
56
|
var active = new WeakMap();
|
|
57
|
+
var storage = new WeakMap();
|
|
45
58
|
var retries = new WeakMap();
|
|
46
59
|
var profileKey = function (profile) {
|
|
47
60
|
return "".concat(profile.serialNumber, "/").concat(profile.offsetsHex).concat(profile.whiteCalibrationHex);
|
|
@@ -57,7 +70,7 @@ export var validColourSensorProfile = function (value) {
|
|
|
57
70
|
var _a, _b, _c, _d, _e, _f;
|
|
58
71
|
var c = channel;
|
|
59
72
|
return [(_b = (_a = profile.signal) === null || _a === void 0 ? void 0 : _a.airMin) === null || _b === void 0 ? void 0 : _b[c], (_d = (_c = profile.signal) === null || _c === void 0 ? void 0 : _c.airMax) === null || _d === void 0 ? void 0 : _d[c], (_f = (_e = profile.signal) === null || _e === void 0 ? void 0 : _e.margin) === null || _f === void 0 ? void 0 : _f[c]]
|
|
60
|
-
.every(function (v) { return Number.isFinite(v) && v >= 0; }) && profile.signal.airMin[c] <= profile.signal.airMax[c] && profile.signal.margin[c] > 0;
|
|
73
|
+
.every(function (v) { return typeof v === "number" && Number.isFinite(v) && v >= 0; }) && profile.signal.airMin[c] <= profile.signal.airMax[c] && profile.signal.margin[c] > 0;
|
|
61
74
|
});
|
|
62
75
|
};
|
|
63
76
|
export var cacheColourSensorProfile = function (profile) {
|
|
@@ -82,7 +95,20 @@ export var bindColourSensorProfile = function (sensor, profile) {
|
|
|
82
95
|
};
|
|
83
96
|
export var getActiveColourSensorProfile = function (sensor) { var _a; return (_a = active.get(sensor.raft)) === null || _a === void 0 ? void 0 : _a.get(sensor.key); };
|
|
84
97
|
export var getAddonColourSensorProfile = function (raft, addon) { var _a; return (_a = active.get(raft)) === null || _a === void 0 ? void 0 : _a.get(JSON.stringify([addon.id, addon.name])); };
|
|
85
|
-
export var
|
|
98
|
+
export var getColourProfileStorage = function (sensor) { var _a; return (_a = storage.get(sensor.raft)) === null || _a === void 0 ? void 0 : _a.get(sensor.key); };
|
|
99
|
+
export var setColourProfileStorage = function (sensor, evidence) {
|
|
100
|
+
var entries = storage.get(sensor.raft);
|
|
101
|
+
if (!entries) {
|
|
102
|
+
entries = new Map();
|
|
103
|
+
storage.set(sensor.raft, entries);
|
|
104
|
+
}
|
|
105
|
+
entries.set(sensor.key, evidence);
|
|
106
|
+
};
|
|
107
|
+
export var clearActiveColourSensorProfile = function (sensor) {
|
|
108
|
+
var _a, _b;
|
|
109
|
+
(_a = active.get(sensor.raft)) === null || _a === void 0 ? void 0 : _a.delete(sensor.key);
|
|
110
|
+
(_b = storage.get(sensor.raft)) === null || _b === void 0 ? void 0 : _b.delete(sensor.key);
|
|
111
|
+
};
|
|
86
112
|
export var classifyColourAddon = function (addon) {
|
|
87
113
|
var _a;
|
|
88
114
|
var raft = Object.values(window.applicationManager.connectedRafts).find(function (candidate) {
|
|
@@ -91,96 +117,156 @@ export var classifyColourAddon = function (addon) {
|
|
|
91
117
|
});
|
|
92
118
|
return classifyColour(colourChannelsFromValues(addon.vals), raft ? (_a = getAddonColourSensorProfile(raft, addon)) === null || _a === void 0 ? void 0 : _a.signal : undefined).classifiedColour;
|
|
93
119
|
};
|
|
94
|
-
|
|
95
|
-
export var
|
|
96
|
-
var
|
|
120
|
+
/** Caller owns the raw-command lock and has freshly read hardware, offsets and white references. */
|
|
121
|
+
export var hydrateColourSensorProfile = function (sensor, identity, signal, check) { return __awaiter(void 0, void 0, void 0, function () {
|
|
122
|
+
var evidence, profile, result, decoded, key_1, cached, stored, controller_1, abort, timeout, response, records, _a, hardware, unavailable, state, current;
|
|
97
123
|
var _b;
|
|
98
124
|
return __generator(this, function (_c) {
|
|
99
125
|
switch (_c.label) {
|
|
100
126
|
case 0:
|
|
101
|
-
release = lockColourSensorOperation(sensor.raft, true);
|
|
102
|
-
if (!release)
|
|
103
|
-
return [2 /*return*/];
|
|
104
|
-
check = function () { return assertColourSensorActive(sensor, signal); };
|
|
105
|
-
_c.label = 1;
|
|
106
|
-
case 1:
|
|
107
|
-
_c.trys.push([1, , 13, 14]);
|
|
108
127
|
check();
|
|
109
128
|
clearActiveColourSensorProfile(sensor);
|
|
110
|
-
|
|
129
|
+
evidence = { source: "defaultRules", eeprom: {
|
|
130
|
+
status: "firmwareNotAudited", address: COLOUR_PROFILE_EEPROM_ADDRESS, formatVersion: COLOUR_PROFILE_EEPROM_FORMAT,
|
|
131
|
+
} };
|
|
132
|
+
if (!supportsColourProfileEEPROM(identity)) return [3 /*break*/, 2];
|
|
133
|
+
return [4 /*yield*/, readColourSensorRegister(sensor, COLOUR_PROFILE_EEPROM_ADDRESS, signal, check)];
|
|
134
|
+
case 1:
|
|
135
|
+
result = _c.sent();
|
|
136
|
+
evidence.eeprom.checkedAtMs = result.receivedAtMs;
|
|
137
|
+
if (result.status === "ok") {
|
|
138
|
+
decoded = decodeColourProfileEEPROM(result.value, identity);
|
|
139
|
+
evidence.eeprom = __assign(__assign(__assign({}, evidence.eeprom), { status: decoded.status, hex: result.value }), (decoded.status === "verified" ? { readbackMatches: true } : { reason: decoded.reason }));
|
|
140
|
+
if (decoded.status === "verified") {
|
|
141
|
+
profile = __assign(__assign({ schemaVersion: 1 }, identity), { signal: decoded.signal });
|
|
142
|
+
evidence.source = "eeprom";
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
else {
|
|
146
|
+
evidence.eeprom.status = "readFailed";
|
|
147
|
+
evidence.eeprom.reason = result.reason;
|
|
148
|
+
}
|
|
149
|
+
_c.label = 2;
|
|
111
150
|
case 2:
|
|
112
|
-
|
|
113
|
-
if (readiness.status !== "ok" || !readiness.value)
|
|
114
|
-
return [2 /*return*/];
|
|
115
|
-
return [4 /*yield*/, readColourSensorHardware(sensor, signal, check)];
|
|
116
|
-
case 3:
|
|
117
|
-
hardware = _c.sent();
|
|
118
|
-
if (hardware.status !== "ok" || hardware.value.commsOk === 0 || !hardware.value.serialNumber ||
|
|
119
|
-
!/^[a-zA-Z0-9_-]{1,128}$/.test(hardware.value.serialNumber))
|
|
120
|
-
return [2 /*return*/];
|
|
121
|
-
return [4 /*yield*/, readColourSensorRegister(sensor, "4020", signal, check)];
|
|
122
|
-
case 4:
|
|
123
|
-
white = _c.sent();
|
|
124
|
-
if (white.status !== "ok")
|
|
125
|
-
return [2 /*return*/];
|
|
126
|
-
return [4 /*yield*/, readColourSensorRegister(sensor, "4018", signal, check)];
|
|
127
|
-
case 5:
|
|
128
|
-
offsets = _c.sent();
|
|
129
|
-
if (offsets.status !== "ok")
|
|
130
|
-
return [2 /*return*/];
|
|
131
|
-
identity = { serialNumber: hardware.value.serialNumber, offsetsHex: offsets.value, whiteCalibrationHex: white.value };
|
|
151
|
+
if (!!profile) return [3 /*break*/, 10];
|
|
132
152
|
key_1 = profileKey(identity);
|
|
133
|
-
|
|
153
|
+
cached = memory.get(key_1);
|
|
134
154
|
try {
|
|
135
155
|
stored = JSON.parse(localStorage.getItem(PREFIX + key_1) || "null");
|
|
136
|
-
if (validColourSensorProfile(stored))
|
|
137
|
-
|
|
156
|
+
if (validColourSensorProfile(stored) && profileKey(stored) === key_1)
|
|
157
|
+
cached = stored;
|
|
138
158
|
}
|
|
139
159
|
catch ( /* Native WebViews may have temporary or unavailable storage. */_d) { /* Native WebViews may have temporary or unavailable storage. */ }
|
|
140
|
-
if (
|
|
160
|
+
if (!(cached && profileKey(cached) === key_1 && cached.typeCode === identity.typeCode && cached.firmwareVersion === identity.firmwareVersion)) return [3 /*break*/, 3];
|
|
161
|
+
profile = cached;
|
|
162
|
+
evidence.source = "local";
|
|
163
|
+
return [3 /*break*/, 10];
|
|
164
|
+
case 3:
|
|
141
165
|
controller_1 = new AbortController();
|
|
142
166
|
abort = function () { return controller_1.abort(); };
|
|
143
167
|
signal.addEventListener("abort", abort, { once: true });
|
|
168
|
+
if (signal.aborted)
|
|
169
|
+
abort();
|
|
144
170
|
timeout = setTimeout(abort, 5000);
|
|
145
|
-
_c.label =
|
|
146
|
-
case
|
|
147
|
-
_c.trys.push([
|
|
171
|
+
_c.label = 4;
|
|
172
|
+
case 4:
|
|
173
|
+
_c.trys.push([4, 8, 9, 10]);
|
|
148
174
|
return [4 /*yield*/, fetch("".concat(COLOUR_DATABASE_URL, "/colourSensorProfiles/").concat(key_1, ".json"), { signal: controller_1.signal })];
|
|
149
|
-
case
|
|
175
|
+
case 5:
|
|
150
176
|
response = _c.sent();
|
|
151
|
-
if (!response.ok) return [3 /*break*/,
|
|
177
|
+
if (!response.ok) return [3 /*break*/, 7];
|
|
152
178
|
return [4 /*yield*/, response.json()];
|
|
153
|
-
case
|
|
179
|
+
case 6:
|
|
154
180
|
records = _c.sent();
|
|
155
181
|
if (records && typeof records === "object")
|
|
156
182
|
profile = Object.values(records).filter(validColourSensorProfile)
|
|
157
|
-
.filter(function (value) { return profileKey(value) === key_1
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
183
|
+
.filter(function (value) { return profileKey(value) === key_1 && value.typeCode === identity.typeCode && value.firmwareVersion === identity.firmwareVersion; })
|
|
184
|
+
.sort(function (a, b) { return b.capturedAtMs - a.capturedAtMs; })[0];
|
|
185
|
+
if (profile) {
|
|
186
|
+
evidence.source = "firebase";
|
|
187
|
+
cacheColourSensorProfile(profile);
|
|
188
|
+
}
|
|
189
|
+
_c.label = 7;
|
|
190
|
+
case 7: return [3 /*break*/, 10];
|
|
191
|
+
case 8:
|
|
161
192
|
_a = _c.sent();
|
|
162
|
-
return [3 /*break*/,
|
|
163
|
-
case
|
|
193
|
+
return [3 /*break*/, 10];
|
|
194
|
+
case 9:
|
|
164
195
|
clearTimeout(timeout);
|
|
165
196
|
signal.removeEventListener("abort", abort);
|
|
166
197
|
return [7 /*endfinally*/];
|
|
167
|
-
case
|
|
198
|
+
case 10:
|
|
168
199
|
check();
|
|
200
|
+
return [4 /*yield*/, readColourSensorHardware(sensor, signal, check)];
|
|
201
|
+
case 11:
|
|
202
|
+
hardware = _c.sent();
|
|
203
|
+
if (hardware.status !== "ok" || hardware.value.commsOk === 0 || hardware.value.serialNumber !== identity.serialNumber ||
|
|
204
|
+
hardware.value.typeCode !== identity.typeCode || hardware.value.firmwareVersion !== identity.firmwareVersion) {
|
|
205
|
+
unavailable = __assign(__assign({}, evidence), { source: "defaultRules", eeprom: __assign(__assign({}, evidence.eeprom), { status: "notChecked", reason: "sensorIdentityChangedOrUnavailable", readbackMatches: false }) });
|
|
206
|
+
setColourProfileStorage(sensor, unavailable);
|
|
207
|
+
return [2 /*return*/, unavailable];
|
|
208
|
+
}
|
|
169
209
|
state = sensor.raft.raftStateInfo;
|
|
170
210
|
current = state.addOnInfo.addons.find(function (addon) { return addon.id === sensor.addon.id && addon.name === sensor.addon.name; });
|
|
171
211
|
if (!current || (current.status !== undefined && !(current.status & 128)) ||
|
|
172
|
-
Date.now() - state.addOnInfoValidMs > 1500 || state.addOnInfoValidMs > Date.now() || ((_b = state.power) === null || _b === void 0 ? void 0 : _b.powerStatus.power5VIsOn) === false)
|
|
173
|
-
return [2 /*return
|
|
174
|
-
if (profile && profileKey(profile) === key_1 && profile.typeCode === hardware.value.typeCode &&
|
|
175
|
-
profile.firmwareVersion === hardware.value.firmwareVersion) {
|
|
176
|
-
cacheColourSensorProfile(profile);
|
|
177
|
-
bindColourSensorProfile(sensor, profile);
|
|
212
|
+
Date.now() - state.addOnInfoValidMs > 1500 || state.addOnInfoValidMs > Date.now() || ((_b = state.power) === null || _b === void 0 ? void 0 : _b.powerStatus.power5VIsOn) === false) {
|
|
213
|
+
return [2 /*return*/, __assign(__assign({}, evidence), { source: "defaultRules", eeprom: __assign(__assign({}, evidence.eeprom), { status: "notChecked", reason: "sensorNotFresh" }) })];
|
|
178
214
|
}
|
|
179
|
-
|
|
180
|
-
|
|
215
|
+
if (profile)
|
|
216
|
+
bindColourSensorProfile(sensor, profile);
|
|
217
|
+
setColourProfileStorage(sensor, evidence);
|
|
218
|
+
return [2 /*return*/, evidence];
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
}); };
|
|
222
|
+
// Check physical identity and the complete saved coordinate system before using a persisted profile.
|
|
223
|
+
export var loadColourSensorProfile = function (sensor, signal) { return __awaiter(void 0, void 0, void 0, function () {
|
|
224
|
+
var release, check, readiness, hardware, white, offsets;
|
|
225
|
+
return __generator(this, function (_a) {
|
|
226
|
+
switch (_a.label) {
|
|
227
|
+
case 0:
|
|
228
|
+
release = lockColourSensorOperation(sensor.raft, true);
|
|
229
|
+
if (!release)
|
|
230
|
+
return [2 /*return*/];
|
|
231
|
+
check = function () { return assertColourSensorActive(sensor, signal); };
|
|
232
|
+
_a.label = 1;
|
|
233
|
+
case 1:
|
|
234
|
+
_a.trys.push([1, , 7, 8]);
|
|
235
|
+
check();
|
|
236
|
+
clearActiveColourSensorProfile(sensor);
|
|
237
|
+
return [4 /*yield*/, readColourSensorReadiness(sensor, signal, check)];
|
|
238
|
+
case 2:
|
|
239
|
+
readiness = _a.sent();
|
|
240
|
+
if (readiness.status !== "ok" || !readiness.value)
|
|
241
|
+
return [2 /*return*/];
|
|
242
|
+
return [4 /*yield*/, readColourSensorHardware(sensor, signal, check)];
|
|
243
|
+
case 3:
|
|
244
|
+
hardware = _a.sent();
|
|
245
|
+
if (hardware.status !== "ok" || hardware.value.commsOk === 0 || !hardware.value.serialNumber ||
|
|
246
|
+
!/^[a-zA-Z0-9_-]{1,128}$/.test(hardware.value.serialNumber))
|
|
247
|
+
return [2 /*return*/];
|
|
248
|
+
return [4 /*yield*/, readColourSensorRegister(sensor, "4020", signal, check)];
|
|
249
|
+
case 4:
|
|
250
|
+
white = _a.sent();
|
|
251
|
+
if (white.status !== "ok")
|
|
252
|
+
return [2 /*return*/];
|
|
253
|
+
return [4 /*yield*/, readColourSensorRegister(sensor, "4018", signal, check)];
|
|
254
|
+
case 5:
|
|
255
|
+
offsets = _a.sent();
|
|
256
|
+
if (offsets.status !== "ok")
|
|
257
|
+
return [2 /*return*/];
|
|
258
|
+
if (!hardware.value.typeCode || !hardware.value.firmwareVersion)
|
|
259
|
+
return [2 /*return*/];
|
|
260
|
+
return [4 /*yield*/, hydrateColourSensorProfile(sensor, { serialNumber: hardware.value.serialNumber,
|
|
261
|
+
typeCode: hardware.value.typeCode, firmwareVersion: hardware.value.firmwareVersion,
|
|
262
|
+
offsetsHex: offsets.value, whiteCalibrationHex: white.value }, signal, check)];
|
|
263
|
+
case 6:
|
|
264
|
+
_a.sent();
|
|
265
|
+
return [3 /*break*/, 8];
|
|
266
|
+
case 7:
|
|
181
267
|
release();
|
|
182
268
|
return [7 /*endfinally*/];
|
|
183
|
-
case
|
|
269
|
+
case 8: return [2 /*return*/];
|
|
184
270
|
}
|
|
185
271
|
});
|
|
186
272
|
}); };
|
|
@@ -43,7 +43,7 @@ export type ColourSensorSetup = {
|
|
|
43
43
|
offsets: SensorRead<Channels>;
|
|
44
44
|
whiteCalibration: SensorRead<Channels>;
|
|
45
45
|
};
|
|
46
|
-
export type ColourSensorRegister = "4014" | "4018" | "4020";
|
|
46
|
+
export type ColourSensorRegister = "4014" | "4018" | "401c" | "4020";
|
|
47
47
|
export declare const readColourSensorRegister: (sensor: ColourSensor, address: ColourSensorRegister, signal: AbortSignal, checkActive: () => void) => Promise<SensorRead<string>>;
|
|
48
48
|
export declare const readColourSensorHardware: (sensor: ColourSensor, signal: AbortSignal, checkActive: () => void) => Promise<SensorRead<SensorHardware>>;
|
|
49
49
|
export declare const wakeColourSensor: (sensor: ColourSensor, signal: AbortSignal, checkActive: () => void) => Promise<SensorRead<boolean>>;
|
|
@@ -138,7 +138,7 @@ var readHex = function (sensor, hexWr, bytes, signal, checkActive) {
|
|
|
138
138
|
});
|
|
139
139
|
};
|
|
140
140
|
export var readColourSensorRegister = function (sensor, address, signal, checkActive) {
|
|
141
|
-
return readHex(sensor, "10".concat(address), { "4014": 2, "4018": 4, "4020": 8 }[address], signal, checkActive);
|
|
141
|
+
return readHex(sensor, "10".concat(address), { "4014": 2, "4018": 4, "401c": 4, "4020": 8 }[address], signal, checkActive);
|
|
142
142
|
};
|
|
143
143
|
var mapRead = function (result, convert) {
|
|
144
144
|
return result.status === "ok" ? __assign(__assign({}, result), { value: convert(result.value) }) : result;
|