Skip to content

Commit 4149118

Browse files
committed
add lightSensor typing and endpoints
1 parent a27180e commit 4149118

File tree

8 files changed

+100
-4
lines changed

8 files changed

+100
-4
lines changed

CHANGELOG.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
## [Unreleased](https://github.com/lpgera/dirigera/compare/v1.1.0...HEAD)
44

5-
-
5+
- Add support for VALLHORN's light sensor functionality by introducing the `client.lightSensors` API and the
6+
`LightSensor` type, including the `illuminance` attribute.
67

78
## [1.1.0](https://github.com/lpgera/dirigera/compare/v1.0.0...v1.1.0) - 2024-10-02
89

README.md

+15-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ contributions are welcome!
2020
- [Controllers](#controllers)
2121
- [Environment sensors](#environment-sensors)
2222
- [Lights](#lights)
23+
- [Light sensors](#light-sensors)
2324
- [Motion sensors](#motion-sensors)
2425
- [Outlets](#outlets)
2526
- [Open/close sensors](#openclose-sensors)
@@ -283,9 +284,21 @@ await client.lights.setStartupOnOff({
283284
})
284285
```
285286

286-
#### [Motion sensors](./src/api/motionSensors.ts)
287+
#### [Light sensors](./src/api/lightSensors.ts)
287288

288-
Not tested, feedback required.
289+
The VALLHORN motion sensor has a light sensor built-in.
290+
291+
```typescript
292+
const lightSensors = await client.lightSensors.list()
293+
294+
const lightSensor = await client.lightSensors.get({
295+
id: 'YOUR_DEVICE_ID',
296+
})
297+
298+
const { illuminance } = lightSensor.attributes
299+
```
300+
301+
#### [Motion sensors](./src/api/motionSensors.ts)
289302

290303
```typescript
291304
const motionSensors = await client.motionSensors.list()

src/api/lightSensors.ts

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type { Got } from 'got' with { 'resolution-mode': 'require' }
2+
import type { Device } from '../types/device/Device'
3+
import type { LightSensor } from '../types/device/LightSensor'
4+
5+
export default (got: Got) => {
6+
return {
7+
async list() {
8+
const devices = await got.get(`devices`).json<Device[]>()
9+
return devices.filter(
10+
(d): d is LightSensor => d.deviceType === 'lightSensor'
11+
)
12+
},
13+
14+
async get({ id }: { id: string }) {
15+
const device = await got.get(`devices/${id}`).json<Device>()
16+
if (device.deviceType !== 'lightSensor') {
17+
throw new Error('The requested device is not a lightSensor')
18+
}
19+
return device as LightSensor
20+
},
21+
}
22+
}

src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import blinds from './api/blinds'
1818
import airPurifiers from './api/airPurifiers'
1919
import repeaters from './api/repeaters'
2020
import motionSensors from './api/motionSensors'
21+
import lightSensors from './api/lightSensors'
2122
import environmentSensors from './api/environmentSensors'
2223
import openCloseSensors from './api/openCloseSensors'
2324
import deviceSets from './api/deviceSets'
@@ -37,6 +38,7 @@ export type { EnvironmentSensor } from './types/device/EnvironmentSensor'
3738
export type { Home } from './types/Home'
3839
export type { Hub } from './types/device/Hub'
3940
export type { Light } from './types/device/Light'
41+
export type { LightSensor } from './types/device/LightSensor'
4042
export type { MotionSensor } from './types/device/MotionSensor'
4143
export type { Music } from './types/Music'
4244
export type { OpenCloseSensor } from './types/device/OpenCloseSensor'
@@ -182,6 +184,7 @@ export async function createDirigeraClient({
182184
airPurifiers: airPurifiers(gotInstance),
183185
repeaters: repeaters(gotInstance),
184186
motionSensors: motionSensors(gotInstance),
187+
lightSensors: lightSensors(gotInstance),
185188
environmentSensors: environmentSensors(gotInstance),
186189
openCloseSensors: openCloseSensors(gotInstance),
187190
deviceSets: deviceSets(gotInstance),

src/types/device/Device.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import type { Controller } from './Controller'
77
import type { EnvironmentSensorAttributes } from './EnvironmentSensor'
88
import type { HubAttributes } from './Hub'
99
import type { LightAttributes } from './Light'
10+
import type { LightSensorAttributes } from './LightSensor'
1011
import type { MotionSensorAttributes } from './MotionSensor'
1112
import type { OpenCloseSensorAttributes } from './OpenCloseSensor'
1213
import type { OutletAttributes } from './Outlet'
@@ -61,10 +62,11 @@ export interface Device {
6162
| 'controller'
6263
| 'gateway'
6364
| 'light'
64-
| 'sensor'
6565
| 'outlet'
6666
| 'repeater'
67+
| 'sensor'
6768
| 'speaker'
69+
| 'unknown'
6870
deviceType:
6971
| 'airPurifier'
7072
| 'blinds'
@@ -75,6 +77,7 @@ export interface Device {
7577
| 'blindsController'
7678
| 'gateway'
7779
| 'light'
80+
| 'lightSensor'
7881
| 'motionSensor'
7982
| 'openCloseSensor'
8083
| 'outlet'
@@ -93,6 +96,7 @@ export interface Device {
9396
Partial<EnvironmentSensorAttributes> &
9497
Partial<HubAttributes> &
9598
Partial<LightAttributes> &
99+
Partial<LightSensorAttributes> &
96100
Partial<MotionSensorAttributes> &
97101
Partial<OpenCloseSensorAttributes> &
98102
Partial<OutletAttributes> &

src/types/device/LightSensor.ts

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import type {
2+
CommonDeviceAttributes,
3+
Device,
4+
IdentifiableDeviceAttributes,
5+
JoinableDeviceAttributes,
6+
} from './Device'
7+
8+
export interface LightSensorAttributes
9+
extends CommonDeviceAttributes,
10+
JoinableDeviceAttributes,
11+
Partial<IdentifiableDeviceAttributes> {
12+
illuminance: number
13+
}
14+
15+
export interface LightSensor extends Device {
16+
type: 'unknown'
17+
deviceType: 'lightSensor'
18+
attributes: LightSensorAttributes
19+
isHidden: boolean
20+
}

test/responses/home.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
} from './controller'
1010
import { environmentSensor } from './environmentSensor'
1111
import { colorTemperatureLight, dimmableLight, rgbLight } from './light'
12+
import { lightSensor } from './lightSensor'
1213
import { motionSensor1, motionSensor2 } from './motionSensor'
1314
import { outlet1, outlet2 } from './outlet'
1415
import { repeater } from './repeater'
@@ -31,6 +32,7 @@ const home: Home = {
3132
rgbLight,
3233
colorTemperatureLight,
3334
dimmableLight,
35+
lightSensor,
3436
motionSensor1,
3537
motionSensor2,
3638
outlet1,

test/responses/lightSensor.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { LightSensor } from '../../src/types/device/LightSensor'
2+
3+
export const lightSensor: LightSensor = {
4+
id: '00000000-0000-0000-0000-000000000000',
5+
relationId: '00000000-0000-0000-0000-000000000000',
6+
type: 'unknown',
7+
deviceType: 'lightSensor',
8+
createdAt: '2000-01-01T00:00:00.000Z',
9+
isReachable: true,
10+
lastSeen: '2000-01-01T00:00:00.000Z',
11+
attributes: {
12+
customName: '',
13+
firmwareVersion: '1.0.64',
14+
hardwareVersion: '1',
15+
manufacturer: 'IKEA of Sweden',
16+
model: 'VALLHORN Wireless Motion Sensor',
17+
productCode: 'E2134',
18+
serialNumber: '00000000-0000-0000-0000-000000000000',
19+
illuminance: 1,
20+
identifyPeriod: 0,
21+
identifyStarted: '2000-01-01T00:00:00.000Z',
22+
permittingJoin: false,
23+
},
24+
capabilities: {
25+
canSend: [],
26+
canReceive: ['customName'],
27+
},
28+
deviceSet: [],
29+
remoteLinks: [],
30+
isHidden: false,
31+
}

0 commit comments

Comments
 (0)