Skip to content

Commit b54f438

Browse files
authored
feat: Add NoiseSensorDeviceDetails (#628)
1 parent 36783e0 commit b54f438

File tree

15 files changed

+425
-5
lines changed

15 files changed

+425
-5
lines changed

.storybook/seed-fake.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,42 @@ export const seedFake = (db) => {
468468
errors: [],
469469
})
470470

471+
const device7 = db.addDevice({
472+
workspace_id: ws2.workspace_id,
473+
connected_account_id: ca.connected_account_id,
474+
device_type: 'noiseaware_activity_zone',
475+
created_at: '2023-05-15T15:08:53.000',
476+
name: 'Living Room',
477+
properties: {
478+
online: true,
479+
model: {
480+
manufacturer_display_name: 'NoiseAware',
481+
display_name: 'Indoor Sensor',
482+
},
483+
},
484+
errors: [],
485+
})
486+
487+
db.addNoiseThreshold({
488+
device_id: device7.device_id,
489+
workspace_id: ws2.workspace_id,
490+
created_at: '2023-05-17T00:16:12.000',
491+
noise_threshold_decibels: 70,
492+
starts_daily_at: '22:00:00[America/Los_Angeles]',
493+
ends_daily_at: '06:00:00[America/Los_Angeles]',
494+
name: 'Quiet Hours',
495+
})
496+
497+
db.addNoiseThreshold({
498+
device_id: device7.device_id,
499+
workspace_id: ws2.workspace_id,
500+
created_at: '2023-05-17T00:16:12.000',
501+
noise_threshold_decibels: 75,
502+
starts_daily_at: '06:00:00[America/Los_Angeles]',
503+
ends_daily_at: '22:00:00[America/Los_Angeles]',
504+
name: 'Active Hours',
505+
})
506+
471507
// add climate setting schedules
472508
db.addClimateSettingSchedule({
473509
device_id: device5.device_id,
@@ -532,5 +568,6 @@ export const seedFake = (db) => {
532568
device4,
533569
device5,
534570
device6,
571+
device7,
535572
})
536573
}

assets/icons/noise-levels.svg

Lines changed: 6 additions & 0 deletions
Loading

package-lock.json

