Skip to content

Commit

Permalink
Merge pull request #2020 from FarmBot/watchdog_reporting
Browse files Browse the repository at this point in the history
Watchdog reporting
  • Loading branch information
RickCarlino committed Nov 20, 2020
2 parents aacc3c6 + 8b4ba64 commit 89bac25
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 20 deletions.
1 change: 0 additions & 1 deletion app/models/application_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class << self

DONT_BROADCAST = ["created_at",
"last_saw_api",
"last_saw_mq",
"last_sign_in_at",
"last_sign_in_ip",
"sign_in_count",
Expand Down
2 changes: 0 additions & 2 deletions app/mutations/devices/update.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ class Update < Mutations::Command
optional do
string :name
string :timezone
time :last_saw_mq
boolean :needs_reset
integer :mounted_tool_id, nils: true
integer :ota_hour, nils: true
end
Expand Down
35 changes: 35 additions & 0 deletions app/mutations/devices/watchdog.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module Devices
class Watchdog < Mutations::Command
def execute
affected_users
end

private

def lower_limit
@lower_limit ||= 2.days.ago
end

def upper_limit
@upper_limit ||= 8.hours.ago
end

def time_window
@time_window ||= lower_limit..upper_limit
end

def affected_users
@affected_users ||= User.where(device_id: devices.pluck(:id))
end

def eligible_devices
@eligible_devices ||= Device
.where(last_watchdog: nil)
.or(Device.where("last_watchdog < ?", lower_limit))
end

def devices
eligible_devices.where(last_saw_api: time_window)
end
end
end
2 changes: 0 additions & 2 deletions app/serializers/device_serializer.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
class DeviceSerializer < ApplicationSerializer
attributes :fbos_version,
:last_saw_api,
:last_saw_mq,
:mounted_tool_id,
:name,
:needs_reset,
:ota_hour,
:ota_hour_utc,
:serial_number,
Expand Down
14 changes: 14 additions & 0 deletions db/migrate/20201120162403_add_watchdog_triggered_at_to_devices.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
class AddWatchdogTriggeredAtToDevices < ActiveRecord::Migration[6.0]
def change
add_column :devices, :last_watchdog, :datetime
remove_column :devices, :needs_reset, :boolean # Not used
remove_column :devices, :last_saw_mq, :datetime # 0 production use

if Object.const_defined?("Device")
# Prevent a wave of watchdog alerts after first
# deployment.
puts "===== Setting `last_watchdog` to default value:"
Device.update_all(last_watchdog: Time.now)
end
end
end
8 changes: 4 additions & 4 deletions db/structure.sql
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ CREATE TABLE public.devices (
max_images_count integer DEFAULT 450,
timezone character varying(280),
last_saw_api timestamp without time zone,
last_saw_mq timestamp without time zone,
fbos_version character varying(15),
throttled_until timestamp without time zone,
throttled_at timestamp without time zone,
Expand All @@ -275,9 +274,9 @@ CREATE TABLE public.devices (
serial_number character varying(32),
mqtt_rate_limit_email_sent_at timestamp without time zone,
ota_hour integer DEFAULT 3,
needs_reset boolean DEFAULT false,
first_saw_api timestamp without time zone,
ota_hour_utc integer
ota_hour_utc integer,
last_watchdog timestamp without time zone
);


Expand Down Expand Up @@ -3452,6 +3451,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200910175338'),
('20200914165414'),
('20201105145245'),
('20201118183247');
('20201118183247'),
('20201120162403');


16 changes: 16 additions & 0 deletions lib/tasks/news_user_report.rake
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@ class NewUserReport
TPL = <<~HEREDOC
Below is a list of new installations that need a support check-in:
=== 24 Hour Active Devices Count:
%{active}
=== Devices requiring customer service check-in:
%{dead_bots}
=== New device installations today:
%{daily}
Expand All @@ -30,10 +36,20 @@ class NewUserReport
.sort
end

def active_today
@active_today ||= Device.where("last_saw_api > ?", 1.day.ago).count
end

def dead_bots
@dead_bots ||= Devices::Watchdog.run!().pluck(:email)
end

def message
@message ||= TPL % {
weekly: new_this_week.join("\n"),
daily: new_today.join("\n"),
active: active_today,
dead_bots: dead_bots.join("\n"),
}
end

Expand Down
2 changes: 1 addition & 1 deletion spec/mutations/devices/create_seed_data.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

describe Devices::CreateSeedData do
it "passes `none`" do
device = FactoryBot.create!(:device)
device = FactoryBot.create(:device)
previous_peripherals_count = device.peripherals.count
previous_pin_bindings_count = device.pin_bindings.count
previous_plants_count = device.plants.count
Expand Down
23 changes: 23 additions & 0 deletions spec/mutations/devices/create_seed_data_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require "spec_helper"

describe Devices::CreateSeedData do
it "passes `none`" do
device = FactoryBot.create(:device)
previous_peripherals_count = device.peripherals.count
previous_pin_bindings_count = device.pin_bindings.count
previous_plants_count = device.plants.count
previous_sensors_count = device.sensors.count
previous_sequences_count = device.sequences.count
previous_tool_slots_count = device.tool_slots.count
previous_tools_count = device.tools.count
Devices::CreateSeedData.run!(device: device, product_line: "none")
device.reload
expect(device.peripherals.count).to eq(previous_peripherals_count)
expect(device.pin_bindings.count).to eq(previous_pin_bindings_count)
expect(device.plants.count).to eq(previous_plants_count)
expect(device.sensors.count).to eq(previous_sensors_count)
expect(device.sequences.count).to eq(previous_sequences_count)
expect(device.tool_slots.count).to eq(previous_tool_slots_count)
expect(device.tools.count).to eq(previous_tools_count)
end
end
16 changes: 6 additions & 10 deletions spec/mutations/devices/update_spec.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
require 'spec_helper'
require "spec_helper"

describe Devices::Update do
let(:user) { FactoryBot.create(:user) }
let(:device) { user.device }
let(:user) { FactoryBot.create(:user) }
let(:device) { user.device }


it 'updates an existing device' do
it "updates an existing device" do
previous_name = device.name
p = { last_saw_mq: Time.now.utc, name: "Farmbot", needs_reset: true }
Devices::Update.run!({device: device}, p)
p = { name: "Farmbot1231231" }
Devices::Update.run!({ device: device }, p)
device.reload
expect(device.name).to eq(p[:name])
expect(device.needs_reset).to eq(p[:needs_reset])
expect(device.last_saw_mq.hour).to eq(p[:last_saw_mq].hour)
expect(device.last_saw_mq.min).to eq(p[:last_saw_mq].min)
end
end
21 changes: 21 additions & 0 deletions spec/mutations/devices/watchdog_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require "spec_helper"

describe Devices::Watchdog do
it "barks at devices when they go offline > 8 hours" do
destroy_everything!
too_old = FactoryBot
.create(:user)
.device
.update!(last_saw_api: 3.days.ago, name: "too_old")
woof_woof = FactoryBot
.create(:user)
.device
.update!(last_saw_api: 9.hours.ago, name: "woof_woof")
too_soon = FactoryBot
.create(:user)
.device
.update!(last_saw_api: 6.hours.ago, name: "too_soon")
actual = Devices::Watchdog.run!().map(&:device).map(&:name)
expect(actual).to eq(["woof_woof"])
end
end

0 comments on commit 89bac25

Please sign in to comment.