npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-oneiot-ble

v0.4.4

Published

React Native library for OneIoT BLE devices (H7, L02S, S02R beacons and MKGW4/MKGW8 gateways). Scanning, sensor streams, GATT configuration, provisioning, and gateway MQTT client.

Readme

react-native-oneiot-ble

React Native library for OneIoT BLE devices — scanning, sensor streams, GATT configuration, fleet provisioning, and gateway management (MQTT).

Supported devices

| Prefix | SKU | Product Name | Category | |--------|-------|---------------------------|---------------------| | OHB | H7 | OneIoT Helmet Beacon | Beacon | | OTH | L02S | OneIoT TH Sensor | Beacon | | ORS | S02R | OneIoT Range Sensor | Beacon | | OMG | MKGW4 | OneIoT Mobile Gateway | Gateway (cellular) | | OWG | MKGW8 | OneIoT Warehouse Gateway | Gateway (Wi-Fi/PoE) |

All devices advertise a BLE local name of the form <PREFIX><12-hex-MAC>, e.g. OTHAABBCCDDEEFF. This is the OneIoT Device UUID used everywhere in the API.

Installation

npm install react-native-oneiot-ble react-native-ble-plx sp-react-native-mqtt
# or
yarn add react-native-oneiot-ble react-native-ble-plx sp-react-native-mqtt

cd ios && pod install

sp-react-native-mqtt is an optional peer dependency — only required if you use the GatewayClient for MQTT communication.

iOS setup

Add to ios/YourApp/Info.plist:

<key>NSBluetoothAlwaysUsageDescription</key>
<string>Uses Bluetooth to discover and connect to OneIoT sensors.</string>
<key>UIBackgroundModes</key>
<array>
  <string>bluetooth-central</string>
</array>

Android setup

Add to android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
                 android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
                 android:maxSdkVersion="30" />

Request runtime permissions with react-native-permissions or PermissionsAndroid before scanning.

Quick start

Scan for OneIoT devices

import { useMokoScan } from 'react-native-oneiot-ble';

export function ScanScreen() {
  const { devices, isScanning, start, stop } = useMokoScan();

  useEffect(() => {
    start();
    return stop;
  }, [start, stop]);

  return (
    <FlatList
      data={devices}
      keyExtractor={(d) => d.deviceUuid}
      renderItem={({ item }) => (
        <View>
          <Text>{item.productName} — {item.macFormatted}</Text>
          <Text>RSSI {item.rssi} dBm</Text>
        </View>
      )}
    />
  );
}

Live temperature stream

import { useMokoTemperature } from 'react-native-oneiot-ble';

function TempReading({ deviceUuid }: { deviceUuid: string }) {
  const t = useMokoTemperature(deviceUuid);
  return <Text>{t == null ? '—' : `${t.toFixed(1)} °C`}</Text>;
}

Threshold alarm

useMokoAlarm(
  'OTHAABBCCDDEEFF',
  { type: 'temperatureAbove', threshold: 30 },
  (t) => console.warn(`Overheat! ${t}°C`),
);

Gateway MQTT client

import { GatewayClient } from 'react-native-oneiot-ble';

const client = await GatewayClient.connect({
  broker: {
    host: 'mqtt.example.com',
    port: 8883,
    clientId: 'my-app',
    username: 'user',
    password: 'pass',
    tls: true,
  },
});

await client.subscribeGateway('GW-MAC');
await client.connectBeacon('GW-MAC', 'AABBCCDDEEFF', 'Moko4321').result;
const battery = await client.readBeaconBattery('GW-MAC', 'AABBCCDDEEFF');

Features

1. Device Classification & Identity

Every OneIoT device broadcasts a BLE local name of the form <PREFIX><12-hex-MAC> (e.g. OTHAABBCCDDEEFF). The library treats this "Device UUID" as the primary key across every API.

