Skip to content

Commit

Permalink
Merge pull request #138 from NordicSemiconductor/feat/add-support-for…
Browse files Browse the repository at this point in the history
…-battery-slots

Feat/add support for battery slots
  • Loading branch information
kylebonnici authored Feb 14, 2024
2 parents 92cef3e + 0915884 commit c24129f
Show file tree
Hide file tree
Showing 19 changed files with 206 additions and 97 deletions.
2 changes: 2 additions & 0 deletions src/appReducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { NrfConnectState } from '@nordicsemiconductor/pc-nrfconnect-shared';
import { combineReducers } from 'redux';

import confirmBeforeCloseReducer from './features/confirmBeforeClose/confirmBeforeCloseSlice';
import downloadBatteryModelSlice from './features/pmicControl/downloadBatteryModelSlice';
import pmicControlReducer from './features/pmicControl/pmicControlSlice';
import profilingProjectsReducer from './features/pmicControl/profilingProjectsSlice.';
import profilingReducer from './features/pmicControl/profilingSlice';
Expand All @@ -24,6 +25,7 @@ const appReducer = combineReducers({
profiling: profilingReducer,
pmicControl: pmicControlReducer,
serial: serialReducer,
downloadBatteryModel: downloadBatteryModelSlice,
});

export default appReducer;
42 changes: 13 additions & 29 deletions src/components/FuelGauge/FuelGaugeSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
} from '@nordicsemiconductor/pc-nrfconnect-shared';

