UNPKG

bt-sensors-plugin-sk

Version:

Bluetooth Sensors for Signalk - see https://www.npmjs.com/package/bt-sensors-plugin-sk#supported-sensors for a list of supported sensors

218 lines (179 loc) 7.5 kB
function arduinoDateDecode (elapsedSeconds) { const date = new Date("2000-01-01") date.setTime(date.getTime() + 1000 * elapsedSeconds) return date } const errors= { 0: "Undefined", 1: "Invalid Battery", 2: "Overheat", 3: "Overheat Shutdown", 4: "Generator lead 1 disconnected", 5: "Generator lead 2 disconnected", 6: "Generator lead 3 disconnected", 7: "Short Circuit" } const eventTypes = { 0: "Reboot", 1: "Invalid Battery", 2: "Overheat", 3: "Overheat Shutdown", 4: "Generator lead 1 disconnected", 5: "Generator lead 2 disconnected", 6: "Generator lead 3 disconnected", 7: "Short Circuit", 255: "Debug" } const states= ["Charging Needed", "Charging", "Floating", "Idle"] const BTSensor = require("../BTSensor"); class RemoranWave3 extends BTSensor{ static Domain = BTSensor.SensorDomains.electrical static ImageFile = "RemoranWave3.jpeg" serviceUUID = "81d08df0-c0f8-422a-9d9d-e4379bb1ea3b" info1CharUUID = "62c91222-fafe-4f6e-95f0-afc02bd19f2e" info2CharUUID = "f5d12d34-4390-486c-b906-24ea8906af71" eventUUID = "f12a8e25-59f7-42f2-b7ae-ba96fb25c13c" static async identify(device){ const name = await this.getDeviceProp(device,"Name") if (name == 'Remoran Wave.3') return this else return null } hasGATT(){ return true } usingGATT(){ return true } emitInfo1Data(buffer){ if (buffer.length < 20) { this.debug(`Bad buffer size ${buffer.length}. Buffer size must be 20 bytes or more.`) return } this.emit("versionNumber", buffer.readUInt8(0)) const errors = buffer.readUInt8(2) const errorState = [] for (var i = 0; i < 8; ++i) { var c = 1 << i; errors & c && errorState.push(errors[i]) } this.emit("errors", errorState) this.emit("state", states[buffer.readUInt8(3)]) this.emit("rpm", buffer.readUInt32LE(4)) this.emit( "voltage" , buffer.readFloatLE(8)) this.emit("current", buffer.readFloatLE(12)) this.emit( "power", buffer.readFloatLE(16)) if (buffer.length > 23) { this.emit( "temp", ((buffer.readFloatLE(20))+273.15)) this.emit( "uptime", buffer.readUInt32LE(24)) if (versionNumber>1 && buffer.size > 31) { this.emit("energy", buffer.readFloatLE(32)) } } } emitInfo2Data(buffer){ if (buffer.size < 12) { this.setError(`Bad buffer size ${buffer.length}. Buffer size must be 12 bytes or more.`) return } this.emit("versionNumber", buffer.readUInt8(0)) this.emit("temp", ((buffer.readFloatLE(4))+273.15)) this.emit("uptime", buffer.readUInt32LE(8)) this.emit("lastBootTime", arduinoDateDecode(buffer.readUInt32LE(12))) this.emit("energy", buffer.readFloatLE(16)) } emitEventData(buffer){ if (buffer.length < 14) { this.debug(`Bad buffer size ${buffer.length}. Buffer size must be 14 bytes or more.`) return } const eventType = buffer.readUInt16LE(8) var eventDesc = eventType.toString() if (Object.hasOwn(eventTypes,eventType)) eventDesc = eventTypes[eventType] this.emit("event", { firstDate: arduinoDateDecode(buffer.readUInt32LE(0)), lastDate: arduinoDateDecode(buffer.readUInt32LE(4)), eventType: eventType, count: buffer.readUInt16LE(10), index: buffer.readUInt16LE(12), eventDesc: eventDesc } ) } emitGATT(){ this.info1Characteristic.readValue() .then((buffer)=> this.emitInfo1Data( buffer) ) this.info2Characteristic.readValue() .then((buffer)=> this.emitInfo2Data(buffer) ) this.eventCharacteristic.readValue() .then((buffer)=> this.emitEventData(buffer) ) } initSchema(){ super.initSchema() this.addDefaultParam("id") .default="RemoranWave3" this.getGATTParams()["useGATT"].default=true this.addMetadatum('errorCodes','', 'charger error codes (array)') .default= "electrical.chargers.{id}.errorCodes" this.addMetadatum('state','', 'charger state') .default= "electrical.chargers.{id}.state" this.addMetadatum('voltage','V', 'battery voltage') .default= "electrical.chargers.{id}.battery.voltage" this.addMetadatum('current','A', 'battery current') .default= "electrical.chargers.{id}.battery.current" this.addMetadatum('power','W', 'battery power') .default= "electrical.chargers.{id}.battery.power" this.addMetadatum('temp', 'K', 'charger temperature') .default= "electrical.chargers.{id}.temperature" this.addMetadatum('energy', 'wh', 'energy created today in Wh') .default= "electrical.chargers.{id}.energy" this.addMetadatum('event', '', 'charger event') .default= "electrical.chargers.{id}.event" this.addMetadatum('lastBootTime', 's', 'last boot time') .default= "electrical.chargers.{id}.lastBootTime" this.addMetadatum('rpm', '', 'revolutions per minute') .default= "sensors.{macAndName}.rpm" this.addMetadatum('uptime', 's', 'charger/sensor uptime') .default= "sensors.{macAndName}.uptime" this.addMetadatum('versionNumber', '', 'charger/sensor version number') .default= "sensors.{macAndName}.version" } async initGATTConnection(isReconnecting){ await super.initGATTConnection(isReconnecting) const gattServer = await this.getGATTServer() const service = await gattServer.getPrimaryService(this.serviceUUID) this.info1Characteristic = await service.getCharacteristic(this.info1CharUUID) this.info2Characteristic = await service.getCharacteristic(this.info2CharUUID) this.eventCharacteristic = await service.getCharacteristic(this.eventUUID) } async initGATTNotifications() { await this.info1Characteristic.startNotifications() this.info1Characteristic.on('valuechanged', buffer => { this.emitInfo1Data(buffer) }) await this.info2Characteristic.startNotifications() this.info2Characteristic.on('valuechanged', buffer => { this.emitInfo2Data(buffer) }) await this.eventCharacteristic.startNotifications() this.eventCharacteristic.on('valuechanged', buffer => { this.emitEventData(buffer) }) } async deactivateGATT(){ await this.stopGATTNotifications(this?.info1Characteristic) await this.stopGATTNotifications(this?.info2Characteristic) await this.stopGATTNotifications(this?.eventCharacteristic) await super.deactivateGATT() } } module.exports=RemoranWave3