Browse Source

added getCharacteristic()

master
Anthony Hinsinger 2 days ago
parent
commit
9588778238
  1. 2665
      package-lock.json
  2. 5
      package.json
  3. 1
      src/bluez-gatt.js
  4. 42
      src/bluez.js
  5. 23
      src/ftms-service.js
  6. 15
      src/index.js

2665
package-lock.json generated

File diff suppressed because it is too large Load Diff

5
package.json

@ -18,12 +18,15 @@
"@babel/plugin-syntax-bigint": "^7.8.3", "@babel/plugin-syntax-bigint": "^7.8.3",
"@babel/preset-env": "^7.28.5", "@babel/preset-env": "^7.28.5",
"babel-loader": "^10.0.0", "babel-loader": "^10.0.0",
"pkg": "^5.8.1",
"webpack": "^5.103.0", "webpack": "^5.103.0",
"webpack-cli": "^6.0.1", "webpack-cli": "^6.0.1",
"webpack-node-externals": "^3.0.0" "webpack-node-externals": "^3.0.0"
}, },
"dependencies": { "dependencies": {
"dbus-next": "^0.10.2", "dbus-next": "^0.10.2",
"typescript": "^5.9.3" "typescript": "^5.9.3",
"usocket": "^1.0.2",
"x11": "^2.3.0"
} }
} }

1
src/bluez-gatt.js

@ -82,6 +82,7 @@ export class BaseCharacteritic extends BaseInterface {
super(bus, path, "org.bluez.GattCharacteristic1"); super(bus, path, "org.bluez.GattCharacteristic1");
this.UUID = uuid; this.UUID = uuid;
this.Flags = flags; this.Flags = flags;
this.service = service;
this.Service = service.path; this.Service = service.path;
} }

42
src/bluez.js

@ -26,6 +26,25 @@ export class Bluez {
} }
} }
} }
async getDeviceByServiceUUID(uuid) {
const om = await this.getObjectManager();
const objs = await om.GetManagedObjects();
for (const [path, ifaces] of Object.entries(objs)) {
if (
Object.hasOwn(ifaces, DEVICE_IFACE) &&
Object.hasOwn(ifaces[DEVICE_IFACE], "UUIDs")
) {
const found = ifaces[DEVICE_IFACE]["UUIDs"].value.findIndex(
(u) => u === uuid
);
if (found !== -1) {
return new BluezDevice(this.bus, path);
}
}
}
}
} }
class BluezDevice { class BluezDevice {
@ -44,6 +63,11 @@ class BluezDevice {
return props.Get(DEVICE_IFACE, name); return props.Get(DEVICE_IFACE, name);
} }
async getValue(name) {
const p = await this.getProperty(name);
return p.value;
}
async isConnected() { async isConnected() {
const c = await this.getProperty("Connected"); const c = await this.getProperty("Connected");
return c.value; return c.value;
@ -60,4 +84,22 @@ class BluezDevice {
const device = o.getInterface(DEVICE_IFACE); const device = o.getInterface(DEVICE_IFACE);
await device.Disconnect(); await device.Disconnect();
} }
async getCharacteristic(uuid) {
const o = await this.dbus.getProxyObject("org.bluez", "/");
const om = o.getInterface("org.freedesktop.DBus.ObjectManager");
const managed = await om.GetManagedObjects();
for (const [path, ifaces] of Object.entries(managed)) {
if (
path.startsWith(this.path) &&
Object.hasOwn(ifaces, "org.bluez.GattCharacteristic1") &&
Object.hasOwn(ifaces["org.bluez.GattCharacteristic1"], "UUID") &&
ifaces["org.bluez.GattCharacteristic1"]["UUID"].value === uuid
) {
console.log(path);
// construct gatt char.I
}
}
}
} }

23
src/ftms-service.js

