homebridge#Characteristic TypeScript Examples

The following examples show how to use homebridge#Characteristic. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: util.ts    From homebridge-wiz-lan with Apache License 2.0 7 votes vote down vote up
export function turnOffIfNeeded(
  characteristic: WithUUID<{
    new (): Characteristic;
  }>,
  service: Service,
  useSetValue = false
) {
  const ch = service.getCharacteristic(characteristic);
  if (ch?.value !== 0) {
    useSetValue ? ch.setValue(0) : ch.updateValue(0);
  }
}
Example #2
Source File: accessory.ts    From homebridge-vieramatic with Apache License 2.0 6 votes vote down vote up
async setPowerStatus(nextState: CharacteristicValue): Promise<void> {
    const message = nextState === this.Characteristic.Active.ACTIVE ? 'ON' : 'into STANDBY'
    const currentState = await VieraTV.isTurnedOn(this.device.address)
    this.log.debug('(setPowerStatus)', nextState, currentState)
    if ((nextState === this.Characteristic.Active.ACTIVE) === currentState)
      this.log.debug('TV is already %s: Ignoring!', message)
    else if (nextState === this.Characteristic.Active.ACTIVE && this.userConfig.mac) {
      this.log.debug('sending WOL packets to awake TV')
      // takes 1 sec (10 magic pkts sent with 100ms interval)
      await wakeOnLan(this.userConfig.mac, this.device.address, 10)
      await sleep(1000)
      await this.updateTVstatus(nextState)
      this.log.debug('Turned TV', message)
    } else {
      const cmd = await this.device.sendKey('POWER')
      if (Abnormal(cmd))
        this.log.error('(setPowerStatus)/-> %s - unable to power cycle TV - unpowered ?', message)
      else {
        await this.updateTVstatus(nextState)
        this.log.debug('Turned TV', message)
      }
    }
  }
Example #3
Source File: wiz.ts    From homebridge-wiz-lan with Apache License 2.0 6 votes vote down vote up
initAccessory(platformAccessory: PlatformAccessory) {

    // Already initialized!!
    if (this.initializedAccessories.has(platformAccessory.UUID)) {
      return;
    }

    const device = platformAccessory.context as Device;

    // Skip if it doesn't have the new context schema
    if (typeof device?.model !== "string") {
      return;
    }

    platformAccessory
      .getService(this.Service.AccessoryInformation)!!
      .setCharacteristic(this.Characteristic.Manufacturer, "Wiz")
      .setCharacteristic(this.Characteristic.Model, device.model)
      .setCharacteristic(this.Characteristic.SerialNumber, device.mac);

    const accessory = Accessories.find(accessory => accessory.is(device));

    if (typeof accessory === 'undefined') {
      this.log.warn(`Unknown device ${device.toString()}, skipping...`);
      return;
    } 

    accessory.init(platformAccessory, device, this);

    this.initializedAccessories.add(platformAccessory.UUID);
  }
Example #4
Source File: platform.ts    From homebridge-screenlogic with MIT License 6 votes vote down vote up
/** map pool heat mode to thermostat target heating/coooling state  */
  mapHeatModeToTargetHeatingCoolingState(poolHeatMode: number) {
    switch (poolHeatMode) {
      case Controller.HEAT_MODE_OFF:
        return this.Characteristic.TargetHeatingCoolingState.OFF
      case Controller.HEAT_MODE_HEAT_PUMP:
        return this.Characteristic.TargetHeatingCoolingState.HEAT
      case Controller.HEAT_MODE_SOLAR_PREFERRED:
        return this.Characteristic.TargetHeatingCoolingState.AUTO
      case Controller.HEAT_MODE_SOLAR:
        return this.Characteristic.TargetHeatingCoolingState.COOL
      default:
        return this.Characteristic.TargetHeatingCoolingState.OFF
    }
  }
