Skip to content

Commit

Permalink
[CP-3012] Connection Issue with Mudita Center After Kompakt Restart (#…
Browse files Browse the repository at this point in the history
…1995)

Co-authored-by: robertmudi <158469469+robertmudi@users.noreply.github.com>
Co-authored-by: Tomasz Malecki <135224481+tomaszmaleckimudita@users.noreply.github.com>
Co-authored-by: Łukasz Kowalczyk <37898730+lkowalczyk87@users.noreply.github.com>
Co-authored-by: Michał Kurczewski <michalkurczewski94@gmail.com>
Co-authored-by: patrycja-paczkowska <88655668+patrycja-paczkowska@users.noreply.github.com>
Co-authored-by: Maciej Kupiec <115480562+MaciejMDDV@users.noreply.github.com>
Co-authored-by: mkurczewski <michal@kurczewski.dev>
Co-authored-by: MateuszMudita <165778944+MateuszMudita@users.noreply.github.com>
  • Loading branch information
9 people committed Aug 20, 2024
1 parent 8f6b475 commit 97204be
Show file tree
Hide file tree
Showing 9 changed files with 106 additions and 46 deletions.
3 changes: 2 additions & 1 deletion libs/core/device/modules/base.adapter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,15 @@ export abstract class BaseAdapter<

