Files
Evergreen-Health-Mobile/src/devices/climate/capabilities.ts
T
2026-10-09 16:46:35 +08:00

34 lines
2.7 KiB
TypeScript

import type { HomeAssistantDiscoveredDevice } from '../../services/health'
import { numberValue } from '../parameterState'
export const climateModeLabels: Record<string, string> = {
off: '关闭', cool: '制冷', heat: '制热', fan_only: '送风', dry: '除湿', auto: '自动', heat_cool: '冷暖自动',
}
export function climateCapabilities(device: HomeAssistantDiscoveredDevice) {
const entity = device.entities.find(item => item.entityId === device.primaryControlEntityId && item.domain === 'climate')
const attributes = entity?.attributes ?? {}
const reportedUnit = attributes.temperature_unit ?? attributes.unit_of_measurement
const temperatureUnit = ['°C', '℃'].includes(String(reportedUnit)) ? '℃'
: ['°F', '℉'].includes(String(reportedUnit)) ? '℉' : undefined
const modes = Array.isArray(attributes.hvac_modes)
? attributes.hvac_modes.filter((value): value is string => typeof value === 'string' && Object.prototype.hasOwnProperty.call(climateModeLabels, value)) : []
const fans = Array.isArray(attributes.fan_modes)
? attributes.fan_modes.filter((value): value is string => typeof value === 'string' && Boolean(value.trim())) : []
const features = numberValue(attributes.supported_features)
const supports = (flag: number) => features !== undefined && Number.isInteger(features) && features >= 0 && (features & flag) === flag
const available = device.moduleKey === 'climate' && device.online && entity?.available === true && modes.includes(entity.state)
const min = numberValue(attributes.min_temp), max = numberValue(attributes.max_temp), step = numberValue(attributes.target_temp_step)
const range = min !== undefined && max !== undefined && max > min && step !== undefined && step > 0 && step <= max - min
? { min, max, step } : undefined
const temperature = numberValue(attributes.temperature)
const targetTemperature = temperatureUnit && temperature !== undefined && range && temperature >= range.min && temperature <= range.max ? temperature : undefined
const currentTemperature = temperatureUnit ? numberValue(attributes.current_temperature) : undefined
const fanMode = typeof attributes.fan_mode === 'string' && fans.includes(attributes.fan_mode) ? attributes.fan_mode : undefined
const canToggle = Boolean(available && (entity?.state === 'off'
? supports(256) && modes.some(mode => mode !== 'off') : supports(128) && modes.includes('off')))
return { entity, modes: [...new Set(modes)], fans: [...new Set(fans)], supports, available, range,
targetTemperature, currentTemperature, temperatureUnit, fanMode, canToggle,
canSetTemperature: Boolean(available && temperatureUnit === '℃' && supports(1) && range && targetTemperature !== undefined),
canSetFan: Boolean(available && supports(8) && fans.length > 0) }
}