@@ -47,6 +92,7 @@ export class CaptureSizeSelection
}} />
+
{(this.state.custom || selectedSize.value == Size.custom) &&
@@ -100,26 +146,30 @@ enum Size {
const MAXIMUM = () => ({ label: t("Maximum"), value: Size.maximum });
const CUSTOM = () => ({ label: t("Custom"), value: Size.custom });
-const SIZE_OPTIONS = (
- camera = Camera.RPI,
-): Record => ({
- [Size.maximum]: MAXIMUM(),
- [Size.custom]: CUSTOM(),
- [Size.r320x240]: { label: t("320 x 240 (0.08MP)"), value: Size.r320x240 },
- [Size.r640x480]: { label: t("640 x 480 (0.3MP)"), value: Size.r640x480 },
- [Size.r800x600]: { label: t("800 x 600 (0.5MP)"), value: Size.r800x600 },
- [Size.r1280x960]: { label: t("1280 x 960 (1.3MP)"), value: Size.r1280x960 },
- [Size.r1600x1200]: { label: t("1600 x 1200 (2MP)"), value: Size.r1600x1200 },
- [Size.r2592x1944]: camera == Camera.RPI
- ? { label: t("2592 x 1944 (5MP)"), value: Size.r2592x1944 }
- : undefined,
- [Size.r3280x2464]: camera == Camera.RPI
- ? { label: t("3280 x 2464 (8MP)"), value: Size.r3280x2464 }
- : undefined,
- [Size.r4056x3040]: camera == Camera.RPI
- ? { label: t("4056 x 3040 (12.3MP)"), value: Size.r4056x3040 }
- : undefined,
-});
+type Options = Partial>;
+const SIZE_OPTIONS = (camera = Camera.RPI): Options => {
+ const OPTIONS: Options = {
+ [Size.maximum]: MAXIMUM(),
+ [Size.custom]: CUSTOM(),
+ [Size.r320x240]: { label: t("320 x 240 (0.08MP)"), value: Size.r320x240 },
+ [Size.r640x480]: { label: t("640 x 480 (0.3MP)"), value: Size.r640x480 },
+ [Size.r800x600]: { label: t("800 x 600 (0.5MP)"), value: Size.r800x600 },
+ [Size.r1280x960]: { label: t("1280 x 960 (1.3MP)"), value: Size.r1280x960 },
+ [Size.r1600x1200]: { label: t("1600 x 1200 (2MP)"), value: Size.r1600x1200 },
+ };
+ if (camera == Camera.RPI) {
+ OPTIONS[Size.r2592x1944] = {
+ label: t("2592 x 1944 (5MP)"), value: Size.r2592x1944,
+ };
+ OPTIONS[Size.r3280x2464] = {
+ label: t("3280 x 2464 (8MP)"), value: Size.r3280x2464,
+ };
+ OPTIONS[Size.r4056x3040] = {
+ label: t("4056 x 3040 (12.3MP)"), value: Size.r4056x3040,
+ };
+ }
+ return OPTIONS;
+};
const SIZES: Record> = {
[Size.maximum]: { width: 10000, height: 10000 },
diff --git a/frontend/routes.tsx b/frontend/routes.tsx
index 976fe3b334..68e38040bc 100644
--- a/frontend/routes.tsx
+++ b/frontend/routes.tsx
@@ -66,7 +66,10 @@ export class RootComponent
- {ChildRoute && }
+ {ChildRoute &&
+
+
+ }
diff --git a/frontend/settings/fbos_settings/__tests__/fbos_details_test.tsx b/frontend/settings/fbos_settings/__tests__/fbos_details_test.tsx
index 99d55c7023..8ef5933466 100644
--- a/frontend/settings/fbos_settings/__tests__/fbos_details_test.tsx
+++ b/frontend/settings/fbos_settings/__tests__/fbos_details_test.tsx
@@ -296,6 +296,7 @@ describe(" ", () => {
["Zero W", "rpi", "arduino"],
["3", "rpi3", "arduino"],
["Zero 2 W", "rpi3", "express_k11"],
+ ["Zero 2 W", "rpi3", "express_k12"],
["4", "rpi4", "arduino"],
["Unknown", "", undefined],
])("returns correct pi model: %s", (expected, chip, firmware) => {
diff --git a/frontend/settings/fbos_settings/__tests__/rpi_model_test.tsx b/frontend/settings/fbos_settings/__tests__/rpi_model_test.tsx
index 52a53c8f4e..e5f386bc3c 100644
--- a/frontend/settings/fbos_settings/__tests__/rpi_model_test.tsx
+++ b/frontend/settings/fbos_settings/__tests__/rpi_model_test.tsx
@@ -19,8 +19,10 @@ type TestCase = [string, string, FirmwareHardware, string];
const TEST_CASES: TestCase[] = [
["3", "rpi3", "arduino", "pi 3"],
["4", "rpi4", "farmduino_k16", "pi 4"],
+ ["4", "rpi4", "farmduino_k17", "pi 4"],
["01", "rpi", "express_k10", "zero w"],
["02", "rpi3", "express_k11", "zero 2 w"],
+ ["02", "rpi3", "express_k12", "zero 2 w"],
];
describe(" ", () => {
diff --git a/frontend/settings/fbos_settings/fbos_details.tsx b/frontend/settings/fbos_settings/fbos_details.tsx
index d4d5e942aa..5db999003d 100644
--- a/frontend/settings/fbos_settings/fbos_details.tsx
+++ b/frontend/settings/fbos_settings/fbos_details.tsx
@@ -10,7 +10,7 @@ import { LastSeen } from "./last_seen_row";
import moment from "moment";
import { formatTime } from "../../util";
import {
- boardType, FIRMWARE_CHOICES_DDI, validFirmwareHardware,
+ boardType, FIRMWARE_CHOICES_DDI, hasZero2, validFirmwareHardware,
} from "../firmware/firmware_hardware_support";
import { ExternalUrl, FarmBotRepo } from "../../external_urls";
import { DeviceAccountSettings } from "farmbot/dist/resources/api_resources";
@@ -63,7 +63,7 @@ export const PiDisplay = ({ chip, firmware }: PiDisplayProps): JSX.Element => {
const pi = () => {
switch (chip) {
case "rpi": return "Zero W";
- case "rpi3": return firmware == "express_k11" ? "Zero 2 W" : "3";
+ case "rpi3": return hasZero2(firmware) ? "Zero 2 W" : "3";
case "rpi4": return "4";
default: return t("Unknown");
}
diff --git a/frontend/settings/fbos_settings/rpi_model.tsx b/frontend/settings/fbos_settings/rpi_model.tsx
index 1ee773875b..c308cc6ac6 100644
--- a/frontend/settings/fbos_settings/rpi_model.tsx
+++ b/frontend/settings/fbos_settings/rpi_model.tsx
@@ -8,6 +8,7 @@ import { FirmwareHardware, TaggedDevice } from "farmbot";
import { BotState } from "../../devices/interfaces";
import { StatusIcon } from "../firmware/firmware_hardware_status";
import { Position } from "@blueprintjs/core";
+import { hasZero2 } from "../firmware/firmware_hardware_support";
export const RPI_OPTIONS: Record = {
"3": { label: "Raspberry Pi 3", value: "3" },
@@ -16,13 +17,14 @@ export const RPI_OPTIONS: Record = {
"02": { label: "Raspberry Pi Zero 2 W", value: "02" },
};
-const TARGETS = (firmwareHardware: string): { [x: string]: string } => ({
- "rpi3": firmwareHardware == "express_k11"
- ? "Raspberry Pi Zero 2 W"
- : "Raspberry Pi 3",
- "rpi4": "Raspberry Pi 4",
- "rpi": "Raspberry Pi Zero W",
-});
+const TARGETS =
+ (firmwareHardware: FirmwareHardware | undefined): { [x: string]: string } => ({
+ "rpi3": hasZero2(firmwareHardware)
+ ? "Raspberry Pi Zero 2 W"
+ : "Raspberry Pi 3",
+ "rpi4": "Raspberry Pi 4",
+ "rpi": "Raspberry Pi Zero W",
+ });
export interface RpiModelProps {
dispatch: Function;
@@ -89,7 +91,6 @@ export const StatusDetails = (props: StatusDetailsProps) => {
{selection ? RPI_OPTIONS[selection].label : t("none")}
{t("FarmBot OS")}
- {TARGETS("" + firmwareHardware)["" + target]
- || t("unknown")}
+ {TARGETS(firmwareHardware)["" + target] || t("unknown")}
;
};
diff --git a/frontend/settings/firmware/__tests__/board_type_test.tsx b/frontend/settings/firmware/__tests__/board_type_test.tsx
index c06d40b380..477349fd8c 100644
--- a/frontend/settings/firmware/__tests__/board_type_test.tsx
+++ b/frontend/settings/firmware/__tests__/board_type_test.tsx
@@ -3,6 +3,11 @@ jest.mock("../../../api/crud", () => ({
save: jest.fn(),
}));
+let mockFeatureBoolean = false;
+jest.mock("../../../devices/should_display", () => ({
+ shouldDisplayFeature: () => mockFeatureBoolean,
+}));
+
import React from "react";
import { mount, shallow } from "enzyme";
import { BoardType } from "../board_type";
@@ -78,6 +83,7 @@ describe("
", () => {
});
it("displays boards", () => {
+ mockFeatureBoolean = false;
const wrapper = mount(
);
const { list } = wrapper.find("FBSelect").props();
expect(list).toEqual([
@@ -90,5 +96,13 @@ describe("
", () => {
{ label: "Farmduino (Express v1.1)", value: "express_k11" },
{ label: "None", value: "none" },
]);
+ expect(list?.length).toEqual(8);
+ });
+
+ it("displays more boards", () => {
+ mockFeatureBoolean = true;
+ const wrapper = mount(
);
+ const { list } = wrapper.find("FBSelect").props();
+ expect(list?.length).toEqual(10);
});
});
diff --git a/frontend/settings/firmware/__tests__/firmware_hardware_support_test.ts b/frontend/settings/firmware/__tests__/firmware_hardware_support_test.ts
index 638237dae3..e930618019 100644
--- a/frontend/settings/firmware/__tests__/firmware_hardware_support_test.ts
+++ b/frontend/settings/firmware/__tests__/firmware_hardware_support_test.ts
@@ -20,6 +20,10 @@ describe("boardType()", () => {
expect(boardType("5.0.3.I")).toEqual("farmduino_k16");
});
+ it("returns Farmduino k1.7", () => {
+ expect(boardType("5.0.3.J")).toEqual("farmduino_k17");
+ });
+
it("returns Farmduino Express k1.0", () => {
expect(boardType("5.0.3.E")).toEqual("express_k10");
});
@@ -28,6 +32,10 @@ describe("boardType()", () => {
expect(boardType("5.0.3.D")).toEqual("express_k11");
});
+ it("returns Farmduino Express k1.2", () => {
+ expect(boardType("5.0.3.C")).toEqual("express_k12");
+ });
+
it("returns Arduino/RAMPS", () => {
expect(boardType("5.0.3.R")).toEqual("arduino");
});
diff --git a/frontend/settings/firmware/firmware_hardware_support.ts b/frontend/settings/firmware/firmware_hardware_support.ts
index 16cc73fe69..aea0d40a1d 100644
--- a/frontend/settings/firmware/firmware_hardware_support.ts
+++ b/frontend/settings/firmware/firmware_hardware_support.ts
@@ -1,10 +1,12 @@
import { FirmwareHardware, TaggedFbosConfig } from "farmbot";
+import { shouldDisplayFeature } from "../../devices/should_display";
+import { Feature } from "../../devices/interfaces";
export const isFwHardwareValue = (x?: unknown): x is FirmwareHardware => {
const values: FirmwareHardware[] = [
"arduino",
- "farmduino", "farmduino_k14", "farmduino_k15", "farmduino_k16",
- "express_k10", "express_k11",
+ "farmduino", "farmduino_k14", "farmduino_k15", "farmduino_k16", "farmduino_k17",
+ "express_k10", "express_k11", "express_k12",
"none",
];
return !!values.includes(x as FirmwareHardware);
@@ -13,11 +15,13 @@ export const isFwHardwareValue = (x?: unknown): x is FirmwareHardware => {
const ordered: FirmwareHardware[] = [
"express_k10",
"express_k11",
+ "express_k12",
"arduino",
"farmduino",
"farmduino_k14",
"farmduino_k15",
"farmduino_k16",
+ "farmduino_k17",
"none",
];
@@ -35,13 +39,17 @@ export const getFwHardwareValue =
};
const NO_BUTTONS = ["arduino", "farmduino", "none"];
-const EXPRESS_BOARDS = ["express_k10", "express_k11"];
+const EXPRESS_BOARDS = ["express_k10", "express_k11", "express_k12"];
const NO_SENSORS = [...EXPRESS_BOARDS];
const NO_ENCODERS = [...EXPRESS_BOARDS];
const NO_TOOLS = [...EXPRESS_BOARDS];
const NO_ETHERNET = ["express_k10"];
+const NO_ZERO_2 = ["express_k10"];
const NO_EXTRA_BUTTONS = [...EXPRESS_BOARDS];
const NO_TMC = ["arduino", "farmduino", "farmduino_k14"];
+const HAS_WEEDER = [
+ "arduino", "farmduino", "farmduino_k14", "farmduino_k15", "farmduino_k16",
+];
const NO_ROTARY = ["arduino", "farmduino", "farmduino_k14", "farmduino_k15"]
.concat(EXPRESS_BOARDS);
@@ -66,12 +74,19 @@ export const hasSensors = (firmwareHardware: FirmwareHardware | undefined) =>
export const hasUTM = (firmwareHardware: FirmwareHardware | undefined) =>
!firmwareHardware || !NO_TOOLS.includes(firmwareHardware);
+export const hasWeeder = (firmwareHardware: FirmwareHardware | undefined) =>
+ !firmwareHardware || HAS_WEEDER.includes(firmwareHardware);
+
export const hasRotaryTool = (firmwareHardware: FirmwareHardware | undefined) =>
!firmwareHardware || !NO_ROTARY.includes(firmwareHardware);
export const hasEthernet = (firmwareHardware: FirmwareHardware | undefined) =>
!firmwareHardware || !NO_ETHERNET.includes(firmwareHardware);
+export const hasZero2 = (firmwareHardware: FirmwareHardware | undefined) =>
+ isExpress(firmwareHardware)
+ && !NO_ZERO_2.includes(firmwareHardware as FirmwareHardware);
+
const getBoardIdentifier =
(firmwareVersion: string | undefined): string =>
firmwareVersion ? firmwareVersion.split(".")[3] : "undefined";
@@ -112,8 +127,10 @@ const FIRMWARE_LOOKUP: { [id: string]: FirmwareHardware } = {
G: "farmduino_k14",
H: "farmduino_k15",
I: "farmduino_k16",
+ J: "farmduino_k17",
E: "express_k10",
D: "express_k11",
+ C: "express_k12",
};
enum BoardLabels {
@@ -122,8 +139,10 @@ enum BoardLabels {
farmduino_k14 = "Farmduino (Genesis v1.4)",
farmduino_k15 = "Farmduino (Genesis v1.5)",
farmduino_k16 = "Farmduino (Genesis v1.6)",
+ farmduino_k17 = "Farmduino (Genesis v1.7)",
express_k10 = "Farmduino (Express v1.0)",
express_k11 = "Farmduino (Express v1.1)",
+ express_k12 = "Farmduino (Express v1.2)",
none = "None",
}
@@ -133,8 +152,10 @@ enum KitLabels {
farmduino_k14 = "Genesis v1.4",
farmduino_k15 = "Genesis v1.5",
farmduino_k16 = "Genesis v1.6",
+ farmduino_k17 = "Genesis v1.7",
express_k10 = "Express v1.0",
express_k11 = "Express v1.1",
+ express_k12 = "Express v1.2",
none = "None",
unknown = "Farmduino",
}
@@ -145,8 +166,10 @@ const KIT_LOOKUP = {
farmduino_k14: KitLabels.farmduino_k14,
farmduino_k15: KitLabels.farmduino_k15,
farmduino_k16: KitLabels.farmduino_k16,
+ farmduino_k17: KitLabels.farmduino_k17,
express_k10: KitLabels.express_k10,
express_k11: KitLabels.express_k11,
+ express_k12: KitLabels.express_k12,
none: KitLabels.none,
unknown: KitLabels.unknown,
};
@@ -156,8 +179,10 @@ const FARMDUINO = { label: BoardLabels.farmduino, value: "farmduino" };
const FARMDUINO_K14 = { label: BoardLabels.farmduino_k14, value: "farmduino_k14" };
const FARMDUINO_K15 = { label: BoardLabels.farmduino_k15, value: "farmduino_k15" };
const FARMDUINO_K16 = { label: BoardLabels.farmduino_k16, value: "farmduino_k16" };
+const FARMDUINO_K17 = { label: BoardLabels.farmduino_k17, value: "farmduino_k17" };
const EXPRESS_K10 = { label: BoardLabels.express_k10, value: "express_k10" };
const EXPRESS_K11 = { label: BoardLabels.express_k11, value: "express_k11" };
+const EXPRESS_K12 = { label: BoardLabels.express_k12, value: "express_k12" };
const NONE = { label: BoardLabels.none, value: "none" };
export const FIRMWARE_CHOICES_DDI = {
@@ -166,8 +191,10 @@ export const FIRMWARE_CHOICES_DDI = {
[FARMDUINO_K14.value]: FARMDUINO_K14,
[FARMDUINO_K15.value]: FARMDUINO_K15,
[FARMDUINO_K16.value]: FARMDUINO_K16,
+ [FARMDUINO_K17.value]: FARMDUINO_K17,
[EXPRESS_K10.value]: EXPRESS_K10,
[EXPRESS_K11.value]: EXPRESS_K11,
+ [EXPRESS_K12.value]: EXPRESS_K12,
[NONE.value]: NONE,
};
@@ -177,7 +204,9 @@ export const getFirmwareChoices = () => ([
FARMDUINO_K14,
FARMDUINO_K15,
FARMDUINO_K16,
+ ...(shouldDisplayFeature(Feature.farmduino_k17) ? [FARMDUINO_K17] : []),
EXPRESS_K10,
EXPRESS_K11,
+ ...(shouldDisplayFeature(Feature.express_k12) ? [EXPRESS_K12] : []),
NONE,
]);
diff --git a/frontend/settings/firmware/firmware_path.tsx b/frontend/settings/firmware/firmware_path.tsx
index 9e79e9ac3b..d74428518f 100644
--- a/frontend/settings/firmware/firmware_path.tsx
+++ b/frontend/settings/firmware/firmware_path.tsx
@@ -18,7 +18,7 @@ export const ChangeFirmwarePath = (props: ChangeFirmwarePathProps) => {
label: t("ttyAMA0 (recommended for Express v1.0)"), value: "ttyAMA0",
},
ttyUSB0: {
- label: t("ttyUSB0 (recommended for Express v1.1)"), value: "ttyUSB0",
+ label: t("ttyUSB0 (recommended for Express v1.1+)"), value: "ttyUSB0",
},
manual: { label: t("Manual input"), value: "manual" },
};
diff --git a/frontend/settings/hardware_settings/default_values.ts b/frontend/settings/hardware_settings/default_values.ts
index 1cb7a42ea5..0b1532312f 100644
--- a/frontend/settings/hardware_settings/default_values.ts
+++ b/frontend/settings/hardware_settings/default_values.ts
@@ -155,9 +155,11 @@ export const getDefaultFwConfigValue =
case "farmduino_k14":
case "farmduino_k15":
case "farmduino_k16":
+ case "farmduino_k17":
return DEFAULT_GENESIS_FIRMWARE_CONFIG_VALUES[key];
case "express_k10":
case "express_k11":
+ case "express_k12":
return DEFAULT_EXPRESS_FIRMWARE_CONFIG_VALUES[key];
default:
return DEFAULT_FIRMWARE_CONFIG_VALUES[key];
diff --git a/frontend/tools/__tests__/add_tool_test.tsx b/frontend/tools/__tests__/add_tool_test.tsx
index 8cc32dd9d3..8195a9f364 100644
--- a/frontend/tools/__tests__/add_tool_test.tsx
+++ b/frontend/tools/__tests__/add_tool_test.tsx
@@ -107,8 +107,10 @@ describe("
", () => {
["farmduino_k14", 6],
["farmduino_k15", 8],
["farmduino_k16", 9],
+ ["farmduino_k17", 9],
["express_k10", 3],
["express_k11", 3],
+ ["express_k12", 3],
])("adds peripherals: %s", (firmware, expectedAdds) => {
const p = fakeProps();
p.firmwareHardware = firmware;
diff --git a/frontend/tools/add_tool.tsx b/frontend/tools/add_tool.tsx
index 88fdd1a62c..7e7296336e 100644
--- a/frontend/tools/add_tool.tsx
+++ b/frontend/tools/add_tool.tsx
@@ -103,6 +103,7 @@ export class RawAddTool extends React.Component
{
...TROUGHS,
];
case "farmduino_k16":
+ case "farmduino_k17":
return [
...BASE_TOOLS,
t("Rotary Tool"),
@@ -111,6 +112,7 @@ export class RawAddTool extends React.Component {
];
case "express_k10":
case "express_k11":
+ case "express_k12":
return [
...BASE_TOOLS,
...TROUGHS,
diff --git a/frontend/util/version.ts b/frontend/util/version.ts
index a6095fc264..78e2ad166b 100644
--- a/frontend/util/version.ts
+++ b/frontend/util/version.ts
@@ -76,6 +76,7 @@ export function semverCompare(left: string, right: string): SemverResult {
* for shouldDisplay()
*/
export enum MinVersionOverride {
+ DEMO = "99.99.99",
NEVER = "999.999.999",
}
@@ -84,6 +85,8 @@ export enum FbosVersionFallback {
}
const fallbackData: MinOsFeatureLookup = {
+ [Feature.express_k12]: MinVersionOverride.NEVER, // available: "15.4.6",
+ [Feature.farmduino_k17]: MinVersionOverride.DEMO, // available: "15.4.6",
[Feature.planted_at_now]: MinVersionOverride.NEVER,
};
diff --git a/frontend/wizard/checks.tsx b/frontend/wizard/checks.tsx
index 8a10e5aa8b..8e33747446 100644
--- a/frontend/wizard/checks.tsx
+++ b/frontend/wizard/checks.tsx
@@ -333,13 +333,17 @@ const SEED_DATA_OPTION_TO_FW_HARDWARE: Record = {
"genesis_1.4": "farmduino_k14",
"genesis_1.5": "farmduino_k15",
"genesis_1.6": "farmduino_k16",
+ "genesis_1.7": "farmduino_k17",
"genesis_xl_1.4": "farmduino_k14",
"genesis_xl_1.5": "farmduino_k15",
"genesis_xl_1.6": "farmduino_k16",
+ "genesis_xl_1.7": "farmduino_k17",
"express_1.0": "express_k10",
"express_1.1": "express_k11",
+ "express_1.2": "express_k12",
"express_xl_1.0": "express_k10",
"express_xl_1.1": "express_k11",
+ "express_xl_1.2": "express_k12",
"none": "none",
};
@@ -349,8 +353,10 @@ const FW_HARDWARE_TO_RPI: Record = {
"farmduino_k14": "3",
"farmduino_k15": "3",
"farmduino_k16": undefined,
+ "farmduino_k17": "4",
"express_k10": "01",
"express_k11": "02",
+ "express_k12": "02",
"none": "3",
};
diff --git a/frontend/wizard/data.ts b/frontend/wizard/data.ts
index bfa7e09139..7396aff850 100644
--- a/frontend/wizard/data.ts
+++ b/frontend/wizard/data.ts
@@ -46,7 +46,7 @@ import {
} from "./checks";
import { TaggedWizardStepResult } from "farmbot";
import {
- hasEthernet, hasExtraButtons, hasRotaryTool, hasUTM, isExpress,
+ hasEthernet, hasExtraButtons, hasRotaryTool, hasUTM, hasWeeder, isExpress,
} from "../settings/firmware/firmware_hardware_support";
import { BooleanSetting } from "../session_keys";
import { ExternalUrl } from "../external_urls";
@@ -1397,7 +1397,7 @@ export const WIZARD_STEPS = (props: WizardStepDataProps): WizardSteps => {
outcomes: [
],
},
- ...(hasUTM(firmwareHardware)
+ ...(hasWeeder(firmwareHardware)
? [{
section: WizardSectionSlug.tools,
slug: WizardStepSlug.weeder,
diff --git a/lib/tasks/releases.rake b/lib/tasks/releases.rake
index 4dddfd4678..f23d115d58 100644
--- a/lib/tasks/releases.rake
+++ b/lib/tasks/releases.rake
@@ -54,6 +54,17 @@ namespace :releases do
release
end
+ def self.get_brief_release_info
+ info = []
+ Release.all.map do |r|
+ if r.platform == "rpi"
+ info.push("#{r.channel.ljust(8)} #{r.version.ljust(14)}" +
+ "#{r.created_at.to_s.slice(0, 10)}")
+ end
+ end
+ info.join("\n")
+ end
+
def self.print_all_existing_releases
puts ""
Release.all.map do |r|
@@ -61,12 +72,7 @@ namespace :releases do
"#{r.platform.ljust(6)} #{r.version.ljust(14)} #{r.created_at}"
end
puts ""
- Release.all.map do |r|
- if r.platform == "rpi"
- puts "#{r.channel.ljust(8)} #{r.version.ljust(14)}" +
- "#{r.created_at.to_s.slice(0, 10)}"
- end
- end
+ puts get_brief_release_info
puts ""
end
@@ -93,6 +99,31 @@ namespace :releases do
exit 1
end
end
+
+ def self.post_summary
+ webhook_url = ENV["RELEASE_WEBHOOK_URL"]
+ if webhook_url
+ server = Release.first.image_url.split("/")[3].split("-")[1]
+ title = "current releases: #{server}"
+ info = title + "\n```#{get_brief_release_info}```"
+ payload = {
+ "mrkdwn": true,
+ "text": title,
+ "blocks": [
+ {
+ "type": "section",
+ "text": {
+ "type": "mrkdwn",
+ "text": info,
+ }
+ }
+ ],
+ }.to_json
+ Faraday.post(webhook_url,
+ payload,
+ "Content-Type" => "application/json")
+ end
+ end
end
desc "Send upgrade notification to devices that are online"
@@ -118,5 +149,6 @@ namespace :releases do
release.destroy!
end
ReleaseTask.print_all_existing_releases
+ ReleaseTask.post_summary
end
end
diff --git a/package.json b/package.json
index 4a0de367dd..d13c9b5dda 100644
--- a/package.json
+++ b/package.json
@@ -31,16 +31,16 @@
"author": "farmbot.io",
"license": "MIT",
"dependencies": {
- "@blueprintjs/core": "5.5.1",
- "@blueprintjs/select": "5.0.16",
+ "@blueprintjs/core": "5.6.0",
+ "@blueprintjs/select": "5.0.17",
"@monaco-editor/react": "4.6.0",
- "@parcel/transformer-sass": "2.10.1",
- "@parcel/transformer-typescript-tsc": "2.10.1",
+ "@parcel/transformer-sass": "2.10.2",
+ "@parcel/transformer-typescript-tsc": "2.10.2",
"@types/lodash": "4.14.200",
"@types/markdown-it": "13.0.5",
- "@types/node": "20.8.9",
+ "@types/node": "20.8.10",
"@types/promise-timeout": "1.3.2",
- "@types/react": "18.2.33",
+ "@types/react": "18.2.34",
"@types/react-color": "3.0.9",
"@types/react-dom": "18.2.14",
"@types/ws": "8.5.8",
@@ -48,19 +48,19 @@
"bowser": "2.11.0",
"browser-speech": "1.1.1",
"events": "3.3.0",
- "farmbot": "15.8.1",
+ "farmbot": "15.8.5",
"i18next": "23.6.0",
"lodash": "4.17.21",
"markdown-it": "13.0.2",
"markdown-it-emoji": "2.0.2",
"moment": "2.29.4",
"monaco-editor": "0.44.0",
- "mqtt": "5.1.3",
- "npm": "10.2.1",
- "parcel": "2.10.1",
+ "mqtt": "5.1.4",
+ "npm": "10.2.3",
+ "parcel": "2.10.2",
"process": "0.11.10",
"promise-timeout": "1.3.0",
- "punycode": "2.3.0",
+ "punycode": "2.3.1",
"querystring-es3": "0.2.1",
"react": "18.2.0",
"react-color": "2.19.3",
@@ -76,14 +76,14 @@
},
"devDependencies": {
"@types/enzyme": "3.10.12",
- "@types/jest": "29.5.6",
+ "@types/jest": "29.5.7",
"@types/readable-stream": "4.0.4",
- "@typescript-eslint/eslint-plugin": "6.9.0",
- "@typescript-eslint/parser": "6.9.0",
+ "@typescript-eslint/eslint-plugin": "6.9.1",
+ "@typescript-eslint/parser": "6.9.1",
"@wojtekmaj/enzyme-adapter-react-17": "0.8.0",
"coveralls": "3.1.1",
"enzyme": "3.11.0",
- "eslint": "8.52.0",
+ "eslint": "8.53.0",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-jest": "27.6.0",
diff --git a/spec/controllers/api/ai/ai_controller_spec.rb b/spec/controllers/api/ai/ai_controller_spec.rb
index 1a95ec6c62..43f98cc342 100644
--- a/spec/controllers/api/ai/ai_controller_spec.rb
+++ b/spec/controllers/api/ai/ai_controller_spec.rb
@@ -8,7 +8,7 @@
def chunk(content, done=nil)
"data: {\"id\":\"id\",\"object\":\"chat.completion.chunk\"," \
"\"created\":12345,\"model\":\"gpt-4\",\"choices\":[{\"delta\":{" \
- "\"content\":\"#{content}\"},\"index\":0,\"finish_reason\":#{done.to_json}}]}"
+ "\"content\":\"#{content}\"},\"index\":0,\"finish_reason\":#{done.to_json}}]}\n\n"
end
URL_PATTERN = /raw\.githubusercontent\.com/
diff --git a/spec/controllers/api/demo_accounts/demo_account_controller_spec.rb b/spec/controllers/api/demo_accounts/demo_account_controller_spec.rb
index acc52e2197..ee7591c09c 100644
--- a/spec/controllers/api/demo_accounts/demo_account_controller_spec.rb
+++ b/spec/controllers/api/demo_accounts/demo_account_controller_spec.rb
@@ -7,7 +7,7 @@
it "creates a guest account", :slow do
Transport.current.clear!
secret = SecureRandom.alphanumeric.downcase
- p = { secret: secret }
+ p = { secret: secret, product_line: "genesis_1.7" }
run_jobs_now { post :create, body: p.to_json }
user, secret_again = Transport
.current
diff --git a/spec/controllers/api/devices/devices_controller_seed_spec.rb b/spec/controllers/api/devices/devices_controller_seed_spec.rb
index 8a9c027815..22b32b30a2 100644
--- a/spec/controllers/api/devices/devices_controller_seed_spec.rb
+++ b/spec/controllers/api/devices/devices_controller_seed_spec.rb
@@ -268,7 +268,7 @@ def settings_default_map_size_y?(device)
expect(device.reload.name).to eq(old_name)
end
- def start_tests(product_line, publish = true)
+ def start_tests(product_line, publish = true, demo = false)
u = FactoryBot.create(:user)
ClimateControl.modify AUTHORIZED_PUBLISHER: u.email do
if publish
@@ -295,7 +295,7 @@ def start_tests(product_line, publish = true)
end
sign_in user
run_jobs_now do
- post :seed, body: { product_line: product_line }.to_json
+ post :seed, body: { product_line: product_line, demo: demo }.to_json
end
expect(response.status).to eq(200)
device.reload
@@ -680,6 +680,81 @@ def check_slot_pairing(slot, expected_name)
expect(settings_default_map_size_y?(device)).to eq(1400)
end
+ it "seeds accounts with Genesis 1.7 data" do
+ start_tests "genesis_1.7"
+
+ expect(peripherals_lighting?(device).pin).to eq(7)
+ expect(peripherals_peripheral_4?(device).pin).to eq(10)
+ expect(peripherals_peripheral_5?(device).pin).to eq(12)
+ expect(peripherals_vacuum?(device).pin).to be(9)
+ expect(peripherals_water?(device).pin).to be(8)
+ expect(peripherals_rotary_tool?(device).pin).to eq(2)
+ expect(peripherals_rotary_tool_reverse?(device).pin).to eq(3)
+ expect(pin_bindings_button_1?(device).special_action).to eq("emergency_lock")
+ expect(pin_bindings_button_2?(device).special_action).to eq("emergency_unlock")
+ expect(plants?(device)).to be false
+ expect(sensors_soil_sensor?(device).pin).to eq(59)
+ expect(sensors_tool_verification?(device).pin).to eq(63)
+ expect(settings_device_name?(device)).to eq(Names::GENESIS)
+ expect(settings_change_firmware_config_defaults?(device)).to be(true)
+ expect(settings_soil_height?(device)).to eq(-200)
+ expect(settings_gantry_height?(device)).to eq(120)
+ expect(settings_firmware?(device)).to eq("farmduino_k17")
+ expect(settings_hide_sensors?(device)).to be(false)
+ expect(tool_slots_slot_1?(device).name).to eq("Slot")
+ expect(tool_slots_slot_2?(device).name).to eq("Slot")
+ expect(tool_slots_slot_3?(device).name).to eq("Slot")
+ expect(tool_slots_slot_4?(device).name).to eq("Slot")
+ expect(tool_slots_slot_5?(device).name).to eq("Slot")
+ expect(tool_slots_slot_6?(device).name).to eq("Slot")
+ expect(tool_slots_slot_7?(device).name).to eq("Slot")
+ expect(tool_slots_slot_8?(device).name).to eq("Slot")
+ expect(tool_slots_slot_9?(device)).to_not be
+
+ check_slot_pairing(tool_slots_slot_1?(device), "Seeder")
+ check_slot_pairing(tool_slots_slot_2?(device), "Seed Bin")
+ check_slot_pairing(tool_slots_slot_3?(device), "Seed Tray")
+ check_slot_pairing(tool_slots_slot_4?(device), "Watering Nozzle")
+ check_slot_pairing(tool_slots_slot_5?(device), "Soil Sensor")
+ check_slot_pairing(tool_slots_slot_6?(device), "Rotary Tool")
+ check_slot_pairing(tool_slots_slot_7?(device), "Seed Trough 1")
+ check_slot_pairing(tool_slots_slot_8?(device), "Seed Trough 2")
+
+ expect(tools_seed_bin?(device)).to be
+ expect(tools_seed_tray?(device)).to be
+ expect(tools_seed_trough_1?(device)).to be
+ expect(tools_seed_trough_2?(device)).to be
+ expect(tools_seeder?(device)).to be_kind_of(Tool)
+ expect(tools_soil_sensor?(device)).to be_kind_of(Tool)
+ expect(tools_watering_nozzle?(device)).to be_kind_of(Tool)
+ expect(tools_weeder?(device)).to_not be
+ expect(tools_rotary?(device)).to be_kind_of(Tool)
+ expect(sequences_pickup_seed?(device)).to be
+ expect(sequences_plant_seed?(device)).to be_kind_of(Sequence)
+ expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(device)).to be_kind_of(Sequence)
+ expect(point_groups_spinach?(device)).to_not be
+ expect(point_groups_broccoli?(device)).to_not be
+ expect(point_groups_beet?(device)).to_not be
+ expect(point_groups_all_plants?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_points?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_weeds?(device)).to be_kind_of(PointGroup)
+ expect(sequences_find_home?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all_plants?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all?(device)).to be_kind_of(Sequence)
+ expect(sequences_photo_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_weed_detection_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_soil_height_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_dispense_water?(device)).to be_kind_of(Sequence)
+ expect(sequences_mount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence)
+ expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence)
+ expect(settings_default_map_size_x?(device)).to eq(2900)
+ expect(settings_default_map_size_y?(device)).to eq(1400)
+ end
+
it "seeds accounts with Genesis XL 1.4 data" do
start_tests "genesis_xl_1.4"
@@ -828,6 +903,81 @@ def check_slot_pairing(slot, expected_name)
expect(settings_default_map_size_y?(device)).to eq(2900)
end
+ it "seeds accounts with Genesis XL 1.7 data" do
+ start_tests "genesis_xl_1.7"
+
+ expect(peripherals_lighting?(device).pin).to eq(7)
+ expect(peripherals_peripheral_4?(device).pin).to eq(10)
+ expect(peripherals_peripheral_5?(device).pin).to eq(12)
+ expect(peripherals_vacuum?(device).pin).to be(9)
+ expect(peripherals_water?(device).pin).to be(8)
+ expect(peripherals_rotary_tool?(device).pin).to eq(2)
+ expect(peripherals_rotary_tool_reverse?(device).pin).to eq(3)
+ expect(pin_bindings_button_1?(device).special_action).to eq("emergency_lock")
+ expect(pin_bindings_button_2?(device).special_action).to eq("emergency_unlock")
+ expect(plants?(device)).to be false
+ expect(sensors_soil_sensor?(device).pin).to eq(59)
+ expect(sensors_tool_verification?(device).pin).to eq(63)
+ expect(settings_device_name?(device)).to eq(Names::GENESIS_XL)
+ expect(settings_change_firmware_config_defaults?(device)).to be(true)
+ expect(settings_soil_height?(device)).to eq(-200)
+ expect(settings_gantry_height?(device)).to eq(120)
+ expect(settings_firmware?(device)).to eq("farmduino_k17")
+ expect(settings_hide_sensors?(device)).to be(false)
+ expect(tool_slots_slot_1?(device).name).to eq("Slot")
+ expect(tool_slots_slot_2?(device).name).to eq("Slot")
+ expect(tool_slots_slot_3?(device).name).to eq("Slot")
+ expect(tool_slots_slot_4?(device).name).to eq("Slot")
+ expect(tool_slots_slot_5?(device).name).to eq("Slot")
+ expect(tool_slots_slot_6?(device).name).to eq("Slot")
+ expect(tool_slots_slot_7?(device).name).to eq("Slot")
+ expect(tool_slots_slot_8?(device).name).to eq("Slot")
+ expect(tool_slots_slot_9?(device)).to_not be
+
+ check_slot_pairing(tool_slots_slot_1?(device), "Seeder")
+ check_slot_pairing(tool_slots_slot_2?(device), "Seed Bin")
+ check_slot_pairing(tool_slots_slot_3?(device), "Seed Tray")
+ check_slot_pairing(tool_slots_slot_4?(device), "Watering Nozzle")
+ check_slot_pairing(tool_slots_slot_5?(device), "Soil Sensor")
+ check_slot_pairing(tool_slots_slot_6?(device), "Rotary Tool")
+ check_slot_pairing(tool_slots_slot_7?(device), "Seed Trough 1")
+ check_slot_pairing(tool_slots_slot_8?(device), "Seed Trough 2")
+
+ expect(tools_seed_bin?(device)).to be
+ expect(tools_seed_tray?(device)).to be
+ expect(tools_seed_trough_1?(device)).to be
+ expect(tools_seed_trough_2?(device)).to be
+ expect(tools_seeder?(device)).to be_kind_of(Tool)
+ expect(tools_soil_sensor?(device)).to be_kind_of(Tool)
+ expect(tools_watering_nozzle?(device)).to be_kind_of(Tool)
+ expect(tools_weeder?(device)).to_not be
+ expect(tools_rotary?(device)).to be_kind_of(Tool)
+ expect(sequences_pickup_seed?(device)).to be
+ expect(sequences_plant_seed?(device)).to be_kind_of(Sequence)
+ expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(device)).to be_kind_of(Sequence)
+ expect(point_groups_spinach?(device)).to_not be
+ expect(point_groups_broccoli?(device)).to_not be
+ expect(point_groups_beet?(device)).to_not be
+ expect(point_groups_all_plants?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_points?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_weeds?(device)).to be_kind_of(PointGroup)
+ expect(sequences_find_home?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all_plants?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all?(device)).to be_kind_of(Sequence)
+ expect(sequences_photo_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_weed_detection_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_soil_height_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_dispense_water?(device)).to be_kind_of(Sequence)
+ expect(sequences_mount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_dismount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence)
+ expect(sequences_pick_from_seed_tray?(device)).to be_kind_of(Sequence)
+ expect(settings_default_map_size_x?(device)).to eq(5900)
+ expect(settings_default_map_size_y?(device)).to eq(2900)
+ end
+
it "seeds accounts with Genesis XL 1.6 data" do
start_tests "genesis_xl_1.6"
@@ -1042,6 +1192,75 @@ def check_slot_pairing(slot, expected_name)
expect(settings_default_map_size_y?(device)).to eq(1200)
end
+ it "seeds accounts with Express 1.2 data" do
+ start_tests "express_1.2"
+
+ expect(peripherals_lighting?(device).pin).to eq(7)
+ expect(peripherals_peripheral_4?(device)).to_not be
+ expect(peripherals_peripheral_5?(device)).to_not be
+ expect(peripherals_vacuum?(device).pin).to be(9)
+ expect(peripherals_water?(device).pin).to be(8)
+ expect(peripherals_rotary_tool?(device)).to_not be
+ expect(peripherals_rotary_tool_reverse?(device)).to_not be
+ expect(pin_bindings_button_1?(device).special_action).to eq("emergency_lock")
+ expect(pin_bindings_button_2?(device).special_action).to eq("emergency_unlock")
+ expect(plants?(device)).to be false
+ expect(sensors_soil_sensor?(device)).to_not be
+ expect(sensors_tool_verification?(device)).to_not be
+ expect(settings_device_name?(device)).to eq(Names::EXPRESS)
+ expect(settings_change_firmware_config_defaults?(device)).to be(false)
+ expect(settings_soil_height?(device)).to eq(-200)
+ expect(settings_gantry_height?(device)).to eq(140)
+ expect(settings_firmware?(device)).to eq("express_k12")
+ expect(settings_hide_sensors?(device)).to be(true)
+ expect(tool_slots_slot_1?(device).name).to eq("Slot")
+ expect(tool_slots_slot_2?(device).name).to eq("Slot")
+ expect(tool_slots_slot_3?(device)).to_not be
+ expect(tool_slots_slot_4?(device)).to_not be
+ expect(tool_slots_slot_5?(device)).to_not be
+ expect(tool_slots_slot_6?(device)).to_not be
+ expect(tool_slots_slot_7?(device)).to_not be
+ expect(tool_slots_slot_8?(device)).to_not be
+ expect(tool_slots_slot_9?(device)).to_not be
+
+ check_slot_pairing(tool_slots_slot_1?(device), "Seed Trough 1")
+ check_slot_pairing(tool_slots_slot_2?(device), "Seed Trough 2")
+
+ expect(tools_seed_bin?(device)).to_not be
+ expect(tools_seed_tray?(device)).to_not be
+ expect(tools_seed_trough_1?(device)).to be
+ expect(tools_seed_trough_2?(device)).to be
+ expect(tools_seeder?(device)).to_not be
+ expect(tools_soil_sensor?(device)).to_not be
+ expect(tools_watering_nozzle?(device)).to be_kind_of(Tool)
+ expect(tools_weeder?(device)).to_not be
+ expect(tools_rotary?(device)).to_not be
+ expect(sequences_pickup_seed?(device)).to be
+ expect(sequences_plant_seed?(device)).to be_kind_of(Sequence)
+ expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(device)).to be_kind_of(Sequence)
+ expect(point_groups_spinach?(device)).to_not be
+ expect(point_groups_broccoli?(device)).to_not be
+ expect(point_groups_beet?(device)).to_not be
+ expect(point_groups_all_plants?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_points?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_weeds?(device)).to be_kind_of(PointGroup)
+ expect(sequences_find_home?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all_plants?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all?(device)).to be_kind_of(Sequence)
+ expect(sequences_photo_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_weed_detection_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_soil_height_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_dispense_water?(device)).to be_kind_of(Sequence)
+ expect(sequences_mount_tool?(device)).to_not be
+ expect(sequences_dismount_tool?(device)).to_not be
+ expect(sequences_mow_all_weeds?(device)).to_not be
+ expect(sequences_pick_from_seed_tray?(device)).to_not be
+ expect(settings_default_map_size_x?(device)).to eq(2900)
+ expect(settings_default_map_size_y?(device)).to eq(1200)
+ end
+
it "seeds accounts with Express XL 1.0 data" do
start_tests "express_xl_1.0"
@@ -1180,8 +1399,77 @@ def check_slot_pairing(slot, expected_name)
expect(settings_default_map_size_y?(device)).to eq(2400)
end
+ it "seeds accounts with Express XL 1.2 data" do
+ start_tests "express_xl_1.2"
+
+ expect(peripherals_lighting?(device).pin).to eq(7)
+ expect(peripherals_peripheral_4?(device)).to_not be
+ expect(peripherals_peripheral_5?(device)).to_not be
+ expect(peripherals_vacuum?(device).pin).to be(9)
+ expect(peripherals_water?(device).pin).to be(8)
+ expect(peripherals_rotary_tool?(device)).to_not be
+ expect(peripherals_rotary_tool_reverse?(device)).to_not be
+ expect(pin_bindings_button_1?(device).special_action).to eq("emergency_lock")
+ expect(pin_bindings_button_2?(device).special_action).to eq("emergency_unlock")
+ expect(plants?(device)).to be false
+ expect(sensors_soil_sensor?(device)).to_not be
+ expect(sensors_tool_verification?(device)).to_not be
+ expect(settings_device_name?(device)).to eq(Names::EXPRESS_XL)
+ expect(settings_change_firmware_config_defaults?(device)).to be(false)
+ expect(settings_soil_height?(device)).to eq(-200)
+ expect(settings_gantry_height?(device)).to eq(140)
+ expect(settings_firmware?(device)).to eq("express_k12")
+ expect(settings_hide_sensors?(device)).to be(true)
+ expect(tool_slots_slot_1?(device).name).to eq("Slot")
+ expect(tool_slots_slot_2?(device).name).to eq("Slot")
+ expect(tool_slots_slot_3?(device)).to_not be
+ expect(tool_slots_slot_4?(device)).to_not be
+ expect(tool_slots_slot_5?(device)).to_not be
+ expect(tool_slots_slot_6?(device)).to_not be
+ expect(tool_slots_slot_7?(device)).to_not be
+ expect(tool_slots_slot_8?(device)).to_not be
+ expect(tool_slots_slot_9?(device)).to_not be
+
+ check_slot_pairing(tool_slots_slot_1?(device), "Seed Trough 1")
+ check_slot_pairing(tool_slots_slot_2?(device), "Seed Trough 2")
+
+ expect(tools_seed_bin?(device)).to_not be
+ expect(tools_seed_tray?(device)).to_not be
+ expect(tools_seed_trough_1?(device)).to be
+ expect(tools_seed_trough_2?(device)).to be
+ expect(tools_seeder?(device)).to_not be
+ expect(tools_soil_sensor?(device)).to_not be
+ expect(tools_watering_nozzle?(device)).to be_kind_of(Tool)
+ expect(tools_weeder?(device)).to_not be
+ expect(tools_rotary?(device)).to_not be
+ expect(sequences_pickup_seed?(device)).to be
+ expect(sequences_plant_seed?(device)).to be_kind_of(Sequence)
+ expect(sequences_take_photo_of_plant?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(device)).to be_kind_of(Sequence)
+ expect(point_groups_spinach?(device)).to_not be
+ expect(point_groups_broccoli?(device)).to_not be
+ expect(point_groups_beet?(device)).to_not be
+ expect(point_groups_all_plants?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_points?(device)).to be_kind_of(PointGroup)
+ expect(point_groups_all_weeds?(device)).to be_kind_of(PointGroup)
+ expect(sequences_find_home?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all_plants?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_all?(device)).to be_kind_of(Sequence)
+ expect(sequences_photo_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_weed_detection_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_soil_height_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_grid?(device)).to be_kind_of(Sequence)
+ expect(sequences_dispense_water?(device)).to be_kind_of(Sequence)
+ expect(sequences_mount_tool?(device)).to_not be
+ expect(sequences_dismount_tool?(device)).to_not be
+ expect(sequences_mow_all_weeds?(device)).to_not be
+ expect(sequences_pick_from_seed_tray?(device)).to_not be
+ expect(settings_default_map_size_x?(device)).to eq(6000)
+ expect(settings_default_map_size_y?(device)).to eq(2400)
+ end
+
it "seeds accounts with demo account data" do
- start_tests "demo_account"
+ start_tests "genesis_1.7", true, true
expect(plants?(device)).to be true
expect(point_groups_spinach?(device)).to be_kind_of(PointGroup)
@@ -1190,7 +1478,7 @@ def check_slot_pairing(slot, expected_name)
end
it "seeds accounts when sequence versions not available: demo account" do
- start_tests "demo_account", false
+ start_tests "genesis_1.7", false, true
expect(sequences_grid?(device)).to be_kind_of(Sequence)
end
@@ -1207,6 +1495,18 @@ def check_slot_pairing(slot, expected_name)
expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence)
end
+ it "seeds accounts when sequence versions not available: Genesis XL 1.7" do
+ start_tests "genesis_xl_1.7", false
+
+ expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence)
+ end
+
+ it "seeds accounts when sequence versions not available: Genesis 1.7" do
+ start_tests "genesis_1.7", false
+
+ expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence)
+ end
+
it "does not seed accounts" do
start_tests "none"
diff --git a/spec/mutations/sequences/publish_spec.rb b/spec/mutations/sequences/publish_spec.rb
index 1612fcf228..8b69a8feea 100644
--- a/spec/mutations/sequences/publish_spec.rb
+++ b/spec/mutations/sequences/publish_spec.rb
@@ -138,7 +138,7 @@
it "does not allow guests to publish" do
run_jobs_now do
- Users::CreateDemo.run!(secret: SecureRandom.hex)
+ Users::CreateDemo.run!(secret: SecureRandom.hex, product_line: "genesis_1.7")
end
guest = User.find_by!("email LIKE '%@farmbot.guest'")
device = guest.device