Skip to content

Commit fea3427

Browse files
stopping point
1 parent 40999e4 commit fea3427

4 files changed

Lines changed: 215 additions & 3 deletions

File tree

src/features/deviceInteraction/CurrentWorkflowExecutionDisplay.jsx/CurrentWorkflowExecutionDisplay.jsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ function TimerEstimate(props) {
4646

4747
export default function CurrentWorkflowExecutionDisplay() {
4848
const executingWorkflow = useSelector((state) => state.workflow);
49+
const targetTemperature = useSelector(
50+
(state) => state.deviceInteraction.targetTemperature
51+
);
4952
const isF = useSelector((state) => state.settings.isF);
5053
const [isRemovedFromDom, setIsRemovedFromDom] = useState(false);
5154
const containerRef = useRef();
@@ -104,7 +107,25 @@ export default function CurrentWorkflowExecutionDisplay() {
104107
stepDisplayName = "Loop";
105108
break;
106109
case WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS:
107-
stepDisplayName = "Heating from x to y";
110+
const heatStep = payload.conditions.find(
111+
(x) => x.nextTemp === targetTemperature
112+
);
113+
if (heatStep) {
114+
const previousHeat = isF
115+
? convertToFahrenheitFromCelsius(heatStep.ifTemp)
116+
: heatStep.ifTemp;
117+
const nextHeat = isF
118+
? convertToFahrenheitFromCelsius(heatStep.nextTemp)
119+
: heatStep.nextTemp;
120+
stepDisplayName = `Heating from ${previousHeat} to ${nextHeat}`;
121+
} else {
122+
stepDisplayName = `Heating to ${
123+
isF
124+
? convertToFahrenheitFromCelsius(payload.default.temp)
125+
: payload.default.temp
126+
}`;
127+
}
128+
108129
break;
109130
default:
110131
stepDisplayName = "Unknown";
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { StyledLabel } from "./WorkflowItemEditor";
2+
import StyledControl from "../shared/styledComponents/FormControl";
3+
import Control from "react-bootstrap/FormControl";
4+
5+
export default function ConditionalHeatItemEditor() {
6+
return (
7+
<>
8+
<div>
9+
<StyledLabel style={{ minWidth: "fit-content" }}>
10+
If Heat isn't specified set heat to
11+
</StyledLabel>
12+
<StyledControl
13+
type="number"
14+
inputMode="decimal"
15+
value={3}
16+
onChange={(e) => console.log(e)}
17+
onBlur={() => {}}
18+
isValid={false}
19+
isInvalid={true}
20+
/>
21+
<Control.Feedback type="invalid">error</Control.Feedback>
22+
23+
<StyledLabel style={{ minWidth: "fit-content" }}>
24+
If Heat isn't specified set heat to
25+
</StyledLabel>
26+
<StyledControl
27+
type="number"
28+
inputMode="decimal"
29+
value={3}
30+
onChange={(e) => console.log(e)}
31+
onBlur={() => {}}
32+
isValid={false}
33+
isInvalid={true}
34+
/>
35+
<Control.Feedback type="invalid">error 2</Control.Feedback>
36+
</div>
37+
</>
38+
);
39+
}

src/features/workflowEditor/WorkflowButtons.jsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,107 @@ export default function WorkFlow() {
225225
executeWithManagedSetTimeout(next);
226226
};
227227
}
228+
case WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS: {
229+
return async (next) => {
230+
const turnHeatOn = () => {
231+
const blePayload = async () => {
232+
const characteristic = getCharacteristic(heatOnUuid);
233+
const buffer = convertToUInt8BLE(0);
234+
await characteristic.writeValue(buffer);
235+
};
236+
AddToQueue(blePayload);
237+
};
238+
const payload = item.payload;
239+
dispatch(setCurrentWorkflowStepId(index + 1));
240+
const currentTargetTemperature =
241+
store.getState().deviceInteraction.targetTemperature;
242+
const nextCondition = payload.conditions.find(
243+
(x) => x.ifTemp === currentTargetTemperature
244+
);
245+
const nextTemp = nextCondition
246+
? nextCondition.nextTemp
247+
: payload.default.temp;
248+
const nextWait = nextCondition
249+
? nextCondition.wait
250+
: payload.default.wait;
251+
const writePayloadTempToDevice = () => {
252+
const blePayload = async () => {
253+
if (isValueInValidVolcanoCelciusRange(nextTemp)) {
254+
const characteristic =
255+
getCharacteristic(writeTemperatureUuid);
256+
const buffer = convertToUInt32BLE(nextTemp * 10);
257+
await characteristic.writeValue(buffer);
258+
dispatch(setTargetTemperature(nextTemp));
259+
}
260+
};
261+
262+
AddToQueue(blePayload);
263+
};
264+
265+
writePayloadTempToDevice();
266+
turnHeatOn();
267+
let previousTemperature;
268+
let sameTemperatureIntervalStreak;
269+
currentIntervals.push(
270+
setInterval(() => {
271+
const blePayload = async () => {
272+
const currentTemperature =
273+
store.getState().deviceInteraction.currentTemperature;
274+
275+
if (previousTemperature !== currentTemperature) {
276+
previousTemperature = currentTemperature;
277+
sameTemperatureIntervalStreak = 0;
278+
} else {
279+
sameTemperatureIntervalStreak++;
280+
}
281+
282+
//this is arbitrary. If the on change event is missed heat will hang forever waiting for the target temperature to be reach (even tho it is on the device)
283+
//I thought it we read the same temperature 7 times in a row then we should probably reach out to the device.
284+
if (sameTemperatureIntervalStreak > 7) {
285+
sameTemperatureIntervalStreak = 0;
286+
const blePayload = async () => {
287+
const temperatureCharacteristic = getCharacteristic(
288+
currentTemperatureUuid
289+
);
290+
const value = await temperatureCharacteristic.readValue();
291+
const currentTemperature =
292+
convertCurrentTemperatureCharacteristicToCelcius(value);
293+
dispatch(setCurrentTemperature(currentTemperature));
294+
previousTemperature = currentTemperature;
295+
sameTemperatureIntervalStreak = 0;
296+
};
297+
298+
AddToQueue(blePayload);
299+
}
300+
if (currentTemperature >= nextTemp) {
301+
clearIntervals();
302+
clearTimeouts();
303+
if (nextWait === 0) {
304+
alert("Click okay to resume the workflow!");
305+
}
306+
307+
executeWithManagedSetTimeout(next, nextWait * 1000);
308+
}
309+
310+
// if the temperature is changed to be below the target we will never get there.
311+
// The workflow must continue onward by any means necessary, therefore we shall set the payload temperature again
312+
if (
313+
store.getState().deviceInteraction.targetTemperature <
314+
nextTemp
315+
) {
316+
writePayloadTempToDevice();
317+
}
318+
319+
if (!store.getState().deviceInteraction.isHeatOn) {
320+
turnHeatOn();
321+
dispatch(setIsHeatOn(true));
322+
}
323+
};
324+
AddToQueue(blePayload);
325+
}, 300)
326+
);
327+
};
328+
}
228329
case WorkflowItemTypes.WAIT: {
229330
return async (next) => {
230331
dispatch(setCurrentWorkflowStepId(index + 1));

src/features/workflowEditor/WorkflowItemEditor.jsx

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,14 @@ import PrideText from "../../themes/PrideText";
2424
import { useEffect } from "react";
2525
import Drag from "./DND/WorkflowItemDrag";
2626
import WorkflowItemDrop from "./DND/WorkflowItemDrop";
27+
import ConditionalHeatItemEditor from "./ConditionalHeatItemEditor";
2728
const StyledSelect = styled(Select)`
2829
color: ${(props) => props.theme.primaryFontColor};
2930
background-color: ${(props) => props.theme.backgroundColor};
3031
border-color: ${(props) => props.theme.borderColor};
3132
`;
3233

33-
const StyledLabel = styled(Label)`
34+
export const StyledLabel = styled(Label)`
3435
align-items: center;
3536
margin-right: auto;
3637
`;
@@ -65,6 +66,7 @@ export default function WorkflowItemEditor(props) {
6566
setPayloadInput(nextPayloadInput);
6667
}
6768
}, [isF, props.item]);
69+
6870
let initialPayloadInputState;
6971
if (props.item.type !== WorkflowItemTypes.HEAT_ON) {
7072
initialPayloadInputState = props.item.payload;
@@ -138,6 +140,46 @@ export default function WorkflowItemEditor(props) {
138140
case WorkflowItemTypes.LOOP_UNTIL_TARGET_TEMPERATURE: {
139141
return MIN_CELSIUS_TEMP;
140142
}
143+
case WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS: {
144+
return {
145+
default: {
146+
temp: MIN_CELSIUS_TEMP,
147+
wait: 5,
148+
},
149+
conditions: [
150+
{
151+
ifTemp: MIN_CELSIUS_TEMP,
152+
nextTemp: 180,
153+
wait: 5,
154+
},
155+
{
156+
ifTemp: 180,
157+
nextTemp: 185,
158+
wait: 5,
159+
},
160+
{
161+
ifTemp: 185,
162+
nextTemp: 190,
163+
wait: 5,
164+
},
165+
{
166+
ifTemp: 190,
167+
nextTemp: 195,
168+
wait: 5,
169+
},
170+
{
171+
ifTemp: 195,
172+
nextTemp: 200,
173+
wait: 5,
174+
},
175+
{
176+
ifTemp: 200,
177+
nextTemp: MIN_CELSIUS_TEMP,
178+
wait: 5,
179+
},
180+
],
181+
};
182+
}
141183
default: {
142184
return undefined;
143185
}
@@ -273,10 +315,16 @@ export default function WorkflowItemEditor(props) {
273315
<option value={WorkflowItemTypes.LOOP_UNTIL_TARGET_TEMPERATURE}>
274316
Loop Workflow
275317
</option>
318+
<option value={WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS}>
319+
Conditional Temperature Set
320+
</option>
276321
</StyledSelect>
277322
</div>
278323

279-
{props.item.type !== WorkflowItemTypes.HEAT_OFF && (
324+
{![
325+
WorkflowItemTypes.HEAT_OFF,
326+
WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS,
327+
].includes(props.item.type) && (
280328
<StyledPayloadDiv>
281329
<StyledLabel>{getPayloadLabelByType(props.item.type)}</StyledLabel>
282330
<StyledControl
@@ -292,6 +340,9 @@ export default function WorkflowItemEditor(props) {
292340
<Control.Feedback type="invalid">{errorMessage}</Control.Feedback>
293341
</StyledPayloadDiv>
294342
)}
343+
{props.item.type === WorkflowItemTypes.HEAT_ON_WITH_CONDITIONS && (
344+
<ConditionalHeatItemEditor />
345+
)}
295346
</WorkflowItemDiv>
296347
<WorkflowItemDrop
297348
key={`${props.workflowId} ${props.item.id} ${props.item.itemIndex}`}

0 commit comments

Comments
 (0)