UniSet  2.7.0
IOController.h
1 /*
2  * Copyright (c) 2015 Pavel Vainerman.
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, version 2.1.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11  * Lesser General Lesser Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  */
16 // --------------------------------------------------------------------------
21 // --------------------------------------------------------------------------
22 #ifndef IOController_H_
23 #define IOController_H_
24 //---------------------------------------------------------------------------
25 #include <unordered_map>
26 #include <list>
27 #include <sigc++/sigc++.h>
28 #include "IOController_i.hh"
29 #include "UniSetTypes.h"
30 #include "UniSetManager.h"
31 #include "Configuration.h"
32 #include "Mutex.h"
33 //---------------------------------------------------------------------------
34 namespace uniset
35 {
45  class IOController:
46  public UniSetManager,
47  public POA_IOController_i
48  {
49  public:
50 
51  IOController( const std::string& name, const std::string& section );
52  IOController( const uniset::ObjectId id );
53  virtual ~IOController();
54 
55  virtual uniset::ObjectType getType() override
56  {
57  return uniset::ObjectType("IOController");
58  }
59 
60  virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override;
61 
62  virtual CORBA::Long getValue( uniset::ObjectId sid ) override;
63 
64  // -------------------- !!!!!!!!! ---------------------------------
65  // Реализуются конкретным i/o контроллером
66  // Не забывайте писать реализацию этих функций
67  virtual void setValue( uniset::ObjectId sid, CORBA::Long value,
68  uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
69 
70  // ----------------------------------------------------------------
71  virtual void setUndefinedState( uniset::ObjectId sid,
72  CORBA::Boolean undefined,
73  uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
74 
75 
76  virtual IOController_i::SensorInfoSeq* getSensorSeq( const uniset::IDSeq& lst ) override;
77  virtual uniset::IDSeq* setOutputSeq( const IOController_i::OutSeq& lst, uniset::ObjectId sup_id ) override;
78 
79  // ----------------------------------------------------------------
80  virtual UniversalIO::IOType getIOType( uniset::ObjectId sid ) override;
81 
82  virtual IOController_i::SensorInfoSeq* getSensorsMap() override;
83  virtual IOController_i::SensorIOInfo getSensorIOInfo( uniset::ObjectId sid ) override;
84 
85  virtual CORBA::Long getRawValue( uniset::ObjectId sid ) override;
86  virtual void calibrate( uniset::ObjectId sid,
88  uniset::ObjectId adminId ) override;
89 
90  IOController_i::CalibrateInfo getCalibrateInfo( uniset::ObjectId sid ) override;
91 
92  inline IOController_i::SensorInfo SensorInfo( const uniset::ObjectId sid,
93  const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode())
94  {
96  si.id = sid;
97  si.node = node;
98  return si;
99  };
100 
101  uniset::Message::Priority getPriority( const uniset::ObjectId id );
102 
103  virtual IOController_i::ShortIOInfo getTimeChange( const uniset::ObjectId id ) override;
104 
105  virtual IOController_i::ShortMapSeq* getSensors() override;
106 
107 #ifndef DISABLE_REST_API
108  // http API
109  virtual Poco::JSON::Object::Ptr httpHelp( const Poco::URI::QueryParameters& p ) override;
110  virtual Poco::JSON::Object::Ptr httpRequest( const std::string& req, const Poco::URI::QueryParameters& p ) override;
111 #endif
112 
113  public:
114 
115  // предварительное объявление..
116  struct USensorInfo;
117  typedef std::unordered_map<uniset::ObjectId, std::shared_ptr<USensorInfo>> IOStateList;
118 
119  // ================== Достпуные сигналы =================
125  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeSignal;
126  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeUndefinedStateSignal;
127 
128  // signal по изменению определённого датчика
129  ChangeSignal signal_change_value( uniset::ObjectId sid );
130 
131  // signal по изменению любого датчика
132  ChangeSignal signal_change_value();
133 
134  // сигналы по изменению флага "неопределённое состояние" (обрыв датчика например)
135  ChangeUndefinedStateSignal signal_change_undefined_state( uniset::ObjectId sid );
136  ChangeUndefinedStateSignal signal_change_undefined_state();
137  // -----------------------------------------------------------------------------------------
138  // полнейшее нарушение икапсуляции
139  // но пока, это попытка оптимизировать работу с IOController через указатель.
140  // Т.е. работая с датчиками через итераторы..
141 #if 1
142  inline IOStateList::iterator ioBegin()
143  {
144  return ioList.begin();
145  }
146  inline IOStateList::iterator ioEnd()
147  {
148  return ioList.end();
149  }
150  inline IOStateList::iterator find( uniset::ObjectId k )
151  {
152  return ioList.find(k);
153  }
154 #endif
155  inline int ioCount() const noexcept
156  {
157  return ioList.size();
158  }
159 
160  protected:
161 
162  // доступ к элементам через итератор
163  // return итоговое значение
164  virtual long localSetValueIt( IOStateList::iterator& it, const uniset::ObjectId sid,
165  CORBA::Long value, uniset::ObjectId sup_id );
166 
167  virtual long localGetValue( IOStateList::iterator& it, const uniset::ObjectId sid );
168 
173  virtual void localSetUndefinedState( IOStateList::iterator& it, bool undefined,
174  const uniset::ObjectId sid );
175 
176  // -- работа через указатель ---
177  virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, uniset::ObjectId sup_id );
178  long localGetValue( std::shared_ptr<USensorInfo>& usi) ;
179 
180 #ifndef DISABLE_REST_API
181  // http API
182  virtual Poco::JSON::Object::Ptr request_get( const std::string& req, const Poco::URI::QueryParameters& p );
183  virtual Poco::JSON::Object::Ptr request_sensors( const std::string& req, const Poco::URI::QueryParameters& p );
184  void getSensorInfo( Poco::JSON::Array::Ptr& jdata, std::shared_ptr<USensorInfo>& s , bool shortInfo = false );
185 #endif
186 
187  // переопределяем для добавления вызова регистрации датчиков
188  virtual bool deactivateObject() override;
189  virtual bool activateObject() override;
190 
192  virtual void activateInit();
193 
195  virtual void sensorsRegistration() {};
197  virtual void sensorsUnregistration();
198 
199  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> InitSignal;
200 
201  // signal по изменению определённого датчика
202  InitSignal signal_init();
203 
205  void ioRegistration(std::shared_ptr<USensorInfo>& usi );
206 
208  void ioUnRegistration( const uniset::ObjectId sid );
209 
210  // ------------------------------
212  SensorIOInfo(long v, UniversalIO::IOType t, const IOController_i::SensorInfo& si,
213  uniset::Message::Priority p = uniset::Message::Medium,
214  long defval = 0, IOController_i::CalibrateInfo* ci = 0,
216  {
218  ai.si = si;
219  ai.type = t;
220  ai.value = v;
221  ai.priority = p;
222  ai.default_val = defval;
223  ai.real_value = v;
224  ai.blocked = false;
225  ai.supplier = sup_id;
226 
227  if( ci != 0 )
228  ai.ci = *ci;
229  else
230  {
231  ai.ci.minRaw = 0;
232  ai.ci.maxRaw = 0;
233  ai.ci.minCal = 0;
234  ai.ci.maxCal = 0;
235  ai.ci.precision = 0;
236  }
237 
238  return std::move(ai);
239  };
240 
242  virtual void logging( uniset::SensorMessage& sm );
243 
245  virtual void dumpToDB();
246 
247  IOController();
248 
249  // доступ к списку c изменением только для своих
250  IOStateList::iterator myioBegin();
251  IOStateList::iterator myioEnd();
252  IOStateList::iterator myiofind( uniset::ObjectId id );
253 
254  void initIOList( const IOStateList&& l );
255 
256  typedef std::function<void(std::shared_ptr<USensorInfo>&)> UFunction;
257  // функция работает с mutex
258  void for_iolist( UFunction f );
259 
260  private:
261  friend class NCRestorer;
262  friend class SMInterface;
263 
264  std::mutex siganyMutex;
265  ChangeSignal sigAnyChange;
266 
267  std::mutex siganyundefMutex;
268  ChangeSignal sigAnyUndefChange;
269  InitSignal sigInit;
270 
271  IOStateList ioList;
272  uniset::uniset_rwmutex ioMutex;
274  bool isPingDBServer; // флаг связи с DBServer-ом
275  uniset::ObjectId dbserverID = { uniset::DefaultObjectId };
276 
277  std::mutex loggingMutex;
279  public:
280 
281  struct UThresholdInfo;
282  typedef std::list<std::shared_ptr<UThresholdInfo>> ThresholdExtList;
283 
284  struct USensorInfo:
286  {
287  USensorInfo( const USensorInfo& ) = delete;
288  const USensorInfo& operator=(const USensorInfo& ) = delete;
289  USensorInfo( USensorInfo&& ) = default;
290  USensorInfo& operator=(USensorInfo&& ) = default;
291 
293  {
296  default_val = 0;
297  value = default_val;
299  dbignore = false;
300  undefined = false;
301  blocked = false;
303  }
304 
305  virtual ~USensorInfo() {}
306 
310 
312  const USensorInfo& operator=(const IOController_i::SensorIOInfo& r);
314 
315  // Дополнительные (вспомогательные поля)
318  // userdata (универсальный, но небезопасный способ расширения информации связанной с датчиком)
319  static const size_t MaxUserData = 4;
320  void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr };
323  void* getUserData( size_t index );
324  void setUserData( size_t index, void* data );
325 
326  // сигнал для реализации механизма зависимостией..
327  // (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals)
328  uniset::uniset_rwmutex changeMutex;
329  ChangeSignal sigChange;
330 
331  uniset::uniset_rwmutex undefMutex;
332  ChangeUndefinedStateSignal sigUndefChange;
333 
335  long d_value = { 1 };
336  long d_off_value = { 0 };
337  std::shared_ptr<USensorInfo> d_usi; // shared_ptr на датчик от которого зависит этот.
338 
339  // список пороговых датчиков для данного
341  ThresholdExtList thresholds;
342 
343  size_t nchanges = { 0 }; // количество изменений датчика
344 
345  // функция обработки информации об изменении состояния датчика, от которого зависит данный
346  void checkDepend( std::shared_ptr<USensorInfo>& d_usi, IOController* );
347 
348  void init( const IOController_i::SensorIOInfo& s );
349 
350  inline IOController_i::SensorIOInfo makeSensorIOInfo()
351  {
352  uniset::uniset_rwmutex_rlock lock(val_lock);
354  return s;
355  }
356 
357  inline uniset::SensorMessage makeSensorMessage( bool with_lock = false )
358  {
360  sm.id = si.id;
361  sm.node = si.node; // uniset_conf()->getLocalNode()?
362  sm.sensor_type = type;
363  sm.priority = (uniset::Message::Priority)priority;
364 
365  // лочим только изменяемые поля
366  if( with_lock )
367  {
368  uniset::uniset_rwmutex_rlock lock(val_lock);
369  sm.value = value;
370  sm.sm_tv.tv_sec = tv_sec;
371  sm.sm_tv.tv_nsec = tv_nsec;
372  sm.ci = ci;
373  sm.supplier = supplier;
374  sm.undefined = undefined;
375  }
376  else
377  {
378  sm.value = value;
379  sm.sm_tv.tv_sec = tv_sec;
380  sm.sm_tv.tv_nsec = tv_nsec;
381  sm.ci = ci;
382  sm.supplier = supplier;
383  sm.undefined = undefined;
384  }
385 
386  return sm;
387  }
388  };
389 
393  {
394  UThresholdInfo( uniset::ThresholdId tid, CORBA::Long low, CORBA::Long hi, bool inv,
396  sid(_sid),
397  invert(inv)
398  {
399  id = tid;
400  hilimit = hi;
401  lowlimit = low;
403  }
404 
407 
409  IOController::IOStateList::iterator sit;
410 
412  bool invert;
413 
414  inline bool operator== ( const ThresholdInfo& r ) const
415  {
416  return ((id == r.id) &&
417  (hilimit == r.hilimit) &&
418  (lowlimit == r.lowlimit) &&
419  (invert == r.invert) );
420  }
421 
423  {
425  r.id = id;
426  r.hilimit = hilimit;
427  r.lowlimit = lowlimit;
428  r.invert = invert;
429  r.tv_sec = tv_sec;
430  r.tv_nsec = tv_nsec;
431  r.state = state;
432  return r;
433  }
434 
435  UThresholdInfo( const UThresholdInfo& ) = delete;
436  UThresholdInfo& operator=( const UThresholdInfo& ) = delete;
437  UThresholdInfo( UThresholdInfo&& ) = default;
438  UThresholdInfo& operator=(UThresholdInfo&& ) = default;
439  };
440  };
441  // -------------------------------------------------------------------------
442 } // end of uniset namespace
443 // --------------------------------------------------------------------------
444 #endif
445 // --------------------------------------------------------------------------
uniset::ObjectId supplier
Definition: IOController_i.idl:105
unsigned long tv_nsec
Definition: IOController_i.idl:210
virtual void activateInit()
Definition: IOController.cc:105
IOController::IOStateList::iterator sit
Definition: IOController.h:409
Definition: SMInterface.h:31
uniset::ObjectId sid
Definition: IOController.h:406
Definition: CallbackTimer.h:29
Definition: IOController.h:391
IOController_i::SensorInfo d_si
Definition: IOController.h:334
Definition: IOController_i.idl:92
short precision
Definition: IOController_i.idl:84
long default_val
Definition: IOController_i.idl:101
long minCal
Definition: IOController_i.idl:82
uniset::uniset_rwmutex userdata_lock
Definition: IOController.h:321
unsigned long tv_sec
Definition: IOController_i.idl:209
Definition: IOController_i.idl:203
long ThresholdId
Definition: UniSetTypes_i.idl:31
virtual bool deactivateObject() override
Definition: IOController.cc:78
Definition: IOController.h:284
virtual void sensorsRegistration()
Definition: IOController.h:195
uniset::uniset_rwmutex val_lock
Definition: IOController.h:316
long maxRaw
Definition: IOController_i.idl:81
UniversalIO::IOType type
Definition: IOController_i.idl:98
virtual bool activateObject() override
Definition: IOController.cc:67
bool invert
Definition: IOController.h:412
boolean undefined
Definition: IOController_i.idl:95
sequence< ObjectId > IDSeq
Definition: UniSetTypes_i.idl:82
std::shared_ptr< Configuration > uniset_conf() noexcept
Definition: Configuration.cc:90
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:69
void * userdata[MaxUserData]
Definition: IOController.h:320
unsigned long tv_sec
Definition: IOController_i.idl:103
uniset::ObjectId node
Definition: IOController_i.idl:59
boolean dbignore
Definition: IOController_i.idl:106
Definition: IOController_i.idl:137
long minRaw
Definition: IOController_i.idl:80
Definition: MessageType.h:124
long lowlimit
Definition: IOController_i.idl:207
sigc::signal< void, std::shared_ptr< USensorInfo > &, IOController * > ChangeSignal
Definition: IOController.h:125
virtual void localSetUndefinedState(IOStateList::iterator &it, bool undefined, const uniset::ObjectId sid)
Definition: IOController.cc:184
long priority
Definition: IOController_i.idl:99
boolean blocked
Definition: IOController_i.idl:96
Definition: UniSetManager.h:57
Definition: Mutex.h:31
long maxCal
Definition: IOController_i.idl:83
virtual void logging(uniset::SensorMessage &sm)
сохранение информации об изменении состояния датчика
Definition: IOController.cc:415
long d_off_value
Definition: IOController.h:336
Definition: IOController_i.idl:78
long hilimit
Definition: IOController_i.idl:206
long real_value
Definition: IOController_i.idl:97
void ioUnRegistration(const uniset::ObjectId sid)
Definition: IOController.cc:410
Definition: IOController_i.idl:56
Definition: IOController.h:45
virtual void sensorsUnregistration()
Definition: IOController.cc:84
Definition: IOController_i.idl:199
virtual void dumpToDB()
сохранение состояния всех датчиков в БД
Definition: IOController.cc:443
string< SizeOfObjectType > ObjectType
Definition: UniSetTypes_i.idl:33
boolean invert
Definition: IOController_i.idl:211
CalibrateInfo ci
Definition: IOController_i.idl:102
unsigned long tv_nsec
Definition: IOController_i.idl:104
Definition: UniSetTypes_i.idl:64
Definition: Mutex.h:84
void ioRegistration(std::shared_ptr< USensorInfo > &usi)
Definition: IOController.cc:373
long value
Definition: IOController_i.idl:94
long ObjectId
Definition: UniSetTypes_i.idl:30
long d_value
Definition: IOController.h:335
uniset::ObjectId id
Definition: IOController_i.idl:58