Advertisement
Guest User

Untitled

a guest
Apr 24th, 2017
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.85 KB | None | 0 0
  1. defmodule GrovePi.Sound.HysteresisTrigger do
  2. @behaviour GrovePi.Trigger
  3.  
  4. @default_high_threshold 510
  5. @default_low_threshold 490
  6.  
  7. @moduledoc """
  8. This is the default triggering mechanism for Sound events. Events
  9. are either `loud` or `quiet` and include the trigger state. It
  10. contains to thresholds a `low_threshold` and a `high_threshold` for
  11. triggering `loud` and `quiet` events.
  12.  
  13. This trigger will not fire an event unless it has fired the opposite
  14. event or if it is the first event fired. If a `loud` event fires it
  15. will not be able to fire again unless a `quiet` event is fired. This
  16. is to keep from having a trigger float near the trigger value and
  17. become excessively noisy.
  18.  
  19.  
  20.  
  21. ## Examples
  22. iex> GrovePi.Sound.HysteresisTrigger.init([])
  23. {:ok, %GrovePi.Sound.HysteresisTrigger.State{value: 500, fireable: :any, low_threshold: 490, high_threshold: 510}}
  24.  
  25. iex> GrovePi.Sound.HysteresisTrigger.init(low_threshold: 10, high_threshold: 200)
  26. {:ok, %GrovePi.Sound.HysteresisTrigger.State{value: 500, fireable: :any, low_threshold: 10, high_threshold: 200}}
  27.  
  28. ### When there has been no event
  29.  
  30. iex> GrovePi.Sound.HysteresisTrigger.update(499, %{value: 500, fireable: :any, low_threshold: 490, high_threshold: 500})
  31. {:ok, %{value: 499, fireable: :any, low_threshold: 490, high_threshold: 500}}
  32.  
  33. iex> GrovePi.Sound.HysteresisTrigger.update(489, %{value: 500, fireable: :any, low_threshold: 490, high_threshold: 500})
  34. {:quiet, %{value: 489, fireable: :loud, low_threshold: 490, high_threshold: 500}}
  35.  
  36. iex> GrovePi.Sound.HysteresisTrigger.update(511, %{value: 500, fireable: :any, low_threshold: 490, high_threshold: 500})
  37. {:loud, %{value: 511, fireable: :quiet, low_threshold: 490, high_threshold: 500}}
  38.  
  39. iex> GrovePi.Sound.HysteresisTrigger.update(21, %{value: 500, fireable: :any, low_threshold: 10, high_threshold: 20})
  40. {:loud, %{value: 21, fireable: :quiet, low_threshold: 10, high_threshold: 20}}
  41.  
  42. ### When the last event was loud
  43.  
  44. iex> GrovePi.Sound.HysteresisTrigger.update(511, %{value: 500, fireable: :quiet, low_threshold: 490, high_threshold: 500})
  45. {:ok, %{value: 511, fireable: :quiet, low_threshold: 490, high_threshold: 500}}
  46.  
  47. iex> GrovePi.Sound.HysteresisTrigger.update(501, %{value: 500, fireable: :quiet, low_threshold: 490, high_threshold: 500})
  48. {:ok, %{value: 501, fireable: :quiet, low_threshold: 490, high_threshold: 500}}
  49.  
  50. iex> GrovePi.Sound.HysteresisTrigger.update(489, %{value: 500, fireable: :quiet, low_threshold: 490, high_threshold: 500})
  51. {:quiet, %{value: 489, fireable: :loud, low_threshold: 490, high_threshold: 500}}
  52.  
  53. iex> GrovePi.Sound.HysteresisTrigger.update(9, %{value: 500, fireable: :quiet, low_threshold: 10, high_threshold: 20})
  54. {:quiet, %{value: 9, fireable: :loud, low_threshold: 10, high_threshold: 20}}
  55.  
  56. ### When the last event was quiet
  57.  
  58. iex> GrovePi.Sound.HysteresisTrigger.update(470, %{value: 500, fireable: :loud, low_threshold: 490, high_threshold: 500})
  59. {:ok, %{value: 470, fireable: :loud, low_threshold: 490, high_threshold: 500}}
  60.  
  61. iex> GrovePi.Sound.HysteresisTrigger.update(491, %{value: 500, fireable: :loud, low_threshold: 490, high_threshold: 500})
  62. {:ok, %{value: 491, fireable: :loud, low_threshold: 490, high_threshold: 500}}
  63.  
  64. iex> GrovePi.Sound.HysteresisTrigger.update(521, %{value: 500, fireable: :loud, low_threshold: 490, high_threshold: 500})
  65. {:loud, %{value: 521, fireable: :quiet, low_threshold: 490, high_threshold: 500}}
  66.  
  67. iex> GrovePi.Sound.HysteresisTrigger.update(21, %{value: 500, fireable: :loud, low_threshold: 10, high_threshold: 20})
  68. {:loud, %{value: 21, fireable: :quiet, low_threshold: 10, high_threshold: 20}}
  69. """
  70.  
  71. defmodule State do
  72. @moduledoc false
  73. @enforce_keys [:high_threshold, :low_threshold]
  74. defstruct value: 500, fireable: :any, high_threshold: nil, low_threshold: nil
  75. end
  76.  
  77. @doc """
  78. # Options
  79.  
  80. * `:high_threshold` - The level that must be exceeded to fire a loud event, The default is `510`
  81. * `:low_threshold` - The level that must be recede below to fire a quiet event, The default is `490`
  82. """
  83. def init(opts) do
  84. high_threshold = Keyword.get(opts, :high_threshold, @default_high_threshold)
  85. low_threshold = Keyword.get(opts, :low_threshold, @default_low_threshold)
  86.  
  87. {:ok, %State{high_threshold: high_threshold, low_threshold: low_threshold}}
  88. end
  89.  
  90. def update(new_value, %{fireable: fireable, low_threshold: low_threshold} = state) when new_value < low_threshold and fireable != :loud do
  91. {:quiet, %{state | value: new_value, fireable: :loud}}
  92. end
  93.  
  94. def update(new_value, %{fireable: fireable, high_threshold: high_threshold} = state) when new_value > high_threshold and fireable != :quiet do
  95. {:loud, %{state | value: new_value, fireable: :quiet}}
  96. end
  97.  
  98. def update(new_value, state) do
  99. {:ok, %{state | value: new_value}}
  100. end
  101. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement