Fawkes API  Fawkes Development Version
clock_adapter.cpp
1 
2 /***************************************************************************
3  * clock_adapter.cpp - PLEXIL adapter for Fawkes' clock
4  *
5  * Created: Mon Aug 13 15:49:25 2018
6  * Copyright 2006-2018 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "clock_adapter.h"
24 
25 #include <AdapterConfiguration.hh>
26 #include <AdapterExecInterface.hh>
27 #include <AdapterFactory.hh>
28 #include <State.hh>
29 #include <StateCacheEntry.hh>
30 
31 /** @class ClockPlexilTimeAdapter "clock_adapter.h"
32  * Plexil adapter to provide time from Fawkes time source.
33  * @author Tim Niemueller
34  */
35 
36 /** Constructor.
37  * @param execInterface Reference to the parent AdapterExecInterface object.
38  */
39 ClockPlexilTimeAdapter::ClockPlexilTimeAdapter(PLEXIL::AdapterExecInterface &execInterface)
40 : TimeAdapter(execInterface)
41 {
42 }
43 
44 /** Constructor from configuration XML.
45  * @param execInterface Reference to the parent AdapterExecInterface object.
46  * @param xml A const reference to the XML element describing this adapter
47  * @note The instance maintains a shared pointer to the XML.
48  */
49 ClockPlexilTimeAdapter::ClockPlexilTimeAdapter(PLEXIL::AdapterExecInterface &execInterface,
50  pugi::xml_node const xml)
51 : TimeAdapter(execInterface, xml)
52 {
53 }
54 
55 /** Destructor. */
57 {
58 }
59 
60 /** Initialize adapter.
61  * @return true if initialization was successful, false otherwise.
62  */
63 bool
65 {
66  // Automatically register self for time
67  PLEXIL::g_configuration->registerLookupInterface("time", this);
68  return true;
69 }
70 
71 /** Start adapter.
72  * @return true if starting was successful, false otherwise.
73  */
74 bool
76 {
77  clock_ = reinterpret_cast<fawkes::Clock *>(m_execInterface.getProperty("::Fawkes::Clock"));
78 
79  timer_ = new PlexilTimerThread();
80  timer_->start();
81 
82  return true;
83 }
84 
85 /** Stop adapter.
86  * @return true if successful, false otherwise.
87  */
88 bool
90 {
91  timer_->abort_timer();
92  timer_->cancel();
93  timer_->join();
94  delete timer_;
95 
96  return true;
97 }
98 
99 /** Reset adapter.
100  * @return true if successful, false otherwise.
101  */
102 bool
104 {
105  return true;
106 }
107 
108 /** Shut adapter down.
109  * @return true if successful, false otherwise.
110  */
111 bool
113 {
114  return true;
115 }
116 
117 /** Immediate lookup of value.
118  * @param state state variable to lookup
119  * @param cache_entry cache entry for retrieved value
120  */
121 void
122 ClockPlexilTimeAdapter::lookupNow(PLEXIL::State const &state, PLEXIL::StateCacheEntry &cache_entry)
123 {
124  if (state != PLEXIL::State::timeState()) {
125  //warn("TimeAdapter does not implement lookups for state " << state);
126  cache_entry.setUnknown();
127  return;
128  }
129 
130  cache_entry.update(getCurrentTime());
131 }
132 
133 /** Subscribe to updates for given state.
134  * @param state state variable to subscribe for
135  */
136 void
137 ClockPlexilTimeAdapter::subscribe(const PLEXIL::State &state)
138 {
139  //debugMsg("TimeAdapter:subscribe", " called");
140 }
141 
142 /** Unsubscribe from updates.
143  * @param state state variable to unsubscribe from
144  */
145 void
146 ClockPlexilTimeAdapter::unsubscribe(const PLEXIL::State &state)
147 {
148  timer_->abort_timer();
149 }
150 
151 /** Set thresholds for subscription.
152  * @param state state variable
153  * @param hi high value
154  * @param lo low value
155  */
156 void
157 ClockPlexilTimeAdapter::setThresholds(const PLEXIL::State &state, double hi, double lo)
158 {
159  if (state != PLEXIL::State::timeState()) {
160  //warn("TimeAdapter does not implement lookups for state " << state);
161  return;
162  }
163 
164  fawkes::Time now(clock_);
165  if (now.in_sec() > hi) {
166  warn("FawkesTimeAdapter:setThresholds: timeout already passed");
167  timer_event();
168  } else {
169  timer_->start_timer(this, hi);
170  }
171 }
172 
173 /** Set thresholds for subscription.
174  * @param state state variable
175  * @param hi high value
176  * @param lo low value
177  */
178 void
179 ClockPlexilTimeAdapter::setThresholds(const PLEXIL::State &state, int32_t hi, int32_t lo)
180 {
181  setThresholds(state, (double)hi, (double)lo);
182 }
183 
184 void
186 {
187  m_execInterface.notifyOfExternalEvent();
188 }
189 
190 /** Get the current time from the operating system.
191  * @return A double representing the current time.
192  */
193 double
194 ClockPlexilTimeAdapter::getCurrentTime() throw(PLEXIL::InterfaceError)
195 {
196  fawkes::Time now(clock_);
197  return now.in_sec();
198 }
199 
200 extern "C" {
201 void
202 initFawkesTimeAdapter()
203 {
204  REGISTER_ADAPTER(ClockPlexilTimeAdapter, "FawkesTimeAdapter");
205 }
206 }
ClockPlexilTimeAdapter::ClockPlexilTimeAdapter
ClockPlexilTimeAdapter(PLEXIL::AdapterExecInterface &execInterface)
Constructor.
Definition: clock_adapter.cpp:39
ClockPlexilTimeAdapter::~ClockPlexilTimeAdapter
virtual ~ClockPlexilTimeAdapter()
Destructor.
Definition: clock_adapter.cpp:56
ClockPlexilTimeAdapter::lookupNow
virtual void lookupNow(PLEXIL::State const &state, PLEXIL::StateCacheEntry &cacheEntry)
Immediate lookup of value.
Definition: clock_adapter.cpp:122
ClockPlexilTimeAdapter::stop
virtual bool stop()
Stop adapter.
Definition: clock_adapter.cpp:89
ClockPlexilTimeAdapter::timer_event
virtual void timer_event()
Called for timer events.
Definition: clock_adapter.cpp:185
ClockPlexilTimeAdapter::setThresholds
virtual void setThresholds(const PLEXIL::State &state, double hi, double lo)
Set thresholds for subscription.
Definition: clock_adapter.cpp:157
ClockPlexilTimeAdapter::reset
virtual bool reset()
Reset adapter.
Definition: clock_adapter.cpp:103
ClockPlexilTimeAdapter::shutdown
virtual bool shutdown()
Shut adapter down.
Definition: clock_adapter.cpp:112
ClockPlexilTimeAdapter::unsubscribe
virtual void unsubscribe(const PLEXIL::State &state)
Unsubscribe from updates.
Definition: clock_adapter.cpp:146
fawkes::Time
Definition: time.h:96
PlexilTimerThread
Definition: timer_thread.h:27
PlexilTimerThread::start_timer
void start_timer(CallbackListener *listener, const fawkes::Time &wait_until)
Start timer non-blocking.
Definition: timer_thread.cpp:76
ClockPlexilTimeAdapter::initialize
virtual bool initialize()
Initialize adapter.
Definition: clock_adapter.cpp:64
fawkes::Thread::cancel
void cancel()
Cancel a thread.
Definition: thread.cpp:650
fawkes::Time::in_sec
double in_sec() const
Convet time to seconds.
Definition: time.cpp:224
ClockPlexilTimeAdapter::subscribe
virtual void subscribe(const PLEXIL::State &state)
Subscribe to updates for given state.
Definition: clock_adapter.cpp:137
PlexilTimerThread::abort_timer
void abort_timer()
Abort a currently running timer.
Definition: timer_thread.cpp:94
ClockPlexilTimeAdapter::getCurrentTime
double getCurrentTime()
Get the current time from the operating system.
Definition: clock_adapter.cpp:194
fawkes::Thread::join
void join()
Join the thread.
Definition: thread.cpp:601
ClockPlexilTimeAdapter
An interface adapter using standard POSIX time facilities to implement LookupNow and LookupOnChange.
Definition: clock_adapter.h:35
ClockPlexilTimeAdapter::start
virtual bool start()
Start adapter.
Definition: clock_adapter.cpp:75