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 */
39ClockPlexilTimeAdapter::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 */
49ClockPlexilTimeAdapter::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 */
63bool
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 */
74bool
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 */
88bool
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 */
102bool
104{
105 return true;
106}
107
108/** Shut adapter down.
109 * @return true if successful, false otherwise.
110 */
111bool
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 */
121void
122ClockPlexilTimeAdapter::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 */
136void
137ClockPlexilTimeAdapter::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 */
145void
146ClockPlexilTimeAdapter::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 */
156void
157ClockPlexilTimeAdapter::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 */
178void
179ClockPlexilTimeAdapter::setThresholds(const PLEXIL::State &state, int32_t hi, int32_t lo)
180{
181 setThresholds(state, (double)hi, (double)lo);
182}
183
184void
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 */
193double
194ClockPlexilTimeAdapter::getCurrentTime() throw(PLEXIL::InterfaceError)
195{
196 fawkes::Time now(clock_);
197 return now.in_sec();
198}
199
200extern "C" {
201void
202initFawkesTimeAdapter()
203{
204 REGISTER_ADAPTER(ClockPlexilTimeAdapter, "FawkesTimeAdapter");
205}
206}
An interface adapter using standard POSIX time facilities to implement LookupNow and LookupOnChange.
Definition: clock_adapter.h:38
virtual bool reset()
Reset adapter.
virtual void subscribe(const PLEXIL::State &state)
Subscribe to updates for given state.
virtual bool initialize()
Initialize adapter.
virtual bool shutdown()
Shut adapter down.
virtual bool start()
Start adapter.
virtual void setThresholds(const PLEXIL::State &state, double hi, double lo)
Set thresholds for subscription.
virtual void lookupNow(PLEXIL::State const &state, PLEXIL::StateCacheEntry &cacheEntry)
Immediate lookup of value.
virtual bool stop()
Stop adapter.
virtual ~ClockPlexilTimeAdapter()
Destructor.
virtual void timer_event()
Called for timer events.
double getCurrentTime()
Get the current time from the operating system.
ClockPlexilTimeAdapter(PLEXIL::AdapterExecInterface &execInterface)
Constructor.
virtual void unsubscribe(const PLEXIL::State &state)
Unsubscribe from updates.
Timer support class.
Definition: timer_thread.h:29
void start_timer(CallbackListener *listener, const fawkes::Time &wait_until)
Start timer non-blocking.
void abort_timer()
Abort a currently running timer.
This is supposed to be the central clock in Fawkes.
Definition: clock.h:35
void start(bool wait=true)
Call this method to start the thread.
Definition: thread.cpp:499
void join()
Join the thread.
Definition: thread.cpp:597
void cancel()
Cancel a thread.
Definition: thread.cpp:646
A class for handling time.
Definition: time.h:93
double in_sec() const
Convet time to seconds.
Definition: time.cpp:219