Skip to content

Commit

Permalink
Basic ON/OFF support for restoreIot devices (#106)
Browse files Browse the repository at this point in the history
Co-authored-by: Dusty Greif <[email protected]>
  • Loading branch information
bpro and dgreif authored Feb 4, 2024
1 parent b9dd9b9 commit 08e398a
Show file tree
Hide file tree
Showing 5 changed files with 157 additions and 4 deletions.
3 changes: 3 additions & 0 deletions packages/homebridge-hatch-baby-rest/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { RestPlus } from './rest-plus'
import { RestIot } from './rest-iot'
import { RestMini } from './rest-mini'
import { Restore } from './restore'
import { RestoreIot } from './restore-iot'
import { BehaviorSubject } from 'rxjs'
import { IotDevice } from './iot-device'
import { debounceTime } from 'rxjs/operators'
Expand All @@ -24,6 +25,7 @@ const knownProducts = [
Product.riotPlus,
Product.restMini,
Product.restore,
Product.restoreIot,
],
productFetchQueryString = knownProducts
.map((product) => 'iotProducts=' + product)
Expand Down Expand Up @@ -180,6 +182,7 @@ export class HatchBabyApi {
restIotPluses: createDevices(Product.riotPlus, RestIot),
restMinis: createDevices(Product.restMini, RestMini),
restores: createDevices(Product.restore, Restore),
restoreIots: createDevices(Product.restoreIot, RestoreIot),
}
}
}
9 changes: 6 additions & 3 deletions packages/homebridge-hatch-baby-rest/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
import { RestoreAccessory } from './restore-accessory'
import { RestIot } from './rest-iot'
import { Restore } from './restore'
import { RestoreIot } from './restore-iot'