Lines changed: 31 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,8 @@
133133
"queue": "^7.0.0",
134134
"react-hook-form": "^7.46.1",
135135
"seamapi": "^8.22.0",
136-
"uuid": "^9.0.0"
136+
"uuid": "^9.0.0",
137+
"zoned-time": "^1.1.2"
137138
},
138139
"devDependencies": {
139140
"@emotion/styled": "^11.10.6",

src/lib/dates.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ export const formatTimeZone = (timeZone: string): string => {
2323
return `${timeZone.replaceAll('_', ' ')} (${offset})`
2424
}
2525

26+
export const formatTime = (time: string): string => {
27+
const dateTime = DateTime.fromISO(time)
28+
return dateTime.isValid ? dateTime.toLocaleString(DateTime.TIME_SIMPLE) : ''
29+
}
30+
2631
export const serializeDateTimePickerValue = (
2732
dateTime: DateTime,
2833
timeZone: string

src/lib/icons/NoiseLevels.tsx

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/seam/components/DeviceDetails/DeviceDetails.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,7 @@ export const DeviceOffline: Story = {
8282
export const ThermostatDevice: Story = {
8383
render: (props) => <DeviceDetails {...props} deviceId='device5' />,
8484
}
85+
86+
export const NoiseSensorDevice: Story = {
87+
render: (props) => <DeviceDetails {...props} deviceId='device7' />,
88+
}

src/lib/seam/components/DeviceDetails/DeviceDetails.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import { isLockDevice, isThermostatDevice } from 'seamapi'
1+
import { isLockDevice, isNoiseSensorDevice, isThermostatDevice } from 'seamapi'
22

33
import {
44
type CommonProps,
55
withRequiredCommonProps,
66
} from 'lib/seam/components/common-props.js'
77
import { LockDeviceDetails } from 'lib/seam/components/DeviceDetails/LockDeviceDetails.js'
8+
import { NoiseSensorDeviceDetails } from 'lib/seam/components/DeviceDetails/NoiseSensorDeviceDetails.js'
89
import { ThermostatDeviceDetails } from 'lib/seam/components/DeviceDetails/ThermostatDeviceDetails.js'
910
import { useDevice } from 'lib/seam/devices/use-device.js'
1011
import { useComponentTelemetry } from 'lib/telemetry/index.js'
@@ -67,5 +68,9 @@ export function DeviceDetails({
6768
return <ThermostatDeviceDetails device={device} {...props} />
6869
}
6970

71+
if (isNoiseSensorDevice(device)) {
72+
return <NoiseSensorDeviceDetails device={device} {...props} />
73+
}
74+
7075
return null
7176
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import type { NoiseSensorDevice } from 'seamapi'
2+
3+
import type { NestedSpecificDeviceDetailsProps } from 'lib/seam/components/DeviceDetails/DeviceDetails.js'
4+
import { DeviceInfo } from 'lib/seam/components/DeviceDetails/DeviceInfo.js'
5+
import { DeviceModel } from 'lib/seam/components/DeviceDetails/DeviceModel.js'
6+
import { DeviceImage } from 'lib/ui/device/DeviceImage.js'
7+
import { OnlineStatus } from 'lib/ui/device/OnlineStatus.js'
8+
import { NoiseThresholdsList } from 'lib/ui/noise-sensor/NoiseThresholdsList.js'
9+
10+
interface NoiseSensorDeviceDetailsProps
11+
extends NestedSpecificDeviceDetailsProps {
12+
device: NoiseSensorDevice
13+
}
14+
15+
export function NoiseSensorDeviceDetails({
16+
device,
17+
disableConnectedAccountInformation,
18+
disableResourceIds,
19+
}: NoiseSensorDeviceDetailsProps): JSX.Element | null {
20+
return (
21+
<div className='seam-device-details'>
22+
<div className='seam-body'>
23+
<div className='seam-summary'>
24+
<div className='seam-content'>
25+
<div className='seam-image'>
26+
<DeviceImage device={device} />
27+
</div>
28+
<div className='seam-info'>
29+
<span className='seam-label'>{t.noiseSensor}</span>
30+
<h4 className='seam-device-name'>{device.properties.name}</h4>
31+
<div className='seam-properties'>
32+
<span className='seam-label'>{t.status}:</span>{' '}
33+
<OnlineStatus device={device} />
34+
<DeviceModel device={device} />
35+
</div>
36+
</div>
37+
</div>
38+
</div>
39+
40+
<NoiseThresholdsList device={device} />
41+
42+
<DeviceInfo
43+
device={device}
44+
disableConnectedAccountInformation={
45+
disableConnectedAccountInformation
46+
}
47+
disableResourceIds={disableResourceIds}
48+
/>
49+
</div>
50+
</div>
51+
)
52+
}
53+
54+
const t = {
55+
noiseSensor: 'Noise Sensor',
56+
status: 'Status',
57+
noiseLevel: 'Noise level',
58+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { useQuery, useQueryClient } from '@tanstack/react-query'
2+
import type {
3+
NoiseThresholds,
4+
NoiseThresholdsListRequest,
5+
NoiseThresholdsListResponse,
6+
SeamError,
7+
} from 'seamapi'
8+
9+
import { useSeamClient } from 'lib/seam/use-seam-client.js'
10+
import type { UseSeamQueryResult } from 'lib/seam/use-seam-query-result.js'
11+
12+
export type UseNoiseThresholdsParams = NoiseThresholdsListRequest
13+
export type UseNoiseThresholdsData = NoiseThresholds[]
14+
15+
export function useNoiseThresholds(
16+
params: UseNoiseThresholdsParams
17+
): UseSeamQueryResult<'noiseThresholds', UseNoiseThresholdsData> {
18+
const { client } = useSeamClient()
19+
const queryClient = useQueryClient()
20+
21+
const { data, ...rest } = useQuery<
22+
NoiseThresholdsListResponse['noise_thresholds'],
23+
SeamError
24+
>({
25+
enabled: client != null,
26+
queryKey: ['noise_thresholds', 'list', params],
27+
queryFn: async () => {
28+
if (client == null) return []
29+
return await client.noiseThresholds.list(params)
30+
},
31+
onSuccess: (noiseThresholds) => {
32+
for (const noiseThreshold of noiseThresholds) {
33+
queryClient.setQueryData(
34+
[
35+
'noise_thresholds',
36+
'get',
37+
{ noise_threshold_id: noiseThreshold.noise_threshold_id },
38+
],
39+
noiseThreshold
40+
)
41+
}
42+
},
43+
})
44+
45+
return { ...rest, noiseThresholds: data }
46+
}

0 commit comments

Comments
 (0)