Leosac  0.8.0
Open Source Access Control
LedBuzzerSM.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2014-2016 Leosac
3 
4  This file is part of Leosac.
5 
6  Leosac is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Affero General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  Leosac is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Affero General Public License for more details.
15 
16  You should have received a copy of the GNU Affero General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
22 #include "tools/log.hpp"
23 #include <boost/msm/back/state_machine.hpp>
24 #include <boost/msm/front/functor_row.hpp>
25 #include <boost/msm/front/state_machine_def.hpp>
26 
27 namespace Leosac
28 {
29 namespace Module
30 {
31 namespace LedBuzzer
32 {
33 namespace SM
34 {
35 /********************************************
36 * Define events used in the state machine *
37 ********************************************/
38 
43 {
44 };
45 
49 struct EventBlink
50 {
54  int64_t duration;
55 
59  int64_t speed;
60 };
61 
66 {
67 };
68 
73 {
80  std::vector<std::pair<int, int>> pattern;
81 };
82 
87 {
88 };
89 
90 namespace
91 {
92 namespace msmf = boost::msm::front;
93 }
94 
95 struct LedBuzzerSM_ : msmf::state_machine_def<LedBuzzerSM_>
96 {
97 
99  : playing_pattern_(false)
100  , gpio_(h)
101  , next_update_time_(std::chrono::system_clock::time_point::max())
102  {
103  }
104 
105  struct Idle : msmf::state<>
106  {
107  // Entry action
108  template <class Event, class Fsm>
109  void on_entry(Event const &, Fsm &fsm)
110  {
111  DEBUG("Idle::on_entry()");
112  fsm.next_update_time_ = std::chrono::system_clock::time_point::max();
113  }
114 
115  // Exit action
116  template <class Event, class Fsm>
117  void on_exit(Event const &, Fsm &)
118  {
119  DEBUG("Idle::on_exit()");
120  }
121  };
122 
123  // We want a predefined blinking pattern
124  struct PlayingPattern : msmf::state<>
125  {
126  // Entry action
127  template <class Event, class Fsm>
128  void on_entry(Event const &, Fsm &)
129  {
130  ERROR("Bad event when entering PlayingPattern");
131  assert(0);
132  }
133 
134  template <class Fsm>
135  void on_entry(EventBlinkStop const &, Fsm &)
136  {
137  // we are coming back to PlayingPattern after finishing 1 round of
138  // blinking.
139  }
140 
141  template <class Fsm>
142  void on_entry(EventPlayingPattern const &e, Fsm &fsm)
143  {
144  std::cout << "PlayingPattern::on_entry()" << std::endl;
145  fsm.next_update_time_ = std::chrono::system_clock::now();
146  fsm.playing_pattern_ = true;
147  pattern_ = e.pattern;
148  }
149 
150  // Exit action
151  template <class Event, class Fsm>
152  void on_exit(Event const &, Fsm &fsm)
153  {
154  std::cout << "PlayingPattern::on_exit()" << std::endl;
155  // if we exit to go into blinking we must not clear the playing_pattern
156  // flag
157  // we clear only if we exit due to EventPlayingPatternStop
158  if (std::is_same<Event, EventPlayingPatternStop>::value)
159  fsm.playing_pattern_ = false;
160  }
161 
162  std::vector<std::pair<int, int>> pattern_;
163  };
164 
165  struct StateBlinking : msmf::state<>
166  {
167  // Entry action
168  template <class Event, class Fsm>
169  void on_entry(Event const &, Fsm &)
170  {
171  ERROR("Bad event when entering StateBlinking");
172  assert(0);
173  }
174 
175  template <class Fsm>
176  void on_entry(EventBlink const &e, Fsm &fsm)
177  {
178  DEBUG("StateBlinking::on_entry(). Duration = "
179  << e.duration << ". Speed = " << e.speed);
180  fsm.next_update_time_ = std::chrono::system_clock::now();
181  nb_itr_ = e.duration / e.speed;
182  speed_ = e.speed;
183  fsm.led_state_.duration = e.duration;
184  fsm.led_state_.speed = e.speed;
185  fsm.led_state_.st = Hardware::FLED::State::BLINKING;
186  }
187 
188  // Exit action
189  template <class Event, class Fsm>
190  void on_exit(Event const &, Fsm &fsm)
191  {
192  std::cout << "StateBlinking::on_exit()" << std::endl;
193  // we don't know nor care what is real state. We just care
194  // that it's not blinking anymore.
195  fsm.led_state_.st = Hardware::FLED::State::UNKNOWN;
196  }
197 
198  int speed_;
199  int nb_itr_;
200  };
201 
202  // Set initial state
204 
206  {
207  template <class Event, class Fsm, class SourceState, class TargetState>
208  void operator()(Event const &, Fsm &, SourceState &, TargetState &) const
209  {
210  ERROR("Bad transition");
211  assert(0);
212  }
213 
219  template <class Event, class Fsm, class TargetState>
220  void operator()(Event const &, Fsm &fsm, PlayingPattern &ss,
221  TargetState &) const
222  {
223  if (ss.pattern_.size() == 0)
224  {
225  fsm.process_event(EventPlayingPatternStop());
226  return;
227  }
228  std::pair<int, int> current_pattern = ss.pattern_.back();
229  ss.pattern_.pop_back();
230 
231  // prepare blinking event, then fire it
232  EventBlink b;
233  b.duration = current_pattern.first;
234  b.speed = current_pattern.second;
235  fsm.process_event(b);
236  }
237 
241  template <class Event, class Fsm, class TargetState>
242  void operator()(Event const &, Fsm &fsm, StateBlinking &ss,
243  TargetState &) const
244  {
245  fsm.gpio_.toggle();
246  fsm.next_update_time_ = std::chrono::system_clock::now() +
247  std::chrono::milliseconds(ss.speed_);
248  if (--ss.nb_itr_ == 0)
249  {
250  fsm.process_event(EventBlinkStop());
251  }
252  }
253  };
254 
262  {
263  template <class Fsm, class SourceState, class TargetState>
264  bool operator()(const EventBlinkStop &, Fsm &fsm, SourceState &,
265  TargetState &)
266  {
267  if (std::is_same<TargetState, PlayingPattern>::value)
268  {
269  return fsm.playing_pattern_;
270  }
271  else
272  {
273  return !fsm.playing_pattern_;
274  }
275  }
276  };
277 
278  // Transition table
280  : boost::mpl::vector<
281  // Start Event Next Action Guard
282  msmf::Row<Idle, EventBlink, StateBlinking, msmf::none, msmf::none>,
283  msmf::Row<StateBlinking, EventBlinkStop, Idle, msmf::none,
284  transition_guard>,
285  msmf::Row<StateBlinking, EventBlinkStop, PlayingPattern, msmf::none,
286  transition_guard>,
287  msmf::Row<StateBlinking, EventUpdate, msmf::none, UpdateAction,
288  msmf::none>,
289  msmf::Row<Idle, EventPlayingPattern, PlayingPattern, msmf::none,
290  msmf::none>,
291  msmf::Row<PlayingPattern, EventUpdate, msmf::none, UpdateAction,
292  msmf::none>,
293  msmf::Row<PlayingPattern, EventBlink, StateBlinking, msmf::none,
294  msmf::none>,
295  msmf::Row<PlayingPattern, EventPlayingPatternStop, Idle, msmf::none,
296  msmf::none>>
297  {
298  };
299 
300  std::chrono::system_clock::time_point next_update() const
301  {
302  return next_update_time_;
303  }
304 
309 
317 
318 
323 
328  std::chrono::system_clock::time_point next_update_time_;
329 };
330 }
331 typedef boost::msm::back::state_machine<SM::LedBuzzerSM_> LedBuzzerSM;
332 }
333 }
334 }
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking::on_exit
void on_exit(Event const &, Fsm &fsm)
Definition: LedBuzzerSM.hpp:190
FGPIO.hpp
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern::pattern_
std::vector< std::pair< int, int > > pattern_
Definition: LedBuzzerSM.hpp:162
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::Idle::on_entry
void on_entry(Event const &, Fsm &fsm)
Definition: LedBuzzerSM.hpp:109
Leosac::Module::LedBuzzer::SM::EventPlayingPattern::pattern
std::vector< std::pair< int, int > > pattern
A vector of <duration, speed> that represents our blinking pattern.
Definition: LedBuzzerSM.hpp:80
Leosac::Hardware::FLED::State::UNKNOWN
@ UNKNOWN
Definition: FLED.hpp:65
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern::on_entry
void on_entry(Event const &, Fsm &)
Definition: LedBuzzerSM.hpp:128
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::transition_table
Definition: LedBuzzerSM.hpp:279
ERROR
@ ERROR
Definition: log.hpp:32
DEBUG
@ DEBUG
Definition: log.hpp:35
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::Idle::on_exit
void on_exit(Event const &, Fsm &)
Definition: LedBuzzerSM.hpp:117
Leosac::Hardware::FLED::State::BLINKING
@ BLINKING
Definition: FLED.hpp:64
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::next_update_time_
std::chrono::system_clock::time_point next_update_time_
Next time_point we want to be updated.
Definition: LedBuzzerSM.hpp:328
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::playing_pattern_
bool playing_pattern_
If we are currently blinking in pattern, this will be true.
Definition: LedBuzzerSM.hpp:308
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::transition_guard::operator()
bool operator()(const EventBlinkStop &, Fsm &fsm, SourceState &, TargetState &)
Definition: LedBuzzerSM.hpp:264
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::next_update
std::chrono::system_clock::time_point next_update() const
Definition: LedBuzzerSM.hpp:300
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking::on_entry
void on_entry(Event const &, Fsm &)
Definition: LedBuzzerSM.hpp:169
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_
Definition: LedBuzzerSM.hpp:95
Leosac::Hardware::FLED::State
Definition: FLED.hpp:47
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::Idle
Definition: LedBuzzerSM.hpp:105
Leosac::Hardware::FGPIO
A Facade to a GPIO object.
Definition: FGPIO.hpp:45
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::gpio_
Hardware::FGPIO & gpio_
Facade to the underlying gpio.
Definition: LedBuzzerSM.hpp:322
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern
Definition: LedBuzzerSM.hpp:124
Leosac
This is the header file for a generated source file, GitSHA1.cpp.
Definition: APIStatusCode.hpp:22
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::initial_state
Idle initial_state
Definition: LedBuzzerSM.hpp:203
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking::on_entry
void on_entry(EventBlink const &e, Fsm &fsm)
Definition: LedBuzzerSM.hpp:176
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::UpdateAction
Definition: LedBuzzerSM.hpp:205
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking::nb_itr_
int nb_itr_
Definition: LedBuzzerSM.hpp:199
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::UpdateAction::operator()
void operator()(Event const &, Fsm &fsm, StateBlinking &ss, TargetState &) const
Blink by toggling the GPIO, or return to Idle state.
Definition: LedBuzzerSM.hpp:242
Leosac::Module::LedBuzzer::SM::EventPlayingPatternStop
Fired when playing pattern has terminated.
Definition: LedBuzzerSM.hpp:65
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking
Definition: LedBuzzerSM.hpp:165
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::UpdateAction::operator()
void operator()(Event const &, Fsm &, SourceState &, TargetState &) const
Definition: LedBuzzerSM.hpp:208
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::transition_guard
A transition guard that check EventBlinkStop.
Definition: LedBuzzerSM.hpp:261
log.hpp
Leosac::Module::LedBuzzer::SM::EventUpdate
Fired when we update the state machine.
Definition: LedBuzzerSM.hpp:42
FLED.hpp
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::StateBlinking::speed_
int speed_
Definition: LedBuzzerSM.hpp:198
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern::on_entry
void on_entry(EventBlinkStop const &, Fsm &)
Definition: LedBuzzerSM.hpp:135
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern::on_exit
void on_exit(Event const &, Fsm &fsm)
Definition: LedBuzzerSM.hpp:152
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::led_state_
Hardware::FLED::State led_state_
The state of the LED.
Definition: LedBuzzerSM.hpp:316
Leosac::Module::LedBuzzer::LedBuzzerSM
boost::msm::back::state_machine< SM::LedBuzzerSM_ > LedBuzzerSM
Definition: LedBuzzerSM.hpp:331
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::UpdateAction::operator()
void operator()(Event const &, Fsm &fsm, PlayingPattern &ss, TargetState &) const
Updating PlayingPattern.
Definition: LedBuzzerSM.hpp:220
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::LedBuzzerSM_
LedBuzzerSM_(Hardware::FGPIO &h)
Definition: LedBuzzerSM.hpp:98
Leosac::Module::LedBuzzer::SM::EventBlinkStop
Fired when we are done blinking.
Definition: LedBuzzerSM.hpp:86
Leosac::Module::LedBuzzer::SM::EventPlayingPattern
Fired when we want to "play" a pattern.
Definition: LedBuzzerSM.hpp:72
Leosac::Module::LedBuzzer::SM::LedBuzzerSM_::PlayingPattern::on_entry
void on_entry(EventPlayingPattern const &e, Fsm &fsm)
Definition: LedBuzzerSM.hpp:142