Provides:

  • parseDeviceUuid(name) — takes any BLE local name and returns { valid, sku, prefix, mac, macFormatted, productName }. Handles lowercase input, trims whitespace, validates hex format, returns sku: 'UNKNOWN' for non-OneIoT devices.
  • buildDeviceUuid(sku, mac) — constructs a compliant UUID from a SKU and MAC in any format (AA:BB:CC:DD:EE:FF, aabbccddeeff, aa-bb-cc-dd-ee-ff).
  • isValidDeviceUuid(name) — boolean check for compliance.
  • skuMetadata(sku) — static per-SKU capability inventory: has motion? has T&H? has flash? has ToF? has buzzer? has RFID? Plus category (beacon / gateway).
  • prefixForSku(sku) — reverse lookup (L02SOTH).
  • formatMac(mac) / normalizeMac(mac) — canonical MAC formatting.

Why it matters: iOS hides the hardware MAC and rotates its CBPeripheral.identifier between app installs. Because the Device UUID embeds the MAC in the advertised name, you get a stable, cross-platform identifier that survives reinstalls. useMokoDevice('OTHAABBCCDDEEFF') works identically on iOS and Android.

2. BLE Scanning

Wraps react-native-ble-plx with OneIoT-specific filtering, classification, and typed output. Every advertisement is auto-parsed and mapped to a MokoDevice object.

Provides:

  • BleScanner.scan(options, listener, onError) — continuous scan, returns an unsubscribe function. Multiple listeners are supported (only stops physical scan when all unsubscribe).
  • BleScanner.scanBySku(sku, listener) — filter one SKU at the listener layer.
  • BleScanner.scanOnce({ timeoutMs })Promise<MokoDevice[]> — scans for N ms, resolves with de-duplicated device list (latest observation per device).
  • BleScanner.stopScan() / isScanning().

Scan options:

  • serviceUuids — override the default MOKO service UUID filter (0xFEAA Eddystone, 0xFEAB MOKO custom, 0xEA01 BXP-S).
  • minRssi — drop packets below a signal floor.
  • allowDuplicates — iOS: mandatory true for beacon telemetry (default).
  • scanMode — Android: lowPower (~5 s scan / 500 ms window), balanced (default), lowLatency (continuous, drains battery).
  • timeoutMs — auto-stop after N ms.

Automatic per-packet enrichment: Device UUID parsed and classified, BXP-S sensor payload decoded (if present), RSSI + Tx power + estimated distance computed, first-seen/last-seen timestamps recorded, per-device advertisement count maintained, raw bytes preserved for debug.

Why it matters: Non-OneIoT devices are filtered out automatically. Consumers never handle raw bytes unless they want to.

3. Live Sensor Data (No Connection Needed)

BXP-S devices broadcast sensor readings in every advertisement (~10 Hz). No GATT connection required — just scan and read.

Sensor fields per SKU:

| Field | H7 | L02S | S02R | |---|---|---|---| | Temperature (°C) | — | ✅ | — | | Humidity (%RH) | — | ✅ | — | | Accelerometer XYZ (mg) | ✅ | ✅ | — | | Motion state (moving/static) | ✅ | ✅ | — | | Motion event count | ✅ | ✅ | — | | ToF distance (mm) | — | — | ⏳* | | Battery (voltage OR percent) | ✅ | ✅ | ✅ | | Equipped-sensor bitmap | ✅ | ✅ | ✅ | | Tag ID | ✅ | ✅ | ✅ |

ToF byte position not yet published by MOKO — decoder returns null until spec arrives.

Provides:

  • watchAll(uuid, cb) — every parsed sensor packet, discriminated union by SKU.
  • watchTemperature(uuid, cb) — L02S temperature stream.
  • watchHumidity(uuid, cb) — L02S humidity stream.
  • watchMotion(uuid, cb) — H7/L02S accelerometer + isMoving flag.
  • watchDistance(uuid, cb) — S02R ToF stream.
  • watchBattery(uuid, cb) — battery reading (voltage or percent).
  • getLatest(uuid) — snapshot without waiting for next packet.

Battery dual-encoding: MOKO packs battery into 2 bytes with a special rule: values > 100 = millivolts, ≤ 100 = percent. Library returns a discriminated union { mode: 'voltage', valueMv: 3276 } or { mode: 'percent', valuePct: 90 } so app code never has to check the raw number.

Capability-aware parsing: if a device's equipped-sensor bitmap says no temperature sensor, temperatureC returns null — not a garbage value from unused bytes.

4. Threshold Alarms

Edge-triggered event helpers for common alarm use cases. Fires once when a threshold is crossed, then re-arms only when the value returns to the safe zone.

