Skip to content

Commit

Permalink
Got the 2-way communication working
Browse files Browse the repository at this point in the history
  • Loading branch information
pmalacho-mit committed Dec 10, 2024
1 parent c57ba37 commit 3679c04
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 26 deletions.
1 change: 1 addition & 0 deletions extensions/src/doodlebot/Doodlebot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,7 @@ export default class Doodlebot {
}

async getImageStream() {
if (this.pending["websocket"]) await this.pending["websocket"];
if (!this.connection.ip) return;
const image = document.createElement("img");
image.src = `http://${this.connection.ip}:${port.camera}/${endpoint.video}`;
Expand Down
62 changes: 36 additions & 26 deletions extensions/src/doodlebot/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Environment, ExtensionMenuDisplayDetails, extension, block, buttonBlock } from "$common";
import { DisplayKey, displayKeys, command, type Command, SensorKey, sensorKeys } from "./enums";
import Doodlebot from "./Doodlebot";
import Doodlebot, { NetworkCredentials } from "./Doodlebot";
import { splitArgsString } from "./utils";
import EventEmitter from "events";
import { categoryByGesture, classes, emojiByGesture, gestureDetection, gestureMenuItems, gestures, objectDetection } from "./detection";
Expand Down Expand Up @@ -88,49 +88,59 @@ export default class DoodlebotBlocks extends extension(details, "ui", "indicator
}

private async connectToDoodlebotWithExternalBLE() {
// A few globals that currently must be set the same across the playground and the https frontend
const handshakeMessage = "doodlebot";
const disconnectMessage = "disconnected";
const commandCompleteIdentifier = "done";

const urlParams = new URLSearchParams(window.location.search); // Hack for now
let source: MessageEventSource;
let targetOrigin: string;
const networkCredentials: NetworkCredentials = {
ssid: urlParams.get("ssid"),
password: urlParams.get("password"),
ipOverride: urlParams.get("ip").trim() === "" ? null : urlParams.get("ip")
}

type ExternalPageDetails = { source: MessageEventSource, targetOrigin: string }

await new Promise<void>((resolve) => {
const onInitialMessage = (event: MessageEvent) => {
source = event.source;
targetOrigin = event.origin;
const { source, targetOrigin } = await new Promise<ExternalPageDetails>((resolve) => {
const onInitialMessage = ({ data, source, origin }: MessageEvent) => {
if (typeof data !== "string" || data !== handshakeMessage) return;
window.removeEventListener("message", onInitialMessage);
source.postMessage("ready", { targetOrigin })
resolve();
source.postMessage("ready", { targetOrigin: origin })
resolve({ source, targetOrigin: origin });
}
window.addEventListener("message", onInitialMessage);
});

const doodlebot = new Doodlebot(
{
onDisconnect: () => {
window.addEventListener("message", (event) => {
if (event.data !== disconnectMessage) return;
this.setIndicator("disconnected");
alert("Disconnected from robot"); // Decide how to handle (maybe direct user to close window and go back to https)
});
},
onReceive: (callback) => {
window.addEventListener('message', (event) => {
if (event.data === disconnectMessage) return;
callback(event.data);
});
},
send: (text) => new Promise<void>(resolve => {
const onMessageReturn = ({ data }: MessageEvent<string>) => {
if (data !== text) return;
const onMessageReturn = ({ data, origin }: MessageEvent<string>) => {
if (origin !== targetOrigin || !data.includes(text) || !data.includes(commandCompleteIdentifier)) return;
window.removeEventListener("message", onMessageReturn);
resolve();
}
window.addEventListener("message", onMessageReturn);
source.postMessage(text, { targetOrigin });
})
}),

onReceive: (callback) => {
window.addEventListener('message', ({ data, origin }) => {
if (origin !== targetOrigin || data === disconnectMessage || data.includes(commandCompleteIdentifier)) return;
callback(new CustomEvent<string>("ble", { detail: data }));
});
},

onDisconnect: () => {
window.addEventListener("message", ({ data, origin }) => {
if (origin !== targetOrigin || data !== disconnectMessage) return;
this.setIndicator("disconnected");
alert("Disconnected from robot"); // Decide how to handle (maybe direct user to close window and go back to https)
});
},
},
() => alert("requestBluetooth called"), // placeholder
{ ssid: urlParams.get("ssid"), password: urlParams.get("password"), ipOverride: urlParams.get("ip") },
networkCredentials,
() => alert("save IP called"), // placeholder
)
this.setDoodlebot(doodlebot);
Expand Down

0 comments on commit 3679c04

Please sign in to comment.