Skip to content

Commit

Permalink
feat(battery): use battery_state
Browse files Browse the repository at this point in the history
Breaking: change input of component `power-source`
  • Loading branch information
Rotzbua authored and nurikk committed Nov 21, 2023
1 parent 9cbba57 commit c16faeb
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 48 deletions.
8 changes: 1 addition & 7 deletions src/components/dashboard-page/DeviceFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,7 @@ const DeviceFooter: React.FC<Props> = ({ device, deviceState, lastSeenType }) =>
<span key="linkquality" className="me-1">
<i className="fa fa-signal fa-fw" /> {linkquality} LQI
</span>
{supported && (
<PowerSource
key={'power'}
source={device.power_source}
battery={deviceState.battery as number}
/>
)}
{supported && <PowerSource key={'power'} device={device} deviceState={deviceState} />}
</div>
</div>
</footer>
Expand Down
1 change: 1 addition & 0 deletions src/components/dashboard-page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const genericRendererIgnoredNames = [
'linkquality',
'battery',
'battery_low',
'battery_state',
'illuminance_lux',
'color_temp_startup',
'voltage',
Expand Down
7 changes: 1 addition & 6 deletions src/components/device-page/info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,7 @@ const displayProps = [
translationKey: 'power',
render: (device: Device, deviceStatus: DeviceState) => (
<dd className="col-12 col-md-7">
<PowerSource
showLevel={true}
source={device.power_source}
battery={deviceStatus.battery as number}
batteryLow={deviceStatus.battery_low as boolean}
/>
<PowerSource showLevel={true} device={device} deviceState={deviceStatus} />
</dd>
),
},
Expand Down
93 changes: 65 additions & 28 deletions src/components/power-source/index.tsx
Original file line number Diff line number Diff line change
@@ -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;
}

Expand All @@ -17,47 +16,85 @@ export const powerSourceTypeToTranslationKey = (source: PowerSourceType | undefi
.replace(/[^a-z0-9_]/g, '');
};

const PowerSource: FunctionComponent<PowerSourceProps> = ({ source, battery, batteryLow, showLevel, ...rest }) => {
const PowerSource: FunctionComponent<PowerSourceProps> = ({ 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 (
<span className={`animation-blinking text-danger`} role="alert">
{battery}%
{batteryPercent}%
</span>
);
}
} 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 (
<Fragment>
{showLevel ? (
<span className="pe-2">
{t('battery')} {battery !== undefined ? `${battery}%` : null}
{t('battery')} {batteryFormatted}
</span>
) : null}
<i className={`fa ${batteryClass}`} title={title} {...rest} />
Expand Down
8 changes: 1 addition & 7 deletions src/components/zigbee/DevicesTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,7 @@ export function DevicesTable(
row: {
original: { state, device },
},
}) => (
<PowerSource
source={device.power_source}
battery={state.battery as number}
batteryLow={state.battery_low as boolean}
/>
),
}) => <PowerSource device={device} deviceState={state} />,
},
{
id: 'controls',
Expand Down

0 comments on commit c16faeb

Please sign in to comment.