diff --git a/src/components/dashboard-page/DeviceFooter.tsx b/src/components/dashboard-page/DeviceFooter.tsx index cf8521b68..4d6ecd4da 100644 --- a/src/components/dashboard-page/DeviceFooter.tsx +++ b/src/components/dashboard-page/DeviceFooter.tsx @@ -24,13 +24,7 @@ const DeviceFooter: React.FC = ({ device, deviceState, lastSeenType }) => {linkquality} LQI - {supported && ( - - )} + {supported && } diff --git a/src/components/dashboard-page/index.tsx b/src/components/dashboard-page/index.tsx index 27dbcfb7d..8e785f9ca 100644 --- a/src/components/dashboard-page/index.tsx +++ b/src/components/dashboard-page/index.tsx @@ -26,6 +26,7 @@ const genericRendererIgnoredNames = [ 'linkquality', 'battery', 'battery_low', + 'battery_state', 'illuminance_lux', 'color_temp_startup', 'voltage', diff --git a/src/components/device-page/info.tsx b/src/components/device-page/info.tsx index 2c39004f8..b61ceaa35 100644 --- a/src/components/device-page/info.tsx +++ b/src/components/device-page/info.tsx @@ -161,12 +161,7 @@ const displayProps = [ translationKey: 'power', render: (device: Device, deviceStatus: DeviceState) => (
- +
), }, diff --git a/src/components/power-source/index.tsx b/src/components/power-source/index.tsx index 145d92582..1ea5f0e03 100644 --- a/src/components/power-source/index.tsx +++ b/src/components/power-source/index.tsx @@ -1,12 +1,11 @@ import React, { Fragment, FunctionComponent } from 'react'; -import { PowerSource as PowerSourceType } from '../../types'; -import style from './style.module.css'; import { useTranslation } from 'react-i18next'; +import { Device, DeviceState, PowerSource as PowerSourceType } from '../../types'; +import style from './style.module.css'; interface PowerSourceProps { - source?: PowerSourceType; - battery?: number; - batteryLow?: boolean; + device?: Device; + deviceState?: DeviceState; showLevel?: boolean; } @@ -17,47 +16,85 @@ export const powerSourceTypeToTranslationKey = (source: PowerSourceType | undefi .replace(/[^a-z0-9_]/g, ''); }; -const PowerSource: FunctionComponent = ({ source, battery, batteryLow, showLevel, ...rest }) => { +const PowerSource: FunctionComponent = ({ device, deviceState, showLevel, ...rest }) => { const { t } = useTranslation('zigbee'); - let batteryClass = ''; + let source: string | undefined = undefined; + + if (device !== undefined) { + source = device.power_source; + } switch (source) { case 'Battery': let title = t(powerSourceTypeToTranslationKey(source)); - if (batteryLow !== undefined) { - batteryClass = batteryLow - ? `fa-battery-empty animation-blinking text-danger` - : 'fa-battery-full text-success'; - title += batteryLow ? ' LOW' : ' OK'; + let batteryFormatted = ''; + let batteryClass = 'fa-question'; + let batteryPercent: number | undefined = undefined; + let batteryState: string | undefined = undefined; + let batteryLow: boolean | undefined = undefined; + + if (deviceState !== undefined) { + if (deviceState?.battery !== undefined) { + batteryPercent = deviceState.battery as number; + } + if (deviceState?.battery_state !== undefined) { + batteryState = deviceState.battery_state as string; + } + if (deviceState?.battery_low !== undefined) { + batteryLow = deviceState.battery_low as boolean; + } } - if (battery !== undefined) { - if (battery >= 85) { - batteryClass += ' fa-battery-full'; - } else if (battery >= 75) { - batteryClass += ' fa-battery-three-quarters'; - } else if (battery >= 50) { - batteryClass += ' fa-battery-half'; - } else if (battery >= 25) { - batteryClass += ' fa-battery-quarter'; - } else if (battery >= 10) { - batteryClass += ` fa-battery-empty animation-blinking`; + + // Some devices do not use the standardized feature `battery` to report power level. + if (batteryPercent !== undefined) { + batteryFormatted = batteryPercent + '%'; + if (batteryPercent >= 85) { + batteryClass = 'fa-battery-full'; + } else if (batteryPercent >= 65) { + batteryClass = 'fa-battery-three-quarters'; + } else if (batteryPercent >= 40) { + batteryClass = 'fa-battery-half'; + } else if (batteryPercent >= 20) { + batteryClass = 'fa-battery-quarter'; + } else if (batteryPercent >= 10) { + batteryClass = `fa-battery-empty animation-blinking`; } else { return ( - {battery}% + {batteryPercent}% ); } + } else if (batteryState !== undefined) { + batteryFormatted = batteryState; + switch (batteryState) { + case 'high': + batteryClass = 'fa-battery-full'; + break; + case 'medium': + batteryClass = 'fa-battery-half'; + break; + case 'low': + batteryClass = 'fa-battery-empty animation-blinking'; + break; + } + } else if (batteryLow !== undefined) { + batteryFormatted = batteryLow ? 'LOW' : 'OK'; + batteryClass = batteryLow ? 'fa-battery-empty' : 'fa-battery-full'; + } + // If battery warning triggered: add blink independent of power_level source. + if (batteryLow === true) { + batteryClass += ' animation-blinking text-danger'; } - title += `${battery ? `, ` + t(`power_level`) + ` ${battery}%` : ''}`; - if (!batteryClass) { - batteryClass = 'fa-question'; + + if (batteryFormatted !== '') { + title += `, ` + t(`power_level`) + `: ${batteryFormatted}`; } return ( {showLevel ? ( - {t('battery')} {battery !== undefined ? `${battery}%` : null} + {t('battery')} {batteryFormatted} ) : null} diff --git a/src/components/zigbee/DevicesTable.tsx b/src/components/zigbee/DevicesTable.tsx index 5e72a6283..4864f38ee 100644 --- a/src/components/zigbee/DevicesTable.tsx +++ b/src/components/zigbee/DevicesTable.tsx @@ -161,13 +161,7 @@ export function DevicesTable( row: { original: { state, device }, }, - }) => ( - - ), + }) => , }, { id: 'controls',