Skip to content

Commit

Permalink
Merge pull request #33 from OpenDTU-App/multi-device-preparations
Browse files Browse the repository at this point in the history
  • Loading branch information
CommanderRedYT authored Feb 3, 2024
2 parents b14d762 + a2e416e commit f4e7815
Show file tree
Hide file tree
Showing 25 changed files with 306 additions and 93 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"ios": "react-native run-ios",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "tsc --noEmit",
"start": "react-native start",
"test": "jest --passWithNoTests",
"postinstall": "yarn run npm-license-crawler -onlyDirectDependencies -json licenses.json && patch-package",
Expand Down
34 changes: 23 additions & 11 deletions src/api/ApiHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,42 +52,52 @@ export const ApiProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
console.log('new Api');

useEffect(() => {
dispatch(setTriedToConnect({ triedToConnect: false }));
if (configIndex === null) {
console.log('ApiProvider - configIndex is null');

if (currentConfiguration && configIndex !== null) {
return;
}

dispatch(setTriedToConnect({ triedToConnect: false, index: configIndex }));

if (currentConfiguration) {
console.info(
'Initializing API Handler',
currentConfiguration,
configIndex,
);

api.registerOnDisconnectedHandler(() => {
dispatch(clearOpenDtuState());
dispatch(clearOpenDtuState({ index: configIndex }));
});

api.disconnect();

api.setConfig(currentConfiguration, configIndex);

api.registerOnConnectedHandler(index => {
dispatch(setIsConnected({ isConnected: true }));
dispatch(setIsConnected({ isConnected: true, index: configIndex }));
dispatch(setDeviceState({ deviceState: DeviceState.Connected, index }));
});

api.registerOnDisconnectedHandler(() => {
dispatch(setIsConnected({ isConnected: false }));
dispatch(setIsConnected({ isConnected: false, index: configIndex }));
});

api.registerLiveDataHandler((data, valid, index) => {
dispatch(setTriedToConnect({ triedToConnect: true }));
dispatch(setLiveData({ data, valid }));
dispatch(
setTriedToConnect({ triedToConnect: true, index: configIndex }),
);
dispatch(setLiveData({ data, valid, index: configIndex }));
dispatch(setDeviceState({ deviceState: DeviceState.Connected, index }));
});

api.registerHttpStatusHandler(
({ systemStatus, networkStatus, ntpStatus, mqttStatus }, index) => {
if (systemStatus) {
dispatch(setSystemStatus({ data: systemStatus }));
dispatch(
setSystemStatus({ data: systemStatus, index: configIndex }),
);
dispatch(
updateDtuHostname({
hostname: systemStatus.hostname,
Expand All @@ -103,15 +113,17 @@ export const ApiProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
}

if (networkStatus) {
dispatch(setNetworkStatus({ data: networkStatus }));
dispatch(
setNetworkStatus({ data: networkStatus, index: configIndex }),
);
}

if (ntpStatus) {
dispatch(setNtpStatus({ data: ntpStatus }));
dispatch(setNtpStatus({ data: ntpStatus, index: configIndex }));
}

if (mqttStatus) {
dispatch(setMqttStatus({ data: mqttStatus }));
dispatch(setMqttStatus({ data: mqttStatus, index: configIndex }));
}

setDeviceState({ deviceState: DeviceState.Connected, index });
Expand Down
44 changes: 33 additions & 11 deletions src/api/opendtuapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class OpenDtuApi {
this.baseUrl = baseUrl;
}

public setUserString(userString: string): void {
public setUserString(userString: string | null): void {
this.userString = userString;
}

Expand Down Expand Up @@ -142,7 +142,7 @@ class OpenDtuApi {
this.onDisconnectedHandler = null;
}

private async getSystemStatusFromUrl(
public async getSystemStatusFromUrl(
url: URL,
): Promise<GetSystemStatusReturn> {
// GET <url>/api/system/status
Expand Down Expand Up @@ -288,13 +288,15 @@ class OpenDtuApi {
return;
}

if (this.baseUrl && this.userString) {
if (this.baseUrl) {
const urlObject = new URL(this.baseUrl);
const authString = this.getAuthString();
const protocol = urlObject.protocol === 'https:' ? 'wss' : 'ws';
const host = urlObject.host;

const url = `${protocol}://${authString}${host}/livedata`;
const url = `${protocol}://${authString ?? ''}${host}/livedata`;

console.log(`Connecting websocket to ${url}`);

this.ws = new WebSocket(url);

Expand Down Expand Up @@ -466,9 +468,13 @@ class OpenDtuApi {
);
}

private getAuthString(): string {
private getAuthString(): string | null {
let user = null;

if (!this.userString) {
return null;
}

try {
user = JSON.parse(this.userString || '');
} catch {
Expand All @@ -492,6 +498,10 @@ class OpenDtuApi {
'GET',
);

if (!res) {
return null;
}

if (res.status === 200) {
return await res.json();
}
Expand All @@ -506,6 +516,10 @@ class OpenDtuApi {

const res = await this.makeAuthenticatedRequest('/api/ntp/status', 'GET');

if (!res) {
return null;
}

if (res.status === 200) {
return await res.json();
}
Expand All @@ -520,6 +534,10 @@ class OpenDtuApi {

const res = await this.makeAuthenticatedRequest('/api/mqtt/status', 'GET');

if (!res) {
return null;
}

if (res.status === 200) {
return await res.json();
}
Expand All @@ -531,7 +549,7 @@ class OpenDtuApi {
route: string,
method: string,
body: string | null = null,
): Promise<Response> {
): Promise<Response | null> {
const authString = this.getAuthString();

const controller = new AbortController();
Expand All @@ -546,8 +564,8 @@ class OpenDtuApi {
signal: controller.signal,
headers: {
'X-Requested-With': 'XMLHttpRequest',
Authorization: 'Basic ' + authString,
'Content-Type': 'application/json',
...(authString ? { Authorization: 'Basic ' + authString } : {}),
},
};

Expand All @@ -558,12 +576,16 @@ class OpenDtuApi {
const url = `${authString}${this.baseUrl}${route}`;

console.log('makeAuthenticatedRequest', url, requestOptions);
const res = await fetch(url, requestOptions);
if (res.status === 200) {

try {
const res = await fetch(url, requestOptions);
clearTimeout(abortTimeout);
}

return res;
return res;
} catch (error) {
console.log('makeAuthenticatedRequest error', error);
return null;
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/components/OpenDTUValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { Text, useTheme } from 'react-native-paper';
import type { ValueObject } from '@/types/opendtu/status';

export interface OpenDTUValueProps {
statusValue?: ValueObject;
statusValue?: ValueObject | null;
textWhenInvalid?: string;
textProps?: Omit<TextProps<unknown>, 'children'>;
}
Expand Down
3 changes: 2 additions & 1 deletion src/database/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,8 @@ const DatabaseProvider: FC<PropsWithChildren<unknown>> = ({ children }) => {
const inverters = useAppSelector(
state =>
state.settings.selectedDtuConfig !== null
? state.opendtu.liveData?.inverters ?? null
? state.opendtu.dtuStates[state.settings.selectedDtuConfig]?.liveData
?.inverters ?? null
: null,
(left, right) =>
left === null && right === null
Expand Down
7 changes: 6 additions & 1 deletion src/github/FetchHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import {
setReleases,
} from '@/slices/github';

import useDeviceIndex from '@/hooks/useDeviceIndex';

import ago from '@/utils/ago';

import {
Expand All @@ -20,8 +22,11 @@ import { useAppDispatch, useAppSelector } from '@/store';

const FetchHandler: FC = () => {
const dispatch = useAppDispatch();
const index = useDeviceIndex();

const isConnected = useAppSelector(state => state.opendtu.isConnected);
const isConnected = useAppSelector(state =>
index === null ? undefined : state.opendtu.dtuStates[index]?.isConnected,
);
const latestReleaseRefetchOk = useAppSelector(state =>
state.github.latestRelease.lastUpdate
? ago(state.github.latestRelease.lastUpdate) > 1000 * 60 * 10 // 10 minutes
Expand Down
7 changes: 7 additions & 0 deletions src/hooks/useDeviceIndex.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { useAppSelector } from '@/store';

const useDeviceIndex = (): number | null => {
return useAppSelector(state => state.settings.selectedDtuConfig);
};

export default useDeviceIndex;
22 changes: 22 additions & 0 deletions src/hooks/useDtuState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import type { EqualityFn } from 'react-redux';

import type { OpenDTUDeviceState } from '@/types/opendtu/state';

import useDeviceIndex from '@/hooks/useDeviceIndex';

import { useAppSelector } from '@/store';

const useDtuState = <T>(
selector: (state: OpenDTUDeviceState | undefined) => T,
equalityFn?: EqualityFn<T | undefined>,
): T | undefined => {
const index = useDeviceIndex();

return useAppSelector(
state =>
index === null ? undefined : selector(state.opendtu.dtuStates[index]),
equalityFn,
);
};

export default useDtuState;
11 changes: 9 additions & 2 deletions src/hooks/useHasLiveData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,20 @@ const useHasLiveData = (): boolean => {
);*/

return useAppSelector(state => {
const liveData = state.opendtu.liveData;
const index = state.settings.selectedDtuConfig;

if (index === null) {
console.log('index is null');
return false;
}

const liveData = state.opendtu.dtuStates[index]?.liveData ?? null;
if (liveData === null) {
console.log('liveData is null');
return false;
}

const lastUpdate = liveData.lastUpdate;
const lastUpdate = liveData?.lastUpdate ?? null;
if (lastUpdate === null) {
console.log('lastUpdate is null');
return false;
Expand Down
10 changes: 9 additions & 1 deletion src/hooks/useIsConnected.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import useDeviceIndex from '@/hooks/useDeviceIndex';

import { useAppSelector } from '@/store';

const useIsConnected = (): boolean => {
return useAppSelector(state => state.opendtu.isConnected);
const index = useDeviceIndex();

return useAppSelector(state =>
index === null
? false
: state.opendtu.dtuStates[index]?.isConnected ?? false,
);
};

export default useIsConnected;
15 changes: 12 additions & 3 deletions src/hooks/useLivedata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,18 @@ import { useAppSelector } from '@/store';

const useLivedata = <T>(
selector: (state: LiveData | null) => T,
equalityFn?: EqualityFn<T>,
): T => {
return useAppSelector(state => selector(state.opendtu.liveData), equalityFn);
equalityFn?: EqualityFn<T | null>,
): T | null => {
const currentIndex = useAppSelector(
state => state.settings.selectedDtuConfig,
);
return useAppSelector(
state =>
currentIndex
? selector(state.opendtu.dtuStates[currentIndex]?.liveData ?? null)
: null,
equalityFn,
);
};

export default useLivedata;
10 changes: 9 additions & 1 deletion src/hooks/useTriedToConnect.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import useDeviceIndex from '@/hooks/useDeviceIndex';

import { useAppSelector } from '@/store';

const useTriedToConnect = (): boolean => {
return useAppSelector(state => state.opendtu.triedToConnect);
const index = useDeviceIndex();

return useAppSelector(state =>
index === null
? false
: state.opendtu.dtuStates[index]?.triedToConnect ?? false,
);
};

export default useTriedToConnect;
Loading

0 comments on commit f4e7815

Please sign in to comment.