import type { I2CDeviceConfig, ImplementationConfigBase } from '../lib/adapter-config'; import { Delay } from '../lib/async'; import type { I2cAdapter } from '../main'; import { BigEndianDeviceHandlerBase } from './big-endian-device-handler-base'; import type { DeviceHandlerInfo } from './device-handler-base'; export interface SRF02Config extends ImplementationConfigBase { pollingInterval: number; } export class SRF02Handler extends BigEndianDeviceHandlerBase { private readonly useRegisters: boolean; constructor(deviceConfig: I2CDeviceConfig, adapter: I2cAdapter) { super(deviceConfig, adapter); this.useRegisters = this.name == 'SRF02'; } async startAsync(): Promise { this.debug('Starting'); await this.adapter.extendObject(this.hexAddress, { type: 'device', common: { name: `${this.hexAddress} (${this.name})`, role: 'sensor', }, native: this.deviceConfig, }); await this.adapter.extendObject(`${this.hexAddress}.distance`, { type: 'state', common: { name: `${this.hexAddress} Distance`, read: true, write: false, type: 'number', role: 'value.distance', unit: 'cm', }, }); await this.adapter.extendObject(`${this.hexAddress}.measure`, { type: 'state', common: { name: `${this.hexAddress} Measure`, read: false, write: true, type: 'boolean', role: 'button', }, }); this.adapter.addStateChangeListener( `${this.hexAddress}.measure`, async () => await this.readCurrentValueAsync(), ); if (this.config.pollingInterval > 0) { this.startPolling(async () => await this.readCurrentValueAsync(), this.config.pollingInterval * 1000, 1000); } } async stopAsync(): Promise { this.debug('Stopping'); this.stopPolling(); return Promise.resolve(); } private async readCurrentValueAsync(): Promise { try { // send the range command if (this.useRegisters) { await this.writeByte(0x00, 0x51); } else { await this.sendByte(0x51); } await this.delay(100); // read the measurement data let value: number; if (this.useRegisters) { value = await this.readWord(0x02); } else { const buffer = Buffer.alloc(2); await this.i2cRead(buffer.length, buffer); // masking awai the highest bit (undocumented!) value = buffer.readUInt16BE() & 0x7fff; } await this.setStateAckAsync('distance', value); } catch (e: any) { this.error(`Couldn't read current value: ${e}`); } } private async delay(ms: number): Promise { const delay = new Delay(ms); await delay.runAsnyc(); } } export const SRF02: DeviceHandlerInfo = { type: 'SRF02', createHandler: (deviceConfig, adapter) => new SRF02Handler(deviceConfig, adapter), names: [ { name: 'SRF02', addresses: [0x70] }, { name: 'GY-US42', addresses: [0x70] }, ], config: { 'SRF02.pollingInterval': { type: 'number', label: 'Polling Interval', default: 10, unit: 'sec', min: 0, xs: 7, sm: 5, md: 3, }, }, };