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