1
- import React from 'react' ;
1
+ import React , { useState , useEffect , useMemo , useRef , useCallback } from 'react' ;
2
2
import { connect } from 'react-redux' ;
3
3
import { CWaterPumpAPI } from '../api/CWaterPumpAPI.js' ;
4
4
import { updateSystemStatus } from '../store/slices/SystemStatus.js' ;
5
+ import { changeLastOperationDuration , pumpStartedEvent } from '../store/slices/Temp.js' ;
5
6
6
7
const WaterPumpAPIContext = React . createContext ( ) ;
7
8
@@ -11,22 +12,30 @@ export function useWaterPumpAPI() {
11
12
12
13
const FETCH_STATUS_INTERVAL = 5000 ;
13
14
14
- function _publicWrapper ( { apiObject, apiQueue, _pouringTime, _powerLevel } ) {
15
- if ( null == apiObject ) return { API : null } ;
15
+ function _publicWrapper ( {
16
+ apiObject, apiQueue, _pouringTime, _powerLevel, startTimeRef, onPumpStart
17
+ } ) {
18
+ if ( null == apiObject ) return { API : null } ;
16
19
return {
17
20
API : {
18
21
stopPump : ( ) => {
19
22
apiQueue . push ( {
20
- action : async ( ) => await apiObject . stop ( ) ,
23
+ action : async ( ) => {
24
+ startTimeRef . current = null ; // reset the start time
25
+ return await apiObject . stop ( ) ;
26
+ } ,
21
27
failMessage : 'Failed to stop the pump'
22
28
} ) ;
23
29
} ,
24
30
startPump : ( ) => {
25
31
apiQueue . push ( {
26
- action : async ( ) => await apiObject . start (
27
- _pouringTime . current ,
28
- _powerLevel . current
29
- ) ,
32
+ action : async ( ) => {
33
+ if ( startTimeRef . current === null ) {
34
+ startTimeRef . current = Date . now ( ) ;
35
+ await onPumpStart ( ) ;
36
+ }
37
+ return await apiObject . start ( _pouringTime . current , _powerLevel . current ) ;
38
+ } ,
30
39
failMessage : 'Failed to start the pump'
31
40
} ) ;
32
41
} ,
@@ -44,17 +53,17 @@ function _makeStatusAction(apiObject) {
44
53
async function _processQueue ( { apiQueue, lastUpdateTime, statusAction, updateStatus } ) {
45
54
const deltaTime = Date . now ( ) - lastUpdateTime . current ;
46
55
const hasTasks = ( 0 < apiQueue . length ) ;
47
- if ( ( deltaTime < FETCH_STATUS_INTERVAL ) && ! hasTasks ) return ;
48
-
56
+ if ( ( deltaTime < FETCH_STATUS_INTERVAL ) && ! hasTasks ) return ;
57
+
49
58
const action = hasTasks ? apiQueue . shift ( ) : statusAction ;
50
59
const oldTime = lastUpdateTime . current ;
51
60
lastUpdateTime . current = Number . MAX_SAFE_INTEGER ; // prevent concurrent tasks, just in case
52
61
try {
53
62
await updateStatus ( action ) ;
54
63
lastUpdateTime . current = Date . now ( ) ;
55
- } catch ( error ) {
64
+ } catch ( error ) {
56
65
lastUpdateTime . current = oldTime ;
57
- if ( hasTasks ) { // re-queue the action if it failed
66
+ if ( hasTasks ) { // re-queue the action if it failed
58
67
apiQueue . unshift ( action ) ;
59
68
}
60
69
throw error ;
@@ -65,40 +74,47 @@ function WaterPumpAPIProviderComponent({
65
74
children,
66
75
apiHost, pouringTime, powerLevel,
67
76
updateStatus,
77
+ changeLastOperationDuration,
78
+ onPumpStart,
68
79
} ) {
69
- // to prevent the callbacks from changing when the pouringTime or powerLevel changes
70
- const _pouringTime = React . useRef ( pouringTime ) ;
71
- React . useEffect ( ( ) => { _pouringTime . current = pouringTime ; } , [ pouringTime ] ) ;
72
-
73
- const _powerLevel = React . useRef ( powerLevel ) ;
74
- React . useEffect ( ( ) => { _powerLevel . current = powerLevel ; } , [ powerLevel ] ) ;
75
-
76
- const { apiObject, apiQueue } = React . useMemo (
80
+ const _pouringTime = useRef ( pouringTime ) ;
81
+ useEffect ( ( ) => { _pouringTime . current = pouringTime ; } , [ pouringTime ] ) ;
82
+
83
+ const _powerLevel = useRef ( powerLevel ) ;
84
+ useEffect ( ( ) => { _powerLevel . current = powerLevel ; } , [ powerLevel ] ) ;
85
+
86
+ const startTimeRef = useRef ( null ) ;
87
+ const { apiObject, apiQueue } = useMemo (
77
88
( ) => ( {
78
89
apiObject : new CWaterPumpAPI ( { URL : apiHost } ) ,
79
90
apiQueue : [ ]
80
91
} ) ,
81
92
[ apiHost ]
82
93
) ;
83
- ////////////////
84
- const statusAction = React . useMemo ( ( ) => _makeStatusAction ( apiObject ) , [ apiObject ] ) ;
85
- const lastUpdateTime = React . useRef ( 0 ) ;
86
- const onTick = React . useCallback (
87
- async ( ) => _processQueue ( { apiQueue, lastUpdateTime, statusAction, updateStatus } ) ,
88
- [ apiQueue , lastUpdateTime , updateStatus , statusAction ]
94
+
95
+ const statusAction = useMemo ( ( ) => _makeStatusAction ( apiObject ) , [ apiObject ] ) ;
96
+ const lastUpdateTime = useRef ( 0 ) ;
97
+ const onTick = useCallback (
98
+ async ( ) => {
99
+ if ( null != startTimeRef . current ) { // update the total duration of the last operation
100
+ const T = Date . now ( ) - startTimeRef . current ;
101
+ changeLastOperationDuration ( T ) ;
102
+ }
103
+ _processQueue ( { apiQueue, lastUpdateTime, statusAction, updateStatus } ) ;
104
+ } ,
105
+ [ apiQueue , lastUpdateTime , statusAction , updateStatus , changeLastOperationDuration ]
89
106
) ;
90
107
91
- // Run the timer
92
- React . useEffect ( ( ) => {
108
+ useEffect ( ( ) => {
93
109
const timer = setInterval ( onTick , 100 ) ;
94
110
return ( ) => { clearInterval ( timer ) ; } ;
95
111
} , [ onTick ] ) ;
96
112
97
- ////////////////
98
- const value = React . useMemo (
99
- ( ) => _publicWrapper ( { apiObject, apiQueue, _pouringTime, _powerLevel } ) ,
100
- [ apiObject , apiQueue , _pouringTime , _powerLevel ]
113
+ const value = useMemo (
114
+ ( ) => _publicWrapper ( { apiObject, apiQueue, _pouringTime, _powerLevel, startTimeRef, onPumpStart } ) ,
115
+ [ apiObject , apiQueue , _pouringTime , _powerLevel , startTimeRef , onPumpStart ]
101
116
) ;
117
+
102
118
return (
103
119
< WaterPumpAPIContext . Provider value = { value } >
104
120
{ children }
@@ -112,8 +128,11 @@ const WaterPumpAPIProvider = connect(
112
128
pouringTime : state . UI . pouringTime ,
113
129
powerLevel : state . UI . powerLevelInPercents ,
114
130
} ) ,
115
- { updateStatus : updateSystemStatus }
131
+ {
132
+ updateStatus : updateSystemStatus , changeLastOperationDuration,
133
+ onPumpStart : pumpStartedEvent
134
+ }
116
135
) ( WaterPumpAPIProviderComponent ) ;
117
136
118
137
export default WaterPumpAPIProvider ;
119
- export { WaterPumpAPIProvider } ;
138
+ export { WaterPumpAPIProvider } ;
0 commit comments