UniSet  2.8.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 <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 
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  static const long not_specified_value = { std::numeric_limits<long>::max() };
120 
121  // ================== Доступные сигналы =================
127  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeSignal;
128  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> ChangeUndefinedStateSignal;
129 
130  // signal по изменению определённого датчика
131  ChangeSignal signal_change_value( uniset::ObjectId sid );
132 
133  // signal по изменению любого датчика
134  ChangeSignal signal_change_value();
135 
136  // сигналы по изменению флага "неопределённое состояние" (обрыв датчика например)
137  ChangeUndefinedStateSignal signal_change_undefined_state( uniset::ObjectId sid );
138  ChangeUndefinedStateSignal signal_change_undefined_state();
139  // -----------------------------------------------------------------------------------------
140  // полнейшее нарушение инкапсуляции
141  // но пока, это попытка оптимизировать работу с IOController через указатель.
142  // Т.е. работая с датчиками через итераторы..
143 #if 1
144  inline IOStateList::iterator ioBegin()
145  {
146  return ioList.begin();
147  }
148  inline IOStateList::iterator ioEnd()
149  {
150  return ioList.end();
151  }
152  inline IOStateList::iterator find( uniset::ObjectId k )
153  {
154  return ioList.find(k);
155  }
156 #endif
157  inline int ioCount() const noexcept
158  {
159  return ioList.size();
160  }
161 
162  protected:
163 
164  // доступ к элементам через итератор
165  // return итоговое значение
166  virtual long localSetValueIt( IOStateList::iterator& it, const uniset::ObjectId sid,
167  CORBA::Long value, uniset::ObjectId sup_id );
168 
169  virtual long localGetValue( IOStateList::iterator& it, const uniset::ObjectId sid );
170 
175  virtual void localSetUndefinedState( IOStateList::iterator& it, bool undefined,
176  const uniset::ObjectId sid );
177 
178  // -- работа через указатель ---
179  virtual long localSetValue( std::shared_ptr<USensorInfo>& usi, CORBA::Long value, uniset::ObjectId sup_id );
180  long localGetValue( std::shared_ptr<USensorInfo>& usi) ;
181 
182 #ifndef DISABLE_REST_API
183  // http API
184  virtual Poco::JSON::Object::Ptr request_get( const std::string& req, const Poco::URI::QueryParameters& p );
185  virtual Poco::JSON::Object::Ptr request_sensors( const std::string& req, const Poco::URI::QueryParameters& p );
186  void getSensorInfo( Poco::JSON::Array::Ptr& jdata, std::shared_ptr<USensorInfo>& s , bool shortInfo = false );
187 #endif
188 
189  // переопределяем для добавления вызова регистрации датчиков
190  virtual bool deactivateObject() override;
191  virtual bool activateObject() override;
192 
194  virtual void activateInit();
195 
197  virtual void sensorsRegistration() {};
199  virtual void sensorsUnregistration();
200 
201  typedef sigc::signal<void, std::shared_ptr<USensorInfo>&, IOController*> InitSignal;
202 
203  // signal по изменению определённого датчика
204  InitSignal signal_init();
205 
207  void ioRegistration(std::shared_ptr<USensorInfo>& usi );
208 
210  void ioUnRegistration( const uniset::ObjectId sid );
211 
212  // ------------------------------
214  SensorIOInfo(long v, UniversalIO::IOType t, const IOController_i::SensorInfo& si,
215  uniset::Message::Priority p = uniset::Message::Medium,
216  long defval = 0, IOController_i::CalibrateInfo* ci = 0,
218  {
220  ai.si = si;
221  ai.type = t;
222  ai.value = v;
223  ai.priority = p;
224  ai.default_val = defval;
225  ai.real_value = v;
226  ai.blocked = false;
227  ai.supplier = sup_id;
228 
229  if( ci != 0 )
230  ai.ci = *ci;
231  else
232  {
233  ai.ci.minRaw = 0;
234  ai.ci.maxRaw = 0;
235  ai.ci.minCal = 0;
236  ai.ci.maxCal = 0;
237  ai.ci.precision = 0;
238  }
239 
240  return ai;
241  };
242 
244  virtual void logging( uniset::SensorMessage& sm );
245 
247  virtual void dumpToDB();
248 
249  IOController();
250 
251  // доступ к списку c изменением только для своих
252  IOStateList::iterator myioBegin();
253  IOStateList::iterator myioEnd();
254  IOStateList::iterator myiofind( uniset::ObjectId id );
255 
256  void initIOList( const IOStateList&& l );
257 
258  typedef std::function<void(std::shared_ptr<USensorInfo>&)> UFunction;
259  // функция работает с mutex
260  void for_iolist( UFunction f );
261 
262  private:
263  friend class NCRestorer;
264  friend class SMInterface;
265 
266  std::mutex siganyMutex;
267  ChangeSignal sigAnyChange;
268 
269  std::mutex siganyundefMutex;
270  ChangeSignal sigAnyUndefChange;
271  InitSignal sigInit;
272 
273  IOStateList ioList;
274  uniset::uniset_rwmutex ioMutex;
276  bool isPingDBServer; // флаг связи с DBServer-ом
277  uniset::ObjectId dbserverID = { uniset::DefaultObjectId };
278 
279  std::mutex loggingMutex;
281  public:
282 
283  struct UThresholdInfo;
284  typedef std::list<std::shared_ptr<UThresholdInfo>> ThresholdExtList;
285 
286  struct USensorInfo:
288  {
289  USensorInfo( const USensorInfo& ) = delete;
290  const USensorInfo& operator=(const USensorInfo& ) = delete;
291  USensorInfo( USensorInfo&& ) = default;
292  USensorInfo& operator=(USensorInfo&& ) = default;
293 
294  USensorInfo();
295  virtual ~USensorInfo() {}
296 
300 
302  const USensorInfo& operator=(const IOController_i::SensorIOInfo& r);
304 
305  // Дополнительные (вспомогательные поля)
308  // userdata (универсальный, но небезопасный способ расширения информации связанной с датчиком)
309  static const size_t MaxUserData = 4;
310  void* userdata[MaxUserData] = { nullptr, nullptr, nullptr, nullptr };
313  void* getUserData( size_t index );
314  void setUserData( size_t index, void* data );
315 
316  // сигнал для реализации механизма зависимостей..
317  // (все зависимые датчики подключаются к нему (см. NCRestorer::init_depends_signals)
318  uniset::uniset_rwmutex changeMutex;
319  ChangeSignal sigChange;
320 
321  uniset::uniset_rwmutex undefMutex;
322  ChangeUndefinedStateSignal sigUndefChange;
323 
325  long d_value = { 1 };
326  long d_off_value = { 0 };
327  std::shared_ptr<USensorInfo> d_usi; // shared_ptr на датчик от которого зависит этот.
328 
329  // список пороговых датчиков для данного
331  ThresholdExtList thresholds;
332 
333  size_t nchanges = { 0 }; // количество изменений датчика
334 
335  long undef_value = { not_specified_value }; // значение для "неопределённого состояния датчика"
336 
337  // функция обработки информации об изменении состояния датчика, от которого зависит данный
338  void checkDepend( std::shared_ptr<USensorInfo>& d_usi, IOController* );
339 
340  void init( const IOController_i::SensorIOInfo& s );
341 
342  inline IOController_i::SensorIOInfo makeSensorIOInfo()
343  {
346  return s;
347  }
348 
349  inline uniset::SensorMessage makeSensorMessage( bool with_lock = false )
350  {
352  sm.id = si.id;
353  sm.node = si.node; // uniset_conf()->getLocalNode()?
354  sm.sensor_type = type;
355  sm.priority = (uniset::Message::Priority)priority;
356 
357  // лочим только изменяемые поля
358  if( with_lock )
359  {
361  sm.value = value;
362  sm.sm_tv.tv_sec = tv_sec;
363  sm.sm_tv.tv_nsec = tv_nsec;
364  sm.ci = ci;
365  sm.supplier = supplier;
366  sm.undefined = undefined;
367  }
368  else
369  {
370  sm.value = value;
371  sm.sm_tv.tv_sec = tv_sec;
372  sm.sm_tv.tv_nsec = tv_nsec;
373  sm.ci = ci;
374  sm.supplier = supplier;
375  sm.undefined = undefined;
376  }
377 
378  return sm;
379  }
380  };
381 
385  {
386  UThresholdInfo( uniset::ThresholdId tid, CORBA::Long low, CORBA::Long hi, bool inv,
388  sid(_sid),
389  invert(inv)
390  {
391  id = tid;
392  hilimit = hi;
393  lowlimit = low;
395  }
396 
399 
401  IOController::IOStateList::iterator sit;
402 
404  bool invert;
405 
406  inline bool operator== ( const ThresholdInfo& r ) const
407  {
408  return ((id == r.id) &&
409  (hilimit == r.hilimit) &&
410  (lowlimit == r.lowlimit) &&
411  (invert == r.invert) );
412  }
413 
414  UThresholdInfo( const UThresholdInfo& ) = delete;
415  UThresholdInfo& operator=( const UThresholdInfo& ) = delete;
416  UThresholdInfo( UThresholdInfo&& ) = default;
417  UThresholdInfo& operator=(UThresholdInfo&& ) = default;
418  };
419  };
420  // -------------------------------------------------------------------------
421 } // end of uniset namespace
422 // --------------------------------------------------------------------------
423 #endif
424 // --------------------------------------------------------------------------
uniset::ObjectId supplier
Definition: IOController_i.idl:106
virtual void activateInit()
Definition: IOController.cc:105
IOController::IOStateList::iterator sit
Definition: IOController.h:401
uniset::ObjectId sid
Definition: IOController.h:398
Definition: CommonEventLoop.h:14
Definition: IOController.h:383
IOController_i::SensorInfo d_si
Definition: IOController.h:324
Definition: IOController_i.idl:93
uniset::uniset_rwmutex userdata_lock
Definition: IOController.h:311
Definition: IOController_i.idl:204
long ThresholdId
Definition: UniSetTypes_i.idl:31
virtual bool deactivateObject() override
Definition: IOController.cc:78
Definition: IOController.h:286
virtual void sensorsRegistration()
Definition: IOController.h:197
uniset::uniset_rwmutex val_lock
Definition: IOController.h:306
UniversalIO::IOType type
Definition: IOController_i.idl:99
virtual bool activateObject() override
Definition: IOController.cc:67
bool invert
Definition: IOController.h:404
boolean undefined
Definition: IOController_i.idl:96
sequence< ObjectId > IDSeq
Definition: UniSetTypes_i.idl:89
std::shared_ptr< Configuration > uniset_conf() noexcept
Definition: Configuration.cc:91
const ObjectId DefaultObjectId
Definition: UniSetTypes.h:69
void * userdata[MaxUserData]
Definition: IOController.h:310
unsigned long tv_sec
Definition: IOController_i.idl:104
uniset::ObjectId node
Definition: IOController_i.idl:60
Definition: IOController_i.idl:138
Definition: MessageType.h:126
long lowlimit
Definition: IOController_i.idl:208
sigc::signal< void, std::shared_ptr< USensorInfo > &, IOController * > ChangeSignal
Definition: IOController.h:127
virtual void localSetUndefinedState(IOStateList::iterator &it, bool undefined, const uniset::ObjectId sid)
Definition: IOController.cc:188
long priority
Definition: IOController_i.idl:100
Definition: UniSetManager.h:57
Definition: Mutex.h:31
virtual void logging(uniset::SensorMessage &sm)
сохранение информации об изменении состояния датчика
Definition: IOController.cc:428
long d_off_value
Definition: IOController.h:326
Definition: IOController_i.idl:79
long hilimit
Definition: IOController_i.idl:207
void ioUnRegistration(const uniset::ObjectId sid)
Definition: IOController.cc:423
Definition: IOController_i.idl:57
Definition: IOController.h:46
virtual void sensorsUnregistration()
Definition: IOController.cc:84
Definition: IOController_i.idl:200
virtual void dumpToDB()
сохранение состояния всех датчиков в БД
Definition: IOController.cc:456
string< SizeOfObjectType > ObjectType
Definition: UniSetTypes_i.idl:33
CalibrateInfo ci
Definition: IOController_i.idl:103
unsigned long tv_nsec
Definition: IOController_i.idl:105
Definition: UniSetTypes_i.idl:64
Definition: Mutex.h:84
void ioRegistration(std::shared_ptr< USensorInfo > &usi)
Definition: IOController.cc:386
long value
Definition: IOController_i.idl:95
long ObjectId
Definition: UniSetTypes_i.idl:30
long d_value
Definition: IOController.h:325
uniset::ObjectId id
Definition: IOController_i.idl:59