UniSet  2.24.2
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 <limits>
28 #include <sigc++/sigc++.h>
29 #include "IOController_i.hh"
30 #include "UniSetTypes.h"
31 #include "UniSetManager.h"
32 #include "Configuration.h"
33 #include "Mutex.h"
34 #include "DBServer.h"
35 //---------------------------------------------------------------------------
36 namespace uniset
37 {
47  class IOController:
48  public UniSetManager,
49  public POA_IOController_i
50  {
51  public:
52 
53  IOController( const std::string& name, const std::string& section );
54  IOController( const uniset::ObjectId id );
55  virtual ~IOController();
56 
57  void setDBServer( const std::shared_ptr<uniset::DBServer>& dbserver );
58 
59  virtual uniset::ObjectType getType() override
60  {
61  return uniset::ObjectType("IOController");
62  }
63 
64  virtual uniset::SimpleInfo* getInfo( const char* userparam = "" ) override;
65 
66  // ----------------------------------------------------------------
67  // Публичный (IDL) интерфейс IOController_i
68  // ----------------------------------------------------------------
69 
70  virtual CORBA::Long getValue( uniset::ObjectId sid ) override;
71 
72  virtual void setValue( uniset::ObjectId sid, CORBA::Long value,
73  uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
74  virtual void setUndefinedState( uniset::ObjectId sid,
75  CORBA::Boolean undefined,
76  uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
77 
78  virtual void freezeValue( uniset::ObjectId sid,
79  CORBA::Boolean set,
80  CORBA::Long value,
81  uniset::ObjectId sup_id = uniset::DefaultObjectId ) override;
82 
83  virtual IOController_i::SensorInfoSeq* getSensorSeq( const uniset::IDSeq& lst ) override;
84  virtual uniset::IDSeq* setOutputSeq( const IOController_i::OutSeq& lst, uniset::ObjectId sup_id ) override;
85 
86  // ----------------------------------------------------------------
87  virtual UniversalIO::IOType getIOType( uniset::ObjectId sid ) override;
88 
89  virtual IOController_i::SensorInfoSeq* getSensorsMap() override;
90  virtual IOController_i::SensorIOInfo getSensorIOInfo( uniset::ObjectId sid ) override;
91 
92  virtual CORBA::Long getRawValue( uniset::ObjectId sid ) override;
93  virtual void calibrate( uniset::ObjectId sid,
95  uniset::ObjectId adminId ) override;
96 
97  IOController_i::CalibrateInfo getCalibrateInfo( uniset::ObjectId sid ) override;
98 
99  inline IOController_i::SensorInfo SensorInfo( const uniset::ObjectId sid,
100  const uniset::ObjectId node = uniset::uniset_conf()->getLocalNode())
101  {
103  si.id = sid;
104  si.node = node;
105  return si;
106  };
107 
108  uniset::Message::Priority getPriority( const uniset::ObjectId id );
109 
110  virtual IOController_i::ShortIOInfo getTimeChange( const uniset::ObjectId id ) override;
111 
112  virtual IOController_i::ShortMapSeq* getSensors() override;
113 
114 #ifndef DISABLE_REST_API
115  // http API
116  virtual Poco::JSON::Object::Ptr httpHelp( const Poco::URI::QueryParameters& p ) override;
117  virtual Poco::JSON::Object::Ptr httpRequest( const std::string& req, const Poco::URI::QueryParameters& p ) override;
118 #endif
119 
120  public:
121 
122  // предварительное объявление..
123  struct USensorInfo;
124  typedef std::unordered_map<uniset::ObjectId, std::shared_ptr<USensorInfo>> IOStateList;
125 
126  static const long not_specified_value = { std::numeric_limits<long>::max() };
127 
128  // ================== Доступные сигналы =================
134  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeSignal;
135  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeUndefinedStateSignal;
136 
137  // signal по изменению определённого датчика
138  ChangeSignal signal_change_value( uniset::ObjectId sid );
139 
140  // signal по изменению любого датчика
141  ChangeSignal signal_change_value();
142 
143  // сигналы по изменению флага "неопределённое состояние" (обрыв датчика например)
144  ChangeUndefinedStateSignal signal_change_undefined_state( uniset::ObjectId sid );
145  ChangeUndefinedStateSignal signal_change_undefined_state();
146  // -----------------------------------------------------------------------------------------
147  // полнейшее нарушение инкапсуляции
148  // но пока, это попытка оптимизировать работу с IOController через указатель.
149  // Т.е. работая с датчиками через итераторы..
150 #if 1
151  inline IOStateList::iterator ioBegin()
152  {
153  return ioList.begin();
154  }
155  inline IOStateList::iterator ioEnd()
156  {
157  return ioList.end();
158  }
159  inline IOStateList::iterator find( uniset::ObjectId k )
160  {
161  return ioList.find(k);
162  }
163 #endif
164  inline int ioCount() const noexcept
165  {
166  return ioList.size();
167  }
168 
169  protected:
170 
171  // доступ к элементам через итератор
172  // return итоговое значение
173  virtual long localSetValueIt( IOStateList::iterator& it, const uniset::ObjectId sid,
174  CORBA::Long value, uniset::ObjectId sup_id );
175 
176  virtual long localGetValue( IOStateList::iterator& it, const uniset::ObjectId sid );
177 
182  virtual void localSetUndefinedState( IOStateList::iterator& it, bool undefined,
183  const uniset::ObjectId sid );
184 
185  virtual void localFreezeValueIt( IOController::IOStateList::iterator& li,
186  uniset::ObjectId sid,
187  CORBA::Boolean set,
188  CORBA::Long value,
189  uniset::ObjectId sup_id );
190 
191  virtual void localFreezeValue( std::shared_ptr<USensorInfo>& usi,
192  CORBA::Boolean set,
193  CORBA::Long value,
194  uniset::ObjectId sup_id );
195 
196 
197  // -- работа через указатель ---
198  virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, uniset::ObjectId sup_id );
199  long localGetValue( std::shared_ptr<USensorInfo>& usi) ;
200 
201 #ifndef DISABLE_REST_API
202  // http API
203  virtual Poco::JSON::Object::Ptr request_get( const std::string& req, const Poco::URI::QueryParameters& p );
204  virtual Poco::JSON::Object::Ptr request_sensors( const std::string& req, const Poco::URI::QueryParameters& p );
205  void getSensorInfo( Poco::JSON::Array::Ptr& jdata, std::shared_ptr<USensorInfo>& s, bool shortInfo = false );
206 #endif
207 
208  // переопределяем для добавления вызова регистрации датчиков
209  virtual bool deactivateObject() override;
210  virtual bool activateObject() override;
211 
213  virtual void activateInit();
214 
216  virtual void sensorsRegistration() {};
218  virtual void sensorsUnregistration();
219 
220  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> InitSignal;
221 
222  // signal по изменению определённого датчика
223  InitSignal signal_init();
224 
226  void ioRegistration(std::shared_ptr<USensorInfo>& usi );
227 
229  void ioUnRegistration( const uniset::ObjectId sid );
230 
231  // ------------------------------
233  SensorIOInfo(long v, UniversalIO::IOType t, const IOController_i::SensorInfo& si,
234  uniset::Message::Priority p = uniset::Message::Medium,
235  long defval = 0, IOController_i::CalibrateInfo* ci = 0,
238  {
240  ai.si = si;
241  ai.type = t;
242  ai.value = v;
243  ai.priority = p;
244  ai.default_val = defval;
245  ai.real_value = v;
246  ai.blocked = false;
247  ai.supplier = sup_id;
248  ai.depend_sid = depend_sid;
249 
250  if( ci != 0 )
251  ai.ci = *ci;
252  else
253  {
254  ai.ci.minRaw = 0;
255  ai.ci.maxRaw = 0;
256  ai.ci.minCal = 0;
257  ai.ci.maxCal = 0;
258  ai.ci.precision = 0;
259  }
260 
261  return ai;
262  };
263 
265  virtual void logging( uniset::SensorMessage& sm );
266 
268  virtual void dumpToDB();
269 
270  IOController();
271 
272  // доступ к списку c изменением только для своих
273  IOStateList::iterator myioBegin();
274  IOStateList::iterator myioEnd();
275  IOStateList::iterator myiofind( uniset::ObjectId id );
276 
277  void initIOList( const IOStateList&& l );
278 
279  typedef std::function<void(std::shared_ptr<USensorInfo>&)> UFunction;
280  // функция работает с mutex
281  void for_iolist( UFunction f );
282 
283  private:
284  friend class NCRestorer;
285  friend class SMInterface;
286 
287  std::mutex siganyMutex;
288  ChangeSignal sigAnyChange;
289 
290  std::mutex siganyundefMutex;
291  ChangeSignal sigAnyUndefChange;
292  InitSignal sigInit;
293 
294  IOStateList ioList;
295  uniset::uniset_rwmutex ioMutex;
297  bool isPingDBServer; // флаг связи с DBServer-ом
298  uniset::ObjectId dbserverID = { uniset::DefaultObjectId };
299  std::shared_ptr<uniset::DBServer> dbserver = { nullptr };
300 
301  std::mutex loggingMutex;
303  public:
304 
305  struct UThresholdInfo;
306  typedef std::list<std::shared_ptr<UThresholdInfo>> ThresholdExtList;
307 
308  struct USensorInfo:
310  {
311  USensorInfo( const USensorInfo& ) = delete;
312  const USensorInfo& operator=(const USensorInfo& ) = delete;
313  USensorInfo( USensorInfo&& ) = default;
314  USensorInfo& operator=(USensorInfo&& ) = default;
315 
316  USensorInfo();
317  virtual ~USensorInfo() {}
318 
322 
324  const USensorInfo& operator=(const IOController_i::SensorIOInfo& r);
326 
327  // Дополнительные (вспомогательные поля)
330  // userdata (универсальный, но небезопасный способ расширения информации связанной с датчиком)
331  static const size_t MaxUserData = 4;
332  void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr };
335  void* getUserData( size_t index );
336  void setUserData( size_t index, void* data );
337 
338  // сигнал для реализации механизма зависимостей..
339  // (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals)
340  uniset::uniset_rwmutex changeMutex;
341  ChangeSignal sigChange;
342 
343  uniset::uniset_rwmutex undefMutex;
344  ChangeUndefinedStateSignal sigUndefChange;
345 
346  long d_value = { 1 };
347  long d_off_value = { 0 };
348  std::shared_ptr<USensorInfo> d_usi; // shared_ptr на датчик от которого зависит этот.
349 
350  // список пороговых датчиков для данного
352  ThresholdExtList thresholds;
353 
354  size_t nchanges = { 0 }; // количество изменений датчика
355 
356  long undef_value = { not_specified_value }; // значение для "неопределённого состояния датчика"
357  long frozen_value = { 0 };
358 
359  // функция обработки информации об изменении состояния датчика, от которого зависит данный
360  void checkDepend( std::shared_ptr<USensorInfo>& d_usi, IOController* );
361 
362  void init( const IOController_i::SensorIOInfo& s );
363 
364  inline IOController_i::SensorIOInfo makeSensorIOInfo()
365  {
368  return s;
369  }
370 
371  inline uniset::SensorMessage makeSensorMessage( bool with_lock = false )
372  {
374  sm.id = si.id;
375  sm.node = si.node; // uniset_conf()->getLocalNode()?
376  sm.sensor_type = type;
377  sm.priority = (uniset::Message::Priority)priority;
378 
379  // лочим только изменяемые поля
380  if( with_lock )
381  {
383  sm.value = value;
384  sm.sm_tv.tv_sec = tv_sec;
385  sm.sm_tv.tv_nsec = tv_nsec;
386  sm.ci = ci;
387  sm.supplier = supplier;
388  sm.undefined = undefined;
389  }
390  else
391  {
392  sm.value = value;
393  sm.sm_tv.tv_sec = tv_sec;
394  sm.sm_tv.tv_nsec = tv_nsec;
395  sm.ci = ci;
396  sm.supplier = supplier;
397  sm.undefined = undefined;
398  }
399 
400  return sm;
401  }
402  };
403 
407  {
408  UThresholdInfo( uniset::ThresholdId tid, CORBA::Long low, CORBA::Long hi, bool inv,
410  sid(_sid),
411  invert(inv)
412  {
413  id = tid;
414  hilimit = hi;
415  lowlimit = low;
417  }
418 
421 
423  IOController::IOStateList::iterator sit;
424 
426  bool invert;
427 
428  inline bool operator== ( const ThresholdInfo& r ) const
429  {
430  return ((id == r.id) &&
431  (hilimit == r.hilimit) &&
432  (lowlimit == r.lowlimit) &&
433  (invert == r.invert) );
434  }
435 
436  UThresholdInfo( const UThresholdInfo& ) = delete;
437  UThresholdInfo& operator=( const UThresholdInfo& ) = delete;
438  UThresholdInfo( UThresholdInfo&& ) = default;
439  UThresholdInfo& operator=(UThresholdInfo&& ) = default;
440  };
441  };
442  // -------------------------------------------------------------------------
443 } // end of uniset namespace
444 // --------------------------------------------------------------------------
445 #endif
446 // --------------------------------------------------------------------------
Definition: IOController.h:50
virtual void dumpToDB()
сохранение состояния всех датчиков в БД
Definition: IOController.cc:537
virtual void sensorsUnregistration()
Definition: IOController.cc:86
virtual void activateInit()
Definition: IOController.cc:107
virtual bool deactivateObject() override
Definition: IOController.cc:80
virtual void sensorsRegistration()
Definition: IOController.h:216
virtual bool activateObject() override
Definition: IOController.cc:69
void ioUnRegistration(const uniset::ObjectId sid)
Definition: IOController.cc:491
virtual void localSetUndefinedState(IOStateList::iterator &it, bool undefined, const uniset::ObjectId sid)
Definition: IOController.cc:190
void ioRegistration(std::shared_ptr< USensorInfo > &usi)
Definition: IOController.cc:454
sigc::signal< void, std::shared_ptr< USensorInfo > &, IOController * > ChangeSignal
Definition: IOController.h:134
virtual void logging(uniset::SensorMessage &sm)
сохранение информации об изменении состояния датчика
Definition: IOController.cc:501
Definition: MessageType.h:127
Definition: UniSetManager.h:60
Definition: Mutex.h:85
Definition: Mutex.h:32
@ NormalThreshold
Definition: IOController_i.idl:205
Definition: CommonEventLoop.h:15
string< SizeOfObjectType > ObjectType
Definition: UniSetTypes_i.idl:33
long ThresholdId
Definition: UniSetTypes_i.idl:31
sequence< ObjectId > IDSeq
Definition: UniSetTypes_i.idl:89
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:70
std::shared_ptr< Configuration > uniset_conf() noexcept
Definition: Configuration.cc:90
long ObjectId
Definition: UniSetTypes_i.idl:30
Definition: IOController_i.idl:83
Definition: IOController_i.idl:97
uniset::ObjectId supplier
Definition: IOController_i.idl:110
unsigned long tv_sec
Definition: IOController_i.idl:108
boolean undefined
Definition: IOController_i.idl:99
CalibrateInfo ci
Definition: IOController_i.idl:107
UniversalIO::IOType type
Definition: IOController_i.idl:103
long priority
Definition: IOController_i.idl:104
unsigned long tv_nsec
Definition: IOController_i.idl:109
long value
Definition: IOController_i.idl:98
Definition: IOController_i.idl:58
uniset::ObjectId node
Definition: IOController_i.idl:60
uniset::ObjectId id
Definition: IOController_i.idl:59
Definition: IOController_i.idl:144
Definition: IOController_i.idl:210
long lowlimit
Definition: IOController_i.idl:213
long hilimit
Definition: IOController_i.idl:212
Definition: IOController.h:310
void * userdata[MaxUserData]
Definition: IOController.h:332
uniset::uniset_rwmutex userdata_lock
Definition: IOController.h:333
long d_off_value
Definition: IOController.h:347
long d_value
Definition: IOController.h:346
uniset::uniset_rwmutex val_lock
Definition: IOController.h:328
Definition: IOController.h:407
IOController::IOStateList::iterator sit
Definition: IOController.h:423
uniset::ObjectId sid
Definition: IOController.h:420
bool invert
Definition: IOController.h:426
Definition: UniSetTypes_i.idl:65