acc.state.set(acc.state^lowest_bit);
PendingCommand cmd(acc, Accessory::ACTIVATE, i);
command_queue.push(cmd);
+
+ monitor.reset_peak();
}
else
accessory_queue.pop_front();
Time::TimeStamp t = Time::now();
if(t>off_timeout)
{
+ Accessory &acc = *active_accessory;
+
+ if(acc.kind==Accessory::TURNOUT && monitor.get_peak()<0.5f)
+ {
+ unsigned bit = 1<<active_index;
+ if(acc.uncertain&bit)
+ acc.uncertain &= ~bit;
+ else
+ {
+ signal_turnout_failed.emit(acc.address);
+ acc.state.rollback();
+ acc.target ^= bit;
+ }
+ }
+
off_timeout = Time::TimeStamp();
- PendingCommand cmd(*active_accessory, Accessory::DEACTIVATE, active_index);
+ PendingCommand cmd(acc, Accessory::DEACTIVATE, active_index);
command_queue.push(cmd);
}
}
address(a),
bits(b),
state(0),
+ uncertain((1<<bits)-1),
+ target(0),
active_time(500*Time::msec)
{ }
bool set(T v) { if(v==pending) return false; pending = v; ++serial; return true; }
bool commit(unsigned short s) { if(s!=serial) return false; current = pending; return true; }
+ void rollback() { pending = current; ++serial; }
operator T() const { return current; }
};
unsigned address;
unsigned bits;
ControlledVariable<unsigned> state;
+ unsigned uncertain;
unsigned target;
Msp::Time::TimeDelta active_time;