Skip to content

Commit

Permalink
statemachine fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
pa-pa committed Sep 6, 2016
1 parent d84e1ca commit 888e0d6
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 77 deletions.
2 changes: 1 addition & 1 deletion Alarm.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ class Alarm: public Link {
~Alarm() {
}
public:
bool asyn :1;
bool asyn;
uint32_t tick;

virtual void trigger(AlarmClock&) = 0;
Expand Down
4 changes: 2 additions & 2 deletions Button.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class Button: public Alarm {
};

protected:
uint8_t stat :3;
uint8_t repeat :5;
uint8_t stat;
uint8_t repeat;
uint8_t pin;

public:
Expand Down
10 changes: 5 additions & 5 deletions Channel.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@
namespace as {

class Device;
class ActionMsg;
class ActionSetMsg;
class RemoteEventMsg;

template<class List1Type,class List3Type,class List4Type,int PeerCount>
class Channel {
Device* dev;
bool change : 1; // the status is changed, we may need to send a status
uint8_t num : 3; // max 7 channels per device
uint16_t addr : 12; // max address 4095
bool change; // the status is changed, we may need to send a status
uint8_t num ; // channels per device
uint16_t addr ; // start address in eeprom

public:
typedef List1Type List1;
Expand Down Expand Up @@ -147,7 +147,7 @@ class Channel {
return List4Type::size() > 0;
}

bool process (const ActionMsg& msg) {
bool process (const ActionSetMsg& msg) {
return true;
}

Expand Down
8 changes: 4 additions & 4 deletions Message.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class InfoPeerListMsg;

class DeviceInfoMsg;
class RemoteEventMsg;
class ActionMsg;
class ActionSetMsg;

class Message {
public:
Expand Down Expand Up @@ -260,7 +260,7 @@ class Message {
const ConfigWriteIndexMsg& configWriteIndex () const { return *(ConfigWriteIndexMsg*)this; }

const RemoteEventMsg& remoteEvent () const { return *(RemoteEventMsg*)this; }
const ActionMsg& action () const { return *(ActionMsg*)this; }
const ActionSetMsg& action () const { return *(ActionSetMsg*)this; }

// cast to write message types
AckMsg& ack () { return *(AckMsg*)this; }
Expand Down Expand Up @@ -333,9 +333,9 @@ class RemoteEventMsg : public Message {
bool isLong () const { return (command() & 0x40) == 0x40; }
};

class ActionMsg : public Message {
class ActionSetMsg : public Message {
protected:
ActionMsg() {}
ActionSetMsg() {}
public:
uint8_t channel () const { return subcommand(); }
uint8_t value () const { return *data(); }
Expand Down
2 changes: 1 addition & 1 deletion MultiChannelDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class MultiChannelDevice : public Device {
}
else if( msg.type() == AS_MESSAGE_ACTION ) {
if( msg.command() == AS_ACTION_SET ) {
const ActionMsg& pm = msg.action();
const ActionSetMsg& pm = msg.action();
ChannelType& c = channel(pm.channel());
c.process(pm);
sendAck(msg,c);
Expand Down
2 changes: 1 addition & 1 deletion SwitchChannel.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class SwitchChannel : public Channel<SwitchList1,SwitchList3,EmptyList,PeerCount
BaseChannel::changed(true);
}

bool process (const ActionMsg& msg) {
bool process (const ActionSetMsg& msg) {
status( msg.value(), msg.delay() );
return true;
}
Expand Down
48 changes: 13 additions & 35 deletions SwitchStateMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,29 @@ namespace as {

void SwitchStateMachine::switchState(uint8_t oldstate,uint8_t newstate) {}

void SwitchStateMachine::setState (uint8_t next,uint16_t duration) {
if( next != AS_CM_JT_NONE ) {
void SwitchStateMachine::setState (uint8_t next,uint32_t delay,const SwitchPeerList& lst,uint8_t deep) {
// check deep to prevent infinite recursion
if( next != AS_CM_JT_NONE && deep < 4) {
// first cancel possible running alarm
aclock.cancel(alarm);
if( state != next ) {
switchState(state,next);
// if state is different
if (state != next) {
switchState(state, next);
state = next;
}
if( duration != 0xffff ) {
alarm.action(AS_CM_JT_ON ? AS_CM_JT_OFF : AS_CM_JT_ON);
alarm.set(intTimeCvt(duration));
aclock.add(alarm);
}
}
}

void SwitchStateMachine::jumpToTarget(SwitchPeerList lst) {
uint8_t next = getNextState(state,lst);
if( next != AS_CM_JT_NONE ) {
// get rest of delay value
uint32_t olddelay = aclock.get(alarm);
// first cancel possible running alarm
aclock.cancel(alarm);
// get delay
uint8_t dly = getDelayForState(next,lst);
// signal state change, if any
if( state != next ) {
switchState(state,next);
state = next;
if (delay == DELAY_NO) {
// go immediately to the next state
next = getNextState();
delay = getDelayForState(next,lst);
setState(next, delay, lst, ++deep);
}
if( dly == 0 ) {
// switch immediately to next state
jumpToTarget(lst);
}
else if( dly != 0xff ) {
uint32_t delayvalue = byteTimeCvt(dly);
// setup alarm to process after delay
alarm.action(AS_CM_JT_NONE); // NONE means JumpToTarget
else if (delay != DELAY_INFINITE) {
alarm.list(lst);
alarm.set(max(delayvalue,olddelay));
alarm.set(delay);
aclock.add(alarm);
}
}
}


}

86 changes: 58 additions & 28 deletions SwitchStateMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,29 +10,27 @@ namespace as {

class SwitchStateMachine {

#define DELAY_NO 0x00
#define DELAY_INFINITE 0xffffffff

class StateAlarm : public Alarm {
SwitchStateMachine& sm;
SwitchPeerList lst;
uint8_t act;
public:
StateAlarm(SwitchStateMachine& m) : Alarm(0), sm(m), lst(0), act(AS_CM_JT_NONE) {}
StateAlarm(SwitchStateMachine& m) : Alarm(0), sm(m), lst(0) {}
void list(SwitchPeerList l) {lst=l;}
void action (uint8_t a) {act=a;}
virtual void trigger (AlarmClock& clock) {
if( act != AS_CM_JT_NONE ) {
sm.setState(act,0xffff);
}
else {
sm.jumpToTarget(lst);
}
uint8_t next = sm.getNextState();
uint32_t dly = sm.getDelayForState(next,lst);
sm.setState(next,dly,lst);
}
};


uint8_t state : 4;
uint8_t state;
StateAlarm alarm;

void setState (uint8_t state,uint16_t duration);
void setState (uint8_t state,uint32_t duration,const SwitchPeerList& lst=SwitchPeerList(0),uint8_t deep=0);

protected:
~SwitchStateMachine () {}
Expand All @@ -42,14 +40,32 @@ class SwitchStateMachine {

virtual void switchState(uint8_t oldstate,uint8_t newstate);

void jumpToTarget(SwitchPeerList lst);
void jumpToTarget(const SwitchPeerList& lst) {
uint8_t next = getJumpTarget(state,lst);
if( next != AS_CM_JT_NONE ) {
// get delay
uint32_t dly = getDelayForState(next,lst);
// switch to next
setState(next,dly,lst);
}
}

void toggleState () {
setState( state == AS_CM_JT_ON ? AS_CM_JT_OFF : AS_CM_JT_ON, 0xffff);
setState( state == AS_CM_JT_ON ? AS_CM_JT_OFF : AS_CM_JT_ON, DELAY_INFINITE);
}

uint8_t getNextState(uint8_t state,const SwitchPeerList& lst) const {
uint8_t getNextState () {
switch( state ) {
case AS_CM_JT_ONDELAY: return AS_CM_JT_ON;
case AS_CM_JT_ON: return AS_CM_JT_OFFDELAY;
case AS_CM_JT_OFFDELAY: return AS_CM_JT_OFF;
case AS_CM_JT_OFF: return AS_CM_JT_ONDELAY;
}
return AS_CM_JT_NONE;
}

uint8_t getJumpTarget(uint8_t stat,const SwitchPeerList& lst) const {
switch( stat ) {
case AS_CM_JT_ONDELAY: return lst.jtDlyOn();
case AS_CM_JT_ON: return lst.jtOn();
case AS_CM_JT_OFFDELAY: return lst.jtDlyOff();
Expand All @@ -58,28 +74,42 @@ class SwitchStateMachine {
return AS_CM_JT_NONE;
}

uint8_t getDelayForState(uint8_t state,const SwitchPeerList& lst) const {
switch( state ) {
case AS_CM_JT_ONDELAY: return lst.onDly();
case AS_CM_JT_ON: return lst.onTime();
case AS_CM_JT_OFFDELAY: return lst.offDly();
case AS_CM_JT_OFF: return lst.offTime();
default: break;
uint32_t getDelayForState(uint8_t stat,const SwitchPeerList& lst) const {
if( lst.valid() == false ) {
return getDefaultDelay(stat);
}
uint8_t value = 0;
switch( stat ) {
case AS_CM_JT_ONDELAY: value = lst.onDly(); break;
case AS_CM_JT_ON: value = lst.onTime(); break;
case AS_CM_JT_OFFDELAY: value = lst.offDly(); break;
case AS_CM_JT_OFF: value = lst.offTime(); break;
}
return byteTimeCvt(value);
}

uint32_t getDefaultDelay(uint8_t stat) const {
switch( stat ) {
case AS_CM_JT_ON:
case AS_CM_JT_OFF:
return DELAY_INFINITE;
}
return 0;
return DELAY_NO;
}

bool delayActive () const { return aclock.get(alarm) > 0; }

// get timer count in 1/10s
uint32_t byteTimeCvt(uint8_t tTime) {
static uint32_t byteTimeCvt(uint8_t tTime) {
if( tTime == 0xff ) return 0xffffffff;
const uint16_t c[8] = {1,10,50,100,600,3000,6000,36000};
return (uint16_t)(tTime & 0x1F) * c[tTime >> 5];
}

// get timer count in 1/10s
uint32_t intTimeCvt(uint16_t iTime) {
if (iTime == 0) return 0;
static uint32_t intTimeCvt(uint16_t iTime) {
if (iTime == 0x00) return 0x00;
if (iTime == 0xffff) return 0xffffffff;

uint8_t tByte;
if ((iTime & 0x1F) != 0) {
Expand All @@ -97,16 +127,16 @@ class SwitchStateMachine {
jumpToTarget(lst);
break;
case AS_CM_ACTIONTYPE_TOGGLE_TO_COUNTER:
setState((counter & 0x01) == 0x01 ? AS_CM_JT_ON : AS_CM_JT_OFF, 0xffff);
setState((counter & 0x01) == 0x01 ? AS_CM_JT_ON : AS_CM_JT_OFF, DELAY_INFINITE);
break;
case AS_CM_ACTIONTYPE_TOGGLE_INVERSE_TO_COUNTER:
setState((counter & 0x01) == 0x00 ? AS_CM_JT_ON : AS_CM_JT_OFF, 0xffff);
setState((counter & 0x01) == 0x00 ? AS_CM_JT_ON : AS_CM_JT_OFF, DELAY_INFINITE);
break;
}
}

void status (uint8_t stat, uint16_t delay) {
setState( stat == 0 ? AS_CM_JT_OFF : AS_CM_JT_ON, delay );
setState( stat == 0 ? AS_CM_JT_OFF : AS_CM_JT_ON, intTimeCvt(delay) );
}

uint8_t status () const {
Expand Down

0 comments on commit 888e0d6

Please sign in to comment.