112 lines
2.5 KiB
C
112 lines
2.5 KiB
C
#ifndef MEYRULE_H
|
|
#define MEYRULE_H
|
|
|
|
#include <Arduino.h>
|
|
#include <mcp2515.h>;
|
|
|
|
struct Rule
|
|
{
|
|
uint16_t sourceDevId;
|
|
byte sourceMeyPinId;
|
|
uint16_t targetDevId;
|
|
byte targetMeyPinId;
|
|
bool toggle;
|
|
bool inverse;
|
|
Rule *nextRule = NULL;
|
|
|
|
void AddRule(Rule *rule)
|
|
{
|
|
if (this->nextRule == NULL)
|
|
{
|
|
this->nextRule = rule;
|
|
rule->nextRule = NULL;
|
|
} else {
|
|
this->nextRule->AddRule(rule);
|
|
}
|
|
}
|
|
|
|
void Traverse( uint16_t deviceId, uint8_t dt, uint8_t state, void (*handle)(uint16_t, uint8_t, uint8_t, Rule*))
|
|
{
|
|
|
|
if ( this->sourceDevId == deviceId && this->sourceMeyPinId == state)
|
|
handle(deviceId, dt, state, this);
|
|
|
|
if (this->nextRule != NULL)
|
|
this->nextRule->Traverse(deviceId, dt, state, handle);
|
|
|
|
}
|
|
};
|
|
|
|
|
|
typedef struct RemotePinInfo
|
|
{
|
|
const byte MAX_REMOTE_PIN_COUNT = 64;
|
|
uint16_t DeviceId = 0; // the id of the device
|
|
uint8_t pinState = 0; // bitmap of 8 MeyPin states of the device. 0000 0100, MeyPin #3 is HIGH in this example
|
|
RemotePinInfo *next = NULL;
|
|
|
|
bool getPinState(byte meyPin)
|
|
{
|
|
return (this->pinState >> (meyPin - 1)) & 1;
|
|
}
|
|
|
|
void setPinState(byte meyPin, bool state)
|
|
{
|
|
if (state)
|
|
this->pinState = this->pinState | (1 << (meyPin - 1)); // 0001 0000
|
|
else
|
|
this->pinState = this->pinState & (~(1 << (meyPin - 1))); // 1110 1111 -> not
|
|
}
|
|
|
|
|
|
int16_t Count()
|
|
{
|
|
if (this->next == NULL) return 1;
|
|
return this->next->Count() + 1;
|
|
}
|
|
|
|
RemotePinInfo* FindOrAdd(uint16_t deviceId, byte count = 0)
|
|
{
|
|
if (count > MAX_REMOTE_PIN_COUNT)
|
|
return NULL;
|
|
|
|
|
|
if (this->DeviceId == 0 && this->pinState == 0)
|
|
{
|
|
this->DeviceId = deviceId;
|
|
this->pinState = 0;
|
|
}
|
|
|
|
if (this->DeviceId == deviceId)
|
|
{
|
|
//ToggleDebug();
|
|
return this;
|
|
}
|
|
|
|
if (next != NULL)
|
|
{
|
|
return next->FindOrAdd(deviceId, count + 1);
|
|
}
|
|
|
|
RemotePinInfo *theNext = new RemotePinInfo;
|
|
theNext->DeviceId = deviceId;
|
|
theNext->pinState = 0;
|
|
theNext->next = NULL;
|
|
|
|
this->next = theNext;
|
|
return this->next;
|
|
}
|
|
|
|
};
|
|
|
|
extern RemotePinInfo remotePinInfo;
|
|
extern Rule *rules;
|
|
|
|
void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
|
void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
|
void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId);
|
|
void HandleRules(can_frame *frame);
|
|
void PutRule(Rule *rule);
|
|
void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule);
|
|
#endif
|