From d75e4c7cef680020427b494f986a9b607b2554eb Mon Sep 17 00:00:00 2001 From: aeter Date: Sat, 11 Mar 2017 02:05:10 +0200 Subject: [PATCH] Close #801 - peak detector min datapoints (#1924) Closes -- https://github.com/cantino/huginn/issues/801 Testing -- ran rspec About -- Adds an option `min_events` to the peak detector agent. The agent will start looking for peaks only after min number of events are accumulated. --- app/models/agents/peak_detector_agent.rb | 13 +++++++++---- ...n_events_option_to_peak_detector_agents.rb | 19 +++++++++++++++++++ .../models/agents/peak_detector_agent_spec.rb | 12 +++++++++++- 3 files changed, 39 insertions(+), 5 deletions(-) create mode 100755 db/migrate/20170307190555_add_min_events_option_to_peak_detector_agents.rb diff --git a/app/models/agents/peak_detector_agent.rb b/app/models/agents/peak_detector_agent.rb index 1fc10f41..2aed2378 100644 --- a/app/models/agents/peak_detector_agent.rb +++ b/app/models/agents/peak_detector_agent.rb @@ -12,6 +12,8 @@ module Agents Set `expected_receive_period_in_days` to the maximum amount of time that you'd expect to pass between Events being received by this Agent. You may set `window_duration_in_days` to change the default memory window length of `14` days, `min_peak_spacing_in_days` to change the default minimum peak spacing of `2` days (peaks closer together will be ignored), and `std_multiple` to change the default standard deviation threshold multiple of `3`. + + You may set `min_events` for the minimal number of accumulated events before the agent starts detecting. MD event_description <<-MD @@ -26,8 +28,8 @@ module Agents MD def validate_options - unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? - errors.add(:base, "expected_receive_period_in_days, value_path, and message are required") + unless options['expected_receive_period_in_days'].present? && options['message'].present? && options['value_path'].present? && options['min_events'].present? + errors.add(:base, "expected_receive_period_in_days, value_path, min_events and message are required") end end @@ -36,7 +38,8 @@ module Agents 'expected_receive_period_in_days' => "2", 'group_by_path' => "filter", 'value_path' => "count", - 'message' => "A peak of {{count}} was found in {{filter}}" + 'message' => "A peak of {{count}} was found in {{filter}}", + 'min_events' => '4', } end @@ -58,7 +61,9 @@ module Agents memory['peaks'] ||= {} memory['peaks'][group] ||= [] - if memory['data'][group].length > 4 && (memory['peaks'][group].empty? || memory['peaks'][group].last < event.created_at.to_i - peak_spacing) + return if memory['data'][group].length <= options['min_events'].to_i + + if memory['peaks'][group].empty? || memory['peaks'][group].last < event.created_at.to_i - peak_spacing average_value, standard_deviation = stats_for(group, :skip_last => 1) newest_value, newest_time = memory['data'][group][-1].map(&:to_f) diff --git a/db/migrate/20170307190555_add_min_events_option_to_peak_detector_agents.rb b/db/migrate/20170307190555_add_min_events_option_to_peak_detector_agents.rb new file mode 100755 index 00000000..582908a0 --- /dev/null +++ b/db/migrate/20170307190555_add_min_events_option_to_peak_detector_agents.rb @@ -0,0 +1,19 @@ +class AddMinEventsOptionToPeakDetectorAgents < ActiveRecord::Migration[5.0] + def up + Agents::PeakDetectorAgent.find_each do |agent| + if agent.options['min_events'].nil? + agent.options['min_events'] = '4' + agent.save(validate: false) + end + end + end + + def down + Agents::PeakDetectorAgent.find_each do |agent| + if agent.options['min_events'].present? + agent.options.delete 'min_events' + agent.save(validate: false) + end + end + end +end diff --git a/spec/models/agents/peak_detector_agent_spec.rb b/spec/models/agents/peak_detector_agent_spec.rb index 7c2e2c5c..abefd29a 100644 --- a/spec/models/agents/peak_detector_agent_spec.rb +++ b/spec/models/agents/peak_detector_agent_spec.rb @@ -8,7 +8,8 @@ describe Agents::PeakDetectorAgent do 'expected_receive_period_in_days' => "2", 'group_by_path' => "filter", 'value_path' => "count", - 'message' => "A peak was found" + 'message' => "A peak was found", + 'min_events' => "4", } } @@ -68,6 +69,15 @@ describe Agents::PeakDetectorAgent do :pattern => { 'filter' => "something" }) expect(@agent.memory['peaks']['something'].length).to eq(2) end + + it 'waits and accumulates min events before triggering for peaks' do + @agent.options['min_peak_spacing_in_days'] = 1/24.0 + @agent.options['min_events'] = '10' + @agent.receive build_events(:keys => ['count'], + :values => [1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 1, 1, 10, 1].map {|i| [i]}, + :pattern => { 'filter' => "something" }) + expect(@agent.memory['peaks']['something'].length).to eq(1) + end end describe "validation" do