Reputation: 69
I have written a python code with which I can get the bluetooth data of the surrounding Devices. I need to run this code on the browser and it should be able to see the data of the surrounding ibeacon devices when everyone is requested by the client. Way too many for that I tried but failed. I thought that I should use pyodide as a last resort, and at the moment I want to run python code with which I get the blutooth data of the surrounding devices with pyodide.
1-) First, the index.i have included the pyodide cdn in the html file 2-) Then pyodide.i created the js file and wrote the following codes in it
async function main(){
let pyodide = await loadPyodide();
await pyodide.runPythonAsync(`
from pyodide.http import pyfetch
response = await pyfetch("beacon.py")
with open("beacon.py", "wb") as f:
f.write(await response.bytes())
`)
pkg = pyodide.pyimport("main()");
pkg.do_something();
}
main();
3-) From the outside in this code beacon.py i want to include the file and beacon.py i want to run the main() function in it. This is beacon.py codes
import asyncio
from uuid import UUID
import json
from construct import Array, Byte, Const, Int8sl, Int16ub, Struct
from construct.core import ConstError
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
ibeacon_format = Struct(
"type_length" / Const(b"\x02\x15"),
"uuid" / Array(16, Byte),
"major" / Int16ub,
"minor" / Int16ub,
"power" / Int8sl,
)
class UUIDEncoder(json.JSONEncoder):
def default(self, uuid):
if isinstance(uuid, UUID):
# if the obj is uuid, we simply return the value of uuid
return uuid.hex
return json.JSONEncoder.default(self, uuid)
def device_found(
device: BLEDevice, advertisement_data: AdvertisementData
):
"""Decode iBeacon."""
try:
macadress = device.address
name = advertisement_data.local_name
apple_data = advertisement_data.manufacturer_data[0x004C]
ibeacon = ibeacon_format.parse(apple_data)
uuid = UUID(bytes=bytes(ibeacon.uuid))
minor = ibeacon.minor
major = ibeacon.major
power = ibeacon.power
rssi = device.rssi
rssi = int(rssi)
# beacons = {
# "Mac Adress" : macadress,
# "Local Name" : name ,
# "UUID":uuid,
# "Major":major,
# "Minor":minor,
# "TX Power":power,
# "RSSI":rssi
# }
print(f"Mac Adress : {macadress}")
print(f"Local Name : {name}")
print(f"UUID : {uuid}")
print(f"Major : {major}")
print(f"Minor : {minor}")
print(f"TX power : {power} dBm")
print(f"RSSI : {rssi} dBm")
print(47 * "-")
except KeyError:
pass
except ConstError:
pass
async def main():
"""Scan for devices."""
scanner = BleakScanner()
scanner.register_detection_callback(device_found)
while (True):
await scanner.start()
await asyncio.sleep(0.5)
await scanner.stop()
asyncio.run(main())
4-) Normally Beacon.py all the libraries in the file are installed, but I get the following error
File "/home/pyodide/beacon.py", line 4, in <module>
from construct import Array, Byte, Const, Int8sl, Int16ub, Struct
ModuleNotFoundError: No module named 'construct'
5-) I don't know why I'm getting this error. I hope I was able to explain my problem well. Beacon.py how can I include the main() function in the file in pyodide via pyodide and how can I run this code on the web?
Upvotes: 0
Views: 651
Reputation: 11201
Pyodide runs in the browser sandbox, which does not allow to interact with drivers in general (and Bluetooth devices in particular) directly. So you will not be able to use the bleak
package from Pyodide.
You can however access Bluetooth devices via the Web Bluetooth API which you can use from Python using the Pyodide FFI.
As to the ImportError about construct
, that package needs to be compiled for the emscripten/wasm32 architecture and currently is not included in the Pyodide distribution. You can build the corresponding wheel yourself with these instructions
Upvotes: 2