Jacdac service clients (#539)
* host -> service, virtual -> client * more renamings * more renames * fixing files * more shuffle * cleaner starting modes * fixing file * add fixed instance * more blocks notations * more blocks * fix stack overflow * updated namespaces * fixing renaming * refactoring cleaning
This commit is contained in:
Родитель
16c088f65b
Коммит
5e463fa6f6
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class AccelerometerHostDriver extends jacdac.SensorHostDriver {
|
||||
export class AccelerometerService extends jacdac.SensorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.ACCELEROMETER_DEVICE_CLASS);
|
||||
input.onGesture(Gesture.Shake, () => this.raiseHostEvent(Gesture.Shake));
|
||||
|
@ -20,4 +20,7 @@ namespace jacdac {
|
|||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="accelerometer service"
|
||||
export const accelerometerService = new AccelerometerService("accelerometer");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class ButtonHostDriver extends SensorHostDriver {
|
||||
export class ButtonService extends SensorService {
|
||||
private button: Button;
|
||||
constructor(name: string, button: Button) {
|
||||
super(name, jacdac.BUTTON_DEVICE_CLASS);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
enum JacdacGesture {
|
||||
enum JDGesture {
|
||||
/**
|
||||
* Raised when shaken
|
||||
*/
|
||||
|
@ -56,7 +56,7 @@ enum JacdacGesture {
|
|||
EightG = DAL.ACCELEROMETER_EVT_8G
|
||||
}
|
||||
|
||||
const enum JacdacDimension {
|
||||
const enum JDDimension {
|
||||
//% block=x
|
||||
X = 0,
|
||||
//% block=y
|
||||
|
@ -69,7 +69,7 @@ const enum JacdacDimension {
|
|||
|
||||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class AccelerometerVirtualDriver extends SensorVirtualDriver {
|
||||
export class AccelerometerClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.ACCELEROMETER_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -78,28 +78,28 @@ namespace jacdac {
|
|||
* Reads the current x value from the sensor
|
||||
*/
|
||||
get x(): number {
|
||||
return this.get(JacdacDimension.X);
|
||||
return this.get(JDDimension.X);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current y value from the sensor
|
||||
*/
|
||||
get y(): number {
|
||||
return this.get(JacdacDimension.Y);
|
||||
return this.get(JDDimension.Y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current z value from the sensor
|
||||
*/
|
||||
get z(): number {
|
||||
return this.get(JacdacDimension.Z);
|
||||
return this.get(JDDimension.Z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the current strength value from the sensor
|
||||
*/
|
||||
get strength(): number {
|
||||
return this.get(JacdacDimension.Strength);
|
||||
return this.get(JDDimension.Strength);
|
||||
}
|
||||
|
||||
|
||||
|
@ -109,13 +109,13 @@ namespace jacdac {
|
|||
*/
|
||||
//% blockId=jacdacaccget block="jacdac %accelerometer %dimension"
|
||||
//% group="Accelerometer" weight=5
|
||||
get(dimension: JacdacDimension): number {
|
||||
get(dimension: JDDimension): number {
|
||||
const s = this.state;
|
||||
if (!s || s.length < 6) return 0;
|
||||
switch (dimension) {
|
||||
case JacdacDimension.X:
|
||||
case JacdacDimension.Y:
|
||||
case JacdacDimension.Z:
|
||||
case JDDimension.X:
|
||||
case JDDimension.Y:
|
||||
case JDDimension.Z:
|
||||
return s.getNumber(NumberFormat.Int16LE, dimension * 2);
|
||||
default: // strength
|
||||
let r = 0;
|
||||
|
@ -134,11 +134,11 @@ namespace jacdac {
|
|||
*/
|
||||
//% blockId=jacadacacconevent block="jacdac %accelerometer on %gesture"
|
||||
//% group="Accelerometer"
|
||||
onEvent(gesture: JacdacGesture, handler: () => void) {
|
||||
onEvent(gesture: JDGesture, handler: () => void) {
|
||||
control.onEvent(this.id, gesture, handler);
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="accelerometer"
|
||||
export const accelerometerService = new AccelerometerVirtualDriver("accelerometer");
|
||||
export const accelerometerClient = new AccelerometerClient("accelerometer");
|
||||
}
|
|
@ -1,10 +1,9 @@
|
|||
namespace jacdac {
|
||||
class BatteryDriver extends Driver {
|
||||
/* export class BatteryService extends Service {
|
||||
private level: () => number;
|
||||
constructor(level: () => number) {
|
||||
super("bat", DriverType.HostDriver, jacdac.BATTERY_DEVICE_CLASS, 1);
|
||||
super("bat", jacdac.BATTERY_DEVICE_CLASS, 1);
|
||||
this.level = level;
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
protected updateControlPacket() {
|
||||
|
@ -12,23 +11,13 @@ namespace jacdac {
|
|||
this.log(`level ${batteryLevel}`);
|
||||
this.controlData.setNumber(NumberFormat.UInt8LE, 0, batteryLevel);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send battery level over jacdac
|
||||
* @param level
|
||||
*/
|
||||
//%
|
||||
export function broadcastBatteryLevel(level: () => number) {
|
||||
new BatteryDriver(level);
|
||||
}
|
||||
} */
|
||||
|
||||
class BatterySniffer extends Driver {
|
||||
handler: (serialNumber: number, level: number) => void;
|
||||
constructor(handler: (serialNumber: number, level: number) => void) {
|
||||
super("batmon", DriverType.SnifferDriver, jacdac.BATTERY_DEVICE_CLASS);
|
||||
this.handler = handler;
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
public handleControlPacket(pkt: Buffer): boolean {
|
|
@ -3,14 +3,13 @@ namespace jacdac {
|
|||
constructor(name: string) {
|
||||
super(name, 0, DAL.JD_DRIVER_CLASS_BRIDGE);
|
||||
this.supressLog = true; // too verbose
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables this driver as a bridge
|
||||
*/
|
||||
enable() {
|
||||
this._proxy.setBridge();
|
||||
start() {
|
||||
if (!this.hasProxy()) {
|
||||
super.start();
|
||||
if (this._proxy) this._proxy.setBridge();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,7 +26,7 @@ namespace jacdac {
|
|||
const data = cp.data;
|
||||
if (data.length)
|
||||
console.log(" " + cp.data.toHex());
|
||||
return true;
|
||||
return true;
|
||||
} else {
|
||||
console.log(`jd>p ${packet.address} ${packet.size}b`)
|
||||
const data = packet.data;
|
||||
|
@ -38,13 +37,14 @@ namespace jacdac {
|
|||
}
|
||||
}
|
||||
|
||||
let _logAllDriver : LogAllDriver;
|
||||
let _logAllDriver: LogAllDriver;
|
||||
/**
|
||||
* Show ALL jacdac packets on console
|
||||
*/
|
||||
export function logAllPackets() {
|
||||
if (!_logAllDriver)
|
||||
if (!_logAllDriver) {
|
||||
_logAllDriver = new LogAllDriver();
|
||||
_logAllDriver.enable();
|
||||
_logAllDriver.start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,7 +11,7 @@ const enum JDButtonEvent {
|
|||
|
||||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class ButtonVirtualDriver extends SensorVirtualDriver {
|
||||
export class ButtonClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.BUTTON_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -40,5 +40,5 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
//% fixedInstance whenUsed block="button"
|
||||
export const buttonService = new ButtonVirtualDriver("button");
|
||||
export const buttonClient = new ButtonClient("button");
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
namespace jacdac {
|
||||
/**
|
||||
* Receives messages from console.log
|
||||
*/
|
||||
class ConsoleService extends Service {
|
||||
constructor() {
|
||||
super("log", DriverType.HostDriver, jacdac.LOGGER_DEVICE_CLASS); // TODO pickup type from DAL
|
||||
}
|
||||
|
||||
public handlePacket(pkt: Buffer): boolean {
|
||||
const packet = new JDPacket(pkt);
|
||||
const packetSize = packet.size;
|
||||
if (!packetSize) return true;
|
||||
|
||||
const priority = packet.data.getNumber(NumberFormat.UInt8LE, 0);
|
||||
// shortcut
|
||||
if (priority < console.minPriority) return true;
|
||||
|
||||
// send message to console
|
||||
let str = "";
|
||||
for (let i = 1; i < packetSize; i++)
|
||||
str += String.fromCharCode(packet.data.getNumber(NumberFormat.UInt8LE, i));
|
||||
|
||||
// pipe to console TODO suppress forwarding
|
||||
console.add(priority, str);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
let _consoleService: ConsoleService;
|
||||
/**
|
||||
* Listens for console messages from other devices
|
||||
*/
|
||||
//% blockId=jacdac_listen_console block="jacdac listen console"
|
||||
//% group="Console"
|
||||
export function listenConsole() {
|
||||
if (!_consoleService) {
|
||||
_consoleService = new ConsoleService();
|
||||
_consoleService.start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ enum JacdacLightCondition {
|
|||
|
||||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class LightSensorVirtualDriver extends SensorVirtualDriver {
|
||||
export class LightSensorClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.LIGHT_SENSOR_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ namespace jacdac {
|
|||
/**
|
||||
* Reads the current x value from the sensor
|
||||
*/
|
||||
//% blockId=jacdaclightsensorlevel block="jacdac %lightsensor light level"
|
||||
//% group="Light sensor"
|
||||
get level(): number {
|
||||
const s = this.state;
|
||||
if (!s || s.length < 1) return 0;
|
||||
|
@ -45,5 +47,5 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
//% fixedInstance whenUsed block="light sensor"
|
||||
export const lightSensorService = new LightSensorVirtualDriver("lightsensor");
|
||||
export const lightSensorClient = new LightSensorClient("lightsensor");
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
namespace jacdac {
|
||||
let _logBroadcastDriver: LoggerBroadcastDriver;
|
||||
/**
|
||||
* Sends console messages over JacDac
|
||||
*/
|
||||
//% blockId=jacdac_broadcast_console block="jacdac broadcast console"
|
||||
//% group="Console"
|
||||
export function broadcastConsole() {
|
||||
if (!_logBroadcastDriver)
|
||||
_logBroadcastDriver = new LoggerBroadcastDriver();
|
||||
}
|
||||
|
||||
class LoggerBroadcastDriver extends Driver {
|
||||
public suppressForwading: boolean;
|
||||
constructor() {
|
||||
super("log", DriverType.VirtualDriver, jacdac.LOGGER_DEVICE_CLASS);
|
||||
this.supressLog = true;
|
||||
this.suppressForwading = false;
|
||||
jacdac.addDriver(this);
|
||||
console.addListener((priority, text) => this.broadcastLog(priority, text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a log message through jacdac
|
||||
* @param str
|
||||
*/
|
||||
private broadcastLog(priority: ConsolePriority, str: string) {
|
||||
if (!this.isConnected || this.suppressForwading)
|
||||
return;
|
||||
|
||||
let cursor = 0;
|
||||
while (cursor < str.length) {
|
||||
const txLength = Math.min(str.length - cursor, DAL.JD_SERIAL_DATA_SIZE - 1);
|
||||
const buf = control.createBuffer(txLength + 1);
|
||||
buf.setNumber(NumberFormat.UInt8LE, 0, priority);
|
||||
for (let i = 0; i < txLength; i++) {
|
||||
buf.setNumber(NumberFormat.UInt8LE, i + 1, str.charCodeAt(i + cursor));
|
||||
}
|
||||
this.sendPacket(buf);
|
||||
cursor += txLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let _logListenerDriver: LoggerListenDriver;
|
||||
/**
|
||||
* Listens for console messages from other devices
|
||||
*/
|
||||
//% blockId=jacdac_listen_console block="jacdac listen console"
|
||||
//% group="Console"
|
||||
export function listenConsole() {
|
||||
if (!_logListenerDriver)
|
||||
_logListenerDriver = new LoggerListenDriver();
|
||||
}
|
||||
|
||||
class LoggerListenDriver extends Driver {
|
||||
constructor() {
|
||||
super("log", DriverType.HostDriver, jacdac.LOGGER_DEVICE_CLASS); // TODO pickup type from DAL
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
public handlePacket(pkt: Buffer): boolean {
|
||||
const packet = new JDPacket(pkt);
|
||||
const packetSize = packet.size;
|
||||
if (!packetSize) return true;
|
||||
|
||||
const priority = packet.data.getNumber(NumberFormat.UInt8LE, 0);
|
||||
// shortcut
|
||||
if (priority < console.minPriority) return true;
|
||||
|
||||
// send message to console
|
||||
let str = "";
|
||||
for (let i = 1; i < packetSize; i++)
|
||||
str += String.fromCharCode(packet.data.getNumber(NumberFormat.UInt8LE, i));
|
||||
|
||||
// pipe to console TODO suppress forwarding
|
||||
console.add(priority, str);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class MicrophoneVirtualDriver extends SensorVirtualDriver {
|
||||
export class MicrophoneClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.MICROPHONE_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ namespace jacdac {
|
|||
/**
|
||||
* Reads the current x value from the sensor
|
||||
*/
|
||||
//% blockId=jacdacmicrophonevent block="jacdac %microphone sound level"
|
||||
//% group="Microphone"
|
||||
get level(): number {
|
||||
const s = this.state;
|
||||
if (!s || s.length < 1) return 0;
|
||||
|
@ -38,5 +40,5 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
//% fixedInstance whenUsed block="microphone"
|
||||
export const microhponeService = new MicrophoneVirtualDriver("microphone");
|
||||
export const microphoneCLient = new MicrophoneClient("microphone");
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class PixelVirtualDriver extends ActuatorVirtualDriver {
|
||||
export class PixelClient extends ActuatorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.PIXEL_DEVICE_CLASS, 4);
|
||||
}
|
||||
|
@ -34,5 +34,5 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
//% fixedInstance whenUsed block="pixel"
|
||||
export const pixelService = new PixelVirtualDriver("pixel");
|
||||
export const pixelService = new PixelClient("pixel");
|
||||
}
|
|
@ -2,18 +2,17 @@
|
|||
"name": "jacdac-drivers",
|
||||
"description": "Virtual drivers for jacdac - beta",
|
||||
"files": [
|
||||
"sensordriver.ts",
|
||||
"bridgedriver.ts",
|
||||
"buttondriver.ts",
|
||||
"lightsensordriver.ts",
|
||||
"loggerdriver.ts",
|
||||
"messagebusdriver.ts",
|
||||
"batterydriver.ts",
|
||||
"accelerometerdriver.ts",
|
||||
"touchbuttondriver.ts",
|
||||
"microphonedriver.ts",
|
||||
"thermometerdriver.ts",
|
||||
"switchdriver.ts"
|
||||
"sensorclient.ts",
|
||||
"bridge.ts",
|
||||
"buttonclient.ts",
|
||||
"lightsensorclient.ts",
|
||||
"console.ts",
|
||||
"battery.ts",
|
||||
"accelerometerclient.ts",
|
||||
"touchbuttonclient.ts",
|
||||
"microphoneclient.ts",
|
||||
"thermometerclient.ts",
|
||||
"switchclient.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
"test.ts"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
//% weight=1
|
||||
export class SensorVirtualDriver extends VirtualDriver {
|
||||
export class SensorClient extends Client {
|
||||
// virtual mode only
|
||||
protected _localTime: number;
|
||||
protected _lastState: Buffer;
|
||||
|
@ -10,7 +10,6 @@ namespace jacdac {
|
|||
constructor(name: string, deviceClass: number) {
|
||||
super(name, DriverType.VirtualDriver, deviceClass);
|
||||
this._lastState = control.createBuffer(0);
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
public get state() {
|
||||
|
@ -23,7 +22,7 @@ namespace jacdac {
|
|||
*/
|
||||
//% blockid=jacdacsensorstreaming block="jacdac %sensor set streaming %on"
|
||||
//% on.shadow=toggleOnOff weight=1
|
||||
//% group="Sensors"
|
||||
//% group="Services"
|
||||
public setStreaming(on: boolean) {
|
||||
const msg = control.createBuffer(1);
|
||||
msg.setNumber(NumberFormat.UInt8LE, 0, on ? SensorCommand.StartStream : SensorCommand.StopStream);
|
|
@ -7,7 +7,7 @@ const enum JDSwitchDirection {
|
|||
|
||||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class SwitchVirtualDriver extends SensorVirtualDriver {
|
||||
export class SwitchClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.SWITCH_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -36,5 +36,5 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
//% fixedInstance whenUsed block="switch"
|
||||
export const switchButtonService = new SwitchVirtualDriver("switch");
|
||||
export const switchClient = new SwitchClient("switch");
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
jacdac.listenEvent(9008, DAL.DEVICE_BUTTON_EVT_CLICK);
|
||||
jacdac.broadcastEvent(9008, DAL.DEVICE_BUTTON_EVT_CLICK);
|
||||
control.onEvent(9008, DAL.DEVICE_BUTTON_EVT_CLICK, function () {
|
||||
console.log('click')
|
||||
})
|
|
@ -1,4 +1,4 @@
|
|||
enum JacDacTemperatureCondition {
|
||||
enum JDTemperatureCondition {
|
||||
//% block="hot"
|
||||
Hot = DAL.SENSOR_THRESHOLD_HIGH, // ANALOG_THRESHOLD_HIGH
|
||||
//% block="cold"
|
||||
|
@ -6,7 +6,7 @@ enum JacDacTemperatureCondition {
|
|||
}
|
||||
|
||||
|
||||
enum JacDacTemperatureUnit {
|
||||
enum JDTemperatureUnit {
|
||||
//% block="°C"
|
||||
Celsius = 0,
|
||||
//% block="°F"
|
||||
|
@ -15,7 +15,7 @@ enum JacDacTemperatureUnit {
|
|||
|
||||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class ThermometerVirtualDriver extends SensorVirtualDriver {
|
||||
export class ThermometerClient extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.THERMOMETER_DEVICE_CLASS);
|
||||
}
|
||||
|
@ -23,12 +23,15 @@ namespace jacdac {
|
|||
/**
|
||||
* Reads the current x value from the sensor
|
||||
*/
|
||||
temperature(unit: JacDacTemperatureUnit): number {
|
||||
//% blockId=jddevice_temperature block="temperature in %unit"
|
||||
//% group="Thermometer"
|
||||
//% weight=26
|
||||
temperature(unit: JDTemperatureUnit): number {
|
||||
const s = this.state;
|
||||
if (!s || s.length < 2) return 0;
|
||||
const t = s.getNumber(NumberFormat.Int16LE, 0);
|
||||
switch(unit) {
|
||||
case JacDacTemperatureUnit.Fahrenheit: (t * 18) / 10 + 32;
|
||||
case JDTemperatureUnit.Fahrenheit: (t * 18) / 10 + 32;
|
||||
default: return t;
|
||||
}
|
||||
}
|
||||
|
@ -40,14 +43,14 @@ namespace jacdac {
|
|||
*/
|
||||
//% blockId=jacadacthermoonevent block="jacdac %lightsensor on %lightCondition"
|
||||
//% group="Thermometer"
|
||||
onTemperatureConditionChanged(condition: JacDacTemperatureCondition, temperature: number, unit: JacDacTemperatureUnit, handler: () => void): void {
|
||||
if (unit == JacDacTemperatureUnit.Fahrenheit)
|
||||
onTemperatureConditionChanged(condition: JDTemperatureCondition, temperature: number, unit: JDTemperatureUnit, handler: () => void): void {
|
||||
if (unit == JDTemperatureUnit.Fahrenheit)
|
||||
temperature = (temperature - 32) * 5 / 9;
|
||||
this.setThreshold(condition == JacDacTemperatureCondition.Cold, temperature);
|
||||
this.setThreshold(condition == JDTemperatureCondition.Cold, temperature);
|
||||
control.onEvent(this.id, condition, handler);
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="thermometer"
|
||||
export const thermometerService = new ThermometerVirtualDriver("thermometer");
|
||||
export const thermometerClient = new ThermometerClient("thermometer");
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace jacdac {
|
||||
//% fixedInstances
|
||||
export class TouchButtonVirtualDriver extends SensorVirtualDriver {
|
||||
export class TouchButtonVirtualDriver extends SensorClient {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.TOUCHBUTTON_DEVICE_CLASS);
|
||||
}
|
|
@ -1,11 +1,10 @@
|
|||
namespace jacdac {
|
||||
export class ActuatorHostDriver extends Driver {
|
||||
export class ActuatorService extends Service {
|
||||
state: Buffer;
|
||||
|
||||
constructor(name: string, deviceClass: number, stateLength: number, controlDataLength?: number) {
|
||||
super(name, DriverType.HostDriver, deviceClass, controlDataLength);
|
||||
super(name, deviceClass, controlDataLength);
|
||||
this.state = control.createBuffer(stateLength);
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
public handlePacket(pkt: Buffer): boolean {
|
||||
|
@ -19,13 +18,12 @@ namespace jacdac {
|
|||
}
|
||||
}
|
||||
|
||||
export class ActuatorVirtualDriver extends Driver {
|
||||
export class ActuatorClient extends Client {
|
||||
protected state: Buffer;
|
||||
|
||||
constructor(name: string, deviceClass: number, stateLength: number, controlDataLength?: number) {
|
||||
super(name, DriverType.VirtualDriver, deviceClass, controlDataLength);
|
||||
super(name, deviceClass, controlDataLength);
|
||||
this.state = control.createBuffer(stateLength);
|
||||
jacdac.addDriver(this);
|
||||
this.onDriverEvent(JacDacDriverEvent.Connected, () => this.notifyChange());
|
||||
}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
namespace jacdac {
|
||||
class ConsoleClient extends Client {
|
||||
public suppressForwading: boolean;
|
||||
constructor() {
|
||||
super("log", DriverType.VirtualDriver, jacdac.LOGGER_DEVICE_CLASS);
|
||||
this.supressLog = true;
|
||||
this.suppressForwading = false;
|
||||
console.addListener((priority, text) => this.broadcast(priority, text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a log message through jacdac
|
||||
* @param str
|
||||
*/
|
||||
private broadcast(priority: ConsolePriority, str: string) {
|
||||
if (!this.isConnected || this.suppressForwading)
|
||||
return;
|
||||
|
||||
let cursor = 0;
|
||||
while (cursor < str.length) {
|
||||
const txLength = Math.min(str.length - cursor, DAL.JD_SERIAL_DATA_SIZE - 1);
|
||||
const buf = control.createBuffer(txLength + 1);
|
||||
buf.setNumber(NumberFormat.UInt8LE, 0, priority);
|
||||
for (let i = 0; i < txLength; i++) {
|
||||
buf.setNumber(NumberFormat.UInt8LE, i + 1, str.charCodeAt(i + cursor));
|
||||
}
|
||||
this.sendPacket(buf);
|
||||
cursor += txLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let _consoleClient: ConsoleClient;
|
||||
/**
|
||||
* Sends console messages over JacDac
|
||||
*/
|
||||
//% blockId=jacdac_broadcast_console block="jacdac broadcast console"
|
||||
//% group="Console"
|
||||
export function broadcastConsole() {
|
||||
if (!_consoleClient) {
|
||||
_consoleClient = new ConsoleClient();
|
||||
_consoleClient.start();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,6 +10,7 @@ namespace jacdac {
|
|||
SnifferDriver = DAL.JD_DEVICE_FLAGS_REMOTE | DAL.JD_DEVICE_FLAGS_BROADCAST, // the driver is not enumerated, and receives all packets of the same class (including control packets)
|
||||
};
|
||||
|
||||
//% fixedInstances
|
||||
export class Driver {
|
||||
public name: string;
|
||||
protected _proxy: JacDacDriverStatus;
|
||||
|
@ -26,7 +27,8 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
get id(): number {
|
||||
return this._proxy.id;
|
||||
this.start();
|
||||
return this._proxy ? this._proxy.id : -1;
|
||||
}
|
||||
|
||||
hasProxy(): boolean {
|
||||
|
@ -50,11 +52,13 @@ namespace jacdac {
|
|||
}
|
||||
|
||||
get isConnected(): boolean {
|
||||
this.start();
|
||||
return this._proxy && this._proxy.isConnected;
|
||||
}
|
||||
|
||||
protected get device(): jacdac.JDDevice {
|
||||
return new jacdac.JDDevice(this._proxy.device);
|
||||
this.start();
|
||||
return this._proxy ? new jacdac.JDDevice(this._proxy.device) : undefined;
|
||||
}
|
||||
|
||||
public log(text: string) {
|
||||
|
@ -68,6 +72,7 @@ namespace jacdac {
|
|||
* @param handler
|
||||
*/
|
||||
public onDriverEvent(event: JacDacDriverEvent, handler: () => void) {
|
||||
this.start();
|
||||
control.onEvent(this._proxy.id, event, handler);
|
||||
}
|
||||
|
||||
|
@ -90,9 +95,27 @@ namespace jacdac {
|
|||
protected sendPacket(pkt: Buffer) {
|
||||
jacdac.sendPacket(pkt, this.device.address);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register and starts the driver
|
||||
*/
|
||||
//% blockId=jacdachoststart block="start %service"
|
||||
//% group="Services"
|
||||
start() {
|
||||
if (!this._proxy)
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
}
|
||||
|
||||
export class VirtualDriver extends Driver {
|
||||
//% fixedInstances
|
||||
export class Service extends Driver {
|
||||
constructor(name: string, deviceClass: number, controlDataLength?: number) {
|
||||
super(name, DriverType.VirtualDriver, deviceClass, controlDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstances
|
||||
export class Client extends Driver {
|
||||
constructor(name: string, deviceClass: number, controlDataLength?: number) {
|
||||
super(name, DriverType.VirtualDriver, deviceClass, controlDataLength);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace jacdac {
|
|||
export const THERMOMETER_DEVICE_CLASS = JD_DEVICE_CLASS_MAKECODE_START + 8;
|
||||
export const SWITCH_DEVICE_CLASS = JD_DEVICE_CLASS_MAKECODE_START + 9;
|
||||
export const PIXEL_DEVICE_CLASS = JD_DEVICE_CLASS_MAKECODE_START + 10;
|
||||
export const HAPTIC_DEVICE_CLASS = JD_DEVICE_CLASS_MAKECODE_START + 11;
|
||||
|
||||
// events
|
||||
export const JD_MESSAGE_BUS_ID = JD_DEVICE_CLASS_MAKECODE_START;
|
||||
|
|
|
@ -3,28 +3,24 @@ namespace jacdac {
|
|||
/**
|
||||
* A driver that listens for message bus events
|
||||
*/
|
||||
export class MessageBusDriver extends Driver {
|
||||
export class MessageBusService extends Driver {
|
||||
suppressForwarding: boolean;
|
||||
|
||||
constructor() {
|
||||
super("bus", DriverType.BroadcastDriver, DAL.JD_DRIVER_CLASS_MESSAGE_BUS);
|
||||
this.suppressForwarding = false;
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
raiseEvent(id: number, value: number) {
|
||||
this.start();
|
||||
const event = control.createBuffer(4);
|
||||
event.setNumber(NumberFormat.UInt16LE, 0, id);
|
||||
event.setNumber(NumberFormat.UInt16LE, 2, value);
|
||||
this.sendPacket(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pipes matching events to JacDac bus
|
||||
* @param id
|
||||
* @param value
|
||||
*/
|
||||
listenEvent(id: number, value: number) {
|
||||
broadcastEvent(id: number, value: number) {
|
||||
this.start();
|
||||
//control.dmesg(`jd> msgbus> listen event ${id} ${value}`)
|
||||
control.onEvent(id, value, () => {
|
||||
if (this.suppressForwarding) return;
|
||||
|
@ -49,24 +45,16 @@ namespace jacdac {
|
|||
}
|
||||
}
|
||||
|
||||
let _messageBus: MessageBusDriver;
|
||||
/**
|
||||
* Gets the message bus driver
|
||||
*/
|
||||
export function messageBus(): MessageBusDriver {
|
||||
if (!_messageBus) {
|
||||
//control.dmesg("jd> starting message bus")
|
||||
_messageBus = new MessageBusDriver();
|
||||
}
|
||||
return _messageBus;
|
||||
}
|
||||
//% fixedInstance whenUsed block="message bus service"
|
||||
export const messageBusService = new MessageBusService();
|
||||
|
||||
/**
|
||||
* Pipes specific events through JACDAC
|
||||
*/
|
||||
//%
|
||||
export function listenEvent(src: number, value: number) {
|
||||
messageBus().listenEvent(src, value);
|
||||
//% block="broadcast events|from %src|with value %value" weight=5
|
||||
//% group="Control"
|
||||
export function broadcastEvent(src: number, value: number) {
|
||||
messageBusService.broadcastEvent(src, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,7 +77,7 @@ namespace jacdac {
|
|||
//% block="raise event|from %src|with value %value" weight=5
|
||||
//% group="Control"
|
||||
export function raiseEvent(src: number, value: number) {
|
||||
messageBus().raiseEvent(src, value);
|
||||
messageBusService.raiseEvent(src, value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -104,7 +92,7 @@ namespace jacdac {
|
|||
//% group="Broadcast"
|
||||
export function sendMessage(msg: number): void {
|
||||
// 0 is MICROBIT_EVT_ANY, shifting by 1
|
||||
messageBus().raiseEvent(JD_MESSAGE_BUS_ID, msg + 1);
|
||||
messageBusService.raiseEvent(JD_MESSAGE_BUS_ID, msg + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,7 +106,7 @@ namespace jacdac {
|
|||
//% help=jacdac/on-received-message
|
||||
//% group="Broadcast"
|
||||
export function onReceivedMessage(msg: number, handler: () => void) {
|
||||
messageBus(); // start message bus
|
||||
messageBusService.start();
|
||||
control.onEvent(JD_MESSAGE_BUS_ID, msg + 1, handler);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
//% weight=5 advanced=true
|
||||
//% blockGap=8
|
||||
//% groups='["Broadcast", "Console", "Services", "Control"]'
|
||||
namespace jacdac {
|
||||
|
||||
}
|
|
@ -11,7 +11,10 @@
|
|||
"pxtparts.json",
|
||||
"pxt.json",
|
||||
"shims.d.ts",
|
||||
"actuatordriver.ts"
|
||||
"actuator.ts",
|
||||
"messagebus.ts",
|
||||
"console.ts",
|
||||
"ns.ts"
|
||||
],
|
||||
"testFiles": [
|
||||
],
|
||||
|
|
|
@ -27,7 +27,7 @@ namespace jacdac {
|
|||
/**
|
||||
* JacDac service running on sensor and streaming data out
|
||||
*/
|
||||
export class SensorHostDriver extends Driver {
|
||||
export class SensorService extends Service {
|
||||
static MAX_SILENCE = 500;
|
||||
private sensorState: SensorState;
|
||||
private _sendTime: number;
|
||||
|
@ -35,11 +35,10 @@ namespace jacdac {
|
|||
public streamingInterval: number; // millis
|
||||
|
||||
constructor(name: string, deviceClass: number, controlLength = 0) {
|
||||
super(name, DriverType.HostDriver, deviceClass, 1 + controlLength);
|
||||
super(name, deviceClass, 1 + controlLength);
|
||||
this.sensorState = SensorState.Stopped;
|
||||
this._sendTime = 0;
|
||||
this.streamingInterval = 50;
|
||||
jacdac.addDriver(this);
|
||||
}
|
||||
|
||||
public updateControlPacket() {
|
||||
|
@ -120,7 +119,7 @@ namespace jacdac {
|
|||
// did the state change?
|
||||
if (this.isConnected
|
||||
&& (!this._sendState
|
||||
|| (control.millis() - this._sendTime > SensorHostDriver.MAX_SILENCE)
|
||||
|| (control.millis() - this._sendTime > SensorService.MAX_SILENCE)
|
||||
|| !jacdac.bufferEqual(state, this._sendState))) {
|
||||
|
||||
// send state and record time
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class LightSensorHostDriver extends jacdac.SensorHostDriver {
|
||||
export class LightSensorService extends jacdac.SensorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.LIGHT_SENSOR_DEVICE_CLASS);
|
||||
input.onLightConditionChanged(LightCondition.Bright, () => this.raiseHostEvent(LightCondition.Bright));
|
||||
|
@ -12,4 +12,7 @@ namespace jacdac {
|
|||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstances whenUsed block="light sensor service"
|
||||
export const lightSensorService = new LightSensorService("lightsensor");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class MicrophoneHostDriver extends jacdac.SensorHostDriver {
|
||||
export class MicrophoneService extends jacdac.SensorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.MICROPHONE_DEVICE_CLASS);
|
||||
input.onLoudSound(() => this.raiseHostEvent(DAL.LEVEL_THRESHOLD_HIGH));
|
||||
|
@ -11,4 +11,7 @@ namespace jacdac {
|
|||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="microphone service"
|
||||
export const microphoneService = new MicrophoneService("microphone");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class PixelHostDriver extends ActuatorHostDriver {
|
||||
export class PixelService extends ActuatorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.PIXEL_DEVICE_CLASS, 4);
|
||||
}
|
||||
|
@ -20,4 +20,7 @@ namespace jacdac {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed
|
||||
export const pixelService = new PixelService("pixel");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class SwitchHostDriver extends SensorHostDriver {
|
||||
export class SwitchService extends SensorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.SWITCH_DEVICE_CLASS);
|
||||
input.onSwitchMoved(SwitchDirection.Left, () => this.raiseHostEvent(SwitchDirection.Left));
|
||||
|
@ -12,4 +12,7 @@ namespace jacdac {
|
|||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="switch service"
|
||||
export const switchService = new SwitchService("switch");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class TemperatureHostDriver extends jacdac.SensorHostDriver {
|
||||
export class ThermometerService extends jacdac.SensorService {
|
||||
constructor(name: string) {
|
||||
super(name, jacdac.THERMOMETER_DEVICE_CLASS);
|
||||
input.onTemperatureConditionChanged(TemperatureCondition.Cold, 10, TemperatureUnit.Celsius, () => this.raiseHostEvent(TemperatureCondition.Cold));
|
||||
|
@ -12,4 +12,7 @@ namespace jacdac {
|
|||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
//% fixedInstance whenUsed block="thermometer service"
|
||||
export const thermometerService = new ThermometerService("therm");
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
namespace jacdac {
|
||||
export class TouchButtonHostDriver extends SensorHostDriver {
|
||||
export class TouchButtonService extends SensorService {
|
||||
private button: TouchButton;
|
||||
constructor(name: string, button: TouchButton) {
|
||||
super(name, jacdac.TOUCHBUTTON_DEVICE_CLASS);
|
||||
|
|
Загрузка…
Ссылка в новой задаче