Provides:

  • onTemperatureAbove(uuid, °C, cb) — cold-chain over-temperature alarm.
  • onTemperatureBelow(uuid, °C, cb) — freezer thaw alarm.
  • onHumidityAbove(uuid, %, cb) — condensation alarm.
  • onMotionDetected(uuid, cb) — fires on transition static → moving.
  • onDistanceBelow(uuid, mm, cb) — S02R proximity alarm.
  • onProximityEnter(uuid, rssi, cb) — device came within a signal-strength boundary.

Why edge-triggered: BXP-S broadcasts ~10 Hz. If temperature stays at 32 °C for 2 minutes, a level-triggered alarm would fire 1200 times. These helpers fire exactly once until the value drops below the threshold.

5. Signal Strength & Proximity

Turn noisy raw RSSI into stable distance/proximity data suitable for UI.

Provides:

  • estimateDistance(rssi, txPower, pathLossN?) — log-distance path loss model. n defaults to 2.5 (typical indoor); set 2 for free space, 4 for heavy walls.
  • proximityZoneFromRssi(rssi) / proximityZoneFromDistance(m) — classify into immediate (< 0.5 m), near (< 3 m), far (< 30 m), out.
  • calibrateTxPower(samplesAt1m) — median-based Tx-power calibration helper.

Smoothing filters (all implement push(rssi) → smoothed):

  • KalmanRssiSmoother — recommended default; drastically reduces jitter with configurable process/measurement noise.
  • ExponentialMovingAverageSmoother — cheaper, one α parameter.
  • MovingAverageSmoother — simplest, configurable window.
  • createSmoother(method) — factory returning any of the above.

Why it matters: Raw BLE RSSI swings 10–15 dBm packet-to-packet even for a stationary device. Direct UI binding produces flickering distance readouts.

6. Session Device Tracker

Long-lived in-memory store that merges advertisement events into a live device list. Backs the React hooks.

Provides:

  • start() / stop() — attach/detach from scanner. Idempotent.
  • list() — all devices seen this session.
  • getByUuid(uuid) / getBySku(sku) — lookups.
  • count() / countBySku() — fleet counts.
  • onSeen(cb) — fires when a new device appears.
  • onLost(cb) — fires when a device goes stale (see forgetStaleAfter).
  • onUpdate(cb) — fires on every packet.
  • forgetStaleAfter(ms) — auto-evict devices not seen for N ms. Pass null to disable.
  • ingest(device) — manually feed a device from an external source (e.g. MQTT gateway uplink).
  • reset() — clear session state.

Merging behaviour: Each new packet updates rssi, lastSeenAt, adCount, sensor data (if present), and raw bytes. firstSeenAt is preserved.

7. Bluetooth Adapter & Permissions

Adapter-state helpers and permission-status queries. Explicitly does not request permissions — apps use react-native-permissions or PermissionsAndroid for that.

Provides:

  • Bluetooth.getState()poweredOn / poweredOff / unauthorized / resetting / unsupported / unknown.
  • Bluetooth.observeState(cb) — reactive stream, fires immediately with current state.
  • Bluetooth.getPermissionStatus() — best-effort permission inspection.
  • Bluetooth.canScan() — boolean helper.

Why status-only: requesting Bluetooth permissions is UX-sensitive (Android requires runtime prompts with rationale strings, iOS shows a system dialog on first CBCentralManager init). Different apps handle this differently — the library stays out of the way.

8. GATT Device Configuration (API locked, wire protocol pending MOKO)

Open a GATT connection to a beacon and reconfigure it. All methods are typed and callable today, but throw MokoError('gatt_error', '…pending MOKO GATT spec') until MOKO ships the BXP-S wire protocol. Public API will not change when implementations land.

Connection lifecycle:

  • MokoConnect.connect(uuid, { password, timeoutMs })DeviceHandle. Default password Moko4321.
  • MokoConnect.disconnect(uuid).
  • MokoConnect.isConnected(uuid).
  • MokoConnect.onConnectionChange(uuid, cb) — subscribe to connect/disconnect events.

DeviceHandle read operations:

  • readInfo(){ model, manufacturer, hwVersion, fwVersion, serialNumber }.
  • readBattery() → dual-mode battery.

