Не удается подключить мой ноутбук с Windows с адаптером BLE к устройству BLE

Я пытаюсь настроить демонстрацию на основе Nodejs на своем ноутбуке Windows с дополнительным адаптером BLE для подключения моего ноутбука к другому Устройство BLE (Anki Overdrive). Я видел эту демонстрацию в Интернете, и мне было любопытно, смогу ли я ее настроить. Я выполнил все инструкции, но потерпел неудачу, потому что исходная демонстрация была сделана с помощью MacBook, в котором используется другой тип встроенного адаптера BLE. Я также попробовал его с MacBook, и он работал более чем хорошо, но я хотел бы настроить его на устройстве с Windows. Я приложил часть кода Nodejs, который должен возвращать периферийный идентификатор устройства BLE:

//UUID for Anki Overdrive Car be15beef6186407e83810bd89c4d8df4

var noble = require('noble');

noble.on('stateChange', function(state) {
  if (state === 'poweredOn') {
    noble.startScanning();

    setTimeout(function() {
       noble.stopScanning();
       process.exit(0);
     }, 2000);
  } else {
    noble.stopScanning();
  }
});

noble.on('discover', function(peripheral) {
  var serviceUuids = JSON.stringify(peripheral.advertisement.serviceUuids);
  if(serviceUuids.indexOf("be15beef6186407e83810bd89c4d8df4") > -1) {
    console.log('Car discovered. ID: ' + peripheral.id); 
  }
});

На данный момент я выяснил, что встроенный BLE от MacBook отправляет обратно идентификатор периферийного устройства. Для сравнения, адаптер Windows BLE возвращает только MAC-адрес другого BLE устройства. Может кто-нибудь помочь мне? Я действительно понятия не имею, что я могу сделать, чтобы решить проблему.

Для лучшего понимания я предоставил ссылку на исходную демонстрацию, которая была настроена с помощью MacBook. https://github.com/IBM-Bluemix/node-mqtt-for-anki-overdrive.

Спасибо заранее.


person fdbenjamin    schedule 27.02.2017    source источник
comment
Что происходит на устройстве Windows? Вы видите что-нибудь в консоли, например. Автомобиль обнаружен. ID: ХХХ? Вы можете попробовать увеличить время ожидания 2000, чтобы дать адаптеру Windows больше времени для обнаружения устройства.   -  person davidgyoung    schedule 27.02.2017
comment
@davidgyoung Я получаю вывод консоли, но вместо реального идентификатора периферийного устройства, как это делает MacBook, возвращается MAC-адрес (даже там написано, что автомобиль обнаружил ID: XX-XX-XX-XX-XX-XX). Обычно я должен получить 32-битную строку. Но в любом случае попробую ваше решение. Спасибо заранее.   -  person fdbenjamin    schedule 27.02.2017
comment
Хорошо, так что он обнаруживает это просто отлично. Хорошие новости — нет необходимости увеличивать время ожидания. Судя по приведенному коду, все в порядке. Вам нужно показать больше кода, хотя бы ту часть, которая что-то делает с возвращенным идентификатором.   -  person davidgyoung    schedule 27.02.2017


Ответы (1)


Работать с автомобилями Anki Overdrive всегда проблематично.

В следующих фрагментах показан код, соответствующий вашему вопросу.

Отказ от ответственности: я создал WIP Anki Overdrive SDK [1], который пытается облегчить жизнь (фрагменты скопированы оттуда)

  1. Сканировать устройства с помощью Noble (scanner.js)