Example #5
Source File: abstractSplitTemperatureThresholdCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 6 votes vote down vote up
// Override default handleUpdatedSnapshot() to ignore based on mode
  handleUpdatedSnapshot(snapshot: GetDeviceResponse['result']['snapshot']) {
    const targetState = this.localService.getCharacteristic(
      this.localPlatform.Characteristic.TargetHeaterCoolerState,
    ).value
    const requiredState =
      this.mode === 'cool'
        ? this.localPlatform.Characteristic.TargetHeaterCoolerState.COOL
        : this.localPlatform.Characteristic.TargetHeaterCoolerState.HEAT
    if (targetState !== requiredState) {
      this.logDebug(
        `Target state is not "${this.mode}", ignoring snapshot update`,
      )
    }
    super.handleUpdatedSnapshot(snapshot)
  }
Example #6
Source File: platform.ts    From homebridge-tapo-p100 with Apache License 2.0 6 votes vote down vote up
constructor(
    public readonly log: Logger,
    config: PlatformConfig,
    public readonly api: API,
  ) {
    this.log.debug('config.json: %j', config);
    this.config = parseConfig(config);
    this.log.debug('config: %j', this.config);
    this.log.debug('Finished initializing platform:', this.config.name);
    this.customCharacteristics = Characteristics(api.hap.Characteristic);
    this.FakeGatoHistoryService = fakegato(this.api);
    // When this event is fired it means Homebridge has restored all cached accessories from disk.
    // Dynamic Platform plugins should only register new accessories after this event was fired,
    // in order to ensure they weren't added to homebridge already. This event can also be used
    // to start discovery of new accessories.
    this.api.on('didFinishLaunching', () => {
      log.debug('Executed didFinishLaunching callback');
      // run the method to discover / register your devices as accessories
      this.discoverDevices();
    });
  }
Example #7
Source File: tasmotaFanService.ts    From homebridge-tasmota with Apache License 2.0 6 votes vote down vote up
constructor(
    public readonly platform: tasmotaPlatform,
    public readonly accessory: PlatformAccessory,
    protected readonly uniq_id: string,
  ) {

    super(platform, accessory, uniq_id);

    this.service = this.accessory.getService(this.uuid) || this.accessory.addService(this.platform.Service.Fan,
      accessory.context.device[this.uniq_id].name, this.uuid);

    if (!this.service.displayName) {
      this.service.setCharacteristic(this.platform.Characteristic.Name, accessory.context.device[this.uniq_id].name);
    }

    if (this.service.getCharacteristic(this.platform.Characteristic.On).listenerCount('set') < 1) {
      this.characteristic = this.service.getCharacteristic(this.platform.Characteristic.On)
        .on('set', this.setOn.bind(this));
      this.enableStatus();
    }

    // Does the Fan include a RotationSpeed characteristic

    if (accessory.context.device[this.uniq_id].bri_cmd_t) {
      (this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed) ||
        this.service.addCharacteristic(this.platform.Characteristic.RotationSpeed))
        .on('set', this.setRotationSpeed.bind(this));
    } else if (accessory.context.device[this.uniq_id].spds) {
      (this.service.getCharacteristic(this.platform.Characteristic.RotationSpeed) ||
        this.service.addCharacteristic(this.platform.Characteristic.RotationSpeed))
        .on('set', this.setRotationSpeedFixed.bind(this));
      //        .setProps({     // This causes an issue with validateUserInput in Characteristic and 33.3333 becomes 0
      //          minStep: 33.33333333333333,
      //        });
    }

  }
Example #8
Source File: currentTemperatureCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 6 votes vote down vote up
constructor(
    platform: HomebridgeLgThinqPlatform,
    service: Service,
    deviceId: string,
  ) {
    super(
      platform,
      service,
      deviceId,
      platform.Characteristic.CurrentTemperature,
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore This won't be used for a read-only characteristic
      '',
      'airState.tempState.current',
    )
  }
