Skip to content

Commit

Permalink
feat(device): add xiaomi aqara magic cube
Browse files Browse the repository at this point in the history
  • Loading branch information
Neonox31 committed Jul 29, 2018
1 parent 8bc3365 commit 4b4bd13
Show file tree
Hide file tree
Showing 3 changed files with 454 additions and 1 deletion.
6 changes: 5 additions & 1 deletion src/device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { ZiGate } from './zigate'
import debug from './debug'
import { ZGXiaomiAqaraDoorSensorDevice } from './devices/xiaomi/aqara-door-sensor'
import { ZGXiaomiAqaraWeatherSensorDevice } from './devices/xiaomi/aqara-weather-sensor'
import { ZGXiaomiAqaraMagicCubeDevice } from './devices/xiaomi/aqara-magic-cube'

export interface ZGDevice {}

export enum ZGDeviceType {
XiaomiAqaraButton,
XiaomiAqaraDoorSensor,
XiaomiAqaraWeatherSensor
XiaomiAqaraWeatherSensor,
XiaomiAqaraMagicCube
}

export function createZGDevice(
Expand All @@ -25,6 +27,8 @@ export function createZGDevice(
return new ZGXiaomiAqaraDoorSensorDevice(zigate, shortAddress)
case ZGDeviceType.XiaomiAqaraWeatherSensor:
return new ZGXiaomiAqaraWeatherSensorDevice(zigate, shortAddress)
case ZGDeviceType.XiaomiAqaraMagicCube:
return new ZGXiaomiAqaraMagicCubeDevice(zigate, shortAddress)
default:
throw new Error(`Unsupported device type : ${deviceType}`)
}
Expand Down
144 changes: 144 additions & 0 deletions src/devices/xiaomi/aqara-magic-cube.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { Observable } from 'rxjs'
import { filter, map, tap } from 'rxjs/operators'
import { ZGDevice } from '../../device'
import { ZiGate } from '../../zigate'
import { asAttributeReportMessage, ZGMessageCode } from '../../message'
import { AttributeType, ZGAttributeReportMessage } from '../../messages/attribute-report'
import debug from '../../debug'
import { asCommonBatteryPayload, BatteryType } from './utils/battery'
import { CommonAxis, CommonBatteryPayload, CommonRemotePayload } from '../../common'

const shakeMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x2 &&
msg.getPayload().clusterId === 0x0012 &&
msg.getPayload().attributeId === 0x0055 &&
msg.getPayload().attributeType === AttributeType.UInt16 &&
msg.getPayload().attributeData === 0x0000
)
}

const slideMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x2 &&
msg.getPayload().clusterId === 0x0012 &&
msg.getPayload().attributeId === 0x0055 &&
msg.getPayload().attributeType === AttributeType.UInt16 &&
msg.getPayload().attributeData === 0x0103
)
}

const horizontalRotationMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x3 &&
msg.getPayload().clusterId === 0x000c &&
msg.getPayload().attributeId === 0xff05 &&
msg.getPayload().attributeType === AttributeType.UInt16
)
}

const verticalRotationMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x2 &&
msg.getPayload().clusterId === 0x0012 &&
msg.getPayload().attributeId === 0x0055 &&
msg.getPayload().attributeType === AttributeType.UInt16
)
}

const tapMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x2 &&
msg.getPayload().clusterId === 0x0012 &&
msg.getPayload().attributeId === 0x0055 &&
msg.getPayload().attributeType === AttributeType.UInt16 &&
msg.getPayload().attributeData === 0x0204
)
}

const batteryMessages = (msg: ZGAttributeReportMessage) => {
return (
msg.getPayload().srcEndpoint === 0x1 &&
msg.getPayload().clusterId === 0x0 &&
msg.getPayload().attributeId === 0xff01 &&
msg.getPayload().attributeSize === 0x002a
)
}

const asCommonRotationRemotePayload = (msg: ZGAttributeReportMessage): CommonRemotePayload => {
const axis = msg.getPayload().clusterId === 0x000c ? CommonAxis.Horizontal : CommonAxis.Vertical

const degrees = msg.getPayload().attributeData as number

return {
rotation: {
axis,
degrees
}
}
}

export class ZGXiaomiAqaraMagicCubeDevice implements ZGDevice {
label = 'xiaomi-aqara-magic-cube'
shortAddress: string

messages$: Observable<ZGAttributeReportMessage>
shake$: Observable<CommonRemotePayload>
slide$: Observable<CommonRemotePayload>
rotate$: Observable<CommonRemotePayload>
tap$: Observable<CommonRemotePayload>
battery$: Observable<CommonBatteryPayload>

constructor(zigate: ZiGate, shortAddress: string) {
this.shortAddress = shortAddress

this.messages$ = zigate.messages$.pipe(
filter(msg => msg.getCode() === ZGMessageCode.AttributeReport),
map(asAttributeReportMessage),
filter(msg => msg.getPayload().srcAddress === this.shortAddress)
)

this.shake$ = this.messages$.pipe(
filter(shakeMessages),
map(_ => ({ shake: true })),
tap((payload: CommonRemotePayload) =>
debug(`device:${this.label}:${this.shortAddress}:remote`)(payload)
)
)

this.slide$ = this.messages$.pipe(
filter(slideMessages),
map(_ => ({ slide: true })),
tap((payload: CommonRemotePayload) =>
debug(`device:${this.label}:${this.shortAddress}:remote`)(payload)
)
)

this.rotate$ = this.messages$.pipe(
filter(
(msg: ZGAttributeReportMessage) =>
horizontalRotationMessages(msg) || verticalRotationMessages(msg)
),
map(asCommonRotationRemotePayload),
tap((payload: CommonRemotePayload) =>
debug(`device:${this.label}:${this.shortAddress}:remote`)(payload)
)
)

this.tap$ = this.messages$.pipe(
filter(tapMessages),
map(_ => ({ tap: true })),
tap((payload: CommonRemotePayload) =>
debug(`device:${this.label}:${this.shortAddress}:remote`)(payload)
)
)

this.battery$ = this.messages$.pipe(
filter(batteryMessages),
map(msg => asCommonBatteryPayload(msg, BatteryType.CR1632)),
tap((payload: CommonBatteryPayload) =>
debug(`device:${this.label}:${this.shortAddress}:battery`)(payload)
)
)
}
}
Loading

0 comments on commit 4b4bd13

Please sign in to comment.