Skip to content

Commit aa9ae91

Browse files
fix 3D soil moisture map
1 parent d1bc4cf commit aa9ae91

File tree

14 files changed

+271
-30
lines changed

14 files changed

+271
-30
lines changed

frontend/farm_designer/__tests__/three_d_garden_map_test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ describe("<ThreeDGardenMap />", () => {
101101
expectedConfig.cableDebug = true;
102102
expectedConfig.eventDebug = true;
103103
expectedConfig.lightsDebug = true;
104+
expectedConfig.moistureDebug = true;
104105
expectedConfig.surfaceDebug = SurfaceDebugOption.normals;
105106
expectedConfig.lowDetail = true;
106107
expectedConfig.solar = true;

frontend/farm_designer/three_d_garden_map.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ export const ThreeDGardenMap = (props: ThreeDGardenMapProps) => {
106106
config.eventDebug = !!getValue("eventDebug");
107107
config.cableDebug = !!getValue("cableDebug");
108108
config.lightsDebug = !!getValue("lightsDebug");
109+
config.moistureDebug = !!getValue("moistureDebug");
109110
config.surfaceDebug = getValue("surfaceDebug");
110111
config.sun = getValue("sun");
111112
config.ambient = getValue("ambient");

frontend/settings/dev/__tests__/dev_settings_test.tsx

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ jest.mock("../../../config_storage/actions", () => ({
44
getWebAppConfigValue: jest.fn(() => () => JSON.stringify(mockDevSettings)),
55
}));
66

7+
jest.mock("../../../api/crud", () => ({
8+
initSave: jest.fn(),
9+
edit: jest.fn(),
10+
save: jest.fn(),
11+
}));
12+
13+
import { fakeState } from "../../../__test_support__/fake_state";
14+
const mockState = fakeState();
15+
jest.mock("../../../redux/store", () => ({
16+
store: {
17+
dispatch: jest.fn(),
18+
getState: () => mockState,
19+
}
20+
}));
21+
722
import React from "react";
823
import { render, screen, fireEvent } from "@testing-library/react";
924
import { mount, shallow } from "enzyme";
@@ -13,9 +28,15 @@ import {
1328
DevWidget3dCameraRow,
1429
DevWidgetAllOrderOptionsRow,
1530
DevWidgetChunkingDisabledRow,
31+
Dev3dDebugSettings,
1632
} from "../dev_settings";
1733
import { DevSettings } from "../dev_support";
1834
import { setWebAppConfigValue } from "../../../config_storage/actions";
35+
import { edit, initSave, save } from "../../../api/crud";
36+
import {
37+
buildResourceIndex,
38+
} from "../../../__test_support__/resource_index_builder";
39+
import { fakeFarmwareEnv } from "../../../__test_support__/fake_state/resources";
1940

2041
describe("<DevWidgetFBOSRow />", () => {
2142
it("changes override value", () => {
@@ -160,3 +181,44 @@ describe("<DevWidgetChunkingDisabledRow />", () => {
160181
localStorage.removeItem("DISABLE_CHUNKING");
161182
});
162183
});
184+
185+
describe("<Dev3dDebugSettings />", () => {
186+
it("adds env", () => {
187+
mockState.resources = buildResourceIndex([]);
188+
render(<Dev3dDebugSettings />);
189+
const toggle = screen.getAllByText("no")[0];
190+
fireEvent.click(toggle);
191+
expect(initSave).toHaveBeenCalledWith("FarmwareEnv", {
192+
key: "3D_eventDebug",
193+
value: 1,
194+
});
195+
expect(edit).not.toHaveBeenCalled();
196+
expect(save).not.toHaveBeenCalled();
197+
});
198+
199+
it("edits env", () => {
200+
const env = fakeFarmwareEnv();
201+
env.body.key = "3D_eventDebug";
202+
env.body.value = 0;
203+
mockState.resources = buildResourceIndex([env]);
204+
render(<Dev3dDebugSettings />);
205+
const toggle = screen.getAllByText("no")[0];
206+
fireEvent.click(toggle);
207+
expect(initSave).not.toHaveBeenCalled();
208+
expect(edit).toHaveBeenCalledWith(env, { value: 1 });
209+
expect(save).toHaveBeenCalled();
210+
});
211+
212+
it("turns off setting", () => {
213+
const env = fakeFarmwareEnv();
214+
env.body.key = "3D_eventDebug";
215+
env.body.value = 1;
216+
mockState.resources = buildResourceIndex([env]);
217+
render(<Dev3dDebugSettings />);
218+
const toggle = screen.getAllByText("yes")[0];
219+
fireEvent.click(toggle);
220+
expect(initSave).not.toHaveBeenCalled();
221+
expect(edit).toHaveBeenCalledWith(env, { value: 0 });
222+
expect(save).toHaveBeenCalled();
223+
});
224+
});

frontend/settings/dev/dev_settings.tsx

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ import React from "react";
22
import { Row, BlurableInput, ToggleButton } from "../../ui";
33
import { DevSettings } from "./dev_support";
44
import { store } from "../../redux/store";
5+
import { INITIAL } from "../../three_d_garden/config";
6+
import { edit, initSave, save } from "../../api/crud";
7+
import { selectAllFarmwareEnvs } from "../../resources/selectors_by_kind";
58

69
export const DevWidgetFERow = () =>
710
<Row className="grid-exp-1">
@@ -102,6 +105,35 @@ export const DevWidgetChunkingDisabledRow = () =>
102105
: () => localStorage.setItem("DISABLE_CHUNKING", "true")} />
103106
</Row>;
104107

108+
export const Dev3dDebugSettings = () => {
109+
const dispatch = store.dispatch as Function;
110+
const farmwareEnvs = selectAllFarmwareEnvs(store.getState().resources.index);
111+
return <>
112+
{Object.keys(INITIAL)
113+
.filter(key => key.includes("Debug"))
114+
.map(key => "3D_" + key)
115+
.map(key => {
116+
const farmwareEnv = farmwareEnvs.filter(e => e.body.key == key)[0];
117+
const value = farmwareEnv?.body.value ? 1 : 0;
118+
return <Row key={key} className="grid-exp-1">
119+
<label style={{ textTransform: "none" }}>
120+
{key}
121+
</label>
122+
<ToggleButton
123+
toggleValue={!!value}
124+
toggleAction={() => {
125+
if (farmwareEnv) {
126+
dispatch(edit(farmwareEnv, { value: value == 0 ? 1 : 0 }));
127+
dispatch(save(farmwareEnv.uuid));
128+
} else {
129+
dispatch(initSave("FarmwareEnv", { key, value: 1 }));
130+
}
131+
}} />
132+
</Row>;
133+
})}
134+
</>;
135+
};
136+
105137
export const DevSettingsRows = () =>
106138
<div className={"dev-settings-rows grid"}>
107139
<DevWidgetFERow />
@@ -111,5 +143,6 @@ export const DevSettingsRows = () =>
111143
<DevWidgetFBOSRow />
112144
<DevWidgetAllOrderOptionsRow />
113145
<DevWidgetChunkingDisabledRow />
146+
<Dev3dDebugSettings />
114147
<p>Demo Queue Length: {store.getState().bot.demoQueueLength}</p>
115148
</div>;

frontend/settings/three_d_settings.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const DEFAULTS: Partial<Record<keyof Config, number>> = {
3939
eventDebug: 0,
4040
cableDebug: 0,
4141
lightsDebug: 0,
42+
moistureDebug: 0,
4243
surfaceDebug: SurfaceDebugOption.none,
4344
ambient: 75,
4445
sun: 75,

frontend/three_d_garden/__tests__/garden_model_test.tsx

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { clone } from "lodash";
1212
import { INITIAL, SurfaceDebugOption } from "../config";
1313
import { render, screen } from "@testing-library/react";
1414
import {
15-
fakePlant, fakePoint, fakeWeed,
15+
fakePlant, fakePoint, fakeSensor, fakeSensorReading, fakeWeed,
1616
} from "../../__test_support__/fake_state/resources";
1717
import { fakeAddPlantProps } from "../../__test_support__/fake_props";
1818
import { ASSETS } from "../constants";
@@ -109,6 +109,7 @@ describe("<GardenModel />", () => {
109109
p.config.lab = true;
110110
p.config.lightsDebug = true;
111111
p.config.surfaceDebug = SurfaceDebugOption.normals;
112+
p.config.moistureDebug = true;
112113
p.activeFocus = "plant";
113114
p.addPlantProps = undefined;
114115
const { container } = render(<GardenModel {...p} />);
@@ -119,7 +120,34 @@ describe("<GardenModel />", () => {
119120
it("renders debug options", () => {
120121
mockIsDesktop = false;
121122
const p = fakeProps();
123+
const sensor = fakeSensor();
124+
sensor.body.id = 1;
125+
sensor.body.label = "soil moisture";
126+
p.sensors = [sensor];
127+
const reading0 = fakeSensorReading();
128+
reading0.body.pin = 1;
129+
reading0.body.x = 100;
130+
reading0.body.y = 100;
131+
reading0.body.z = 100;
132+
reading0.body.value = 1000;
133+
const reading1 = fakeSensorReading();
134+
reading1.body.pin = 1;
135+
reading1.body.x = 0;
136+
reading1.body.y = 0;
137+
reading1.body.z = 0;
138+
reading1.body.value = 1000;
139+
p.sensorReadings = [reading0, reading1];
122140
p.config.surfaceDebug = SurfaceDebugOption.height;
141+
p.config.moistureDebug = true;
142+
const { container } = render(<GardenModel {...p} />);
143+
expect(container).toContainHTML("gray");
144+
});
145+
146+
it("renders without sensor readings", () => {
147+
mockIsDesktop = false;
148+
const p = fakeProps();
149+
p.sensorReadings = undefined;
150+
p.config.moistureDebug = true;
123151
const { container } = render(<GardenModel {...p} />);
124152
expect(container).toContainHTML("gray");
125153
});

frontend/three_d_garden/bed/__tests__/bed_test.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ describe("<Bed />", () => {
102102
soilSurfaceGeometry: new BufferGeometry(),
103103
moistureSurfaceGeometry: new BufferGeometry(),
104104
getZ: () => 0,
105+
showMoistureMap: true,
106+
sensorReadings: [],
105107
});
106108

107109
it("renders bed", () => {

frontend/three_d_garden/bed/bed.tsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
import { AxisNumberProperty } from "../../farm_designer/map/interfaces";
2525
import {
2626
TaggedCurve, TaggedGenericPointer, TaggedImage,
27+
TaggedSensorReading,
2728
} from "farmbot";
2829
import { GetWebAppConfigValue } from "../../config_storage/actions";
2930
import { DesignerState } from "../../farm_designer/interfaces";
@@ -39,8 +40,7 @@ import {
3940
import { ThreeElements } from "@react-three/fiber";
4041
import { ImageTexture } from "../garden";
4142
import { VertexNormalsHelper } from "three/examples/jsm/Addons";
42-
import { BooleanSetting } from "../../session_keys";
43-
import { MoistureTexture } from "../garden/moisture_texture";
43+
import { MoistureSurface, MoistureTexture } from "../garden/moisture_texture";
4444
import { HeightMaterial } from "../garden/height_material";
4545

4646
const soil = (
@@ -109,6 +109,8 @@ export interface BedProps {
109109
images?: TaggedImage[];
110110
soilSurfaceGeometry: BufferGeometry;
111111
moistureSurfaceGeometry: BufferGeometry;
112+
showMoistureMap: boolean;
113+
sensorReadings: TaggedSensorReading[];
112114
}
113115

114116
export const Bed = (props: BedProps) => {
@@ -243,14 +245,13 @@ export const Bed = (props: BedProps) => {
243245
z={0} />,
244246
[props.images, props.config, props.addPlantProps]);
245247

246-
const moistureVisible = !!props.addPlantProps?.getConfigValue(
247-
BooleanSetting.show_moisture_interpolation_map);
248-
249248
const moistureTexture = React.useMemo(() =>
250249
<MoistureTexture
251250
config={props.config}
251+
sensorReadings={props.sensorReadings}
252252
geometry={props.moistureSurfaceGeometry} />, [
253253
props.config,
254+
props.sensorReadings,
254255
props.moistureSurfaceGeometry,
255256
]);
256257

@@ -273,7 +274,7 @@ export const Bed = (props: BedProps) => {
273274
};
274275

275276
const SurfaceMaterial = getSurfaceMaterial();
276-
const surfaceTexture = moistureVisible
277+
const surfaceTexture = props.showMoistureMap
277278
? moistureTexture
278279
: soilTexture;
279280

@@ -388,6 +389,20 @@ export const Bed = (props: BedProps) => {
388389
</Soil>
389390
</Detailed>
390391
</React.Suspense>
392+
{props.config.moistureDebug &&
393+
<MoistureSurface
394+
geometry={props.moistureSurfaceGeometry}
395+
sensorReadings={props.sensorReadings}
396+
config={props.config}
397+
color={"black"}
398+
radius={50}
399+
readingZOverride={600}
400+
position={[
401+
threeSpace(0, bedLengthOuter) + bedXOffset,
402+
threeSpace(bedWidthOuter, bedWidthOuter) + bedYOffset,
403+
zZero(props.config),
404+
]}
405+
/>}
391406
{legXPositions.map((x, index) =>
392407
<Group key={index}>
393408
{legYPositions(index).map(y =>

frontend/three_d_garden/config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export interface Config {
7474
cableDebug: boolean;
7575
zoomBeaconDebug: boolean;
7676
lightsDebug: boolean;
77+
moistureDebug: boolean;
7778
surfaceDebug: number;
7879
sun: number;
7980
ambient: number;
@@ -181,6 +182,7 @@ export const INITIAL: Config = {
181182
cableDebug: false,
182183
zoomBeaconDebug: false,
183184
lightsDebug: false,
185+
moistureDebug: false,
184186
surfaceDebug: SurfaceDebugOption.none,
185187
sun: 75,
186188
ambient: 75,
@@ -228,7 +230,7 @@ export const BOOLEAN_KEYS = [
228230
"viewCube", "stats", "config", "zoom", "pan", "rotate", "bounds", "threeAxes",
229231
"xyDimensions", "zDimension", "promoInfo", "settingsBar", "zoomBeacons",
230232
"solar", "utilitiesPost", "packaging", "lab", "people", "lowDetail",
231-
"eventDebug", "cableDebug", "zoomBeaconDebug", "lightsDebug",
233+
"eventDebug", "cableDebug", "zoomBeaconDebug", "lightsDebug", "moistureDebug",
232234
"animate", "animateSeasons", "negativeZ",
233235
"waterFlow", "exaggeratedZ", "showSoilPoints", "urlParamAutoAdd",
234236
"light", "vacuum", "north", "desk",
@@ -416,6 +418,7 @@ export const PRESETS: Record<string, Config> = {
416418
cableDebug: true,
417419
zoomBeaconDebug: true,
418420
lightsDebug: true,
421+
moistureDebug: true,
419422
surfaceDebug: SurfaceDebugOption.normals,
420423
animate: true,
421424
animateSeasons: false,
@@ -447,7 +450,7 @@ const OTHER_CONFIG_KEYS: (keyof Config)[] = [
447450
"threeAxes", "xyDimensions", "zDimension", "labelsOnHover", "promoInfo",
448451
"settingsBar", "zoomBeacons", "pan", "rotate",
449452
"solar", "utilitiesPost", "packaging", "lab",
450-
"people", "scene", "lowDetail", "sun", "ambient",
453+
"people", "scene", "lowDetail", "sun", "ambient", "moistureDebug",
451454
"eventDebug", "cableDebug", "zoomBeaconDebug", "lightsDebug", "surfaceDebug",
452455
"animate", "distanceIndicator", "kitVersion", "negativeZ", "waterFlow",
453456
"light", "vacuum", "rotary", "animateSeasons",

frontend/three_d_garden/config_overlays.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ export const PrivateOverlay = (props: OverlayProps) => {
392392
<Toggle {...common} configKey={"cableDebug"} />
393393
<Toggle {...common} configKey={"zoomBeaconDebug"} />
394394
<Toggle {...common} configKey={"lightsDebug"} />
395+
<Toggle {...common} configKey={"moistureDebug"} />
395396
<Slider {...common} configKey={"surfaceDebug"} min={0} max={2} />
396397
<Toggle {...common} configKey={"animate"} />
397398
<Toggle {...common} configKey={"animateSeasons"} />

0 commit comments

Comments
 (0)