Example #9
Source File: accessory.ts    From homebridge-vieramatic with Apache License 2.0 6 votes vote down vote up
async updateTVstatus(nextState: CharacteristicValue): Promise<void> {
    const tvService = this.accessory.getService(this.Service.Television)
    const speakerService = this.accessory.getService(this.Service.TelevisionSpeaker)
    const customSpeakerService = this.accessory.getService(this.Service.Fan)

    if (!tvService || !speakerService) return

    speakerService.updateCharacteristic(this.Characteristic.Active, nextState)
    tvService.updateCharacteristic(this.Characteristic.Active, nextState)

    if (nextState === true) {
      const [cmd, volume] = [await this.device.getMute(), await this.getVolume()]
      const muted = Ok(cmd) ? cmd.value : true

      speakerService
        .updateCharacteristic(this.Characteristic.Mute, muted)
        .updateCharacteristic(this.Characteristic.Volume, volume)

      if (customSpeakerService)
        customSpeakerService
          .updateCharacteristic(this.Characteristic.On, !muted)
          .updateCharacteristic(this.Characteristic.RotationSpeed, volume)
    } else if (customSpeakerService)
      customSpeakerService.updateCharacteristic(this.Characteristic.On, nextState)
  }
Example #10
Source File: targetHeaterCoolerStateCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 6 votes vote down vote up
constructor(
    platform: HomebridgeLgThinqPlatform,
    service: Service,
    deviceId: string,
    deviceSupportsHeat = false,
  ) {
    super(
      platform,
      service,
      deviceId,
      platform.Characteristic.TargetHeaterCoolerState,
      'Set',
      'airState.opMode',
    )
    this.deviceSupportsHeat = deviceSupportsHeat

    if (this.deviceSupportsHeat) {
      this.logError(
        'Warning: Your model may support a "drying" or "dehumidification" mode. ' +
          'This is NOT natively supported by Homekit, and using it may show errors in Homebridge or cause temporary instability.',
      )
    }
  }
Example #11
Source File: platform.ts    From homebridge-vieramatic with Apache License 2.0 6 votes vote down vote up
constructor(
    readonly log: Logger,
    private readonly config: PlatformConfig,
    private readonly api: API
  ) {
    this.storage = new Storage(api)
    this.Characteristic = this.api.hap.Characteristic
    this.Service = this.api.hap.Service

    this.log.debug('Finished initializing platform:', this.config.platform)

    this.api.on('didFinishLaunching', async () => {
      log.debug('Executed didFinishLaunching callback')
      await this.discoverDevices()
    })
  }
Example #12
Source File: swingModeCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 6 votes vote down vote up
constructor(
    platform: HomebridgeLgThinqPlatform,
    service: Service,
    deviceId: string,
  ) {
    super(
      platform,
      service,
      deviceId,
      platform.Characteristic.SwingMode,
      'Set',
      'airState.wDir.vStep',
    )
  }
Example #13
Source File: TasmotaService.ts    From homebridge-tasmota with Apache License 2.0 6 votes vote down vote up
constructor(
    public readonly platform: tasmotaPlatform,
    public readonly accessory: PlatformAccessory,
    protected readonly uniq_id: string,
  ) {
    /* eslint-disable */
    this.CustomCharacteristic = require('./lib/CustomCharacteristics')(platform.Service, platform.Characteristic);
    this.uuid = this.platform.api.hap.uuid.generate(this.accessory.context.device[this.uniq_id].uniq_id);
    this.device_class = accessory.context.device[this.uniq_id].dev_cla;

    this.nunjucksEnvironment = new nunjucks.Environment();

    // Home Assistant device template filters

    this.nunjucksEnvironment.addFilter('is_defined', function(val, cb) {
      // console.log('is_defined', val, cb);
      if (val || val === 0) {
        cb(null, val);
      } else {
        cb(new Error('missing key'), val);
      }
    }, true);

    this.nunjucksEnvironment.addGlobal('float', float);

    nunjucks.installJinjaCompat();
    nunjucks.configure({
      autoescape: true,
    });

  }