@ -1,6 +1,11 @@
import { BaseInterface } from "./base"; import { BaseInterface } from "./base";
import { BaseService, BaseCharacteritic, BaseApplication } from "./bluez-gatt"; import { BaseService, BaseCharacteritic, BaseApplication } from "./bluez-gatt";
const Mode = Object.freeze({
SIM: Symbol("sim"),
ERG: Symbol("erg"),
});
export class FTMSService extends BaseService { export class FTMSService extends BaseService {
UUID = "00001826-0000-1000-8000-00805f9b34fb"; UUID = "00001826-0000-1000-8000-00805f9b34fb";
Primary = true; Primary = true;
@ -30,6 +35,7 @@ class FTMSFeature extends BaseCharacteritic {
} }
class FTMSControlPoint extends BaseCharacteritic { class FTMSControlPoint extends BaseCharacteritic {
mode = Mode.SIM;
wind = 0; wind = 0;
grade = 0; grade = 0;
crr = 0; crr = 0;
@ -57,10 +63,16 @@ class FTMSControlPoint extends BaseCharacteritic {
} else if (value[0] === 0x01) { } else if (value[0] === 0x01) {
// reset machine // reset machine
this.notify([0x80, 0x01, 0x01]); this.notify([0x80, 0x01, 0x01]);
} else if (value[0] === 0x05) {
// set target power aka ERG mode
this.mode = Mode.ERG;
const power = view.getInt16(1, true);
this.notify([0x80, 0x05, 0x01]);
} else if (value[0] === 0x07) { } else if (value[0] === 0x07) {
// start/resume // start/resume
this.notify([0x80, 0x07, 0x01]); this.notify([0x80, 0x07, 0x01]);
} else if (value[0] === 0x11) { } else if (value[0] === 0x11) {
this.mode = Mode.SIM;
// set simulations param (wind, grade, etc) // set simulations param (wind, grade, etc)
const wind = view.getInt16(1, true); const wind = view.getInt16(1, true);
const grade = view.getInt16(3, true); const grade = view.getInt16(3, true);
@ -72,13 +84,12 @@ class FTMSControlPoint extends BaseCharacteritic {
this.crr = crr * 0.001; this.crr = crr * 0.001;
this.cw = cw * 0.01; this.cw = cw * 0.01;
console.log(wind * 0.001); console.log(
console.log(grade * 0.01); `wind=${this.wind} - grade=${this.grade} - crr=${this.crr} - cw=${this.cw}`
console.log(crr * 0.0001); );
console.log(cw * 0.01);
this.notify([0x80, 0x11, 0x01]); this.notify([0x80, 0x11, 0x01]);
} else { } else {
this.notify([0x80, value[0], 0x02]);
console.log("FTMS Control point op code " + value[0] + "not supported"); console.log("FTMS Control point op code " + value[0] + "not supported");
} }
} }
@ -107,7 +118,7 @@ class IndoorBikeData extends BaseCharacteritic {
this.Notifying = true; this.Notifying = true;
this.interval = setInterval(() => { this.interval = setInterval(() => {
console.log("FTMS Notif Indoor Bike"); //console.log("FTMS Notif Indoor Bike");
// 0x44 0x02 = fields included: cadence (2), power (6), hr (9) // 0x44 0x02 = fields included: cadence (2), power (6), hr (9)
// 0x00 0x00 = average speed, always included // 0x00 0x00 = average speed, always included
// cadence is *2 (resolution 0.5 s^-1) // cadence is *2 (resolution 0.5 s^-1)

15
src/index.js

@ -41,17 +41,22 @@ async function main() {
await gattmgr.RegisterApplication("/eu/atoy", {}); await gattmgr.RegisterApplication("/eu/atoy", {});
console.log("BLE GATT application registered"); console.log("BLE GATT application registered");
return;
const bz = new Bluez(); const bz = new Bluez();
const pafers = await bz.getDevice("PAFERS_53B9A3");
console.log("Searching PAFERS device...");
const pafers = await bz.getDeviceByServiceUUID(
"72d70001-501f-46f7-95f9-23846ee1aba3"
);
if (!pafers) { if (!pafers) {
console.log("Device not found");
process.exit(1); process.exit(1);
} }
const name = await pafers.getValue("Name");
const iscon = await pafers.isConnected(); const iscon = await pafers.isConnected();
console.log("connected: " + iscon);
console.log("Found " + name + " (connected=" + iscon + ")");
/*bz.on("interfacesAdded", () => { /*bz.on("interfacesAdded", () => {
@ -61,6 +66,8 @@ async function main() {
await pafers.connect(); await pafers.connect();
} }
const char1 = await pafers.getCharacteristic("72d70003-501f-46f7-95f9-23846ee1aba3");
return; return;
const root = await bus.getProxyObject("org.bluez", "/"); const root = await bus.getProxyObject("org.bluez", "/");

Loading…
Cancel
Save