Identity & security:

  • rename(newDeviceUuid) — write new OneIoT-scheme name.
  • setPassword(newPassword) — max 16 chars.

Radio config:

  • setTxPower(dbm) — −40 to +8 dBm.
  • setAdvInterval(ms) — 100–10000 ms.
  • setConnectable(bool).

Slot configuration (3 slots per device):

  • getSlots()SlotConfig[].
  • setSlot(index, config) — configure one slot with frame type (Eddystone-UID/URL/TLM, iBeacon, SensorInfo, None), ADV interval, ADV duration, standby duration, Tx power.
  • setTrigger(config) — with before/after states and lock duration.

Actuators:

  • blinkLED({ count, color?, intervalMs? }).
  • buzz({ durationMs }) — H7 only.

Lifecycle:

  • factoryReset(), reboot().

9. Fleet Provisioning

Turn a batch of factory-fresh devices into a labelled fleet — connect, read MAC, write OneIoT-scheme name, verify.

Provides:

  • Provisioner.isProvisioned(device) — does the current name match the scheme?
  • Provisioner.needsProvisioning() — list devices in range missing correct names.
  • Provisioner.assignName(platformId, sku, password?) — connect, look up MAC, write OXX+MAC name. Returns the new Device UUID.
  • Provisioner.batchProvision(devices, options) — iterate over a list with onProgress(done, total) and onDeviceComplete({ deviceUuid, error }) callbacks.
  • Provisioner.verifyFleet(expectedUuids){ present, missing, extra } — health check before deployment.
  • Provisioner.exportManifest() → JSON manifest with SKU, MAC, provisioned-at timestamp for every device.

Why it matters: Assigning distinct names is the ONE thing that makes the entire OneIoT device-classification story deterministic. Without it, all H7 / L02S / S02R units look identical on scan. This module makes intake a 30-second-per-device workflow.

10. Gateway BLE Provisioning (API locked, protocol pending MOKO)

First-time onboarding of MKGW4 (cellular) and MKGW8 (Wi-Fi/PoE) gateways over BLE — push network + MQTT credentials so the gateway comes online.

Provides:

  • Gateway.provisionMKGW4(platformId, { apn, mqtt }) — cellular: APN name/user/pass + MQTT broker config.
  • Gateway.provisionMKGW8(platformId, { wifi?, ethernet?, mqtt }) — Wi-Fi (SSID + password + security type) OR Ethernet (DHCP or static IP with netmask/gateway/DNS) + MQTT config.
  • Gateway.testConnection(platformId) — dry-run network + MQTT reachability check.
  • Gateway.factoryReset(platformId).

Note: MKGW8 also supports Wi-Fi AP provisioning at http://192.168.22.1 (AP SSID MKGW8LD-XXXX, password Moko4321). The BLE path is an alternative for zero-touch onboarding once MOKO ships the spec.

11. Gateway MQTT Client (Cloud Operations)

Full-featured JSON-over-MQTT client implementing the MOKO Gateway Remote Management Commands V2.3 protocol. Talks to gateways over the cloud to remotely manage the beacons they've connected.

Provides:

  • GatewayClient.connect({ broker, requestTimeoutMs, topics }) — establish MQTT session.
  • .disconnect() / .isConnected().
  • .subscribeGateway(gwMac) — subscribe to a gateway's up/down topics.

Fleet discovery:

  • .getGatewayInfo(gwMac) → status, uptime, connected-beacon count, MQTT connection state.
  • .onGatewayOnline(cb) / .onGatewayOffline(cb) — LWT-based presence.

Beacon operations via gateway:

  • .listConnectedBeacons(gwMac) — list of (mac, sku) currently connected.
  • .connectBeacon(gwMac, beaconMac, password) — returns { ack: Promise, result: Promise } two-stage promise (ack from gateway, result from BLE round-trip).
  • .disconnectBeacon(gwMac, beaconMac).
  • .readBeaconInfo(gwMac, beaconMac)DeviceInfo.
  • .readBeaconBattery(gwMac, beaconMac) → dual-mode battery.
  • .setBeaconSlot(gwMac, beaconMac, slotIndex, config).
  • .setBeaconTrigger(gwMac, beaconMac, config).
  • .blinkBeaconLED(gwMac, beaconMac, config).