export const pluginName = 'homebridge-hatch-baby-rest'
export const platformName = 'HatchBabyRest'
Expand Down Expand Up @@ -65,7 +66,7 @@ export class HatchBabyRestPlatform implements DynamicPlatformPlugin {
this.config.email && this.config.password
? new HatchBabyApi(this.config)
: undefined,
{ restPluses, restMinis, restores, restIots, restIotPluses } =
{ restPluses, restMinis, restores, restoreIots, restIots, restIotPluses } =
hatchBabyApi
? await hatchBabyApi.getDevices()
: {
Expand All @@ -74,6 +75,7 @@ export class HatchBabyRestPlatform implements DynamicPlatformPlugin {
restores: [],
restIots: [],
restIotPluses: [],
restoreIots: [],
},
{ api } = this,
cachedAccessoryIds = Object.keys(this.homebridgeAccessories),
Expand All @@ -86,10 +88,11 @@ export class HatchBabyRestPlatform implements DynamicPlatformPlugin {
...restIots,
...restIotPluses,
...restores,
...restoreIots,
]

this.log.info(
`Configuring ${restPluses.length} Rest+, ${restMinis.length} Rest Mini, ${restIots.length} Rest 2nd Gen, ${restIotPluses.length} Rest+ 2nd Gen, and ${restores.length} Restore`,
`Configuring ${restPluses.length} Rest+, ${restMinis.length} Rest Mini, ${restIots.length} Rest 2nd Gen, ${restIotPluses.length} Rest+ 2nd Gen, ${restores.length} Restore, and ${restoreIots.length} Restore 2nd Gen`,
)

devices.forEach((device) => {
Expand All @@ -111,7 +114,7 @@ export class HatchBabyRestPlatform implements DynamicPlatformPlugin {
homebridgeAccessory =
this.homebridgeAccessories[uuid] || createHomebridgeAccessory()

if (device instanceof Restore || device instanceof RestIot) {
if (device instanceof Restore || device instanceof RestIot || device instanceof RestoreIot) {
new RestoreAccessory(device, homebridgeAccessory)
} else if ('onBrightness' in device) {
new LightAndSoundMachineAccessory(device, homebridgeAccessory)
Expand Down
3 changes: 2 additions & 1 deletion packages/homebridge-hatch-baby-rest/restore-accessory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { PlatformAccessory } from 'homebridge'
import { BaseAccessory } from '../shared/base-accessory'
import { RestIot } from './rest-iot'
import { Restore } from './restore'
import { RestoreIot } from './restore-iot'
import { logInfo } from '../shared/util'

export class RestoreAccessory extends BaseAccessory {
constructor(restore: Restore | RestIot, accessory: PlatformAccessory) {
constructor(restore: Restore | RestIot | RestoreIot, accessory: PlatformAccessory) {
super(restore, accessory)

const { Service, Characteristic } = hap,
Expand Down
66 changes: 66 additions & 0 deletions packages/homebridge-hatch-baby-rest/restore-iot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import {
IotDeviceInfo,
RestoreIotState,
RestIotFavorite,
} from '../shared/hatch-sleep-types'
import { distinctUntilChanged, map } from 'rxjs/operators'
import { BaseDevice } from '../shared/base-accessory'
import { IotDevice } from './iot-device'
import { BehaviorSubject } from 'rxjs'
import { thingShadow as AwsIotDevice } from 'aws-iot-device-sdk'
import { apiPath, RestClient } from './rest-client'

export class RestoreIot extends IotDevice<RestoreIotState> implements BaseDevice {
readonly model = 'RestoreIot'

constructor(
public readonly info: IotDeviceInfo,
public readonly onIotClient: BehaviorSubject<AwsIotDevice>,
public readonly restClient: RestClient
) {
super(info, onIotClient)
}

onSomeContentPlaying = this.onState.pipe(
map((state) => state.current.playing !== 'none'),
distinctUntilChanged()
)

onFirmwareVersion = this.onState.pipe(map((state) => state.deviceInfo.f))

private setCurrent(
playing: RestoreIotState['current']['playing'],
step: number,
srId: number
) {
this.update({
current: {
playing,
step,
srId,
},
})
}

async turnOnRoutine() {
const routines = await this.fetchRoutines()
this.setCurrent('routine', 1, routines[0].id)
}

turnOff() {
this.setCurrent('none', 0, 0)
}

async fetchRoutines() {
const routinePath = apiPath(
`service/app/routine/v2/fetch?macAddress=${encodeURIComponent(
this.info.macAddress
)}&types=routine`
),
routines = await this.restClient.request<RestIotFavorite[]>({
url: routinePath,
method: 'GET',
})
return routines.sort((a, b) => a.displayOrder - b.displayOrder)
}
}
80 changes: 80 additions & 0 deletions packages/shared/hatch-sleep-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -492,3 +492,83 @@ export interface RestMiniState {
connected: boolean
rssi: number
}

export interface RestoreIotState {
env: 'prod' | string
alarmsDisabled: boolean
nightlightOn: boolean
nightlightIntensity: number
toddlerLockOn: boolean
snoozeDuration: number
current: {
srId: number
playing: 'none' | 'remote' | 'routine' | string
step: number
color: {
i: number
id: number
r: number
g: number
b: number
w: number
duration: number
until: 'indefinite'
}
sound: IotSound
}
dataVersion: string
sleepScene: {
srId: number
enabled: boolean
}
timer: { s: string; d: number }
timezone: string
rF: {
v: string
i: boolean
u: string
}
deviceInfo: { f: string; fR: number; hwVersion: string }
clock: {
i: number
turnOffAt: string
turnOnAt: string
flags: number
turnOffMode: 'never' | string
turnDimAt: string
turnBrightAt: string
}
toddlerLock: {
turnOffAt: string
turnOnAt: string
turnOnMode: 'never' | string
}
lucky: number
LDR: 'OK' | string
LWTP: boolean
debug: number
logging: number
owned: boolean
lastReset: 'PowerOn' | string
ota: { status: string; downloadProgress: number; installProgress: number }
REX: { lock: number; key: number; command: 'none' | string }
connected: boolean
rssi: number
streaming: { status: 'none' | string }
knockThreshold: number
knockDuration: number
activeTap: boolean
knockAxis: number
snooze: {
active: boolean
startTime: string
}
hwDebugFlags: number
touch: {
flags: number
poll_rate_hz: number
refire_delay_ms: number
refire_rate_hz: number
step_size: number
}
}

0 comments on commit 08e398a

Please sign in to comment.