Example #14
Source File: filterLifeCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 6 votes vote down vote up
constructor(
    platform: HomebridgeLgThinqPlatform,
    service: Service,
    deviceId: string,
  ) {
    super(
      platform,
      service,
      deviceId,
      platform.Characteristic.FilterLifeLevel,
      'Operation',
      // @ts-expect-error This characteristic is a hack
      '_fake_filter_life',
    )
  }
Example #15
Source File: platform.ts    From homebridge-samsungtv-control2 with MIT License 5 votes vote down vote up
constructor(
    public readonly log: Logger,
    public readonly config: PlatformConfig,
    public readonly api: API,
  ) {
    this.log = log
    this.config = config
    this.api = api

    this.Service = api.hap.Service
    this.Characteristic = api.hap.Characteristic

    this.log.debug(`Got config`, this.config)

    // Add devices
    api.on(APIEvent.DID_FINISH_LAUNCHING, async () => {
      const dir = path.join(api.user.storagePath(), `.${PLUGIN_NAME}`)
      this.log.debug(`Using node-persist path:`, dir)
      await storage.init({
        dir,
        logging: (...args) => this.log.debug(`${PLATFORM_NAME} db -`, ...args),
      })

      let devices = await this.discoverDevices()
      devices = await this.applyConfig(devices)
      this.devices = await this.checkDevicePairing(devices)

      // Register all TV's
      for (const device of this.devices) {
        // Log all devices so that the user knows how to configure them
        this.log.info(
          chalk`Found device {blue ${device.name}} (${device.modelName}), usn: {green ${device.usn}}`,
        )
        this.log.debug(
          `${device.name} - (ip: ${device.lastKnownIp}, mac: ${device.mac})`,
        )
        // Register it
        this.registerTV(device.usn)
      }

      // Regularly discover upnp devices and update ip's, locations for registered devices
      setInterval(async () => {
        const devices = await this.discoverDevices()
        this.devices = await this.applyConfig(devices)
        /**
         * @todo
         * add previously not registered devices
         */
      }, 1000 * 60 * 5 /* 5min */)

      /**
       * @TODO
       * Add subscriptions to update getters
       */
    })
  }
Example #16
Source File: platform.ts    From homebridge-lg-thinq-ac with Apache License 2.0 5 votes vote down vote up
public readonly Characteristic: typeof Characteristic =
    this.api.hap.Characteristic
Example #17
Source File: accessory.ts    From homebridge-vieramatic with Apache License 2.0 5 votes vote down vote up
private configureInputSource(type: InputType, configuredName: string, identifier: number): void {
    const fn = (element: HdmiInput): boolean => element.id === identifier.toString()

    const visibility = (): string => {
      let idx: number
      let hidden: number
      const { inputs } = this.storage.data

      switch (type) {
        case 'HDMI':
          idx = inputs.hdmi.findIndex((x: HdmiInput) => fn(x))
          // by default all hdmiInputs will be visible
          hidden = inputs.hdmi[idx].hidden ?? 0
          break
        case 'APPLICATION':
          idx = identifier - 1000
          // by default all apps will be hidden
          hidden = inputs.applications[idx].hidden ?? 1
          break
        // case 'TUNER':
        default:
          // by default TUNER is visible
          hidden = inputs.TUNER.hidden ?? 0
      }
      return hidden.toFixed(0)
    }

    const source = this.accessory.addService(
      this.Service.InputSource,
      configuredName.toLowerCase().replace(/\s/gu, ''),
      identifier
    )
    const visibilityState = (state: CharacteristicValue): void => {
      let idx: number
      const id = source.getCharacteristic(this.Characteristic.Identifier).value ?? 500
      const { inputs } = this.storage.data

      switch (true) {
        case id < 100:
          // hdmi input
          idx = inputs.hdmi.findIndex((x: HdmiInput) => fn(x))
          inputs.hdmi[idx].hidden = state as InputVisibility
          break
        case id > 999:
          // APP
          idx = (id as number) - 1000
          inputs.applications[idx].hidden = state as InputVisibility
          break
        // case id === 500:
        default:
          inputs.TUNER.hidden = state as InputVisibility
          break
      }
      source.updateCharacteristic(this.Characteristic.CurrentVisibilityState, state)
    }
    const hidden = visibility()

    source
      .setCharacteristic(
        this.Characteristic.InputSourceType,
        this.Characteristic.InputSourceType[type]
      )
      .setCharacteristic(this.Characteristic.CurrentVisibilityState, hidden)
      .setCharacteristic(this.Characteristic.TargetVisibilityState, hidden)
      .setCharacteristic(this.Characteristic.Identifier, identifier)
      .setCharacteristic(this.Characteristic.ConfiguredName, configuredName)
      .setCharacteristic(
        this.Characteristic.IsConfigured,
        this.Characteristic.IsConfigured.CONFIGURED
      )
    source.getCharacteristic(this.Characteristic.TargetVisibilityState).onSet(visibilityState)

    const svc = this.accessory.getService(this.Service.Television)
    if (svc) svc.addLinkedService(source)
  }