Real-time sensor streams via MQTT:

  • .enableRealtimeTH(gwMac, beaconMac, cb) — L02S temperature + humidity notify.
  • .enableRealtimeMotion(gwMac, beaconMac, cb) — H7/L02S accelerometer notify.
  • .enableRealtimeDistance(gwMac, beaconMac, cb) — S02R ToF notify.

Uplink stream:

  • .onBeaconUplink(cb) — all beacon-adv frames forwarded by all gateways.

Protocol machinery (all handled internally):

  • msg_id encoding: 1xxx = write, 2xxx = read, 3xxx = notify. Auto-assigned from command tables (BXP-S occupies 500–533).
  • Two-stage promises: connectBeacon returns { ack, result }. ack resolves fast when the gateway echoes the command; result resolves when the BLE round-trip completes (seconds later).
  • Per-(gwMac, bleMac) serialization: MOKO protocol has no client request ID. Concurrent commands to the same beacon would collide, so operations queue automatically.
  • Timeout handling: default 30 s per command, configurable, surfaces MokoError('timeout').
  • Topic conventions: typical MOKO defaults (moko/gw/{mac}/up, moko/gw/{mac}/down) with per-consumer overrides.

Optional MQTT dependency: sp-react-native-mqtt is loaded lazily via require() — apps that only scan don't pay the bundle cost. A Transport interface is exported so consumers can plug in a custom broker (Paho, mqtt.js, etc.).

12. React Hooks (15 total)

All hooks handle mount/unmount lifecycle, clean up subscriptions on unmount, and are safe to use with React 18 StrictMode.

Scanning & devices:

  • useMokoScan(options?){ devices, isScanning, error, start, stop, reset }.
  • useMokoScanBySku(sku) → same, filtered to one SKU.
  • useMokoDevice(deviceUuid) → single-device live state.

Sensor data:

  • useMokoAllSensors(uuid) → latest SensorData (discriminated union).
  • useMokoTemperature(uuid)number | null.
  • useMokoHumidity(uuid)number | null.
  • useMokoMotion(uuid){ x, y, z, isMoving } | null.
  • useMokoDistance(uuid)number | null.
  • useMokoBattery(uuid)Battery | null.

Signal:

  • useMokoRssi(uuid, { smooth?: 'kalman' | 'ema' | 'movingAvg' }) → live RSSI, optionally smoothed.
  • useMokoDistanceEstimate(uuid) → meters.
  • useMokoProximity(uuid)immediate / near / far / out.

Alarms & connection:

  • useMokoAlarm(uuid, { type, threshold }, cb) — declarative threshold alarms.
  • useMokoConnection(uuid){ connected, connect, disconnect, error }.

Adapter:

  • useBluetoothState() → current adapter state.

13. Pure Protocol Utilities (Node-Testable)

Zero React Native dependency — usable from unit tests, backend Node scripts, browser tools.

Provides:

  • parseAdvertisement(bytes) — full BLE AD-structure parser. Handles flags, local names (short & complete), Tx power, 16/32/128-bit service UUIDs, service data, manufacturer-specific data. Never throws — emits warnings for malformed input.
  • parseBxpSSensorInfo(payload) — decode BXP-S 0xEA01/0x80 frame.
  • toSensorData(decoded, sku) — convert decoder output to discriminated union.
  • hexToBytes(hex) / bytesToHex(bytes) — accepts 0x prefix, whitespace, upper/lowercase.
  • uuid128ToUuid16(uuid) — extract 16-bit portion from full 128-bit UUID string.
  • All classifier helpers.

Constants exposed:

  • AD_TYPE.* — BLE AD-type identifiers (Flags, ServiceData16, ManufacturerSpecific, etc.).
  • BXP_S_SERVICE_UUID_16 = 0xEA01.
  • BXP_S_SENSOR_INFO_FRAME = 0x80.

14. Developer Experience

Type safety:

  • Full TypeScript strict mode (including noUncheckedIndexedAccess).
  • Discriminated unions for SensorData — TypeScript narrows based on .kind, so no casting needed.
  • Every public function fully typed with JSDoc.

Error handling:

  • MokoError class with a fixed code enum (bluetooth_off, unauthorized, scan_failed, connect_failed, timeout, gatt_error, mqtt_disconnected, etc.). Consumers switch on code, never parse messages.

