@robotical/sensors-dashboard
Version:
A dashboard tool for depicting Marty data by Robotical
122 lines (113 loc) • 3.73 kB
text/typescript
import Addon from "../models/addons/Addon";
import AddonSub from "../models/addons/AddonSub";
import type MicroBitWebBluetooth from "../microbit/MicroBitWebBluetooth";
import type { MicroBitSensors } from "../microbit/MicroBitWebBluetooth";
import RaftInterface from "./RaftInterface";
export const MICROBIT_SIGNALS = {
tilt: { group: "Tilt", x: "X (°)", y: "Y (°)" },
buttons: { group: "Buttons", a: "A", b: "B" },
touch: { group: "Touch pins", p0: "P0", p1: "P1", p2: "P2" },
gestures: {
group: "Gestures",
moved: "Moved",
shaken: "Shaken",
},
} as const;
const bitValue = (value: number, bit: number) => (value >> bit) & 1;
const binaryValue = (value: number) => (Number(value) === 0 ? 0 : 1);
export default class MicroBitInterface extends RaftInterface {
private unsubscribeSensorListener: (() => void) | null;
constructor(public readonly microBit: MicroBitWebBluetooth) {
super();
this.unsubscribeSensorListener = microBit.addSensorListener(
(sensors) => this.publishSensors(sensors)
);
}
getAvailableAddons() {
const sensors = this.microBit.sensors;
return [
new Addon(MICROBIT_SIGNALS.tilt.group, [
new AddonSub(MICROBIT_SIGNALS.tilt.x, sensors.tiltX / 10),
new AddonSub(MICROBIT_SIGNALS.tilt.y, sensors.tiltY / 10),
]),
new Addon(MICROBIT_SIGNALS.buttons.group, [
new AddonSub(MICROBIT_SIGNALS.buttons.a, binaryValue(sensors.buttonA)),
new AddonSub(MICROBIT_SIGNALS.buttons.b, binaryValue(sensors.buttonB)),
]),
new Addon(MICROBIT_SIGNALS.touch.group, [
new AddonSub(MICROBIT_SIGNALS.touch.p0, binaryValue(sensors.touchPins[0])),
new AddonSub(MICROBIT_SIGNALS.touch.p1, binaryValue(sensors.touchPins[1])),
new AddonSub(MICROBIT_SIGNALS.touch.p2, binaryValue(sensors.touchPins[2])),
]),
new Addon(MICROBIT_SIGNALS.gestures.group, [
new AddonSub(
MICROBIT_SIGNALS.gestures.moved,
bitValue(sensors.gestureState, 2)
),
new AddonSub(
MICROBIT_SIGNALS.gestures.shaken,
bitValue(sensors.gestureState, 0)
),
]),
];
}
unsubscribeFromPublishedData() {
this.unsubscribeSensorListener?.();
this.unsubscribeSensorListener = null;
}
private publishSensors(sensors: MicroBitSensors) {
this.publish(
MICROBIT_SIGNALS.tilt.group,
MICROBIT_SIGNALS.tilt.x,
sensors.tiltX / 10
);
this.publish(
MICROBIT_SIGNALS.tilt.group,
MICROBIT_SIGNALS.tilt.y,
sensors.tiltY / 10
);
this.publish(
MICROBIT_SIGNALS.buttons.group,
MICROBIT_SIGNALS.buttons.a,
binaryValue(sensors.buttonA)
);
this.publish(
MICROBIT_SIGNALS.buttons.group,
MICROBIT_SIGNALS.buttons.b,
binaryValue(sensors.buttonB)
);
this.publish(
MICROBIT_SIGNALS.touch.group,
MICROBIT_SIGNALS.touch.p0,
binaryValue(sensors.touchPins[0])
);
this.publish(
MICROBIT_SIGNALS.touch.group,
MICROBIT_SIGNALS.touch.p1,
binaryValue(sensors.touchPins[1])
);
this.publish(
MICROBIT_SIGNALS.touch.group,
MICROBIT_SIGNALS.touch.p2,
binaryValue(sensors.touchPins[2])
);
this.publish(
MICROBIT_SIGNALS.gestures.group,
MICROBIT_SIGNALS.gestures.moved,
bitValue(sensors.gestureState, 2)
);
this.publish(
MICROBIT_SIGNALS.gestures.group,
MICROBIT_SIGNALS.gestures.shaken,
bitValue(sensors.gestureState, 0)
);
}
private publish(whoAmI: string, addonInput: string, value: number) {
this.dispatchEvent({
type: `on${whoAmI}=>${addonInput}Change`,
value,
whoAmI,
addonInput,
});
}
}