Example #18
Source File: platform.d.ts    From homebridge-tuya-ir with Apache License 2.0 5 votes vote down vote up
readonly Characteristic: typeof Characteristic;
Example #19
Source File: platform.ts    From homebridge-eufy-security with Apache License 2.0 5 votes vote down vote up
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic;
Example #20
Source File: platform.ts    From homebridge-screenlogic with MIT License 5 votes vote down vote up
private updateAccessories(status?: PoolStatus, _err?: Error) {
    if (status) {
      this.airTempAccessory?.updateCurrentTemperature(
        this.normalizeTemperature(status.airTemperature),
      )
      this.airTempAccessory?.updateStatusActive(true)

      this.poolTempAccessory?.updateCurrentTemperature(
        this.normalizeTemperature(status.poolTemperature),
      )
      this.poolTempAccessory?.updateStatusActive(status.isPoolActive)

      this.spaTempAccessory?.updateCurrentTemperature(
        this.normalizeTemperature(status.spaTemperature),
      )
      this.spaTempAccessory?.updateStatusActive(status.isSpaActive)

      if (this.poolThermostatAccessory) {
        this.poolThermostatAccessory.updateCurrentTemperature(
          this.normalizeTemperature(status.poolTemperature),
        )
        this.poolThermostatAccessory.updateTargetTemperature(
          this.normalizeTemperature(status.poolSetPoint),
        )
        this.poolThermostatAccessory.updateCurrentHeatingCoolingState(
          status.isPoolHeating
            ? this.Characteristic.CurrentHeatingCoolingState.HEAT
            : this.Characteristic.CurrentHeatingCoolingState.OFF,
        )

        this.poolThermostatAccessory.updateTargetHeatingCoolingState(
          this.mapHeatModeToTargetHeatingCoolingState(status.poolHeatMode),
        )
      }

      if (this.spaThermostatAccessory) {
        this.spaThermostatAccessory.updateCurrentTemperature(
          this.normalizeTemperature(status.spaTemperature),
        )
        this.spaThermostatAccessory.updateTargetTemperature(
          this.normalizeTemperature(status.spaSetPoint),
        )
        this.spaThermostatAccessory.updateCurrentHeatingCoolingState(
          status.isSpaHeating
            ? this.Characteristic.CurrentHeatingCoolingState.HEAT
            : this.Characteristic.CurrentHeatingCoolingState.OFF,
        )

        this.spaThermostatAccessory.updateTargetHeatingCoolingState(
          this.mapHeatModeToTargetHeatingCoolingState(status.spaHeatMode),
        )
      }

      for (const circuitAccessory of this.circuitAccessories) {
        circuitAccessory.updateOn(
          status.circuitState.get(circuitAccessory.context.id) ? true : false,
        )
      }
    }
  }
