static void _doTimedOff( iOFBack inst ) { iOFBackData data = Data(inst); if( data->timedoff > 0 ){ if( data->timer == 0 ) { iONode nodeD = NodeOp.inst( wFeedback.name(), NULL, ELEMENT_NODE ); data->state = False; data->timer = -1; TraceOp.trc( name, TRCLEVEL_USER1, __LINE__, 9999, "timed off event for %s", FBackOp.getId( inst )); if( data->listenerFun != NULL ) { data->listenerFun( data->listenerObj, data->state, FBackOp.getId( inst ), NULL, NULL, NULL, NULL, 0, 0, True ); } __ctcAction( inst ); __checkAction( inst, NULL ); /* Broadcast to clients. Node4 */ wFeedback.setid( nodeD, FBackOp.getId( inst ) ); wFeedback.setcounter( data->props, data->counter ); wFeedback.setcarcount( nodeD, data->carcount ); wFeedback.setcountedcars( nodeD, data->countedcars ); wFeedback.setstate( nodeD, data->state ); wFeedback.setaddr( nodeD, wFeedback.getaddr( data->props ) ); wFeedback.setbus( nodeD, wFeedback.getbus( data->props ) ); wFeedback.setfbtype( nodeD, wFeedback.getfbtype( data->props ) ); wFeedback.setload( nodeD, wFeedback.getload(data->props) ); wFeedback.setmaxload( nodeD, wFeedback.getmaxload(data->props) ); AppOp.broadcastEvent( nodeD ); { obj listener = ListOp.first( data->listeners ); wFeedback.setstate( data->props, data->state ); while( listener != NULL ) { TraceOp.trc( name, TRCLEVEL_USER1, __LINE__, 9999, "fb [%s](%s) val=%d count=%d call listener %X...", FBackOp.getId(inst), data->state?"ON":"OFF", wFeedback.getval(data->props), data->counter, listener ); listener->event( listener, data->props ); listener = ListOp.next( data->listeners ); }; } } else if( data->timer > 0 ) { data->timer--; } } }
static void _modify( struct OText* inst ,iONode props ) { iOTextData o = Data(inst); Boolean checkActions = False; int cnt = NodeOp.getAttrCnt( props ); int i = 0; if( !StrOp.equals(wText.gettext(o->props), wText.gettext(props)) ) { checkActions = True; } for( i = 0; i < cnt; i++ ) { iOAttr attr = NodeOp.getAttr( props, i ); const char* name = AttrOp.getName( attr ); const char* value = AttrOp.getVal( attr ); NodeOp.setStr( o->props, name, value ); } /* Leave the childs if no new are comming */ if( NodeOp.getChildCnt( o->props ) > 0 ) { cnt = NodeOp.getChildCnt( o->props ); while( cnt > 0 ) { iONode child = NodeOp.getChild( o->props, 0 ); iONode removedChild = NodeOp.removeChild( o->props, child ); if( removedChild != NULL) { NodeOp.base.del(removedChild); } cnt = NodeOp.getChildCnt( o->props ); } } if( NodeOp.getChildCnt( props ) > 0 ) { cnt = NodeOp.getChildCnt( props ); for( i = 0; i < cnt; i++ ) { iONode child = NodeOp.getChild( props, i ); NodeOp.addChild( o->props, (iONode)NodeOp.base.clone(child) ); } } if(checkActions) __checkAction(inst, wText.gettext(o->props)); /* Broadcast to clients. */ { iONode clone = (iONode)NodeOp.base.clone( o->props ); AppOp.broadcastEvent( clone ); } props->base.del(props); }
static Boolean _cmd( iOFBack inst, iONode cmd, Boolean update ) { iOFBackData data = Data(inst); iOControl control = AppOp.getControl(); int error = 0; if( StrOp.equals(wFeedback.reset, wFeedback.getcmd(cmd))) { TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "reset sensor counters [%s]", FBackOp.getId(inst)); FBackOp.resetCounter(inst); iONode clone = (iONode)NodeOp.base.clone( data->props ); AppOp.broadcastEvent( clone ); } else if( StrOp.equals(wFeedback.resetstatus, wFeedback.getcmd(cmd))) { data->state = False; TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "reset sensor status [%s]", FBackOp.getId(inst)); wFeedback.setstate( data->props, data->state ); iONode clone = (iONode)NodeOp.base.clone( data->props ); AppOp.broadcastEvent( clone ); } else if( StrOp.equals(wFeedback.setcounterval, wFeedback.getcmd(cmd))) { data->counter = wFeedback.getcounter(cmd); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "set sensor [%s] counter to %d", FBackOp.getId(inst), data->counter); iONode clone = (iONode)NodeOp.base.clone( data->props ); wFeedback.setcounter( clone, data->counter); AppOp.broadcastEvent( clone ); __checkAction(inst, NULL); } else { if( wFeedback.getfbtype(data->props) == wFeedback.fbtype_wheelcounter && wFeedback.isstate(cmd) ) data->wheelcount++; wFeedback.setiid( cmd, wFeedback.getiid( data->props ) ); wItem.setuidname( cmd, wItem.getuidname( data->props ) ); wFeedback.setbus( cmd, wFeedback.getbus( data->props ) ); wFeedback.setfbtype( cmd, wFeedback.getfbtype( data->props ) ); wFeedback.setaddr( cmd, wFeedback.getaddr( data->props ) ); wFeedback.setactivelow( cmd, wFeedback.isactivelow( data->props ) ); wFeedback.setcounter( cmd, data->counter ); wFeedback.setcarcount( cmd, data->carcount ); wFeedback.setcountedcars( cmd, data->countedcars ); ControlOp.cmd( control, cmd, &error ); } return True; }
static void _event( iOFBack inst, iONode nodeC ) { iOFBackData data = Data(inst); Boolean hasListener = False; Boolean state = wFeedback.isstate( nodeC ); if( TraceOp.getLevel(NULL) & TRCLEVEL_DEBUG ) { char* strNode = (char*)NodeOp.base.toString( nodeC ); TraceOp.trc( name, TRCLEVEL_DEBUG, __LINE__, 9999, "event %s", strNode ); StrOp.free( strNode ); } if( wFeedback.getcutoutaddr(data->props) > 0 && wFeedback.getaddr(nodeC) == wFeedback.getcutoutaddr(data->props) ) { data->shortcut = state; wFeedback.setshortcut(data->props, state); TraceOp.trc( name, state ? TRCLEVEL_EXCEPTION:TRCLEVEL_INFO, __LINE__, 9999, "Sensor [%s] report: %s", wFeedback.getid(data->props), state?"short circuit detected":"Cutout is OK" ); AppOp.broadcastEvent( (iONode)NodeOp.base.clone(data->props) ); nodeC->base.del(nodeC); return; } /* check for active low */ if( wFeedback.isactivelow( data->props ) ) state = !state; /* check for a timed off sensor */ if( data->timedoff > 0 ) { if( !state ) { data->timer = data->timedoff; /* Cleanup Node3 */ nodeC->base.del(nodeC); return; } } data->state = state; if( wFeedback.getfbtype(data->props) == wFeedback.fbtype_wheelcounter ) { if(wFeedback.getwheelcount(nodeC) == 0 && state) { /* using a HAL sensor for 'wheel'(Magnet) counting */ data->wheelcount++; } TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "[%s] COUNTING WHEELS: countedwheels=%d", FBackOp.getId(inst), wFeedback.getwheelcount(nodeC) + data->wheelcount ); /* the plus data->wheelcount is for simulation */ } if(data->state) { data->timer = -1; data->counter++; if( data->carcount > 0 ) { data->countedcars++; TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "[%s] COUNTING CARS: carcount=%d countedcars=%d", FBackOp.getId(inst), data->carcount, data->countedcars ); __checkAction( inst ); } } if( data->carcount > 0 && data->countedcars <= data->carcount ) { /* Cleanup Node3 */ TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "COUNTING CARS: fb[%s] state=%s ident=%d val=%d carcount=%d countedcars=%d", FBackOp.getId(inst), data->state?"ON":"OFF", wFeedback.getidentifier( nodeC ), wFeedback.getval( nodeC ), data->carcount, data->countedcars ); /* Broadcast to clients. Node4 */ if( data->state || data->timedoff == 0 ) { iONode nodeD = NodeOp.inst( wFeedback.name(), NULL, ELEMENT_NODE ); wFeedback.setid( nodeD, FBackOp.getId( inst ) ); wFeedback.setcounter( data->props, data->counter ); wFeedback.setcarcount( nodeD, data->carcount ); wFeedback.setcountedcars( nodeD, data->countedcars ); wFeedback.setstate( nodeD, data->state ); wFeedback.setval( nodeD, wFeedback.getval( nodeC ) ); wFeedback.setaddr( nodeD, wFeedback.getaddr( data->props ) ); wFeedback.setbus( nodeD, wFeedback.getbus( data->props ) ); wFeedback.setfbtype( nodeD, wFeedback.getfbtype( data->props ) ); wFeedback.setidentifier( nodeD, wFeedback.getidentifier( nodeC ) ); wFeedback.setwheelcount( nodeD, wFeedback.getwheelcount( nodeC ) + data->wheelcount ); wFeedback.setload( nodeD, wFeedback.getload(data->props) ); wFeedback.setmaxload( nodeD, wFeedback.getmaxload(data->props) ); AppOp.broadcastEvent( nodeD ); } nodeC->base.del(nodeC); return; } /* reset car counting */ data->carcount = 0; data->countedcars = 0; wFeedback.setstate( data->props, data->state ); wFeedback.setcounter( data->props, data->counter ); wFeedback.setidentifier( data->props, wFeedback.getidentifier( nodeC ) ); wFeedback.setdirection( data->props, wFeedback.isdirection( nodeC ) ); wFeedback.setload( data->props, wFeedback.getload( nodeC ) ); TraceOp.trc( name, TRCLEVEL_USER1, __LINE__, 9999, "fb[%s] state=%s ident=%s dir=%s val=%d count=%d", FBackOp.getId(inst), data->state?"ON":"OFF", wFeedback.getidentifier( nodeC ), wFeedback.isdirection( nodeC )?"fwd":"rev", wFeedback.getval( nodeC ), data->counter ); /* Call listener. */ if( data->listenerFun != NULL ) { data->listenerFun( data->listenerObj, data->state, FBackOp.getId( inst ), wFeedback.getidentifier( nodeC ), wFeedback.getidentifier2( nodeC ), wFeedback.getidentifier3( nodeC ), wFeedback.getidentifier4( nodeC ), wFeedback.getval( nodeC ), wFeedback.getwheelcount( nodeC ) + data->wheelcount, wFeedback.isdirection(nodeC) ); hasListener = True; } { obj listener = ListOp.first( data->listeners ); while( listener != NULL ) { hasListener = True; TraceOp.trc( name, TRCLEVEL_USER1, __LINE__, 9999, "fb [%s](%s) ident=%d val=%d count=%d call listener 0x%08X...", FBackOp.getId(inst), data->state?"ON":"OFF", wFeedback.getidentifier( nodeC ), wFeedback.getval( nodeC ), data->counter, listener ); listener->event( listener, data->props ); listener = ListOp.next( data->listeners ); }; } __ctcAction( inst ); __checkAction( inst ); if(!hasListener) { TraceOp.trc( name, TRCLEVEL_USER1, __LINE__, 9999, "fb[%s] (%s) ident=%s val=%d count=%d has no listener...", FBackOp.getId(inst), data->state?"ON":"OFF", wFeedback.getidentifier( nodeC ), wFeedback.getval( nodeC ), data->counter ); } /* Broadcast to clients. Node4 */ if( data->state || data->timedoff == 0 ) { iONode nodeD = NodeOp.inst( wFeedback.name(), NULL, ELEMENT_NODE ); wFeedback.setiid( nodeD, wFeedback.getiid( data->props ) ); wFeedback.setid( nodeD, FBackOp.getId( inst ) ); wFeedback.setstate( nodeD, data->state ); wFeedback.setval( nodeD, wFeedback.getval( nodeC ) ); wFeedback.setaddr( nodeD, wFeedback.getaddr( data->props ) ); wFeedback.setbus( nodeD, wFeedback.getbus( data->props ) ); wFeedback.setfbtype( nodeD, wFeedback.getfbtype( data->props ) ); wFeedback.setidentifier( nodeD, wFeedback.getidentifier( nodeC ) ); wFeedback.setcounter( nodeD, data->counter ); wFeedback.setcarcount( nodeD, data->carcount ); wFeedback.setcountedcars( nodeD, data->countedcars ); wFeedback.setwheelcount( nodeD, wFeedback.getwheelcount( nodeC ) + data->wheelcount ); wFeedback.setload( nodeD, wFeedback.getload(data->props) ); wFeedback.setmaxload( nodeD, wFeedback.getmaxload(data->props) ); AppOp.broadcastEvent( nodeD ); } if( data->state && wFeedback.getfbtype(data->props) == wFeedback.fbtype_lissy ) { /* timed off */ data->state = False; data->timer = data->timedoff; } /* Cleanup Node3 */ nodeC->base.del(nodeC); }
static void __stateEvent( obj inst, iONode event ) { iOPowerManData data = Data(inst); iONode booster = NULL; MutexOp.wait(data->boostermapmux); booster = (iONode)MapOp.first( data->boostermap ); /* command for all */ TraceOp.trc(name, TRCLEVEL_DEBUG, __LINE__, 9999, "State event from %d", wState.getuid(event)); while( booster != NULL ) { if( wBooster.getuid(booster) == wState.getuid(event) ) { Boolean shortcut = wState.isshortcut(event); wBooster.setpower(booster, wState.ispower(event)); wBooster.setload( booster, wBooster.getload(event) ); wBooster.setvolt( booster, wBooster.getvolt(event) ); wBooster.settemp( booster, wBooster.gettemp(event) ); wBooster.setloadmax( booster, wBooster.getloadmax(event) ); wBooster.setvoltmin( booster, wBooster.getvoltmin(event) ); wBooster.settempmax( booster, wBooster.gettempmax(event) ); TraceOp.trc(name, shortcut?TRCLEVEL_EXCEPTION:TRCLEVEL_DEBUG, __LINE__, 9999, "booster %s(%08X) power is %s, diagnostics: %dmA %dmV %dC %s", wBooster.getid(booster), wBooster.getuid(booster), wState.ispower(event) ? "ON":"OFF", shortcut?wBooster.getloadmax(booster):wBooster.getload(booster), wBooster.getvolt(booster), wBooster.gettemp(booster), shortcut?"OVERLOAD":"" ); if( shortcut != wBooster.isshortcut(booster) ) { wBooster.setshortcut( booster, shortcut ); __informClientOfShortcut(inst, booster, !shortcut); if( !wBooster.isscopt_repoweron(booster) && shortcut ) { iONode pwrcmd = NodeOp.inst( wPwrCmd.name(), NULL, ELEMENT_NODE ); wPwrCmd.setid( pwrcmd, wBooster.getid(booster) ); wPwrCmd.setcmd( pwrcmd, wPwrCmd.off ); PowerManOp.cmd((iOPowerMan)inst, pwrcmd); } if( wBooster.isscopt_poweroffall(booster) && shortcut ) { iONode pwrcmd = NodeOp.inst( wPwrCmd.name(), NULL, ELEMENT_NODE ); wPwrCmd.setcmd( pwrcmd, wPwrCmd.off ); PowerManOp.cmd((iOPowerMan)inst, pwrcmd); } } if( wBooster.isshortcut(booster) ) __checkAction((iOPowerMan)inst, booster, "shortcut"); else __checkAction((iOPowerMan)inst, booster, "load"); AppOp.broadcastEvent( (iONode)NodeOp.base.clone(booster) ); } booster = (iONode)MapOp.next( data->boostermap ); } MutexOp.post(data->boostermapmux); }
static void* __event( void* inst, const void* evt ) { iOTextData data = Data(inst); iONode node = (iONode)evt; char hour[8]; char min[8]; if( node != NULL && StrOp.equals( wText.name(), NodeOp.getName(node))) { iOLoc lc = ModelOp.getLocByIdent(AppOp.getModel(), wText.getreflcid(node), NULL, NULL, NULL, True); iIBlockBase bk = ModelOp.getBlock(AppOp.getModel(), wText.getrefbkid(node)); if( lc == NULL ) lc = ModelOp.getLoc(AppOp.getModel(), wText.getreflcid(node), NULL, False); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "text event [%s-%s][%s]", wText.getreflcid(node), wText.getrefbkid(node), wText.getformat(node) ); /* set value processing */ if( StrOp.equals( wText.getcmd(node), wAction.text_value) ) { int val = VarOp.getValue(wText.getformat(node), NULL); char* msg = StrOp.fmt("%d", val); wText.settext(data->props, msg ); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "new text [%s]", msg); __checkAction(inst, msg); StrOp.free(msg); } /* default update processing */ else if( lc != NULL && bk == NULL ) { char* msg = NULL; char* scidxStr = NULL; char* mvspeedStr = NULL; iOMap map = MapOp.inst(); mvspeedStr = __addActionProperties(map, node); scidxStr = __addLocoProperties(map, lc, hour, min); /*msg = _replaceAllSubstitutions(wText.getformat(node), map);*/ msg = VarOp.getText(wText.getformat(node), map, ' '); if( msg != NULL && StrOp.len(msg) > 0 && msg[0] == '|' ) { char* newStr = StrOp.fmt("%s %s", wText.gettext(data->props), msg ); wText.settext(data->props, newStr ); StrOp.free(newStr); } else wText.settext(data->props, msg ); MapOp.base.del(map); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "new text [%s]", msg); __checkAction(inst, msg); StrOp.free(mvspeedStr); StrOp.free(scidxStr); StrOp.free(msg); } else if( lc != NULL && bk != NULL ) { char* msg = NULL; iOMap map = MapOp.inst(); char* scidxStr = NULL; char* speedStr = NULL; char* mvspeedStr = NULL; mvspeedStr = __addActionProperties(map, node); scidxStr = __addLocoProperties(map, lc, hour, min); speedStr = __addBlockProperties(map, bk); /*msg = _replaceAllSubstitutions(wText.getformat(node), map);*/ msg = VarOp.getText(wText.getformat(node), map, ' '); if( msg != NULL && StrOp.len(msg) > 0 && msg[0] == '|' ) { char* newStr = StrOp.fmt("%s %s", wText.gettext(data->props), msg ); wText.settext(data->props, newStr ); StrOp.free(newStr); } else wText.settext(data->props, msg ); wText.setblock(data->props, bk->base.id(bk) ); if( MapOp.haskey(map, "frombkloc") ) { const char* location = (const char*)MapOp.get(map, "frombkloc"); wText.setlocation(data->props, location ); } else wText.setlocation(data->props, "" ); MapOp.base.del(map); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "new text [%s]", msg); __checkAction(inst, msg); StrOp.free(mvspeedStr); StrOp.free(speedStr); StrOp.free(scidxStr); StrOp.free(msg); } else if( bk != NULL ) { char* msg = NULL; char* speedStr = NULL; char* mvspeedStr = NULL; iOMap map = MapOp.inst(); mvspeedStr = __addActionProperties(map, node); speedStr = __addBlockProperties(map, bk); /*msg = _replaceAllSubstitutions(wText.getformat(node), map);*/ msg = VarOp.getText(wText.getformat(node), map, ' '); wText.setblock(data->props, bk->base.id(bk) ); if( MapOp.haskey(map, "frombkloc") ) wText.setlocation(data->props, (const char*)MapOp.get(map, "frombkloc") ); else wText.setlocation(data->props, "" ); if( msg != NULL && StrOp.len(msg) > 0 && msg[0] == '|' ) { char* newStr = StrOp.fmt("%s %s", wText.gettext(data->props), msg ); wText.settext(data->props, newStr ); StrOp.free(newStr); } else wText.settext(data->props, msg); MapOp.base.del(map); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "new text [%s]", msg); __checkAction(inst, msg); StrOp.free(msg); StrOp.free(speedStr); StrOp.free(mvspeedStr); } else { char* msg = NULL; char* mvspeedStr = NULL; iOMap map = MapOp.inst(); mvspeedStr = __addActionProperties(map, node); /*msg = _replaceAllSubstitutions(wText.getformat(node), map);*/ msg = VarOp.getText(wText.getformat(node), map, ' '); MapOp.base.del(map); if( msg != NULL && StrOp.len(msg) > 0 && msg[0] == '|' ) { char* newStr = StrOp.fmt("%s %s", wText.gettext(data->props), msg ); wText.settext(data->props, newStr ); StrOp.free(newStr); } else wText.settext(data->props, msg); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "new text [%s]", msg); __checkAction(inst, msg); StrOp.free(msg); StrOp.free(mvspeedStr); } if( wText.getaddr(data->props) > 0 ) { iONode node = NodeOp.inst( wText.name(), NULL, ELEMENT_NODE ); wText.setiid( node, wText.getiid( data->props ) ); wText.setbus( node, wText.getbus( data->props ) ); wText.setaddr( node, wText.getaddr( data->props ) ); wText.setdisplay( node, wText.getdisplay( data->props ) ); wText.setid( node, wText.getid( data->props ) ); wText.setblock( node, wText.getblock( data->props ) ); wText.setlocation( node, wText.getlocation( data->props ) ); wText.settext( node, wText.gettext( data->props ) ); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "send text [%s]", wText.gettext( data->props )); ControlOp.cmd( AppOp.getControl(), node, NULL ); } /* Broadcast to clients. */ { iONode node = NodeOp.inst( wText.name(), NULL, ELEMENT_NODE ); wText.setid( node, wText.getid( data->props ) ); wText.setblock( node, wText.getblock( data->props ) ); wText.setlocation( node, wText.getlocation( data->props ) ); wText.settext( node, wText.gettext( data->props ) ); TraceOp.trc( name, TRCLEVEL_INFO, __LINE__, 9999, "broadcast text [%s]", wText.gettext( data->props )); AppOp.broadcastEvent( node ); } } if( node != NULL ) NodeOp.base.del(node); return NULL; }