Logging:

  • Structured logger with 6 levels (silent, error, warn, info, debug, trace).
  • Runtime-adjustable via logger.setLevel().
  • Custom sink support via logger.setSink() — pipe to a file, remote logger, analytics.

Bundle optimization:

  • sideEffects: false in package.json → aggressive tree-shaking.
  • Optional peers: sp-react-native-mqtt marked optional; apps that don't use GatewayClient won't bundle it.
  • Lazy require() for the MQTT module — no import-time cost.

Testability:

  • Pure-TS core (classifier, parsers, signal) has zero RN dependency — testable in Node.
  • 50 unit tests already passing (classifier, BXP-S parser with golden vectors from MOKO's own spec, AD parser, signal filters).
  • __resetForTesting() and __setManager() hooks on singleton services for test isolation.
  • Ships a fake Transport interface for GatewayClient tests.

Build:

  • react-native-builder-bob emits CommonJS, ES Modules, and TypeScript definitions.
  • Compatible with both the old bridge and the new architecture (TurboModule-ready).
  • Autolinking configured (no manual linking).

15. Documentation

  • README.md — full API reference with tables, iOS/Android setup, quick-start snippets.
  • CHANGELOG.md — Keep-a-Changelog format, semver-aligned.
  • JSDoc on every public function including parameter descriptions, return types, behavior notes.
  • Golden-vector tests that reference exact table numbers from MOKO's official specs (e.g. "MK Sensor APP UM V1.2 §Table 5") — future spec updates validate against the same fixtures.
  • Example app (example/App.tsx) — working scan + sensor-display screen you can drop into a bare RN project.

Design notes

  • Device UUID as primary key — the app-level identifier OXX+MAC is stable across iOS reinstalls (embeds hardware MAC), so useMokoDevice('OTHAABBCCDDEEFF') works identically on both platforms.
  • Multi-slot devices — BXP-S beacons may emit multiple slots (before/after trigger, Eddystone + iBeacon + Sensor Info). The tracker de-duplicates by deviceUuid only, not (uuid + name).
  • iOS background scanning — local names are stripped by iOS in background mode. Foreground apps get full classification; background apps lose SKU identification.
  • Coded PHY (Long Range) — L02S supports LE Coded PHY (350 m). iOS CoreBluetooth does not expose Coded PHY scanning. For Long-Range coverage, use MKGW8 gateways.

Blocked pieces (waiting on MOKO)

These have locked APIs but stubbed implementations — will "just work" once MOKO ships the corresponding docs. Consumer code will not need to change.

| Feature | Blocking doc from MOKO | |----------------------------------------------------------------|-------------------------------------------| | GATT beacon configuration (rename, slots, triggers, LED, buzz) | BXP-S BLE Communication Protocol | | MKGW4 BLE provisioning (APN + MQTT push) | MKGW4 APP Integration / BLE Config | | MKGW8 BLE provisioning (Wi-Fi/Ethernet + MQTT push) | MKGW8 BLE Config Protocol | | S02R ToF distance decoding from advertisement | S02R spec update (byte offset) | | MKGW8 MQTT topic structure verification | MKGW8 MQTT Communication Protocol | | MKGW4 uplink JSON schema verification | MKGW4 Firmware / MQTT Communication doc |

Every locked-but-stubbed method throws a specific, actionable MokoError so consumers see clear errors (not silent failures) until wire protocols land.

Roadmap

  • v0.1 (current) — Scanning, sensor streams, tracker, hooks, gateway MQTT client, provisioning + GATT API surface (stubbed pending MOKO wire protocol).
  • v0.2 — Real GATT implementation for BXP-S device configuration (once MOKO ships the wire protocol document).
  • v0.3 — MKGW4/MKGW8 BLE provisioning (once MOKO ships the gateway BLE config protocol document).
  • v0.4 — DFU firmware updates, extended advertising (Coded PHY on Android).

Testing

npm test              # pure-TS unit tests (classifier, parsers, signal)
npm run typecheck
npm run lint
npx bob build         # emit lib/

Native / BLE integration tests require a physical device; use the example/ app as a manual test harness. BLE does not work in the iOS Simulator or Android emulator.

License

MIT © OneIoT