Example #21
Source File: swingModeCharacteristic.ts    From homebridge-lg-thinq-ac with Apache License 2.0 5 votes vote down vote up
export default class SwingModeCharacteristic extends AbstractCharacteristic<
  State,
  ApiValue,
  typeof Characteristic.SwingMode
> {
  private reportedWarningOnce = false

  constructor(
    platform: HomebridgeLgThinqPlatform,
    service: Service,
    deviceId: string,
  ) {
    super(
      platform,
      service,
      deviceId,
      platform.Characteristic.SwingMode,
      'Set',
      'airState.wDir.vStep',
    )
  }

  getStateFromApiValue(apiValue: ApiValue): State {
    if (apiValue > 0 && apiValue < 10) {
      if (!this.reportedWarningOnce) {
        this.logError(
          'Warning: Your A/C unit supports variable swing settings, but this is not supported by Homekit. Ignoring desired swing setting.',
        )
        this.reportedWarningOnce = true
      }
      return this.characteristic.SWING_ENABLED
    }

    switch (apiValue) {
      case 0:
        return this.characteristic.SWING_DISABLED
      case 100:
        return this.characteristic.SWING_ENABLED
      default:
        throw new Error('Unsupported API value: ' + JSON.stringify(apiValue))
    }
  }

  getApiValueFromState(state: State): ApiValue {
    switch (state) {
      case this.characteristic.SWING_DISABLED:
        return 0
      case this.characteristic.SWING_ENABLED:
        return 100
      default:
        throw new Error('Unsupported state: ' + JSON.stringify(state))
    }
  }
}
Example #22
Source File: platform.ts    From homebridge-tapo-p100 with Apache License 2.0 5 votes vote down vote up
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic;
Example #23
Source File: accessory.ts    From homebridge-vieramatic with Apache License 2.0 5 votes vote down vote up
async setVolumeSelector(key: CharacteristicValue): Promise<void> {
    this.log.debug('setVolumeSelector', key)
    const action = key === this.Characteristic.VolumeSelector.INCREMENT ? 'VOLUP' : 'VOLDOWN'
    const cmd = await this.device.sendKey(action)
    if (Abnormal(cmd)) this.log.error('(setVolumeSelector) unable to change volume', cmd.error)
  }
Example #24
Source File: TasmotaService.ts    From homebridge-tasmota with Apache License 2.0 5 votes vote down vote up
statusUpdate(topic, message) {
    debug('statusUpdate', this.service.displayName, topic, message.toString());

    this.accessory.context.timeout = this.platform.autoCleanup(this.accessory);

    try {
      let value = this.parseValue(this.accessory.context.device[this.uniq_id].val_tpl, message.toString());

      // Sensor value tweaks or adjustments needed for homekit

      switch (this.device_class) {
        case 'temperature':
          if (this.accessory.context.device[this.uniq_id].unit_of_meas.toUpperCase() === 'F') {
            value = Math.round((value - 32) * 5 / 9 * 10) / 10;
          }
          break;
        case 'illuminance':
          // normalize LX in the range homebridge expects
          value = (value < 0.0001 ? 0.0001 : (value > 100000 ? 100000 : value));
          break;
        case 'co2':
          if (value > 1200) {
            this.service.setCharacteristic(this.platform.Characteristic.CarbonDioxideDetected, this.platform.Characteristic.CarbonDioxideDetected.CO2_LEVELS_ABNORMAL);
          } else {
            this.service.setCharacteristic(this.platform.Characteristic.CarbonDioxideDetected, this.platform.Characteristic.CarbonDioxideDetected.CO2_LEVELS_NORMAL);
          }
          break;
      }

      if (value instanceof Error) {
        // Error has already been handled
      } else {
        if (this.characteristic.value != value && this.delta(this.characteristic.value, value)) {
          this.platform.log.info('Updating \'%s:%s\' to %s', this.service.displayName, this.characteristic.displayName ?? '', value);
        } else {
          this.platform.log.debug('Updating \'%s:%s\' to %s', this.service.displayName, this.characteristic.displayName ?? '', value);
        }
      }

      this.characteristic.updateValue(value);

    } catch (err) {
      this.platform.log.error('ERROR: Message Parse Error', topic, message.toString())
    }
  }
