• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1<html>
2  <head>
3    <script src="https://cdn.jsdelivr.net/pyodide/v0.19.1/full/pyodide.js"></script>
4  </head>
5
6  <body>
7    <button onclick="runUSB()">USB</button>
8    <button onclick="runSerial()">Serial</button>
9    <br />
10    <br />
11    <div>Output:</div>
12    <textarea id="output" style="width: 100%;" rows="30" disabled></textarea>
13
14    <script>
15        function bufferToHex(buffer) {
16            return [...new Uint8Array(buffer)].map(x => x.toString(16).padStart(2, '0')).join('');
17        }
18
19        const output = document.getElementById("output");
20        const code = document.getElementById("code");
21
22        function addToOutput(s) {
23            output.value += s + "\n";
24        }
25
26      output.value = "Initializing...\n";
27
28      async function main() {
29          let pyodide = await loadPyodide({
30              indexURL: "https://cdn.jsdelivr.net/pyodide/v0.19.1/full/",
31          })
32          output.value += "Ready!\n"
33
34          return pyodide;
35      }
36
37      let pyodideReadyPromise = main();
38
39      async function readLoop(port, packet_source) {
40        const reader = port.readable.getReader()
41            try {
42                while (true) {
43                    console.log('@@@ Reading...')
44                    const { done, value } = await reader.read()
45                    if (done) {
46                        console.log("--- DONE!")
47                        break
48                    }
49
50                    console.log('@@@ Serial data:', bufferToHex(value))
51                    if (packet_source.delegate !== undefined) {
52                        packet_source.delegate.data_received(value)
53                    } else {
54                        console.warn('@@@ delegate not set yet, dropping data')
55                    }
56                }
57            } catch (error) {
58                console.error(error)
59            } finally {
60                reader.releaseLock()
61            }
62      }
63
64      async function runUSB() {
65        const device = await navigator.usb.requestDevice({
66          filters: [
67            {
68                classCode: 0xE0,
69                subclassCode: 0x01
70            }
71          ]
72        });
73
74        if (device.configuration === null) {
75          await device.selectConfiguration(1);
76        }
77        await device.claimInterface(0)
78      }
79
80      async function runSerial() {
81        const ports = await navigator.serial.getPorts()
82          console.log('Paired ports:', ports)
83
84          const port = await navigator.serial.requestPort()
85          await port.open({ baudRate: 1000000 })
86          const writer = port.writable.getWriter()
87      }
88
89      async function run() {
90
91          let pyodide = await pyodideReadyPromise;
92          try {
93              const script = await(await fetch('scanner.py')).text()
94              await pyodide.loadPackage('micropip')
95              await pyodide.runPythonAsync(`
96                  import micropip
97                  await micropip.install('../dist/bumble-0.0.36.dev0+g3adbfe7.d20210807-py3-none-any.whl')
98              `)
99              let output = await pyodide.runPythonAsync(script)
100              addToOutput(output)
101
102              const pythonMain = pyodide.globals.get('main')
103              const packet_source = {}
104              const packet_sink = {
105                  on_packet: (packet) => {
106                    // Variant A, with the conversion done in Javascript
107                      const buffer = packet.toJs()
108                      console.log(`$$$ on_packet: ${bufferToHex(buffer)}`)
109                      // TODO: create an sync queue here instead of blindly calling write without awaiting
110                      /*await*/ writer.write(buffer)
111                      packet.destroy()
112
113                    // Variant B, with the conversion `to_js` done at the Python layer
114                    // console.log(`$$$ on_packet: ${bufferToHex(packet)}`)
115                    //   /*await*/ writer.write(packet)
116                }
117              }
118              serialLooper = readLoop(port, packet_source)
119              pythonResult = await pythonMain(packet_source, packet_sink)
120              console.log(pythonResult)
121              serialResult = await serialLooper
122              writer.releaseLock()
123              await port.close()
124              console.log('### done')
125        } catch (err) {
126          addToOutput(err);
127        }
128      }
129    </script>
130  </body>
131</html>