module.exports = class Scanner {
    constructor() {
        this.peripherals = []
        this.state = undefined
    }

/**
 * Set up noble listeners. Mandatory before scan.
 */
async setUpNoble () {
    try {
        await noble.on('discover', (peripheral) => {
            const isAnkiDevice = function(peripheral) {
                const serviceUuids = JSON.stringify(peripheral.advertisement.serviceUuids)
                return (serviceUuids.indexOf("be15beef6186407e83810bd89c4d8df4") > -1)
            }

            if(isAnkiDevice(peripheral)) {
                this.peripherals.push(peripheral)
            }
        })
        await noble.on('stateChange', (status) => {
            this.state = status
        })
    } catch (err) {
        throw new Error(err)
    }
}

/**
 * Scans for devices and returns peripherals. Scans for 20 seconds before stopping.
 */
async scan() {
    try {
        let that = this
        await waitUntil(() => {
            return (that.state === 'poweredOn')
        }, 20000)
        console.log('Starting to scan...')
        return await waitUntil(() => {
            noble.stopScanning()
            if(that.peripherals.length <= 0) {
                console.log('Scanning...')
                noble.startScanning()
            } else {
                console.log('Found ' + that.peripherals.length + ' devices.')
                return that.peripherals
            }
        }, 20000, 4000)
    } catch (err) {
        throw new Error(err)
    }
}
}
  1. Запустить сканирование и создать объект устройства (anki.js)
async scanDevices() {
    try {
        const that = this
        const scanner = new Scanner()
        scanner.setUpNoble()

        const peripherals = await scanner.scan()  
        const devices = peripherals.map((peripheral) => {
            return new Device(peripheral)
        })

        return devices
    } catch (err) {
        throw new Error(err)
    }

}
  1. Установите идентификатор и serviceUUId периферийного устройства в конструкторе объекта "Устройство" (device.js)
module.exports = class AnkiDevice {
    constructor (peripheral) {
        this.peripheral = peripheral
        this.id = peripheral.uuid
        this.serviceUuids = JSON.stringify(peripheral.advertisement.serviceUuids)
....
  1. Подключиться к машине (device.js)
connect() {
    try {
        const that = this
        console.log('Connecting with ' + this.id)
        const getService = function(services){
            if (os.platform() === 'win32' || os.platform() === 'linux') {
                return services[2]
            } else {
                return service[0] // macOS
            }
        }

        const setCharacteristics = function(characteristics) {
            for(let i in characteristics) {
                const characteristic = characteristics[i]
                if (characteristic.uuid == 'be15bee06186407e83810bd89c4d8df4') {
                    that.readCharacteristic = characteristic
                }

                if (characteristic.uuid == 'be15bee16186407e83810bd89c4d8df4') {
                    that.writeCharacteristic = characteristic
                } 
            }                
        }

        const onConnect = async function() {
            const services = await that.peripheral.discoverServices([])
            const service = await getService(services)
            const characteristics = await service.discoverCharacteristics([])
            await setCharacteristics(characteristics)
            // Listen to own disconnect
            that.peripheral.once('disconnect', () => {
                mediator.private.emit('deviceDisconnected', this)
            })
            mediator.private.emit('deviceConnected', that)
        }

        this.peripheral.once('connect', onConnect)
        this.peripheral.connect()
    } catch(err) {
        throw new Error(err)
    }
}
  1. ТОГДА: активируйте режим SDK (device.js)
activateSDKMode() {
    console.log('Activating SDKMode for ' + this.id)
    const that = this
    if(!this.isConnected) {
        return new Error('Car is not connected yet.')
    }
    const message = coder.encodeSDKActivation()
    this._writeMessage(message)
    .then(() => {
        mediator.private.emit('SDKModeOn', that)
    })
}
  1. ТО: включите ведение журнала (device.js)
turnOnLogging() {
    console.log('Turning logging on for ' + this.id)
    let that = this
    if(!that.isConnected) {
        return new Error('Car is not connected yet.')
    }

    that.readCharacteristic.notify(true)
    that.readCharacteristic.on('read', (data) => {
        that._onMessage(data)
    })
    mediator.private.emit('loggingOn', that)
}

[1] https://github.com/steinroe/anki-overdrive-sdk

person Steinroe    schedule 22.06.2018