From 6209f0cc6337e7690fd2d43005c9d6f5a2a06fb8 Mon Sep 17 00:00:00 2001 From: Peli de Halleux Date: Mon, 8 Oct 2018 09:46:23 -0700 Subject: [PATCH] scratch like broadcast api (#1358) * scratch like broadcast api * always register handler * adding docs * added icon * updated block name * adding DAL support "radio.raiseEvent" * typo * implemented using radiobus * adding docs * adding raise event block * updated shims * updated pxt --- docs/reference/control/raise-event.md | 4 + docs/reference/radio.md | 4 +- docs/reference/radio/raise-event.md | 14 +++ docs/static/libs/radio-broadcast.png | Bin 0 -> 63135 bytes .../radio-broadcast-jsdoc-strings.json | 6 ++ .../_locales/radio-broadcast-strings.json | 6 ++ .../reference/radio/on-received-message.md | 45 ++++++++++ .../docs/reference/radio/send-message.md | 43 +++++++++ libs/radio-broadcast/pxt.json | 11 +++ libs/radio-broadcast/radio-broadcast.ts | 38 ++++++++ libs/radio/_locales/radio-jsdoc-strings.json | 1 + libs/radio/_locales/radio-strings.json | 1 + libs/radio/radio.cpp | 17 ++-- libs/radio/shims.d.ts | 10 +++ package.json | 2 +- pxtarget.json | 3 +- sim/dalboard.ts | 6 +- sim/state/radio.ts | 85 +++++++----------- sim/visuals/microbit.ts | 3 + 19 files changed, 235 insertions(+), 64 deletions(-) create mode 100644 docs/reference/radio/raise-event.md create mode 100644 docs/static/libs/radio-broadcast.png create mode 100644 libs/radio-broadcast/_locales/radio-broadcast-jsdoc-strings.json create mode 100644 libs/radio-broadcast/_locales/radio-broadcast-strings.json create mode 100644 libs/radio-broadcast/docs/reference/radio/on-received-message.md create mode 100644 libs/radio-broadcast/docs/reference/radio/send-message.md create mode 100644 libs/radio-broadcast/pxt.json create mode 100644 libs/radio-broadcast/radio-broadcast.ts diff --git a/docs/reference/control/raise-event.md b/docs/reference/control/raise-event.md index 8a5c8741..42bc4547 100644 --- a/docs/reference/control/raise-event.md +++ b/docs/reference/control/raise-event.md @@ -8,3 +8,7 @@ control.raiseEvent(control.eventSourceId(EventBusSource.MICROBIT_ID_BUTTON_A), c **This is an advanced API.** For more information, see the [@boardname@ runtime messageBus documentation](https://lancaster-university.github.io/microbit-docs/ubit/messageBus/) + +## See Also + +[radio raise event](/reference/radio/raise-event) \ No newline at end of file diff --git a/docs/reference/radio.md b/docs/reference/radio.md index b6182416..6289f3fb 100644 --- a/docs/reference/radio.md +++ b/docs/reference/radio.md @@ -14,6 +14,7 @@ radio.setTransmitPower(7); radio.setTransmitSerialNumber(false); radio.writeReceivedPacketToSerial(); radio.sendBuffer(null); +radio.raiseEvent(0, 0); ``` ```package @@ -32,4 +33,5 @@ radio [setGroup](/reference/radio/set-group), [setTransmitPower](/reference/radio/set-transmit-power), [setTransmitSerialNumber](/reference/radio/set-transmit-serial-number), -[writeReceivedPacketToSerial](/reference/radio/write-received-packet-to-serial) +[writeReceivedPacketToSerial](/reference/radio/write-received-packet-to-serial), +[raiseEvent](/reference/radio/raise-event) diff --git a/docs/reference/radio/raise-event.md b/docs/reference/radio/raise-event.md new file mode 100644 index 00000000..f7862528 --- /dev/null +++ b/docs/reference/radio/raise-event.md @@ -0,0 +1,14 @@ +# Raise Event + +Sends an event over radio to be raised in the event bus of other @boardname@. + +```sig +radio.raiseEvent(control.eventSourceId(EventBusSource.MICROBIT_ID_BUTTON_A), control.eventValueId(EventBusValue.MICROBIT_EVT_ANY)); +``` + +**This is an advanced API.** For more information, see the +[@boardname@ runtime messageBus documentation](https://lancaster-university.github.io/microbit-docs/ubit/messageBus/) + +## See Also + +[control raise event](/reference/control/raise-event) \ No newline at end of file diff --git a/docs/static/libs/radio-broadcast.png b/docs/static/libs/radio-broadcast.png new file mode 100644 index 0000000000000000000000000000000000000000..c8cca2a5026e220aef3c6b1658fb93cdf81e4c7b GIT binary patch literal 63135 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 BaK8Wm literal 0 HcmV?d00001 diff --git a/libs/radio-broadcast/_locales/radio-broadcast-jsdoc-strings.json b/libs/radio-broadcast/_locales/radio-broadcast-jsdoc-strings.json new file mode 100644 index 00000000..70202ac8 --- /dev/null +++ b/libs/radio-broadcast/_locales/radio-broadcast-jsdoc-strings.json @@ -0,0 +1,6 @@ +{ + "radio": "Communicate data using radio packets", + "radio.onReceivedMessage": "Registers code to run for a particular message", + "radio.onReceivedMessage|param|msg": "@param handler ", + "radio.sendMessage": "Broadcasts a message over radio" +} \ No newline at end of file diff --git a/libs/radio-broadcast/_locales/radio-broadcast-strings.json b/libs/radio-broadcast/_locales/radio-broadcast-strings.json new file mode 100644 index 00000000..cd7928a6 --- /dev/null +++ b/libs/radio-broadcast/_locales/radio-broadcast-strings.json @@ -0,0 +1,6 @@ +{ + "radio.onReceivedMessage|block": "on radio $msg received", + "radio.sendMessage|block": "radio send $msg", + "radio|block": "radio", + "{id:category}Radio": "Radio" +} \ No newline at end of file diff --git a/libs/radio-broadcast/docs/reference/radio/on-received-message.md b/libs/radio-broadcast/docs/reference/radio/on-received-message.md new file mode 100644 index 00000000..8946d0fd --- /dev/null +++ b/libs/radio-broadcast/docs/reference/radio/on-received-message.md @@ -0,0 +1,45 @@ +# on Received Message + +Run part of a program when the @boardname@ receives a +message over ``radio``. + +```sig +radio.onReceivedMessage(0, function() {}) +``` + +## Parameters + +* **msg**: The message to listen for. See [send message](/reference/radio/send-message) + +## Examples + +## Example: Broadcasting heart or skull + +Sends a ``heart`` message when ``A`` is pressed, ``skull`` when ``B`` is pressed. On the side, display heart or skull for the message. + +```blocks +enum RadioMessage { + heart, + skull +} +input.onButtonPressed(Button.A, function () { + radio.sendMessage(RadioMessage.heart) +}) +input.onButtonPressed(Button.B, function () { + radio.sendMessage(RadioMessage.skull) +}) +radio.onReceivedMessage(RadioMessage.heart, function () { + basic.showIcon(IconNames.Heart) +}) +radio.onReceivedMessage(RadioMessage.skull, function () { + basic.showIcon(IconNames.Skull) +}) +``` + +## See also + +[send message](/reference/radio/send-message), + +```package +radio-broadcast +``` diff --git a/libs/radio-broadcast/docs/reference/radio/send-message.md b/libs/radio-broadcast/docs/reference/radio/send-message.md new file mode 100644 index 00000000..e8dd9619 --- /dev/null +++ b/libs/radio-broadcast/docs/reference/radio/send-message.md @@ -0,0 +1,43 @@ +# send Message + +Broadcast a coded message to other @boardname@s connected via ``radio``. + +```sig +radio.sendMessage(0); +``` + +## Parameters + +* **msg**: a coded message. + + +## Example: Broadcasting heart or skull + +Sends a ``heart`` message when ``A`` is pressed, ``skull`` when ``B`` is pressed. On the side, display heart or skull for the message. + +```blocks +enum RadioMessage { + heart, + skull +} +input.onButtonPressed(Button.A, function () { + radio.sendMessage(RadioMessage.heart) +}) +input.onButtonPressed(Button.B, function () { + radio.sendMessage(RadioMessage.skull) +}) +radio.onReceivedMessage(RadioMessage.heart, function () { + basic.showIcon(IconNames.Heart) +}) +radio.onReceivedMessage(RadioMessage.skull, function () { + basic.showIcon(IconNames.Skull) +}) +``` + +## See also + +[on received number](/reference/radio/on-received-number) + +```package +radio-broadcast +``` \ No newline at end of file diff --git a/libs/radio-broadcast/pxt.json b/libs/radio-broadcast/pxt.json new file mode 100644 index 00000000..013ac791 --- /dev/null +++ b/libs/radio-broadcast/pxt.json @@ -0,0 +1,11 @@ +{ + "name": "radio-broadcast", + "files": [ + "pxt.json", + "radio-broadcast.ts" + ], + "dependencies": { + "core": "file:../core", + "radio": "file:../radio" + } +} \ No newline at end of file diff --git a/libs/radio-broadcast/radio-broadcast.ts b/libs/radio-broadcast/radio-broadcast.ts new file mode 100644 index 00000000..289dc169 --- /dev/null +++ b/libs/radio-broadcast/radio-broadcast.ts @@ -0,0 +1,38 @@ +namespace radio { + /** + * Gets the message code + */ + //% blockHidden=1 shim=ENUM_GET + //% blockId=radioMessageCode block="$msg" enumInitialMembers="message1" + //% enumName=RadioMessage enumMemberName=msg enumPromptHint="e.g. Start, Stop, Jump..." + export function __message(msg: number): number { + return msg; + } + + /** + * Broadcasts a message over radio + * @param msg + */ + //% blockId=radioBroadcastMessage block="radio send $msg" + //% msg.shadow=radioMessageCode draggableParameters + //% weight=200 + //% blockGap=8 + //% help=radio/send-message + export function sendMessage(msg: number): void { + // 0 is MICROBIT_EVT_ANY, shifting by 1 + radio.raiseEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1); + } + + /** + * Registers code to run for a particular message + * @param msg + * @param handler + */ + //% blockId=radioOnMessageReceived block="on radio $msg received" + //% msg.shadow=radioMessageCode draggableParameters + //% weight=199 + //% help=radio/on-received-message + export function onReceivedMessage(msg: number, handler: () => void) { + control.onEvent(DAL.MES_BROADCAST_GENERAL_ID, msg + 1, handler); + } +} \ No newline at end of file diff --git a/libs/radio/_locales/radio-jsdoc-strings.json b/libs/radio/_locales/radio-jsdoc-strings.json index 709aaef4..f78b49f5 100644 --- a/libs/radio/_locales/radio-jsdoc-strings.json +++ b/libs/radio/_locales/radio-jsdoc-strings.json @@ -16,6 +16,7 @@ "radio.onReceivedNumber": "Registers code to run when the radio receives a number.", "radio.onReceivedString": "Registers code to run when the radio receives a string.", "radio.onReceivedValue": "Registers code to run when the radio receives a key value pair.", + "radio.raiseEvent": "Sends an event over radio to neigboring devices", "radio.receiveNumber": "Reads the next packet from the radio queue and returns the packet's number\npayload or 0 if the packet did not contain a number.", "radio.receiveString": "Reads the next packet from the radio queue and returns the packet's string\npayload or the empty string if the packet did not contain a string.", "radio.receivedBuffer": "Returns the buffer payload from the last packet taken from the radio queue\n(via ``receiveNumber``, ``receiveString``, etc) or the empty string if that\npacket did not contain a string.", diff --git a/libs/radio/_locales/radio-strings.json b/libs/radio/_locales/radio-strings.json index 5499ba73..e2479f5b 100644 --- a/libs/radio/_locales/radio-strings.json +++ b/libs/radio/_locales/radio-strings.json @@ -10,6 +10,7 @@ "radio.onReceivedNumber|block": "on radio received", "radio.onReceivedString|block": "on radio received", "radio.onReceivedValue|block": "on radio received", + "radio.raiseEvent|block": "radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id", "radio.receiveNumber|block": "radio receive number", "radio.receiveString|block": "radio receive string", "radio.receivedSignalStrength|block": "radio received signal strength", diff --git a/libs/radio/radio.cpp b/libs/radio/radio.cpp index d69f6b31..239eb998 100644 --- a/libs/radio/radio.cpp +++ b/libs/radio/radio.cpp @@ -59,14 +59,17 @@ namespace radio { return r; } - void broadcastMessage(int message) { + /** + * Sends an event over radio to neigboring devices + */ + //% blockId=radioRaiseEvent block="radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id" + //% blockExternalInputs=1 + //% advanced=true + //% weight=1 + //% help=radio/raise-event + void raiseEvent(int src, int value) { if (radioEnable() != MICROBIT_OK) return; - uBit.radio.event.eventReceived(MicroBitEvent(MES_BROADCAST_GENERAL_ID, message, CREATE_ONLY)); - } - - void onBroadcastMessageReceived(int message, Action f) { - if (radioEnable() != MICROBIT_OK) return; - registerWithDal(MES_BROADCAST_GENERAL_ID, message, f); + uBit.radio.event.eventReceived(MicroBitEvent(src, value, CREATE_ONLY)); } void setPacketPrefix(uint8_t* buf, int type) { diff --git a/libs/radio/shims.d.ts b/libs/radio/shims.d.ts index 9d89a66b..7074db7e 100644 --- a/libs/radio/shims.d.ts +++ b/libs/radio/shims.d.ts @@ -5,6 +5,16 @@ //% color=#E3008C weight=96 icon="\uf012" declare namespace radio { + /** + * Sends an event over radio to neigboring devices + */ + //% blockId=radioRaiseEvent block="radio raise event|from source %src=control_event_source_id|with value %value=control_event_value_id" + //% blockExternalInputs=1 + //% advanced=true + //% weight=1 + //% help=radio/raise-event shim=radio::raiseEvent + function raiseEvent(src: int32, value: int32): void; + /** * Broadcasts a number over radio to any connected micro:bit in the group. */ diff --git a/package.json b/package.json index d2ec1853..afb741ba 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,6 @@ }, "dependencies": { "pxt-common-packages": "0.24.2", - "pxt-core": "4.1.20" + "pxt-core": "4.1.21" } } diff --git a/pxtarget.json b/pxtarget.json index d52a6e9e..4522a4c2 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -10,7 +10,8 @@ "libs/radio", "libs/devices", "libs/bluetooth", - "libs/servo" + "libs/servo", + "libs/radio-broadcast" ], "cloud": { "workspace": false, diff --git a/sim/dalboard.ts b/sim/dalboard.ts index b311c036..2f463abd 100644 --- a/sim/dalboard.ts +++ b/sim/dalboard.ts @@ -102,15 +102,15 @@ namespace pxsim { switch (msg.type || "") { case "eventbus": - let ev = msg; + const ev = msg; this.bus.queue(ev.id, ev.eventid, ev.value); break; case "serial": - let data = (msg).data || ""; + const data = (msg).data || ""; this.serialState.receiveData(data); break; case "radiopacket": - let packet = msg; + const packet = msg; this.radioState.receivePacket(packet); break; } diff --git a/sim/state/radio.ts b/sim/state/radio.ts index d0e4a201..40b96205 100644 --- a/sim/state/radio.ts +++ b/sim/state/radio.ts @@ -30,7 +30,7 @@ namespace pxsim { Runtime.postMessage({ type: "radiopacket", rssi: -42, // -42 is the strongest signal - serial: b.radioState.bus.transmitSerialNumber ? pxsim.control.deviceSerialNumber() : 0, + serial: b.radioState.transmitSerialNumber ? pxsim.control.deviceSerialNumber() : 0, time: new Date().getTime(), payload }) @@ -52,15 +52,20 @@ namespace pxsim { } } - export class RadioBus { - // uint8_t radioDefaultGroup = MICROBIT_RADIO_DEFAULT_GROUP; + export class RadioState { power = 0; transmitSerialNumber = false; datagram: RadioDatagram; + groupId: number; - constructor(private runtime: Runtime) { + constructor(runtime: Runtime) { this.datagram = new RadioDatagram(runtime); this.power = 6; // default value + this.groupId = 0; + } + + public setGroup(id: number) { + this.groupId = id & 0xff; // byte only } setTransmitPower(power: number) { @@ -71,37 +76,19 @@ namespace pxsim { this.transmitSerialNumber = !!sn; } - broadcast(msg: number, groupId: number) { + raiseEvent(id: number, eventid: number) { Runtime.postMessage({ - type: "event", - id: DAL.MES_BROADCAST_GENERAL_ID, - eventid: msg, + type: "eventbus", + id, + eventid, power: this.power, - group: groupId + group: this.groupId }) } - } - export class RadioState { - bus: RadioBus; - groupId: number; - - constructor(runtime: Runtime) { - this.bus = new RadioBus(runtime); - this.groupId = 0; - } - - public setGroup(id: number) { - this.groupId = id & 0xff; // byte only - } - - public broadcast(msg: number) { - this.bus.broadcast(msg, this.groupId) - } - - public receivePacket(packet: SimulatorRadioPacketMessage) { + receivePacket(packet: SimulatorRadioPacketMessage) { if (this.groupId == packet.payload.groupId) - this.bus.datagram.queue(packet) + this.datagram.queue(packet) } } } @@ -114,12 +101,8 @@ namespace pxsim.radio { BUFFER = 3 } - export function broadcastMessage(msg: number): void { - board().radioState.broadcast(msg); - } - - export function onBroadcastMessageReceived(msg: number, handler: RefAction): void { - pxtcore.registerWithDal(DAL.MES_BROADCAST_GENERAL_ID, msg, handler); + export function raiseEvent(id: number, eventid: number): void { + board().radioState.raiseEvent(id, eventid); } export function setGroup(id: number): void { @@ -127,15 +110,15 @@ namespace pxsim.radio { } export function setTransmitPower(power: number): void { - board().radioState.bus.setTransmitPower(power); + board().radioState.setTransmitPower(power); } export function setTransmitSerialNumber(transmit: boolean): void { - board().radioState.bus.setTransmitSerialNumber(transmit); + board().radioState.setTransmitSerialNumber(transmit); } export function sendNumber(value: number): void { - board().radioState.bus.datagram.send({ + board().radioState.datagram.send({ type: PacketPayloadType.NUMBER, groupId: board().radioState.groupId, numberData: value, @@ -146,7 +129,7 @@ namespace pxsim.radio { if (msg === undefined) return; msg = msg.substr(0, 19); - board().radioState.bus.datagram.send({ + board().radioState.datagram.send({ type: PacketPayloadType.STRING, groupId: board().radioState.groupId, stringData: msg, @@ -157,7 +140,7 @@ namespace pxsim.radio { if (!buf) return; const data = buf.data.slice(0, 18); - board().radioState.bus.datagram.send({ + board().radioState.datagram.send({ type: PacketPayloadType.STRING, groupId: board().radioState.groupId, bufferData: data @@ -166,19 +149,19 @@ namespace pxsim.radio { export function writeValueToSerial(): void { const b = board(); - writePacketToSerial(b, b.radioState.bus.datagram.recv()) + writePacketToSerial(b, b.radioState.datagram.recv()) } export function writeReceivedPacketToSerial(): void { const b = board(); - writePacketToSerial(b, b.radioState.bus.datagram.lastReceived); + writePacketToSerial(b, b.radioState.datagram.lastReceived); } export function sendValue(name: string, value: number) { name = name.substr(0, 12); const msg: number[] = []; msg.push() - board().radioState.bus.datagram.send({ + board().radioState.datagram.send({ type: PacketPayloadType.VALUE, groupId: board().radioState.groupId, stringData: name, @@ -187,17 +170,17 @@ namespace pxsim.radio { } export function receiveNumber(): number { - const packet = board().radioState.bus.datagram.recv(); + const packet = board().radioState.datagram.recv(); return receivedNumber(); } export function receiveString(): string { - const packet = board().radioState.bus.datagram.recv(); + const packet = board().radioState.datagram.recv(); return receivedString(); } export function receivedSignalStrength(): number { - return board().radioState.bus.datagram.lastReceived.rssi; + return board().radioState.datagram.lastReceived.rssi; } export function onDataReceived(handler: RefAction): void { @@ -206,23 +189,23 @@ namespace pxsim.radio { } export function receivedNumber(): number { - return board().radioState.bus.datagram.lastReceived.payload.numberData || 0; + return board().radioState.datagram.lastReceived.payload.numberData || 0; } export function receivedSerial(): number { - return board().radioState.bus.datagram.lastReceived.serial; + return board().radioState.datagram.lastReceived.serial; } export function receivedString(): string { - return initString(board().radioState.bus.datagram.lastReceived.payload.stringData || ""); + return initString(board().radioState.datagram.lastReceived.payload.stringData || ""); } export function receivedBuffer(): RefBuffer { - return new RefBuffer(board().radioState.bus.datagram.lastReceived.payload.bufferData || new Uint8Array(0)) + return new RefBuffer(board().radioState.datagram.lastReceived.payload.bufferData || new Uint8Array(0)) } export function receivedTime(): number { - return board().radioState.bus.datagram.lastReceived.time; + return board().radioState.datagram.lastReceived.time; } function writePacketToSerial(b: DalBoard, p: PacketBuffer) { diff --git a/sim/visuals/microbit.ts b/sim/visuals/microbit.ts index eb090eaa..7fabad54 100644 --- a/sim/visuals/microbit.ts +++ b/sim/visuals/microbit.ts @@ -854,6 +854,9 @@ path.sim-board { switch (msg.type || "") { case "serial": this.flashSystemLed(); break; case "radiopacket": this.flashAntenna(); break; + case "eventbus": + if ((msg).id == DAL.MES_BROADCAST_GENERAL_ID) + this.flashAntenna(); break; } } let tiltDecayer = 0;