diff --git a/app/controllers/api/sensor_readings_controller.rb b/app/controllers/api/sensor_readings_controller.rb
index a0e945873..65feb4c28 100644
--- a/app/controllers/api/sensor_readings_controller.rb
+++ b/app/controllers/api/sensor_readings_controller.rb
@@ -1,7 +1,10 @@
module Api
class SensorReadingsController < Api::AbstractController
+ LIMIT = 5000
+ before_action :clean_old
+
def create
- mutate SensorReadings::Create.run(raw_json, device: current_device)
+ mutate SensorReadings::Create.run(raw_json, device: current_device)
end
def index
@@ -17,10 +20,23 @@ module Api
render json: ""
end
- private
+ private
+
+ def clean_old
+ if current_device.sensor_readings.count > LIMIT
+ current_device
+ .sensor_readings
+ .where
+ .not(id: readings.pluck(:id))
+ .delete_all
+ end
+ end
def readings
- SensorReading.where(device: current_device)
+ @readings ||= SensorReading
+ .where(device: current_device)
+ .order(created_at: :desc)
+ .limit(LIMIT)
end
def reading
diff --git a/app/models/device.rb b/app/models/device.rb
index f2ecf6521..750244f22 100644
--- a/app/models/device.rb
+++ b/app/models/device.rb
@@ -171,9 +171,10 @@ class Device < ApplicationRecord
end
TOO_MANY_CONNECTIONS =
- "Your device is " +
- "reconnecting to the server too often. Please " +
- "see https://developer.farm.bot/docs/connectivity-issues"
+ "Your device is reconnecting to the server too often. " +
+ "This may be a sign of local network issues. " +
+ "Please review the documentation provided at " +
+ "https://software.farm.bot/docs/connecting-farmbot-to-the-internet"
def self.connection_warning(username)
device_id = username.split("_").last.to_i || 0
device = self.find_by(id: device_id)
diff --git a/app/mutations/devices/create_seed_data.rb b/app/mutations/devices/create_seed_data.rb
index 8cc336244..fb0899b39 100644
--- a/app/mutations/devices/create_seed_data.rb
+++ b/app/mutations/devices/create_seed_data.rb
@@ -7,7 +7,9 @@ module Devices
"genesis_1.2" => Devices::Seeders::GenesisOneTwo,
"genesis_1.3" => Devices::Seeders::GenesisOneThree,
"genesis_1.4" => Devices::Seeders::GenesisOneFour,
+ "genesis_1.5" => Devices::Seeders::GenesisOneFive,
"genesis_xl_1.4" => Devices::Seeders::GenesisXlOneFour,
+ "genesis_xl_1.5" => Devices::Seeders::GenesisXlOneFive,
"demo_account" => Devices::Seeders::DemoAccountSeeder,
"none" => Devices::Seeders::None,
diff --git a/app/mutations/devices/seeders/genesis_one_five.rb b/app/mutations/devices/seeders/genesis_one_five.rb
new file mode 100644
index 000000000..dde23e30d
--- /dev/null
+++ b/app/mutations/devices/seeders/genesis_one_five.rb
@@ -0,0 +1,11 @@
+module Devices
+ module Seeders
+ class GenesisOneFive < AbstractGenesis
+ def settings_firmware
+ device
+ .fbos_config
+ .update!(firmware_hardware: FbosConfig::FARMDUINO_K15)
+ end
+ end
+ end
+end
diff --git a/app/mutations/devices/seeders/genesis_xl_one_five.rb b/app/mutations/devices/seeders/genesis_xl_one_five.rb
new file mode 100644
index 000000000..b3e291a1f
--- /dev/null
+++ b/app/mutations/devices/seeders/genesis_xl_one_five.rb
@@ -0,0 +1,23 @@
+module Devices
+ module Seeders
+ class GenesisXlOneFive < AbstractGenesis
+ def settings_firmware
+ device
+ .fbos_config
+ .update!(firmware_hardware: FbosConfig::FARMDUINO_K15)
+ end
+
+ def settings_device_name
+ device.update!(name: "FarmBot Genesis XL")
+ end
+
+ def settings_default_map_size_x
+ device.web_app_config.update!(map_size_x: 5_900)
+ end
+
+ def settings_default_map_size_y
+ device.web_app_config.update!(map_size_y: 2_900)
+ end
+ end
+ end
+end
diff --git a/frontend/devices/components/fbos_settings/__tests__/fbos_details_test.tsx b/frontend/devices/components/fbos_settings/__tests__/fbos_details_test.tsx
index f7cd59033..0c4cdb602 100644
--- a/frontend/devices/components/fbos_settings/__tests__/fbos_details_test.tsx
+++ b/frontend/devices/components/fbos_settings/__tests__/fbos_details_test.tsx
@@ -85,6 +85,26 @@ describe("", () => {
expect(wrapper.text()).toContain("0.0.0");
});
+ it("displays firmware commit link from firmware_commit", () => {
+ const p = fakeProps();
+ const commit = "abcdefgh";
+ p.botInfoSettings.firmware_commit = commit;
+ const wrapper = mount();
+ expect(wrapper.find("a").last().text()).toEqual(commit);
+ expect(wrapper.find("a").last().props().href?.split("/").slice(-1)[0])
+ .toEqual(commit);
+ });
+
+ it("displays firmware commit link from version", () => {
+ const p = fakeProps();
+ const commit = "abcdefgh";
+ p.botInfoSettings.firmware_version = `1.2.3.R.x-${commit}+`;
+ const wrapper = mount();
+ expect(wrapper.find("a").last().text()).toEqual(commit);
+ expect(wrapper.find("a").last().props().href?.split("/").slice(-1)[0])
+ .toEqual(commit);
+ });
+
it("displays commit link", () => {
const p = fakeProps();
p.botInfoSettings.commit = "abcdefgh";
diff --git a/frontend/devices/components/fbos_settings/fbos_details.tsx b/frontend/devices/components/fbos_settings/fbos_details.tsx
index 9070b57cf..43ad6a0c7 100644
--- a/frontend/devices/components/fbos_settings/fbos_details.tsx
+++ b/frontend/devices/components/fbos_settings/fbos_details.tsx
@@ -260,6 +260,8 @@ export function FbosDetails(props: FbosDetailsProps) {
wifi_level_percent, cpu_usage, private_ip,
} = props.botInfoSettings;
const { last_ota, last_ota_checkup } = props.deviceAccount.body;
+ const firmwareCommit = [firmware_commit, firmware_version].includes("---")
+ ? firmware_commit : firmware_version?.split("-")[1] || firmware_commit;
return
{t("Local IP address")}: {private_ip}}
{t("Firmware")}: {reformatFwVersion(firmware_version)}
+ repo={"farmbot-arduino-firmware"} commit={firmwareCommit} />
{t("Firmware code")}: {firmware_version}
{isNumber(uptime) && }
{isNumber(memory_usage) &&
diff --git a/frontend/messages/cards.tsx b/frontend/messages/cards.tsx
index 0dcf9cce9..8b03e50e5 100644
--- a/frontend/messages/cards.tsx
+++ b/frontend/messages/cards.tsx
@@ -23,7 +23,6 @@ import {
import { updateConfig } from "../devices/actions";
import { fetchBulletinContent, seedAccount } from "./actions";
import { startCase } from "lodash";
-import { DevSettings } from "../account/dev/dev_support";
import { Session } from "../session";
export const AlertCard = (props: AlertCardProps) => {
@@ -219,11 +218,11 @@ const SEED_DATA_OPTIONS = (): DropDownItem[] => [
{ label: "Genesis v1.2", value: "genesis_1.2" },
{ label: "Genesis v1.3", value: "genesis_1.3" },
{ label: "Genesis v1.4", value: "genesis_1.4" },
+ { label: "Genesis v1.5", value: "genesis_1.5" },
{ label: "Genesis v1.4 XL", value: "genesis_xl_1.4" },
- ...(DevSettings.futureFeaturesEnabled() ? [
- { label: "Express v1.0", value: "express_1.0" },
- { label: "Express v1.0 XL", value: "express_xl_1.0" },
- ] : []),
+ { label: "Genesis v1.5 XL", value: "genesis_xl_1.5" },
+ { label: "Express v1.0", value: "express_1.0" },
+ { label: "Express v1.0 XL", value: "express_xl_1.0" },
{ label: "Custom Bot", value: "none" },
];
diff --git a/spec/controllers/api/devices/devices_controller_seed_spec.rb b/spec/controllers/api/devices/devices_controller_seed_spec.rb
index ade9cf50d..259e07667 100644
--- a/spec/controllers/api/devices/devices_controller_seed_spec.rb
+++ b/spec/controllers/api/devices/devices_controller_seed_spec.rb
@@ -352,6 +352,50 @@ describe Api::DevicesController do
expect(settings_default_map_size_y?(device)).to eq(1400)
end
+ it "seeds accounts with Genesis 1.5 data" do
+ start_tests "genesis_1.5"
+
+ 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(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 true
+ 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("FarmBot Genesis")
+ expect(settings_enable_encoders?(device)).to be(true)
+ expect(settings_firmware?(device)).to eq("farmduino_k15")
+ expect(settings_hide_sensors?(device)).to be(false)
+ expect(tool_slots_slot_1?(device).name).to eq("Seeder")
+ expect(tool_slots_slot_2?(device).name).to eq("Seed Bin")
+ expect(tool_slots_slot_3?(device).name).to eq("Seed Tray")
+ expect(tool_slots_slot_4?(device).name).to eq("Watering Nozzle")
+ expect(tool_slots_slot_5?(device).name).to eq("Soil Sensor")
+ expect(tool_slots_slot_6?(device).name).to eq("Weeder")
+ expect(tools_seed_bin?(device)).to be
+ expect(tools_seed_tray?(device)).to be
+ expect(tools_seed_trough_1?(device)).to_not be
+ expect(tools_seed_trough_2?(device)).to_not be
+ expect(tools_seed_trough_3?(device)).to_not 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 be_kind_of(Tool)
+ expect(sequences_mount_tool?(device)).to be
+ expect(sequences_pickup_seed_genesis?(device)).to be
+ expect(sequences_pickup_seed_express?(device)).to_not 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_tool_error?(device)).to be_kind_of(Sequence)
+ expect(sequences_unmount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(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"
@@ -404,6 +448,58 @@ describe Api::DevicesController do
expect(settings_default_map_size_y?(device)).to eq(2900)
end
+ it "seeds accounts with Genesis XL 1.5 data" do
+ start_tests "genesis_xl_1.5"
+
+ 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(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 true
+ 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("FarmBot Genesis XL")
+ expect(settings_enable_encoders?(device)).to be(true)
+ expect(settings_firmware?(device)).to eq("farmduino_k15")
+ expect(settings_hide_sensors?(device)).to be(false)
+ expect(tool_slots_slot_1?(device).name).to eq("Seeder")
+ expect(tool_slots_slot_2?(device).name).to eq("Seed Bin")
+ expect(tool_slots_slot_3?(device).name).to eq("Seed Tray")
+ expect(tool_slots_slot_4?(device).name).to eq("Watering Nozzle")
+ expect(tool_slots_slot_5?(device).name).to eq("Soil Sensor")
+ expect(tool_slots_slot_6?(device).name).to eq("Weeder")
+
+ 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), "Weeder")
+
+ expect(tools_seed_bin?(device)).to be
+ expect(tools_seed_tray?(device)).to be
+ expect(tools_seed_trough_1?(device)).to_not be
+ expect(tools_seed_trough_2?(device)).to_not be
+ expect(tools_seed_trough_3?(device)).to_not 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 be_kind_of(Tool)
+ expect(sequences_mount_tool?(device)).to be
+ expect(sequences_pickup_seed_genesis?(device)).to be
+ expect(sequences_pickup_seed_express?(device)).to_not 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_tool_error?(device)).to be_kind_of(Sequence)
+ expect(sequences_unmount_tool?(device)).to be_kind_of(Sequence)
+ expect(sequences_water_plant?(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 Express 1.0 data" do
start_tests "express_1.0"
diff --git a/spec/controllers/api/sensor_readings/controller_spec.rb b/spec/controllers/api/sensor_readings/controller_spec.rb
index 19a1e8612..7f544917c 100644
--- a/spec/controllers/api/sensor_readings/controller_spec.rb
+++ b/spec/controllers/api/sensor_readings/controller_spec.rb
@@ -18,7 +18,7 @@ describe Api::SensorReadingsController do
x: nil,
y: 1,
z: 2,
- mode: 1
+ mode: 1,
}.to_json,
params: { format: :json }
@@ -40,7 +40,7 @@ describe Api::SensorReadingsController do
y: 1,
z: 2,
mode: 1,
- read_at: read_at
+ read_at: read_at,
}.to_json,
params: { format: :json }
@@ -105,5 +105,23 @@ describe Api::SensorReadingsController do
post :create, body: {}.to_json
expect(response.status).to eq(401)
end
+
+ it "cleans up excess logs" do
+ const_reassign(Api::SensorReadingsController, :LIMIT, 5)
+ sign_in user
+ 10.times do |n|
+ FactoryBot.create(:sensor_reading,
+ device: user.device,
+ created_at: n.minutes.ago)
+ end
+ expect(user.device.sensor_readings.count).to eq(10)
+ get :index, params: { format: :json }
+ expect(json.count).to eq(5)
+ expect(user.device.sensor_readings.count).to eq(5)
+ const_reassign(Api::SensorReadingsController, :LIMIT, 5000)
+ first = (json.first[:created_at])
+ last = (json.last[:created_at])
+ expect(first).to be > last
+ end
end
end