Example #25
Source File: platform.ts    From homebridge-tapo-p100 with Apache License 2.0 5 votes vote down vote up
public customCharacteristics: {
    [key: string]: WithUUID<new () => Characteristic>;
  };
Example #26
Source File: platform.d.ts    From homebridge-plugin-govee with Apache License 2.0 5 votes vote down vote up
readonly Characteristic: typeof Characteristic;
Example #27
Source File: platform.ts    From homebridge-plugin-eufy-security with Apache License 2.0 5 votes vote down vote up
async setupPushClient() {
    const storagePath = this.api.user.storagePath();
    const credentialsPath = `${storagePath}/eufy-security-credentials.json`;

    let credentials: PushCredentials;
    if (fs.existsSync(credentialsPath)) {
      this.log.info('credentials found. reusing them...');
      credentials = JSON.parse(fs.readFileSync(credentialsPath).toString());
    } else {
      // Register push credentials
      this.log.info('no credentials found. register new...');
      const pushService = new PushRegisterService();
      credentials = await pushService.createPushCredentials();
      fs.writeFileSync(credentialsPath, JSON.stringify(credentials));
      this.log.info('wait a short time (5sec)...');
      await new Promise((r) => setTimeout(r, 5000));
    }

    // Start push client
    const pushClient = await PushClient.init({
      androidId: credentials.checkinResponse.androidId,
      securityToken: credentials.checkinResponse.securityToken,
    });

    const fcmToken = credentials.gcmResponse.token;
    await new Promise((resolve) => {
      const tHandle = setTimeout(() => {
        this.log.error('registering a push token timed out');
        resolve(true);
      }, 20000);

      this.httpService
        .registerPushToken(fcmToken)
        .catch((err) => {
          clearTimeout(tHandle);
          this.log.error('failed to register push token', err);
          resolve(true);
        })
        .then(() => {
          clearTimeout(tHandle);
          this.log.debug('registered at eufy with:', fcmToken);
          resolve(true);
        });
      
    });

    setInterval(async () => {
      try {
        await this.httpService.pushTokenCheck();
      } catch (err) {
        this.log.warn('failed to confirm push token');
      }
    }, 30 * 1000);

    pushClient.connect((msg) => {
      this.log.debug('push message:', msg);
      const matchingUuid = this.api.hap.uuid.generate(msg.payload?.device_sn);
      const knownAccessory = this.accessories.find(
        (accessory) => accessory.UUID === matchingUuid,
      );
      const event_type = msg.payload?.payload?.event_type;

      if (knownAccessory) {
        if (event_type === MessageTypes.MOTION_DETECTION || event_type === MessageTypes.FACE_DETECTION) {
          // TODO: Implement motion sensor
        } else if (event_type === MessageTypes.PRESS_DOORBELL) {
          knownAccessory
            .getService(this.api.hap.Service.Doorbell)!
            .updateCharacteristic(
              this.api.hap.Characteristic.ProgrammableSwitchEvent,
              this.api.hap.Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS,
            );
        }
      }
    });
  }
Example #28
Source File: platform.ts    From homebridge-zigbee-nt with Apache License 2.0 5 votes vote down vote up
public readonly Characteristic: typeof Characteristic = this.api.hap.Characteristic;
Example #29
Source File: wiz.ts    From homebridge-wiz-lan with Apache License 2.0 5 votes vote down vote up
public readonly Characteristic: typeof Characteristic = this.api.hap
    .Characteristic;