Files
banban/banban-mini/src/services/device.ts
2026-05-09 16:50:42 +08:00

206 lines
5.6 KiB
TypeScript

import { request } from './api'
import { loadCurrentChildBindingContext } from './binding'
export interface DeviceStatus {
device_id: string
child_id?: number | null
child_name?: string | null
sleep_mode?: number | null
disable_time_start?: string | null
disable_time_end?: string | null
timezone?: string | null
power?: number | null
volume?: number | null
signal?: number | null
version?: string | null
settings_updated_at?: string | null
coord_type?: string | null
lat?: number | null
lng?: number | null
accuracy_m?: number | null
altitude_m?: number | null
speed_mps?: number | null
heading_deg?: number | null
source?: number | null
battery_pct?: number | null
device_time?: string | null
server_time?: string | null
location_updated_at?: string | null
}
export interface DeviceAlarmItem {
alarm_id: number
device_id: string
child_id?: number | null
child_name?: string | null
source_msg_id: string
created_at: string
}
export interface DeviceAlarmListResponse {
items: DeviceAlarmItem[]
total: number
}
export interface DeviceVolumeUpdateResponse {
device_id: string
level: number
msg_id: string
}
export interface DeviceSleepScheduleUpdateResponse {
device_id: string
sleep_mode: number
start?: string | null
end?: string | null
timezone: string
msg_id?: string | null
}
export interface DeviceRemoteSleepWakeResponse {
device_id: string
switch: 'on' | 'off'
msg_id: string
}
export interface DeviceFirmwareStatus {
device_id: string
current_version?: string | null
latest_version?: string | null
update_available: boolean
can_update: boolean
update_status: string
progress: number
target_version?: string | null
updated_at?: string | null
}
export interface DeviceFirmwareUpdateResponse extends DeviceFirmwareStatus {
msg_id: string
}
function normalizeTimeValue(value?: string | null): string | null {
if (value === null || value === undefined) return null
const trimmed = String(value).trim()
if (!trimmed) return null
const matched = trimmed.match(/^(\d{1,2}):(\d{2})(?::\d{2})?:?$/)
if (!matched) return trimmed.replace(/:+$/, '')
const hour = matched[1].padStart(2, '0')
return `${hour}:${matched[2]}`
}
function normalizeDeviceStatus(status: DeviceStatus): DeviceStatus {
return {
...status,
disable_time_start: normalizeTimeValue(status.disable_time_start),
disable_time_end: normalizeTimeValue(status.disable_time_end),
}
}
async function resolveDeviceId(deviceId?: string): Promise<string> {
const normalizedDeviceId = String(deviceId || '').trim()
if (normalizedDeviceId) return normalizedDeviceId
const context = await loadCurrentChildBindingContext()
return context.currentBinding?.device_id || ''
}
export async function getDeviceStatus(deviceId?: string): Promise<DeviceStatus | null> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) return null
try {
const result = await request<DeviceStatus>(`/banban/devices/${resolvedDeviceId}/status`)
return normalizeDeviceStatus(result)
} catch (error: any) {
if (error?.status === 404) return null
throw error
}
}
export async function setDeviceVolume(level: number, deviceId?: string): Promise<DeviceVolumeUpdateResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {
throw new Error('当前没有可用设备')
}
return request<DeviceVolumeUpdateResponse>(`/banban/devices/${resolvedDeviceId}/volume`, {
method: 'POST',
data: { level },
})
}
export async function setDeviceSleepSchedule(
start: string,
end: string,
timezone = 'Asia/Shanghai',
deviceId?: string
): Promise<DeviceSleepScheduleUpdateResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {
throw new Error('当前没有可用设备')
}
const result = await request<DeviceSleepScheduleUpdateResponse>(`/banban/devices/${resolvedDeviceId}/sleep-schedule`, {
method: 'POST',
data: { start, end, timezone },
})
return {
...result,
start: normalizeTimeValue(result.start),
end: normalizeTimeValue(result.end),
}
}
export async function setDeviceRemoteSleepWake(
switchValue: 'on' | 'off',
deviceId?: string
): Promise<DeviceRemoteSleepWakeResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {
throw new Error('当前没有可用设备')
}
return request<DeviceRemoteSleepWakeResponse>(`/banban/devices/${resolvedDeviceId}/sleep-wake`, {
method: 'POST',
data: { switch: switchValue },
})
}
export async function getDeviceFirmwareStatus(deviceId?: string): Promise<DeviceFirmwareStatus | null> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) return null
try {
return await request<DeviceFirmwareStatus>(`/banban/devices/${resolvedDeviceId}/firmware`)
} catch (error: any) {
if (error?.status === 404) return null
throw error
}
}
export async function startDeviceFirmwareUpdate(deviceId?: string): Promise<DeviceFirmwareUpdateResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {
throw new Error('当前没有可用设备')
}
return request<DeviceFirmwareUpdateResponse>(`/banban/devices/${resolvedDeviceId}/firmware/update`, {
method: 'POST',
})
}
export async function getDeviceAlarms(
deviceId?: string,
limit = 20
): Promise<DeviceAlarmListResponse> {
const resolvedDeviceId = await resolveDeviceId(deviceId)
if (!resolvedDeviceId) {
return { items: [], total: 0 }
}
return request<DeviceAlarmListResponse>(`/banban/devices/${resolvedDeviceId}/alarms?limit=${limit}`)
}