public connect(): Promise<ResultObject<undefined>> {
return new Promise((resolve) => {
this.serialPort = new SerialPort(this.path, (error) => {
const serialPort = new SerialPort(this.path, (error) => {
if (error) {
resolve(
Result.failed(
new AppError(DeviceError.Initialization, error.message)
)
)
} else {
this.serialPort = serialPort
resolve(Result.success(undefined))
}
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { setDiscoveryStatus } from "Core/discovery-device/actions/base.action"
import { DiscoveryStatus } from "Core/discovery-device/reducers/discovery-device.interface"
import ConnectingContent from "Core/connecting/components/connecting-content.component"
import {
getDevicesSelector,
getAvailableDevicesSelector,
getDevicesSelector,
getFailedDevicesSelector,
handleDeviceActivated,
} from "device-manager/feature"
import { Dispatch } from "Core/__deprecated__/renderer/store"
import { DeviceType } from "device-protocol/models"
import { getAPIConfig } from "generic-view/store"
import { TmpDispatch } from "Core/__deprecated__/renderer/store"
import {
URL_DEVICE_INITIALIZATION,
URL_DISCOVERY_DEVICE,
Expand All @@ -27,7 +29,7 @@ import { useNoNewDevicesDetectedHook } from "Core/discovery-device/hooks/use-no-

const ConfiguredDevicesDiscovery: FunctionComponent = () => {
const history = useHistory()
const dispatch = useDispatch<Dispatch>()
const dispatch = useDispatch<TmpDispatch>()
const devices = useSelector(getDevicesSelector)
const failedDevices = useSelector(getFailedDevicesSelector)
const availableDevices = useSelector(getAvailableDevicesSelector)
Expand All @@ -45,9 +47,23 @@ const ConfiguredDevicesDiscovery: FunctionComponent = () => {
failedDevices.length === 1 &&
noNewDevicesDetectedState
) {
await dispatch(handleDeviceActivated(devices[0].id))
history.push(URL_ONBOARDING.troubleshooting)
return
if (devices[0].deviceType === DeviceType.APIDevice) {
const getAPIConfigResult = await dispatch(
getAPIConfig({ deviceId: devices[0].id })
)
await dispatch(handleDeviceActivated(devices[0].id))
if (getAPIConfigResult.error !== undefined) {
history.push(URL_ONBOARDING.troubleshooting)
} else {
history.push(URL_DEVICE_INITIALIZATION.root)
}

return
} else {
await dispatch(handleDeviceActivated(devices[0].id))
history.push(URL_ONBOARDING.troubleshooting)
return
}
}

if (
Expand Down Expand Up @@ -88,7 +104,8 @@ const ConfiguredDevicesDiscovery: FunctionComponent = () => {
!isAnyDeviceAttachedOnInitialRender.current &&
noNewDevicesDetectedState
) {
history.push(URL_ONBOARDING.troubleshooting)
dispatch(setDiscoveryStatus(DiscoveryStatus.Idle))
history.push(URL_ONBOARDING.root)
return
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* For licensing, see https://github.com/mudita/mudita-center/blob/master/LICENSE.md
*/

import React, { useEffect } from "react"
import React, { useEffect, useRef } from "react"
import { useDispatch, useSelector } from "react-redux"
import { useHistory } from "react-router-dom"
import { delay } from "shared/utils"
Expand All @@ -24,29 +24,46 @@ const DeviceConnecting: FunctionComponent = () => {
const history = useHistory()
const dispatch = useDispatch<TmpDispatch>()
const activeDevice = useSelector(getActiveDevice)
const firstRun = useRef(true)

useEffect(() => {
if (!firstRun.current) {
return
}

firstRun.current = false

const handleConnectDevice = async () => {
if (activeDevice?.id === undefined) {
history.push(URL_DISCOVERY_DEVICE.root)
return
}

await delay(500)
const { payload: ok } = await dispatch(connectDevice(activeDevice.id))

if (!ok) {
history.push(URL_ONBOARDING.troubleshooting)
return
}

if (activeDevice.deviceType !== DeviceType.APIDevice) {
const { payload: ok } = await dispatch(connectDevice(activeDevice.id))

if (!ok) {
history.push(URL_ONBOARDING.troubleshooting)
return
}

await dispatch(configureDevice(activeDevice.id))

history.push(URL_DEVICE_INITIALIZATION.root)
} else {
await dispatch(getAPIConfig({ deviceId: activeDevice.id }))
}
const getAPIConfigResult = await dispatch(
getAPIConfig({ deviceId: activeDevice.id })
)

if (getAPIConfigResult.error !== undefined) {
history.push(URL_ONBOARDING.troubleshooting)
return
}

history.push(URL_DEVICE_INITIALIZATION.root)
history.push(URL_DEVICE_INITIALIZATION.root)
}
}

void handleConnectDevice()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ import { useDispatch, useSelector } from "react-redux"
import { defineMessages } from "react-intl"
import { useHistory } from "react-router-dom"
import { answerMain } from "shared/utils"
import { setSelectDeviceDrawerOpen } from "device-manager/feature"
import {
getDevicesSelector,
setSelectDeviceDrawerOpen,
} from "device-manager/feature"
import { DeviceProtocolMainEvent } from "device-protocol/models"
import { FunctionComponent } from "Core/core/types/function-component.interface"
import { intl } from "Core/__deprecated__/renderer/utils/intl"
Expand All @@ -25,6 +28,7 @@ import {
CONNECTING_LOADER_MODAL_ID,
useLoaderSkipOnConnect,
} from "Core/modals-manager/components/use-loader-skip-on-connect.hook"
import { DeviceState } from "device-manager/models"

const messages = defineMessages({
subtitle: {
Expand All @@ -34,20 +38,21 @@ const messages = defineMessages({

const ConnectingLoaderModal: FunctionComponent = () => {
const dispatch = useDispatch<Dispatch>()
const [openModal, setOpenModal] = useState<boolean>(false)

const [loaderModalOpened, setLoaderModalOpened] = useState<boolean>(false)
const devices = useSelector(getDevicesSelector)
const history = useHistory()

const discoveryStatus = useSelector(getDiscoveryStatus)
const shouldLoaderSkipOnConnect = useLoaderSkipOnConnect()

const devicesInProgress = devices.filter((device) => {
return [DeviceState.Connected, DeviceState.Initialized].includes(
device.state
)
})

useEffect(() => {
const handler = async () => {
if (shouldLoaderSkipOnConnect()) {
setOpenModal(false)
} else {
setOpenModal(true)
}
const handler = () => {
setLoaderModalOpened(!shouldLoaderSkipOnConnect())
}

const unregisterDeviceConnectedListener = answerMain(
Expand All @@ -68,9 +73,12 @@ const ConnectingLoaderModal: FunctionComponent = () => {
useEffect(() => {
let timeoutId: ReturnType<typeof setTimeout>

if (openModal) {
if (loaderModalOpened) {
timeoutId = setTimeout(() => {
setOpenModal(false)
if (devicesInProgress.length > 0) {
return
}
setLoaderModalOpened(false)
const pathname = history.location.pathname
if (
![
Expand All @@ -88,21 +96,27 @@ const ConnectingLoaderModal: FunctionComponent = () => {
const unregister = history.listen((location) => {
if (location.pathname.includes(URL_DISCOVERY_DEVICE.root)) {
clearTimeout(timeoutId)
setOpenModal(false)
setLoaderModalOpened(false)
}
})

return () => {
clearTimeout(timeoutId)
unregister()
}
}, [openModal, dispatch, discoveryStatus, history])
}, [
devicesInProgress.length,
discoveryStatus,
dispatch,
history,
loaderModalOpened,
])

return (
<LoaderModal
data={{ "modal-id": CONNECTING_LOADER_MODAL_ID }}
subtitle={intl.formatMessage(messages.subtitle)}
open={openModal}
open={loaderModalOpened}
layer={ModalLayers.ConnectingLoader}
/>
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export const deactivateDevice = createAsyncThunk<
void,
{ state: ReduxRootState }
>(DeviceManagerEvent.DeactivateDevice, async (_, { dispatch, getState }) => {
dispatch(setActiveDevice(undefined))
await dispatch(setActiveDevice(undefined))
dispatch(setSelectDeviceDrawerOpen(false))
dispatch(setDiscoveryStatus(DiscoveryStatus.Idle))
dispatch(setDeviceInitializationStatus(DeviceInitializationStatus.Idle))
Expand Down
3 changes: 2 additions & 1 deletion libs/device/adapters/src/lib/serial-port-api-device.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ export class SerialPortDeviceAPIAdapter {

public connect(): Promise<ResultObject<undefined>> {
return new Promise((resolve) => {
this.serialPort = new SerialPort(this.path, (error) => {
const serialPort = new SerialPort(this.path, (error) => {
if (error) {
resolve(
Result.failed(
new AppError(DeviceError.Initialization, error.message)
)
)
} else {
this.serialPort = serialPort
this.mountListeners()
resolve(Result.success(undefined))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class APIConfigService {
method: "GET",
body: {},
options: {
connectionTimeOut: 6000,
connectionTimeOut: 2000,
},
})

Expand Down
28 changes: 19 additions & 9 deletions libs/generic-view/store/src/lib/get-api-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,27 @@ import { ApiConfig } from "device/models"
import { ActionName } from "./action-names"
import { getAllFeatures } from "./features/get-all-features"
import { getMenuConfig } from "./get-menu-config"
import { ResultObject } from "Core/core/builder"

export const getAPIConfig = createAsyncThunk<
{ deviceId: string; apiConfig: ApiConfig },
{ deviceId: DeviceId },
{ deviceId: DeviceId; retry?: boolean },
{ state: ReduxRootState }
>(ActionName.GetConfig, async ({ deviceId }, { rejectWithValue, dispatch }) => {
const response = await getAPIConfigRequest(deviceId)
if (response.ok) {
dispatch(getMenuConfig({ deviceId }))
dispatch(getAllFeatures({ deviceId, features: response.data.features }))
return { deviceId, apiConfig: response.data }
>(
ActionName.GetConfig,
async ({ deviceId, retry }, { rejectWithValue, dispatch }) => {
const retryLimit = 25
let retires = 0
let response: ResultObject<ApiConfig>
do {
response = await getAPIConfigRequest(deviceId)
} while (retry && retires++ < retryLimit && !response.ok)

if (response.ok) {
dispatch(getMenuConfig({ deviceId }))
dispatch(getAllFeatures({ deviceId, features: response.data.features }))
return { deviceId, apiConfig: response.data }
}
return rejectWithValue(response.error)
}
return rejectWithValue(response.error)
})
)
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const useAPISerialPortListeners = () => {
return
}
dispatch(addDevice(properties))
dispatch(getAPIConfig({ deviceId: id }))
dispatch(getAPIConfig({ deviceId: id, retry: true }))
}
)
const unregisterDetachedListener = answerMain(
Expand Down

0 comments on commit 97204be

Please sign in to comment.