00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <memory>
00020
00021
00022 #include "LOW_compJalousieController.h"
00023
00024 #include "LOW_netSegment.h"
00025 #include "LOW_platformMisc.h"
00026 #include "LOW_IPCKeyGeneratorFactory.h"
00027 #include "LOW_semaphoreSetFactory.h"
00028
00029
00030
00031
00032
00033
00034
00035
00036 int LOW_compJalousieController::jcCounter = 0;
00037
00038
00039
00040
00041
00042
00043
00044
00045 LOW_compJalousieController::LOW_compJalousieController( const LOW_devDS2405 &inPowerControl,
00046 const LOW_devDS2405 &inDirectionControl,
00047 const float inClosingTime, const float inOpeningTime,
00048 const float inAngleClosingTime, const float inAngleOpeningTime) :
00049 jcSerialNum( jcCounter++),
00050 powerControl(inPowerControl),
00051 directionControl(inDirectionControl),
00052 closingTime(inClosingTime),
00053 openingTime(inOpeningTime),
00054 angleClosingTime(inAngleClosingTime),
00055 angleOpeningTime(inAngleOpeningTime)
00056 {
00057 if ( powerControl.getID() == directionControl.getID() )
00058 throw compJalousieController_error( "Same device for powerControl and directionControl.", __FILE__, __LINE__);
00059
00060 if ( !powerControl.getNetSegment().getHasExternalPower() || !directionControl.getNetSegment().getHasExternalPower() )
00061 throw compJalousieController_error( "Network segment must supply power.", __FILE__, __LINE__);
00062
00063 auto_ptr<LOW_IPCKeyGenerator> keyGenerator (LOW_IPCKeyGeneratorFactory::new_IPCKeyGenerator());
00064 semSet = LOW_semaphoreSetFactory::new_semaphoreSet( keyGenerator->getSemSetKey( powerControl.getID()), LOW_semaphoreSetFactory::getMaxSemaphoresPerSet(), 1);
00065
00066 try {
00067 jcLock lockIt = jcLock( *this);
00068
00069
00070 if ( powerControl.cmd_SearchActive() == true ) {
00071 powerControl.cmd_Match();
00072 if ( powerControl.cmd_SearchActive() == true )
00073 throw compJalousieController_error( "Cannot initialize powerControl.", __FILE__, __LINE__);
00074 }
00075
00076
00077 if ( directionControl.cmd_SearchActive() == true ) {
00078 directionControl.cmd_Match();
00079 if ( directionControl.cmd_SearchActive() == true )
00080 throw compJalousieController_error( "Cannot initialize directionControl.", __FILE__, __LINE__);
00081 }
00082 }
00083 catch (...) {
00084 delete semSet;
00085 throw;
00086 }
00087
00088 powerIsOn = false;
00089 directionIsDown = false;
00090
00091 stop2upDelay = 70;
00092 up2stopDelay = 70;
00093 stop2downDelay = 140;
00094 down2stopDelay = 140;
00095 up2downDelay = 70;
00096 down2upDelay = 70;
00097 }
00098
00099
00100 LOW_compJalousieController::~LOW_compJalousieController()
00101 {
00102 try {
00103 jcLock lockIt = jcLock( *this);
00104 stopMove();
00105 }
00106 catch (...) {
00107 delete semSet;
00108 throw;
00109 }
00110
00111 delete semSet;
00112 }
00113
00114
00115
00116
00117
00118
00119
00120
00121 void LOW_compJalousieController::setPosition( float inPos, float inAngle)
00122 {
00123 jcLock lockIt = jcLock( *this);
00124
00125 if ( inPos<0.0 || inPos>1.0 )
00126 throw compJalousieController_error( "Illegal position parameter.", __FILE__, __LINE__);
00127
00128 if ( inAngle<0.0 || inAngle>1.0 )
00129 throw compJalousieController_error( "Illegal angle parameter.", __FILE__, __LINE__);
00130
00131
00132 if ( inPos > 0.5 ) {
00133
00134
00135 moveDownStop( (closingTime*1000)+((float)fullMovementAdditionMillis));
00136
00137 if ( inPos != 1.0 ) {
00138
00139 moveUpStop( ((1.0-inPos)*(openingTime*1000)));
00140
00141 if ( inAngle != 0.0 ) {
00142
00143 moveDownStop( inAngle*(angleClosingTime*1000));
00144 }
00145 }
00146 else if ( inAngle != 1.0 ) {
00147
00148 moveUpStop( (1.0-inAngle)*(angleOpeningTime*1000));
00149 }
00150 }
00151
00152
00153 else {
00154
00155
00156 moveUpStop( (openingTime*1000)+((float)fullMovementAdditionMillis));
00157
00158 if ( inPos != 0.0 ) {
00159
00160 moveDownStop( inPos*(closingTime*1000));
00161
00162 if ( inAngle != 1.0 ) {
00163
00164 moveUpStop( (1.0-inAngle)*(angleOpeningTime*1000));
00165 }
00166 }
00167 else if ( inAngle != 0.0 ) {
00168
00169 moveDownStop( inAngle*(angleClosingTime*1000));
00170 }
00171 }
00172 }
00173
00174
00175 float LOW_compJalousieController::getClosingTime() const
00176 {
00177 return closingTime;
00178 }
00179
00180
00181 void LOW_compJalousieController::setClosingTime( const float inClosingTime)
00182 {
00183 jcLock lockIt = jcLock( *this);
00184 closingTime = inClosingTime;
00185 }
00186
00187
00188 float LOW_compJalousieController::getOpeningTime() const
00189 {
00190 return openingTime;
00191 }
00192
00193
00194 void LOW_compJalousieController::setOpeningTime( const float inOpeningTime)
00195 {
00196 jcLock lockIt = jcLock( *this);
00197 openingTime = inOpeningTime;
00198 }
00199
00200
00201 float LOW_compJalousieController::getAngleClosingTime() const
00202 {
00203 return angleClosingTime;
00204 }
00205
00206
00207 void LOW_compJalousieController::setAngleClosingTime( const float inAngleClosingTime)
00208 {
00209 jcLock lockIt = jcLock( *this);
00210 angleClosingTime = inAngleClosingTime;
00211 }
00212
00213
00214 float LOW_compJalousieController::getAngleOpeningTime() const
00215 {
00216 return angleOpeningTime;
00217 }
00218
00219
00220 void LOW_compJalousieController::setAngleOpeningTime( const float inAngleOpeningTime)
00221 {
00222 jcLock lockIt = jcLock( *this);
00223 angleOpeningTime = inAngleOpeningTime;
00224 }
00225
00226
00227 void LOW_compJalousieController::measureTransitionDelays()
00228 {
00229 jcLock lockIt = jcLock( *this);
00230
00231 const unsigned int loopCnt = 10;
00232 std::vector<unsigned int> t_sp2up, t_up2sp, t_sp2dn, t_dn2sp, t_up2dn, t_dn2up;
00233 LOW_platformMisc::timestamp_t t_start, t_stop, t_diff;
00234
00235 for( unsigned int a=0; a<loopCnt; a++) {
00236 LOW_platformMisc::getTimestamp( t_start);
00237 moveUp();
00238 LOW_platformMisc::getTimestamp( t_stop);
00239 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00240 t_sp2up.push_back( t_diff.milSec);
00241
00242 LOW_platformMisc::getTimestamp( t_start);
00243 stopMove();
00244 LOW_platformMisc::getTimestamp( t_stop);
00245 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00246 t_up2sp.push_back( t_diff.milSec);
00247
00248 LOW_platformMisc::getTimestamp( t_start);
00249 moveDown();
00250 LOW_platformMisc::getTimestamp( t_stop);
00251 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00252 t_sp2dn.push_back( t_diff.milSec);
00253
00254 LOW_platformMisc::getTimestamp( t_start);
00255 stopMove();
00256 LOW_platformMisc::getTimestamp( t_stop);
00257 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00258 t_dn2sp.push_back( t_diff.milSec);
00259
00260 moveUp();
00261 LOW_platformMisc::getTimestamp( t_start);
00262 moveDown();
00263 LOW_platformMisc::getTimestamp( t_stop);
00264 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00265 t_up2dn.push_back( t_diff.milSec);
00266
00267 moveDown();
00268 LOW_platformMisc::getTimestamp( t_start);
00269 moveUp();
00270 LOW_platformMisc::getTimestamp( t_stop);
00271 LOW_platformMisc::diffTimestamp( t_stop, t_start, t_diff);
00272 t_dn2up.push_back( t_diff.milSec);
00273
00274 stopMove();
00275 }
00276
00277 stop2upDelay = averageMillis( t_sp2up);
00278 up2stopDelay = averageMillis( t_up2sp);
00279 stop2downDelay = averageMillis( t_sp2dn);
00280 down2stopDelay = averageMillis( t_dn2sp);
00281 up2downDelay = averageMillis( t_up2dn);
00282 down2upDelay = averageMillis( t_dn2up);
00283 }
00284
00285
00286 void LOW_compJalousieController::getTransitionDelays( unsigned int &outStop2upDelay, unsigned int &outUp2stopDelay,
00287 unsigned int &outStop2downDelay, unsigned int &outDown2stopDelay,
00288 unsigned int &outUp2downDelay, unsigned int &outDown2upDelay)
00289 {
00290 outStop2upDelay = stop2upDelay;
00291 outUp2stopDelay = up2stopDelay;
00292 outStop2downDelay = stop2downDelay;
00293 outDown2stopDelay = down2stopDelay;
00294 outUp2downDelay = up2downDelay;
00295 outDown2upDelay = down2upDelay;
00296 }
00297
00298
00299 void LOW_compJalousieController::setTransitionDelays( const unsigned int inStop2upDelay, const unsigned int inUp2stopDelay,
00300 const unsigned int inStop2downDelay, const unsigned int inDown2stopDelay,
00301 const unsigned int inUp2downDelay, const unsigned int inDown2upDelay)
00302 {
00303 stop2upDelay = inStop2upDelay;
00304 up2stopDelay = inUp2stopDelay;
00305 stop2downDelay = inStop2downDelay;
00306 down2stopDelay = inDown2stopDelay;
00307 up2downDelay = inUp2downDelay;
00308 down2upDelay = inDown2upDelay;
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 void LOW_compJalousieController::moveUp()
00319 {
00320
00321
00322 setDirectionUp();
00323 setPowerOn();
00324 }
00325
00326
00327 void LOW_compJalousieController::moveDown()
00328 {
00329
00330
00331 setDirectionDown();
00332 setPowerOn();
00333 }
00334
00335
00336 void LOW_compJalousieController::stopMove()
00337 {
00338
00339
00340 setPowerOff();
00341 setDirectionUp();
00342 }
00343
00344
00345 void LOW_compJalousieController::moveUpStop( const unsigned long inMillis)
00346 {
00347
00348
00349 unsigned long sleepTime;
00350 if ( ( ((long)inMillis) - ((int)up2stopDelay) ) < 0 )
00351 sleepTime = 0;
00352 else
00353 sleepTime = inMillis-up2stopDelay;
00354
00355 moveUp();
00356 LOW_platformMisc::milliSleep( sleepTime);
00357 stopMove();
00358 }
00359
00360
00361 void LOW_compJalousieController::moveDownStop( const unsigned long inMillis)
00362 {
00363
00364
00365 unsigned long sleepTime;
00366 if ( ( ((long)inMillis) - ((int)up2stopDelay) ) < 0 )
00367 sleepTime = 0;
00368 else
00369 sleepTime = inMillis-down2stopDelay;
00370
00371 moveDown();
00372 LOW_platformMisc::milliSleep( sleepTime);
00373 stopMove();
00374 }
00375
00376
00377
00378
00379
00380
00381
00382
00383 void LOW_compJalousieController::setPowerOn()
00384 {
00385 if ( powerIsOn )
00386 return;
00387
00388 if ( powerControl.cmd_MatchRead() == true )
00389 throw compJalousieController_error( "Error setting powerControl.", __FILE__, __LINE__);
00390
00391 powerIsOn = true;
00392 }
00393
00394
00395 void LOW_compJalousieController::setPowerOff()
00396 {
00397 if ( ! powerIsOn )
00398 return;
00399
00400 if ( powerControl.cmd_MatchRead() == false )
00401 throw compJalousieController_error( "Error setting powerControl.", __FILE__, __LINE__);
00402
00403 powerIsOn = false;
00404 }
00405
00406
00407 void LOW_compJalousieController::setDirectionDown()
00408 {
00409 if ( directionIsDown )
00410 return;
00411
00412 if ( directionControl.cmd_MatchRead() == true )
00413 throw compJalousieController_error( "Error setting directionControl.", __FILE__, __LINE__);
00414
00415 directionIsDown = true;
00416 }
00417
00418
00419 void LOW_compJalousieController::setDirectionUp()
00420 {
00421 if ( ! directionIsDown )
00422 return;
00423
00424 if ( directionControl.cmd_MatchRead() == false )
00425 throw compJalousieController_error( "Error setting directionControl.", __FILE__, __LINE__);
00426
00427 directionIsDown = false;
00428 }
00429
00430
00431 unsigned int LOW_compJalousieController::averageMillis( const std::vector<unsigned int> &inVals)
00432 {
00433 unsigned long avg = 0;
00434 for ( unsigned int a=0; a<inVals.size(); a++)
00435 avg += inVals[a];
00436 avg /= inVals.size();
00437
00438 return avg;
00439 }
00440
00441
00442
00443
00444
00445
00446
00447
00448 LOW_compJalousieController::jcLock::jcLock( LOW_compJalousieController &inJCComp) :
00449 jcComp(inJCComp)
00450 {
00451 jcComp.semSet->decSem( jcComp.jcSerialNum);
00452 }
00453
00454
00455 LOW_compJalousieController::jcLock::~jcLock()
00456 {
00457 jcComp.semSet->incSem( jcComp.jcSerialNum);
00458 }
00459
00460
00461
00462
00463
00464
00465
00466
00467 LOW_compJalousieController::manualMove::manualMove( LOW_compJalousieController &inJCComp) :
00468 jcLock( inJCComp),
00469 jcComp( inJCComp)
00470 {
00471 }
00472
00473
00474 LOW_compJalousieController::manualMove::~manualMove()
00475 {
00476 stopMove();
00477 }
00478
00479
00480 void LOW_compJalousieController::manualMove::moveUp()
00481 {
00482 jcComp.moveUp();
00483 }
00484
00485
00486 void LOW_compJalousieController::manualMove::moveDown()
00487 {
00488 jcComp.moveDown();
00489 }
00490
00491
00492 void LOW_compJalousieController::manualMove::stopMove()
00493 {
00494 jcComp.stopMove();
00495 }
00496
00497