import { getProfileBuffer } from '../../actions/fileActions';
import { showDialog } from '../../features/pmicControl/downloadBatteryModelSlice';
import { DocumentationTooltip } from '../../features/pmicControl/npm/documentation/documentation';
import {
dialogHandler,
Expand All @@ -29,7 +30,6 @@ import {
getStoredBatterModels,
} from '../../features/pmicControl/pmicControlSlice';
import { setProfilingStage } from '../../features/pmicControl/profilingSlice';
import { writeBatterModel } from '../Profiling/helpers';

export default ({ disabled }: { disabled: boolean }) => {
const dispatch = useDispatch();
Expand All @@ -54,35 +54,23 @@ export default ({ disabled }: { disabled: boolean }) => {

const batteryModelItems: DropdownItem[] = useMemo(() => {
const items = [...hardcodedBatterModels];
if (activeBatteryModel) {
if (
hardcodedBatterModels.filter(
v => v && v.name !== activeBatteryModel.name
).length > 0
)
items.push(activeBatteryModel);
}

storedBatterModels?.forEach(storedBatterModel => {
if (storedBatterModel) items.push(storedBatterModel);
});

const keys = new Set(items.map(item => item.name));
return Array.from(keys).map(key => ({
label: `${key} (${
getClosest(
items.find(batterModel => batterModel.name === key),
latestAdcSample?.tBat ?? 24
)?.capacity ?? ''
return items.map(batterModel => ({
label: `${
batterModel?.slotIndex != null
? `#${batterModel?.slotIndex} `
: ''
}${batterModel.name} (${
getClosest(batterModel, latestAdcSample?.tBat ?? 24)
?.capacity ?? ''
} mAh)`,
value: key,
value: batterModel.name,
}));
}, [
activeBatteryModel,
hardcodedBatterModels,
latestAdcSample?.tBat,
storedBatterModels,
]);
}, [hardcodedBatterModels, latestAdcSample?.tBat, storedBatterModels]);

const selectedActiveItemBatteryMode = useMemo(
() =>
Expand Down Expand Up @@ -112,7 +100,7 @@ export default ({ disabled }: { disabled: boolean }) => {
npmDevice?.setActiveBatteryModel(item.value);
}}
selectedItem={selectedActiveItemBatteryMode}
disabled={disabled}
disabled={disabled || batteryModelItems.length === 0}
/>
<DocumentationTooltip
placement="right-start"
Expand All @@ -125,11 +113,7 @@ export default ({ disabled }: { disabled: boolean }) => {
onClick={() => {
getProfileBuffer()
.then(buffer => {
if (npmDevice) {
dispatch(
writeBatterModel(buffer, npmDevice)
);
}
dispatch(showDialog(buffer));
})
.catch(res => {
dispatch(
Expand Down
96 changes: 96 additions & 0 deletions src/components/FuelGauge/SlotSelectionDownloadDialog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*
* Copyright (c) 2015 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
*/

import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import {
DialogButton,
Dropdown,
DropdownItem,
GenericDialog,
} from '@nordicsemiconductor/pc-nrfconnect-shared';

import {
closeDialog,
getBuffer,
getShowDialog,
} from '../../features/pmicControl/downloadBatteryModelSlice';
import {
getNpmDevice,
getStoredBatterModels,
} from '../../features/pmicControl/pmicControlSlice';

export default () => {
const dispatch = useDispatch();
const npmDevice = useSelector(getNpmDevice);
const storedBatterModels = useSelector(getStoredBatterModels);
const [slot, setSlot] = useState(0);
const buffer = useSelector(getBuffer);
const showDialog = useSelector(getShowDialog);

const items: DropdownItem<number>[] = [];

for (
let i = 0;
i < (npmDevice?.getNumberOfBatteryModelSlots() ?? 0);
i += 1
) {
const module = storedBatterModels?.find(m => m.slotIndex === i);

items.push({
value: i,
label: `Slot ${i}: ${module?.name ?? 'Empty'}`,
});
}

console.log(items);

return showDialog ? (
<GenericDialog
title="Write battery model"
footer={
<>
<DialogButton
onClick={() => {
dispatch(closeDialog());
if (npmDevice && buffer) {
npmDevice.downloadFuelGaugeProfile(
buffer,
slot
);
}
}}
variant="primary"
>
Write
</DialogButton>
<DialogButton
onClick={() => {
dispatch(closeDialog());
}}
variant="secondary"
>
Cancel
</DialogButton>
</>
}
isVisible
>
<div>
{`Writing battery profile will reset the current fuel gauge and
overwrite the model in the slot. Click 'Write' to continue.`}
</div>
<Dropdown
label="Programming slot"
items={items}
onSelect={item => {
setSlot(item.value);
}}
selectedItem={items[slot]}
/>
</GenericDialog>
) : null;
};
4 changes: 3 additions & 1 deletion src/components/Profiling/Dialog/ConfigurationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,9 @@ export default ({ isVisible }: { isVisible: boolean }) => {
setName(event.target.value);
const match =
event.target.value.match(/^[a-zA-Z0-9]+$/);
setValidName(!!match);
setValidName(
!!match && event.target.value !== 'default'
);
}}
value={name}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import { useDispatch, useSelector } from 'react-redux';
import { showSaveDialog } from '../../../actions/fileActions';
import { stringToFile } from '../../../features/helpers';
import { generateParamsFromCSV } from '../../../features/nrfutillNpm/csvProcessing';
import { showDialog } from '../../../features/pmicControl/downloadBatteryModelSlice';
import { getNpmDevice } from '../../../features/pmicControl/pmicControlSlice';
import { getProjectProfileProgress } from '../../../features/pmicControl/profilingProjectsSlice.';
import useIsUIDisabled from '../../../features/useIsUIDisabled';
import {
isProfileReadyForProcessing,
readAndUpdateProjectSettings,
writeBatterModel,
} from '../helpers';
import { ProfilingProject } from '../types';
import AddEditProfileDialog from './AddEditProfileDialog';
Expand Down Expand Up @@ -123,10 +123,7 @@ export default ({
onClick={() => {
if (profile.batteryJson && npmDevice) {
dispatch(
writeBatterModel(
Buffer.from(profile.batteryJson),
npmDevice
)
showDialog(Buffer.from(profile.batteryJson))
);
}
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@ import {
generateParamsFromCSV,
mergeBatteryParams,
} from '../../../features/nrfutillNpm/csvProcessing';
import { showDialog } from '../../../features/pmicControl/downloadBatteryModelSlice';
import { getNpmDevice } from '../../../features/pmicControl/pmicControlSlice';
import {
getProjectProfileProgress,
removeRecentProject,
} from '../../../features/pmicControl/profilingProjectsSlice.';
import useIsUIDisabled from '../../../features/useIsUIDisabled';
import { isProfileReadyForProcessing, writeBatterModel } from '../helpers';
import { isProfileReadyForProcessing } from '../helpers';
import { ProfilingProject } from '../types';
import AddEditProfileDialog from './AddEditProfileDialog';
import AddEditProjectDialog from './AddEditProjectDialog';
Expand Down Expand Up @@ -181,10 +182,7 @@ export default ({
.then(data => {
if (npmDevice) {
dispatch(
writeBatterModel(
Buffer.from(data.json),
npmDevice
)
showDialog(Buffer.from(data.json))
);
}
setGeneratingBatterModel(false);
Expand Down
25 changes: 1 addition & 24 deletions src/components/Profiling/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,7 @@ import path from 'path';

import packageJsons from '../../../package.json';
import { RootState } from '../../appReducer';
import {
dialogHandler,
DOWNLOAD_BATTERY_PROFILE_DIALOG_ID,
} from '../../features/pmicControl/npm/pmicHelpers';
import { NpmDevice, Profile } from '../../features/pmicControl/npm/types';
import { Profile } from '../../features/pmicControl/npm/types';
import {
addRecentProject,
loadRecentProject,
Expand Down Expand Up @@ -148,22 +144,3 @@ export const saveProjectSettings =

export const reloadRecentProjects = (): AppThunk => dispatch =>
dispatch(setRecentProjects(loadRecentProject()));

export const writeBatterModel =
(data: Buffer, npmDevice: NpmDevice): AppThunk =>
dispatch => {
dispatch(
dialogHandler({
uuid: DOWNLOAD_BATTERY_PROFILE_DIALOG_ID,
message: `Write battery profile will reset the current fuel gauge. Click 'Write' to continue.`,
confirmLabel: 'Write',
confirmClosesDialog: false,
cancelLabel: 'Cancel',
title: 'Write',
onConfirm: () => {
npmDevice.downloadFuelGaugeProfile(Buffer.from(data));
},
onCancel: () => {},
})
);
};
42 changes: 42 additions & 0 deletions src/features/pmicControl/downloadBatteryModelSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2015 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-4-Clause
*/

import { createSlice, PayloadAction } from '@reduxjs/toolkit';

import type { RootState } from '../../appReducer';

interface DownloadProfileSlice {
showDialog: boolean;
bufferToWite?: Buffer;
}

const initialState: DownloadProfileSlice = {
showDialog: false,
};

const downloadBatteryProfileSlice = createSlice({
name: 'downloadBatteryProfile',
initialState,
reducers: {
closeDialog() {
return {
...initialState,
};
},
showDialog(state, action: PayloadAction<Buffer>) {
state.showDialog = true;
state.bufferToWite = action.payload;
},
},
});

export const getShowDialog = (state: RootState) =>
state.app.downloadBatteryModel.bufferToWite;
export const getBuffer = (state: RootState) =>
state.app.downloadBatteryModel.bufferToWite;

export const { closeDialog, showDialog } = downloadBatteryProfileSlice.actions;
export default downloadBatteryProfileSlice.reducer;
4 changes: 3 additions & 1 deletion src/features/pmicControl/npm/basePmicDevice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export const baseNpmDevice: IBaseNpmDevice = (
noOfLdos?: number;
noOfGPIOs?: number;
noOfLEDs?: number;
noOfBatterySlots?: number;
},
supportsVersion: string
) => {
Expand Down Expand Up @@ -284,7 +285,7 @@ export const baseNpmDevice: IBaseNpmDevice = (
},

onStoredBatteryModelUpdate: (
handler: (payload: (BatteryModel | null)[]) => void
handler: (payload: BatteryModel[]) => void
) => {
eventEmitter.on('onStoredBatteryModelUpdate', handler);
return () => {
Expand Down Expand Up @@ -344,6 +345,7 @@ export const baseNpmDevice: IBaseNpmDevice = (
getNumberOfLdos: () => devices.noOfLdos ?? 0,
getNumberOfGPIOs: () => devices.noOfGPIOs ?? 0,
getNumberOfLEDs: () => devices.noOfLEDs ?? 0,
getNumberOfBatteryModelSlots: () => devices.noOfBatterySlots ?? 0,

isSupportedVersion: () =>
new Promise<{ supported: boolean; version: string }>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,17 +87,14 @@ export default (
'Battery models stored in database:'
);
if (models.length < 2) {
eventEmitter.emit(
'onStoredBatteryModelUpdate',
undefined
);
eventEmitter.emit('onStoredBatteryModelUpdate', []);
return;
}
const stringModels = models[1].trim().split('\n');
const list = stringModels.map(parseBatteryModel);
eventEmitter.emit(
'onStoredBatteryModelUpdate',
list.length !== 0 ? list : undefined
list.filter(item => item != null)
);
},
noop
Expand Down
Loading

0 comments on commit c24129f

Please sign in to comment.