From 8a1b68cfd245f5db901cadb82b81eda94ec7e067 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Wed, 25 Oct 2023 16:17:02 -0700 Subject: [PATCH 1/5] change express sequence safe z steps --- .../devices/seeders/abstract_express.rb | 25 ++- .../devices/seeders/abstract_genesis.rb | 9 +- .../devices/seeders/abstract_seeder.rb | 8 +- app/mutations/devices/seeders/constants.rb | 5 +- .../devices/seeders/genesis_one_five.rb | 4 +- .../devices/seeders/genesis_one_six.rb | 4 +- .../devices/seeders/genesis_xl_one_five.rb | 4 +- .../devices/seeders/genesis_xl_one_six.rb | 4 +- .../devices/seeders/sequence_fixtures.yml | 158 +++++++++++++++++- .../devices/devices_controller_seed_spec.rb | 44 ++--- 10 files changed, 199 insertions(+), 66 deletions(-) diff --git a/app/mutations/devices/seeders/abstract_express.rb b/app/mutations/devices/seeders/abstract_express.rb index 6a3cd61cfa..96ce1379d2 100644 --- a/app/mutations/devices/seeders/abstract_express.rb +++ b/app/mutations/devices/seeders/abstract_express.rb @@ -33,7 +33,7 @@ def tool_slots_slot_1 add_tool_slot(name: ToolNames::SEED_TROUGH_1, x: 0, y: 25, - z: 0, + z: -100, tool: tools_seed_trough_1, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -43,7 +43,7 @@ def tool_slots_slot_2 add_tool_slot(name: ToolNames::SEED_TROUGH_2, x: 0, y: 50, - z: 0, + z: -100, tool: tools_seed_trough_2, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -79,16 +79,23 @@ def sequences_dismount_tool; end def sequences_pick_up_seed s = SequenceSeeds::PICK_UP_SEED_EXPRESS.deep_dup - s.dig(:body, 1, :body, 0, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 1, :body, 1, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 1, :body, 2, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 2, :args, :pin_number, :args)[:pin_id] = vacuum_id + s.dig(:body, 0, :body, 0, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + s.dig(:body, 0, :body, 1, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + s.dig(:body, 0, :body, 2, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + s.dig(:body, 1, :args, :pin_number, :args)[:pin_id] = vacuum_id + s.dig(:body, 2, :body, 0, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + s.dig(:body, 2, :body, 1, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + s.dig(:body, 2, :body, 2, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id s.dig(:body, 3, :body, 0, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id s.dig(:body, 3, :body, 1, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id s.dig(:body, 3, :body, 2, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 4, :body, 0, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 4, :body, 1, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id - s.dig(:body, 4, :body, 2, :args, :axis_operand, :args)[:tool_id] = seed_trough_1_id + Sequences::Create.run!(s, device: device) + end + + def sequences_plant_seed + s = SequenceSeeds::PLANT_SEED_EXPRESS.deep_dup + + s.dig(:body, 2, :args, :pin_number, :args)[:pin_id] = vacuum_id Sequences::Create.run!(s, device: device) end diff --git a/app/mutations/devices/seeders/abstract_genesis.rb b/app/mutations/devices/seeders/abstract_genesis.rb index d8b4c60f9d..451e177d59 100644 --- a/app/mutations/devices/seeders/abstract_genesis.rb +++ b/app/mutations/devices/seeders/abstract_genesis.rb @@ -139,8 +139,15 @@ def sequences_pick_up_seed Sequences::Create.run!(s, device: device) end + def sequences_plant_seed + s = SequenceSeeds::PLANT_SEED_GENESIS.deep_dup + + s.dig(:body, 2, :args, :pin_number, :args)[:pin_id] = vacuum_id + Sequences::Create.run!(s, device: device) + end + def sequences_find_home - s = SequenceSeeds::FIND_HOME.deep_dup + s = SequenceSeeds::FIND_HOME_GENESIS.deep_dup Sequences::Create.run!(s, device: device) end diff --git a/app/mutations/devices/seeders/abstract_seeder.rb b/app/mutations/devices/seeders/abstract_seeder.rb index 3b215e090f..a07b1be26a 100644 --- a/app/mutations/devices/seeders/abstract_seeder.rb +++ b/app/mutations/devices/seeders/abstract_seeder.rb @@ -122,13 +122,7 @@ def sensors_tool_verification; end def sequences_mount_tool; end def sequences_dismount_tool; end def sequences_pick_up_seed; end - - def sequences_plant_seed - s = SequenceSeeds::PLANT_SEED.deep_dup - - s.dig(:body, 2, :args, :pin_number, :args)[:pin_id] = vacuum_id - Sequences::Create.run!(s, device: device) - end + def sequences_plant_seed; end def sequences_take_photo_of_plant s = SequenceSeeds::TAKE_PHOTO_OF_PLANT.deep_dup diff --git a/app/mutations/devices/seeders/constants.rb b/app/mutations/devices/seeders/constants.rb index 9608059300..fc3b07b8a8 100644 --- a/app/mutations/devices/seeders/constants.rb +++ b/app/mutations/devices/seeders/constants.rb @@ -41,11 +41,12 @@ module SequenceSeeds ALL = YAML.load(File.read(SEQUENCE_FIXTURE_PATH)) PICK_UP_SEED_EXPRESS = ALL.fetch(:PICK_UP_SEED_EXPRESS) PICK_UP_SEED_GENESIS = ALL.fetch(:PICK_UP_SEED_GENESIS) - PLANT_SEED = ALL.fetch(:PLANT_SEED) + PLANT_SEED_GENESIS = ALL.fetch(:PLANT_SEED_GENESIS) + PLANT_SEED_EXPRESS = ALL.fetch(:PLANT_SEED_EXPRESS) TAKE_PHOTO_OF_PLANT = ALL.fetch(:TAKE_PHOTO_OF_PLANT) WATER_PLANT = ALL.fetch(:WATER_PLANT) WATER_ALL_PLANTS = ALL.fetch(:WATER_ALL_PLANTS) - FIND_HOME = ALL.fetch(:FIND_HOME) + FIND_HOME_GENESIS = ALL.fetch(:FIND_HOME_GENESIS) FIND_HOME_EXPRESS = ALL.fetch(:FIND_HOME_EXPRESS) end diff --git a/app/mutations/devices/seeders/genesis_one_five.rb b/app/mutations/devices/seeders/genesis_one_five.rb index d220fae027..48d358b7ef 100644 --- a/app/mutations/devices/seeders/genesis_one_five.rb +++ b/app/mutations/devices/seeders/genesis_one_five.rb @@ -11,7 +11,7 @@ def tool_slots_slot_7 add_tool_slot(name: ToolNames::SEED_TROUGH_1, x: 0, y: 25, - z: 0, + z: -100, tool: tools_seed_trough_1, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -21,7 +21,7 @@ def tool_slots_slot_8 add_tool_slot(name: ToolNames::SEED_TROUGH_2, x: 0, y: 50, - z: 0, + z: -100, tool: tools_seed_trough_2, pullout_direction: ToolSlot::NONE, gantry_mounted: true) diff --git a/app/mutations/devices/seeders/genesis_one_six.rb b/app/mutations/devices/seeders/genesis_one_six.rb index 4cc07671cf..185d29dac3 100644 --- a/app/mutations/devices/seeders/genesis_one_six.rb +++ b/app/mutations/devices/seeders/genesis_one_six.rb @@ -30,7 +30,7 @@ def tool_slots_slot_8 add_tool_slot(name: ToolNames::SEED_TROUGH_1, x: 0, y: 25, - z: 0, + z: -100, tool: tools_seed_trough_1, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -40,7 +40,7 @@ def tool_slots_slot_9 add_tool_slot(name: ToolNames::SEED_TROUGH_2, x: 0, y: 50, - z: 0, + z: -100, tool: tools_seed_trough_2, pullout_direction: ToolSlot::NONE, gantry_mounted: true) diff --git a/app/mutations/devices/seeders/genesis_xl_one_five.rb b/app/mutations/devices/seeders/genesis_xl_one_five.rb index bd8453c95b..15ef0e14ef 100644 --- a/app/mutations/devices/seeders/genesis_xl_one_five.rb +++ b/app/mutations/devices/seeders/genesis_xl_one_five.rb @@ -23,7 +23,7 @@ def tool_slots_slot_7 add_tool_slot(name: ToolNames::SEED_TROUGH_1, x: 0, y: 25, - z: 0, + z: -100, tool: tools_seed_trough_1, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -33,7 +33,7 @@ def tool_slots_slot_8 add_tool_slot(name: ToolNames::SEED_TROUGH_2, x: 0, y: 50, - z: 0, + z: -100, tool: tools_seed_trough_2, pullout_direction: ToolSlot::NONE, gantry_mounted: true) diff --git a/app/mutations/devices/seeders/genesis_xl_one_six.rb b/app/mutations/devices/seeders/genesis_xl_one_six.rb index 98724c0cc9..988abea727 100644 --- a/app/mutations/devices/seeders/genesis_xl_one_six.rb +++ b/app/mutations/devices/seeders/genesis_xl_one_six.rb @@ -42,7 +42,7 @@ def tool_slots_slot_8 add_tool_slot(name: ToolNames::SEED_TROUGH_1, x: 0, y: 25, - z: 0, + z: -100, tool: tools_seed_trough_1, pullout_direction: ToolSlot::NONE, gantry_mounted: true) @@ -52,7 +52,7 @@ def tool_slots_slot_9 add_tool_slot(name: ToolNames::SEED_TROUGH_2, x: 0, y: 50, - z: 0, + z: -100, tool: tools_seed_trough_2, pullout_direction: ToolSlot::NONE, gantry_mounted: true) diff --git a/app/mutations/devices/seeders/sequence_fixtures.yml b/app/mutations/devices/seeders/sequence_fixtures.yml index 51a4adb7a5..8f7d55ade5 100644 --- a/app/mutations/devices/seeders/sequence_fixtures.yml +++ b/app/mutations/devices/seeders/sequence_fixtures.yml @@ -133,7 +133,7 @@ :pin_type: Peripheral :comment: Turn off water -:PLANT_SEED: # =================================== +:PLANT_SEED_GENESIS: # =================================== :args: :locals: :kind: scope_declaration @@ -272,19 +272,159 @@ :axis: z :comment: Move to safe Z position -:PICK_UP_SEED_EXPRESS: # ========================= +:PLANT_SEED_EXPRESS: # =================================== :args: :locals: :kind: scope_declaration :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: parent + :default_value: + :kind: coordinate + :args: + :z: 0 + :y: 0 + :x: 0 :color: yellow - :name: Pick up seed (Express) + :name: Plant seed :body: - - :kind: find_home + - :kind: move + :args: {} + :body: + - :kind: axis_overwrite + :args: + :axis: x + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: y + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: z + :axis_operand: + :kind: special_value + :args: + :label: "soil_height" + - :kind: axis_addition + :args: + :axis: z + :axis_operand: + :kind: numeric + :args: + :number: 150 + - :kind: safe_z + :args: {} + :comment: Move to above plant + - :kind: move + :args: {} + :body: + - :kind: axis_overwrite + :args: + :axis: x + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: y + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: z + :axis_operand: + :kind: special_value + :args: + :label: "soil_height" + - :kind: axis_addition + :args: + :axis: z + :axis_operand: + :kind: numeric + :args: + :number: -25 + - :kind: speed_overwrite + :args: + :axis: z + :speed_setting: + :kind: numeric + :args: + :number: 25 + :comment: Plant seed + - :kind: write_pin :args: - :speed: 100 - :axis: z - :comment: Find home + :pin_mode: 0 + :pin_value: 0 + :pin_number: + :kind: named_pin + :args: + :pin_id: 0 + :pin_type: Peripheral + :comment: Turn off vacuum pump + - :kind: move + :args: {} + :body: + - :kind: axis_overwrite + :args: + :axis: x + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: y + :axis_operand: + :kind: identifier + :args: + :label: parent + - :kind: axis_overwrite + :args: + :axis: z + :axis_operand: + :kind: special_value + :args: + :label: "soil_height" + - :kind: axis_addition + :args: + :axis: z + :axis_operand: + :kind: numeric + :args: + :number: 150 + :comment: Retract needle + - :kind: move + :args: {} + :body: + - :kind: axis_overwrite + :args: + :axis: z + :axis_operand: + :kind: numeric + :args: + :number: 0 + :comment: Move Z to home position + +:PICK_UP_SEED_EXPRESS: # ========================= + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: yellow + :name: Pick up seed + :body: - :kind: move :args: {} :body: @@ -400,7 +540,7 @@ :kind: scope_declaration :args: {} :color: yellow - :name: Pick up seed (Genesis) + :name: Pick up seed :body: - :kind: execute :args: @@ -556,7 +696,7 @@ :point_group_id: 0 :comment: Water all plants -:FIND_HOME: # ========================= +:FIND_HOME_GENESIS: # ========================= :args: :locals: :kind: scope_declaration diff --git a/spec/controllers/api/devices/devices_controller_seed_spec.rb b/spec/controllers/api/devices/devices_controller_seed_spec.rb index 06fe5e4029..3cc80d220b 100644 --- a/spec/controllers/api/devices/devices_controller_seed_spec.rb +++ b/spec/controllers/api/devices/devices_controller_seed_spec.rb @@ -165,12 +165,8 @@ def sequences_dismount_tool?(device) device.sequences.find_by(name: "Dismount Tool") end - def sequences_pickup_seed_genesis?(device) - device.sequences.find_by(name: "Pick up seed (Genesis)") - end - - def sequences_pickup_seed_express?(device) - device.sequences.find_by(name: "Pick up seed (Express)") + def sequences_pickup_seed?(device) + device.sequences.find_by(name: "Pick up seed") end def sequences_plant_seed?(device) @@ -351,8 +347,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -423,8 +418,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -495,8 +489,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -569,8 +562,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -644,8 +636,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -716,8 +707,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -790,8 +780,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to_not be - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -865,8 +854,7 @@ def check_slot_pairing(slot, expected_name) expect(tools_watering_nozzle?(device)).to be_kind_of(Tool) expect(tools_weeder?(device)).to be_kind_of(Tool) expect(tools_rotary?(device)).to be_kind_of(Tool) - expect(sequences_pickup_seed_genesis?(device)).to be - expect(sequences_pickup_seed_express?(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) @@ -933,8 +921,7 @@ def check_slot_pairing(slot, expected_name) 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_genesis?(device)).to_not be - expect(sequences_pickup_seed_express?(device)).to 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) @@ -1001,8 +988,7 @@ def check_slot_pairing(slot, expected_name) 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_genesis?(device)).to_not be - expect(sequences_pickup_seed_express?(device)).to 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) @@ -1069,8 +1055,7 @@ def check_slot_pairing(slot, expected_name) 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_genesis?(device)).to_not be - expect(sequences_pickup_seed_express?(device)).to 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) @@ -1137,8 +1122,7 @@ def check_slot_pairing(slot, expected_name) 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_genesis?(device)).to_not be - expect(sequences_pickup_seed_express?(device)).to 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) From 8cf9754b2d544dcd8c1197a110d48bca5b9be3ab Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Thu, 26 Oct 2023 12:52:56 -0700 Subject: [PATCH 2/5] add multiple bot text to order number error --- app/models/device.rb | 8 +++++++- config/locales/en.yml | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 config/locales/en.yml diff --git a/app/models/device.rb b/app/models/device.rb index fefaad4843..daab8108b3 100644 --- a/app/models/device.rb +++ b/app/models/device.rb @@ -8,6 +8,11 @@ class Device < ApplicationRecord TIMEZONES = TZInfo::Timezone.all_identifiers BAD_TZ = "%{value} is not a valid timezone" BAD_OTA_HOUR = "must be a value from 0 to 23." + ORDER_NUMBER_TAKEN = "has already been taken. " \ + "If you purchased multiple FarmBots with the same " \ + "order number, you may add -1, -2, -3, etc. to " \ + "the end of the order number to register additional " \ + "FarmBots after the first one." THROTTLE_ON = "Device is sending too many logs (%s). " \ "Suspending log storage and display until %s." THROTTLE_OFF = "Cooldown period has ended. " \ @@ -43,7 +48,8 @@ class Device < ApplicationRecord } validates :ota_hour, inclusion: { in: [*0..23], message: BAD_OTA_HOUR, allow_nil: true } - validates :fb_order_number, uniqueness: true, allow_nil: true + validates :fb_order_number, + uniqueness: { message: ORDER_NUMBER_TAKEN, allow_nil: true } before_validation :perform_gradual_upgrade # Give the user back the amount of logs they are allowed to view. diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 0000000000..6117f375f6 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,5 @@ +en: + activerecord: + attributes: + device: + fb_order_number: "Order number" From 67106a754d46c7569879953cf320740c20abaafc Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Thu, 26 Oct 2023 16:13:17 -0700 Subject: [PATCH 3/5] add published sequences to seeder --- .../devices/seeders/abstract_express.rb | 2 + .../devices/seeders/abstract_genesis.rb | 22 ++- .../devices/seeders/abstract_seeder.rb | 42 +++- app/mutations/devices/seeders/constants.rb | 12 ++ .../devices/seeders/genesis_one_six.rb | 8 + .../devices/seeders/genesis_xl_one_six.rb | 8 + app/mutations/devices/seeders/none.rb | 2 + .../devices/seeders/sequence_fixtures.yml | 185 +++++++++++++++++- .../devices/devices_controller_seed_spec.rb | 54 ++++- 9 files changed, 321 insertions(+), 14 deletions(-) diff --git a/app/mutations/devices/seeders/abstract_express.rb b/app/mutations/devices/seeders/abstract_express.rb index 96ce1379d2..e29230bda8 100644 --- a/app/mutations/devices/seeders/abstract_express.rb +++ b/app/mutations/devices/seeders/abstract_express.rb @@ -75,6 +75,8 @@ def tools_weeder; end def tools_rotary; end def sequences_mount_tool; end def sequences_dismount_tool; end + def sequences_mow_all_weeds; end + def sequences_pick_from_seed_tray; end def sequences_pick_up_seed s = SequenceSeeds::PICK_UP_SEED_EXPRESS.deep_dup diff --git a/app/mutations/devices/seeders/abstract_genesis.rb b/app/mutations/devices/seeders/abstract_genesis.rb index 451e177d59..db5f341377 100644 --- a/app/mutations/devices/seeders/abstract_genesis.rb +++ b/app/mutations/devices/seeders/abstract_genesis.rb @@ -110,18 +110,34 @@ def tools_weeder def tools_rotary; end def sequences_mount_tool - install_sequence_version_by_name("Mount Tool") + success = install_sequence_version_by_name(PublicSequenceNames::MOUNT_TOOL) + if !success + s = SequenceSeeds::MOUNT_TOOL.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_dismount_tool - install_sequence_version_by_name("Dismount Tool") + success = install_sequence_version_by_name(PublicSequenceNames::DISMOUNT_TOOL) + if !success + s = SequenceSeeds::DISMOUNT_TOOL.deep_dup + Sequences::Create.run!(s, device: device) + end + end + + def sequences_pick_from_seed_tray + success = install_sequence_version_by_name(PublicSequenceNames::PICK_FROM_SEED_TRAY) + if !success + s = SequenceSeeds::PICK_FROM_SEED_TRAY.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_pick_up_seed s = SequenceSeeds::PICK_UP_SEED_GENESIS.deep_dup seed_bin_id = device.tools.find_by!(name: ToolNames::SEED_BIN).id - mount_tool_id = device.sequences.find_by!(name: "Mount Tool").id + mount_tool_id = device.sequences.find_by!(name: PublicSequenceNames::MOUNT_TOOL).id s.dig(:body, 0, :args)[:sequence_id] = mount_tool_id s.dig(:body, 0, :body, 0, :args, :data_value, :args)[:tool_id] = seeder_id diff --git a/app/mutations/devices/seeders/abstract_seeder.rb b/app/mutations/devices/seeders/abstract_seeder.rb index a07b1be26a..8d689bd726 100644 --- a/app/mutations/devices/seeders/abstract_seeder.rb +++ b/app/mutations/devices/seeders/abstract_seeder.rb @@ -84,6 +84,8 @@ class AbstractSeeder :sequences_soil_height_grid, :sequences_grid, :sequences_dispense_water, + :sequences_mow_all_weeds, + :sequences_pick_from_seed_tray, # EVERYTHING ELSE ======================== :misc, @@ -123,6 +125,8 @@ def sequences_mount_tool; end def sequences_dismount_tool; end def sequences_pick_up_seed; end def sequences_plant_seed; end + def sequences_mow_all_weeds; end + def sequences_pick_from_seed_tray; end def sequences_take_photo_of_plant s = SequenceSeeds::TAKE_PHOTO_OF_PLANT.deep_dup @@ -169,27 +173,51 @@ def sequences_water_all_plants def sequences_find_home; end def sequences_water_all - install_sequence_version_by_name(PublicSequenceNames::WATER_ALL) + success = install_sequence_version_by_name(PublicSequenceNames::WATER_ALL) + if !success + s = SequenceSeeds::WATER_ALL.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_photo_grid - install_sequence_version_by_name(PublicSequenceNames::PHOTO_GRID) + success = install_sequence_version_by_name(PublicSequenceNames::PHOTO_GRID) + if !success + s = SequenceSeeds::PHOTO_GRID.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_weed_detection_grid - install_sequence_version_by_name(PublicSequenceNames::WEED_DETECTION_GRID) + success = install_sequence_version_by_name(PublicSequenceNames::WEED_DETECTION_GRID) + if !success + s = SequenceSeeds::WEED_DETECTION_GRID.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_soil_height_grid - install_sequence_version_by_name(PublicSequenceNames::SOIL_HEIGHT_GRID) + success = install_sequence_version_by_name(PublicSequenceNames::SOIL_HEIGHT_GRID) + if !success + s = SequenceSeeds::SOIL_HEIGHT_GRID.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_grid - install_sequence_version_by_name(PublicSequenceNames::GRID) + success = install_sequence_version_by_name(PublicSequenceNames::GRID) + if !success + s = SequenceSeeds::GRID.deep_dup + Sequences::Create.run!(s, device: device) + end end def sequences_dispense_water - install_sequence_version_by_name(PublicSequenceNames::DISPENSE_WATER) + success = install_sequence_version_by_name(PublicSequenceNames::DISPENSE_WATER) + if !success + s = SequenceSeeds::DISPENSE_WATER.deep_dup + Sequences::Create.run!(s, device: device) + end end def settings_default_map_size_x; end @@ -243,10 +271,12 @@ def install_sequence_version_by_name(name) msg = "Unable to install public sequence: #{name}" device.tell(msg) Rollbar.error(msg) + return false else Sequences::Install.run!( sequence_version: sv, device: device) + return true end end diff --git a/app/mutations/devices/seeders/constants.rb b/app/mutations/devices/seeders/constants.rb index fc3b07b8a8..d1e7483b04 100644 --- a/app/mutations/devices/seeders/constants.rb +++ b/app/mutations/devices/seeders/constants.rb @@ -48,6 +48,16 @@ module SequenceSeeds WATER_ALL_PLANTS = ALL.fetch(:WATER_ALL_PLANTS) FIND_HOME_GENESIS = ALL.fetch(:FIND_HOME_GENESIS) FIND_HOME_EXPRESS = ALL.fetch(:FIND_HOME_EXPRESS) + MOUNT_TOOL = ALL.fetch(:MOUNT_TOOL) + DISMOUNT_TOOL = ALL.fetch(:DISMOUNT_TOOL) + DISPENSE_WATER = ALL.fetch(:DISPENSE_WATER) + SOIL_HEIGHT_GRID = ALL.fetch(:SOIL_HEIGHT_GRID) + GRID = ALL.fetch(:GRID) + WATER_ALL = ALL.fetch(:WATER_ALL) + PHOTO_GRID = ALL.fetch(:PHOTO_GRID) + WEED_DETECTION_GRID = ALL.fetch(:WEED_DETECTION_GRID) + MOW_ALL_WEEDS = ALL.fetch(:MOW_ALL_WEEDS) + PICK_FROM_SEED_TRAY = ALL.fetch(:PICK_FROM_SEED_TRAY) end module PublicSequenceNames @@ -59,6 +69,8 @@ module PublicSequenceNames WEED_DETECTION_GRID = "Weed Detection Grid" MOUNT_TOOL = "Mount Tool" DISMOUNT_TOOL = "Dismount Tool" + MOW_ALL_WEEDS = "Mow All Weeds" + PICK_FROM_SEED_TRAY = "Pick from Seed Tray" end end end diff --git a/app/mutations/devices/seeders/genesis_one_six.rb b/app/mutations/devices/seeders/genesis_one_six.rb index 185d29dac3..de32b75b0a 100644 --- a/app/mutations/devices/seeders/genesis_one_six.rb +++ b/app/mutations/devices/seeders/genesis_one_six.rb @@ -60,6 +60,14 @@ def tools_seed_trough_2 @tools_seed_trough_2 ||= add_tool(ToolNames::SEED_TROUGH_2) end + + def sequences_mow_all_weeds + success = install_sequence_version_by_name(PublicSequenceNames::MOW_ALL_WEEDS) + if !success + s = SequenceSeeds::MOW_ALL_WEEDS.deep_dup + Sequences::Create.run!(s, device: device) + end + end end end end diff --git a/app/mutations/devices/seeders/genesis_xl_one_six.rb b/app/mutations/devices/seeders/genesis_xl_one_six.rb index 988abea727..d2510f3e46 100644 --- a/app/mutations/devices/seeders/genesis_xl_one_six.rb +++ b/app/mutations/devices/seeders/genesis_xl_one_six.rb @@ -72,6 +72,14 @@ def tools_seed_trough_2 @tools_seed_trough_2 ||= add_tool(ToolNames::SEED_TROUGH_2) end + + def sequences_mow_all_weeds + success = install_sequence_version_by_name(PublicSequenceNames::MOW_ALL_WEEDS) + if !success + s = SequenceSeeds::MOW_ALL_WEEDS.deep_dup + Sequences::Create.run!(s, device: device) + end + end end end end diff --git a/app/mutations/devices/seeders/none.rb b/app/mutations/devices/seeders/none.rb index d2bb287513..0ef2ce22c1 100644 --- a/app/mutations/devices/seeders/none.rb +++ b/app/mutations/devices/seeders/none.rb @@ -19,6 +19,8 @@ def sequences_pick_up_seed; end def sequences_plant_seed; end def sequences_take_photo_of_plant; end def sequences_water_plant; end + def sequences_mow_all_weeds; end + def sequences_pick_from_seed_tray; end def point_groups_spinach; end def point_groups_broccoli; end def point_groups_beet; end diff --git a/app/mutations/devices/seeders/sequence_fixtures.yml b/app/mutations/devices/seeders/sequence_fixtures.yml index 8f7d55ade5..81de137d36 100644 --- a/app/mutations/devices/seeders/sequence_fixtures.yml +++ b/app/mutations/devices/seeders/sequence_fixtures.yml @@ -548,7 +548,7 @@ :body: - :kind: parameter_application :args: - :label: parent + :label: Tool :data_value: :kind: tool :args: @@ -728,3 +728,186 @@ :speed: 100 :axis: x :comment: Find home on the X axis + +:MOUNT_TOOL: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: Tool + :default_value: + :kind: location_placeholder + :args: {} + :color: gray + :name: Mount Tool + :body: + - :kind: lua + :args: + :lua: "mount_tool(variable(\"Tool\"))" + +:DISMOUNT_TOOL: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: gray + :name: Dismount Tool + :body: + - :kind: lua + :args: + :lua: "dismount_tool()" + +:WATER_ALL: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: Watering Time (Seconds) + :default_value: + :kind: numeric + :args: + :number: 2 + :color: blue + :name: Water All + :body: + - :kind: lua + :args: + :lua: "local watering_time = variable(\"Watering Time (Seconds)\")\nstart_time = os.time() * 1000\n\nlocal points = api({method = \"GET\", url = \"/api/points\"})\n\nlocal plants = {}\n\nfor k, v in pairs(points) do\n if v.pointer_type == \"Plant\" then\n table.insert(plants, {name = v.name, x = v.x, y = v.y})\n end\nend\n\ntable.sort(plants, function(l, r)\n -- \"close enough\" approximation.\n if math.abs(l.x - r.x) < 150 then\n return l.y < r.y\n else\n return l.x < r.x\n end\nend)\n\ncount = 0\ntotal = #plants\njob = \"Watering all \" .. total .. \" plants\"\n\nsend_message(\n \"info\",\n \"Watering all \" .. total .. \" plants for \" .. watering_time .. \" seconds each\",\n \"toast\")\n\nfor k, v in pairs(plants) do\n coordinates = \"(\" .. v.x .. \", \" .. v.y .. \")\"\n set_job_progress(job, {\n percent = 100 * (count) / total,\n status = \"Moving to \" .. (v.name or \"plant\") .. \" at \" .. coordinates,\n time = start_time\n })\n move_absolute(v.x, v.y, 0)\n set_job_progress(job, {\n percent = 100 * (count + 0.5) / total,\n status = \"Watering \" .. (v.name or \"plant\") .. \" for \" .. watering_time .. \" seconds\",\n time = start_time\n })\n write_pin(8, \"digital\", 1)\n wait(watering_time * 1000)\n write_pin(8, \"digital\", 0)\n count = count + 1\nend\n\nset_job_progress(job, {\n percent = 100,\n status = \"Complete\",\n time = start_time\n})" + +:SOIL_HEIGHT_GRID: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: gray + :name: Soil Height Grid + :body: + - :kind: lua + :args: + :lua: "local grid = photo_grid()\ntype = \"Scan\"\njob = \"Soil Height Grid\"\nstart_time = os.time() * 1000\n\ngrid.each(function(cell)\n set_job_progress(job, {\n percent = 100 * (cell.count - 0.5) / grid.total,\n status = \"Moving\",\n time = start_time\n })\n move_absolute(cell.x, cell.y, cell.z)\n set_job_progress(job, {\n percent = 100 * (cell.count / grid.total),\n status = \"Measuring soil height\",\n time = start_time\n })\n local msg = \"Measuring height at point \" .. cell.count .. \" of \" .. grid.total\n send_message(\"info\", msg)\n measure_soil_height()\nend)\n\nset_job_progress(job, {\n percent = 100,\n status = \"Complete\",\n time = start_time\n})" + +:PICK_FROM_SEED_TRAY: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: Seed Tray + :default_value: + :kind: location_placeholder + :args: {} + - :kind: parameter_declaration + :args: + :label: Seed Tray Cell + :default_value: + :kind: text + :args: + :string: B3 + :color: yellow + :name: Pick from Seed Tray + :body: + - :kind: lua + :args: + :lua: "tray = variable(\"Seed Tray\")\ncell_label = variable(\"Seed Tray Cell\")\ncell = get_seed_tray_cell(tray, cell_label)\ncell_depth = 5\nvacuum_pump_pin = 9\n\n-- Checks\nif not verify_tool() then\n return\nend\n\n-- Send message with cell info\nlocal cell_coordinates = \" (\" .. cell.x .. \", \" .. cell.y .. \", \" .. cell.z - cell_depth .. \")\"\nsend_message(\"info\", \"Picking up seed from cell \" .. cell_label .. cell_coordinates, \"toast\")\n\n-- Job\nstart_time = os.time() * 1000\nfunction job(status, percent)\n set_job_progress(\"Pick from Seed Tray\", {\n status = status,\n percent = percent,\n time = start_time\n })\nend\n\n-- Safe Z move to above the cell\njob(\"Moving to Seed Tray\", 25)\nmove_absolute({\n x = cell.x,\n y = cell.y,\n z = cell.z + 25,\n safe_z = true\n})\n\n-- Pick up seed\njob(\"Picking up seed\", 75)\nwrite_pin(vacuum_pump_pin, \"digital\", 1)\nmove_absolute(cell.x, cell.y, cell.z - cell_depth)\n\n-- Retract Z\njob(\"Retracting Z\", 90)\nmove_absolute(cell.x, cell.y, cell.z + 25)\njob(\"Complete\", 100)" + +:PHOTO_GRID: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: gray + :name: Photo Grid + :body: + - :kind: lua + :args: + :lua: "local grid = photo_grid()\ntype = \"Scan\"\njob = \"Photo Grid\"\nstart_time = os.time() * 1000\n\ngrid.each(function(cell)\n set_job_progress(job, {\n percent = 100 * (cell.count - 0.5) / grid.total,\n status = \"Moving\",\n time = start_time\n })\n move_absolute(cell.x, cell.y, cell.z)\n set_job_progress(job, {\n percent = 100 * (cell.count / grid.total),\n status = \"Taking photo\",\n time = start_time\n })\n local msg = \"Taking photo \" .. cell.count .. \" of \" .. grid.total\n send_message(\"info\", msg)\n take_photo()\nend)\n\nset_job_progress(job, {\n percent = 100,\n status = \"Complete\",\n time = start_time\n})" + +:MOW_ALL_WEEDS: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: red + :name: Mow All Weeds + :body: + - :kind: lua + :args: + :lua: "rotary_tool_pin = 2 -- 3 for REV\nmax_load = tonumber(env(\"rotary_tool_max_load\")) or 90\nrotary_tool_height = tonumber(env(\"rotary_tool_height\")) or 80\nmax_attempts = tonumber(env(\"rotary_tool_max_attempts\")) or 3\nweeds = {}\ncount = 0\n\nfunction job(status, percent)\n set_job_progress(\"Mowing weed at \" .. coords, {\n status = status,\n percent = percent,\n time = job_time\n })\nend\n\npjob_time = os.time() * 1000\nfunction pjob(status, percent)\n set_job_progress(\"Mowing \" .. #weeds .. \" weeds\", {\n status = status,\n percent = percent,\n time = pjob_time\n })\nend\n\nwatcher = function(data)\n if (data.value > max_load) and (env(\"load\") ~= \"stalled\") then\n env(\"load\", \"stalled\")\n soft_stop()\n off(rotary_tool_pin)\n toast(\"Rotary tool max load exceeded (load = \" .. data.value .. \")\", \"warn\")\n end\nend\n\nfunction attempt_weeding()\n attempts = attempts + 1\n env(\"load\", \"nominal\")\n job(\"Moving to weed\", 10)\n move{\n x = weed.x - (weed.radius + 50),\n y = weed.y,\n z = weed.z + rotary_tool_height + 20,\n safe_z = true\n }\n\n on(rotary_tool_pin)\n\n if env(\"load\") == \"stalled\" then\n wait(1500)\n return\n end\n job(\"Descending\", 40)\n move{\n z = weed.z + rotary_tool_height,\n speed = 25\n }\n\n if env(\"load\") == \"stalled\" then\n wait(1500)\n return\n end\n job(\"Mowing\", 50)\n move{\n x = weed.x + (weed.radius + 50),\n speed = 25\n }\n\n if env(\"load\") == \"stalled\" then\n wait(1500)\n return\n end\n job(\"Ascending\", 90)\n move{\n z = weed.z + rotary_tool_height + 20,\n speed = 25\n }\n\n if env(\"load\") == \"stalled\" then\n wait(1500)\n return\n end\n off(rotary_tool_pin)\n success = true\nend\n\nif not verify_tool() then\n return\nend\n\npoints = api({\n method = \"GET\",\n url = \"/api/points\"\n})\n\nfor k, v in pairs(points) do\n if v.pointer_type == \"Weed\" then\n table.insert(weeds, {x = v.x, y = v.y, z = soil_height(v.x, v.y), radius = v.radius})\n end\nend\n\nwatch_pin(60, watcher)\n\nfor k, v in pairs(weeds) do\n weed = v\n count = count + 1\n job_time = os.time() * 1000\n pjob(\"Mowing weed \" .. count .. \" of \" .. #weeds, count / (#weeds + 1) * 100)\n coords = \"(\" .. weed.x .. \", \" .. weed.y .. \", \" .. weed.z .. \")\"\n attempts = 0\n success = false\n while (attempts < max_attempts) and (success == false) do\n attempt_weeding()\n end\n if env(\"load\") == \"stalled\" then\n toast(\"Mowing weed at \" .. coords .. \" failed after \" .. attempts .. \" attempt(s); proceeding...\", \"warn\")\n end\n job(\"Complete\", 100)\nend\npjob(\"Complete\", 100)\ntoast(\"Mowing complete\", \"success\")" + +:GRID: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: Number of points + :default_value: + :kind: coordinate + :args: + :x: 2 + :y: 3 + :z: 1 + - :kind: parameter_declaration + :args: + :label: Spacing + :default_value: + :kind: coordinate + :args: + :x: 50 + :y: 100 + :z: 0 + - :kind: parameter_declaration + :args: + :label: Subsequence + :default_value: + :kind: resource_placeholder + :args: + :resource_type: Sequence + :color: gray + :name: Grid + :body: + - :kind: lua + :args: + :lua: "subsequence = variable(\"Subsequence\")\nstart = variable(\"Starting location\")\nspacing = variable(\"Spacing\")\ngrid_points = variable(\"Number of points\")\ngrid_points_total = grid_points.x * grid_points.y * grid_points.z\njob = subsequence.name .. \" x\" .. grid_points_total\nindex = 0\ngrid_max_x = start.x + (spacing.x * grid_points.x)\ngrid_max_y = start.y + (spacing.y * grid_points.y)\nstart_time = os.time() * 1000\n\nfunction failure(reason) send_message(\"error\", reason, \"toast\") end\n\nif grid_points.x <= 0 or grid_points.y <= 0 or grid_points.z <= 0 then\n failure(\"Number of points must be greater than 0 for all three axes\")\n return\nelseif grid_max_x > garden_size().x or grid_max_y > garden_size().y then\n failure(\"Grid must not exceed the **AXIS LENGTH** for the X or Y axes\")\n return\nend\n\nmsg = \"Executing `\" .. subsequence.name .. \"` \" .. grid_points_total ..\n \" times in a \" .. grid_points.x .. \" x \" .. grid_points.y ..\n \" x \" .. grid_points.z .. \" grid\"\nsend_message(\"info\", msg, \"toast\")\n\n-- Move to each grid point and execute the subsequence\n\nfor grid_index_z = 0, (grid_points.z - 1) do\n z = start.z + (spacing.z * grid_index_z)\n for grid_index_x = 0, (grid_points.x - 1) do\n x = start.x + (spacing.x * grid_index_x)\n for grid_index_y = 0, (grid_points.y - 1) do\n if (grid_index_x % 2) == 0 then\n y = start.y + (spacing.y * grid_index_y)\n else\n reversed_index_y = grid_points.y - 1 - grid_index_y\n y = start.y + (spacing.y * reversed_index_y)\n end\n set_job_progress(job, {\n percent = 100 * index / grid_points_total,\n status = \"Moving\",\n time = start_time\n })\n move_absolute(x, y, z)\n set_job_progress(job, {\n percent = 100 * (index + 0.5) / grid_points_total,\n status = \"Executing subsequence\",\n time = start_time\n })\n cs_eval(subsequence)\n index = index + 1\n end\n end\nend\n\nset_job_progress(job, {\n percent = 100,\n status = \"Complete\",\n time = start_time\n})" + +:DISPENSE_WATER: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :body: + - :kind: parameter_declaration + :args: + :label: Water (mL) + :default_value: + :kind: numeric + :args: + :number: 250 + :color: blue + :name: Dispense Water + :body: + - :kind: lua + :args: + :lua: "-- Get all tools\ntools = api({ url = \"/api/tools/\" })\nif not tools then\n toast(\"API error\", \"error\")\n return\nend\n\n-- Pluck the Watering Nozzle tool\nfor key, tool in pairs(tools) do\n if tool.name == \"Watering Nozzle\" then\n watering_nozzle = tool\n wfr = watering_nozzle.flow_rate_ml_per_s\n end\nend\n\nml = variable(\"Water (mL)\")\n\nif not wfr then\n toast('You must have a tool named \"Watering Nozzle\" to use this sequence.', 'error')\n return\nelseif wfr == 0 then\n toast(\"**WATER FLOW RATE (mL/s)** must be greater than 0 for the Watering Nozzle tool. Refer to the sequence description for setup instructions.\", \"error\")\n return\nelseif ml <= 0 then\n toast(\"Water (mL) must be greater than 0\", \"error\")\n return\nelseif ml > 10000 then\n toast(\"Water (mL) cannot be more than 10,000\", \"error\")\n return\nend\n\nseconds = math.floor(ml / wfr * 100) / 100\ntoast(\"Dispensing \" .. ml .. \"mL of water over \" .. seconds .. \" seconds\")\non(8)\nwait(seconds * 1000)\noff(8)" + +:WEED_DETECTION_GRID: # =================================== + :args: + :locals: + :kind: scope_declaration + :args: {} + :color: gray + :name: Weed Detection Grid + :body: + - :kind: lua + :args: + :lua: "local grid = photo_grid()\ntype = \"Scan\"\njob = \"Weed Detection Grid\"\nstart_time = os.time() * 1000\n\ngrid.each(function(cell)\n set_job_progress(job, {\n percent = 100 * (cell.count - 0.5) / grid.total,\n status = \"Moving\",\n time = start_time\n })\n move_absolute(cell.x, cell.y, cell.z)\n set_job_progress(job, {\n percent = 100 * (cell.count / grid.total),\n status = \"Detecting weeds\",\n time = start_time\n })\n local msg = \"Detecting weeds at location \" .. cell.count .. \" of \" ..\n grid.total\n send_message(\"info\", msg)\n detect_weeds()\nend)\n\nset_job_progress(job, {\n percent = 100,\n status = \"Complete\",\n time = start_time\n})" diff --git a/spec/controllers/api/devices/devices_controller_seed_spec.rb b/spec/controllers/api/devices/devices_controller_seed_spec.rb index 3cc80d220b..8a9c027815 100644 --- a/spec/controllers/api/devices/devices_controller_seed_spec.rb +++ b/spec/controllers/api/devices/devices_controller_seed_spec.rb @@ -158,11 +158,19 @@ def tools_rotary?(device) end def sequences_mount_tool?(device) - device.sequences.find_by(name: "Mount Tool") + device.sequences.find_by(name: PublicSequenceNames::MOUNT_TOOL) end def sequences_dismount_tool?(device) - device.sequences.find_by(name: "Dismount Tool") + device.sequences.find_by(name: PublicSequenceNames::DISMOUNT_TOOL) + end + + def sequences_mow_all_weeds?(device) + device.sequences.find_by(name: PublicSequenceNames::MOW_ALL_WEEDS) + end + + def sequences_pick_from_seed_tray?(device) + device.sequences.find_by(name: PublicSequenceNames::PICK_FROM_SEED_TRAY) end def sequences_pickup_seed?(device) @@ -273,6 +281,8 @@ def start_tests(product_line, publish = true) PublicSequenceNames::WEED_DETECTION_GRID, PublicSequenceNames::MOUNT_TOOL, PublicSequenceNames::DISMOUNT_TOOL, + PublicSequenceNames::MOW_ALL_WEEDS, + PublicSequenceNames::PICK_FROM_SEED_TRAY, ].map do |name| s = Sequences::Create.run!(device: u.device, name: name, @@ -367,6 +377,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -438,6 +450,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -509,6 +523,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -582,6 +598,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -656,6 +674,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -727,6 +747,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -800,6 +822,8 @@ def check_slot_pairing(slot, expected_name) 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_not be + 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 @@ -874,6 +898,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -941,6 +967,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -1008,6 +1036,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -1075,6 +1105,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -1142,6 +1174,8 @@ def check_slot_pairing(slot, expected_name) 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 @@ -1155,10 +1189,22 @@ def check_slot_pairing(slot, expected_name) expect(point_groups_beet?(device)).to be_kind_of(PointGroup) end - it "seeds accounts when sequence versions not available" do + it "seeds accounts when sequence versions not available: demo account" do start_tests "demo_account", false - expect(sequences_grid?(device)).to_not be + expect(sequences_grid?(device)).to be_kind_of(Sequence) + end + + it "seeds accounts when sequence versions not available: Genesis XL 1.6" do + start_tests "genesis_xl_1.6", false + + expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) + end + + it "seeds accounts when sequence versions not available: Genesis 1.6" do + start_tests "genesis_1.6", false + + expect(sequences_mow_all_weeds?(device)).to be_kind_of(Sequence) end it "does not seed accounts" do From 9e859e374eac32b23317ba6f1353c15de631d023 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 27 Oct 2023 11:50:15 -0700 Subject: [PATCH 4/5] fix popup tab nav overlap --- frontend/css/global.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/css/global.scss b/frontend/css/global.scss index bc82a62f23..eec2bda55f 100644 --- a/frontend/css/global.scss +++ b/frontend/css/global.scss @@ -177,6 +177,7 @@ fieldset { .controls-content, .connectivity-content { margin-bottom: 0; + padding-top: 2rem !important; .tabs { display: flex; position: absolute; From 07cf2aa96bd51f276ab9db82be026c80968db181 Mon Sep 17 00:00:00 2001 From: gabrielburnworth Date: Fri, 27 Oct 2023 11:59:33 -0700 Subject: [PATCH 5/5] upgrade deps --- Gemfile.lock | 2 +- package.json | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 7c0c8757cf..7820d7c878 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -148,7 +148,7 @@ GEM faraday (~> 1.0) globalid (1.2.1) activesupport (>= 6.1) - google-apis-core (0.11.1) + google-apis-core (0.11.2) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) diff --git a/package.json b/package.json index 043ed111ec..4a0de367dd 100644 --- a/package.json +++ b/package.json @@ -38,13 +38,13 @@ "@parcel/transformer-typescript-tsc": "2.10.1", "@types/lodash": "4.14.200", "@types/markdown-it": "13.0.5", - "@types/node": "20.8.8", + "@types/node": "20.8.9", "@types/promise-timeout": "1.3.2", - "@types/react": "18.2.31", + "@types/react": "18.2.33", "@types/react-color": "3.0.9", "@types/react-dom": "18.2.14", "@types/ws": "8.5.8", - "axios": "1.5.1", + "axios": "1.6.0", "bowser": "2.11.0", "browser-speech": "1.1.1", "events": "3.3.0", @@ -86,7 +86,7 @@ "eslint": "8.52.0", "eslint-plugin-eslint-comments": "3.2.0", "eslint-plugin-import": "2.29.0", - "eslint-plugin-jest": "27.4.3", + "eslint-plugin-jest": "27.6.0", "eslint-plugin-no-null": "1.0.2", "eslint-plugin-promise": "6.1.1", "eslint-plugin-react": "7.33.2", @@ -101,7 +101,7 @@ "raf": "3.4.1", "react-addons-test-utils": "15.6.2", "react-test-renderer": "18.2.0", - "sass": "1.69.4", + "sass": "1.69.5", "sass-lint": "1.13.1", "ts-jest": "29.1.1", "tslint": "6.1.3"