Files
Martin Linkwitz - NUC c7adbcd1c7 Initial commit
2026-04-04 12:43:12 +02:00

108 lines
2.8 KiB
C

#ifndef MEYRULE_H
#define MEYRULE_H
#include <Arduino.h>
#include <mcp2515.h>;
struct TargetPin{
uint16_t devId;
byte meyPinId;
bool lastPinState = false;
};
struct Rule {
uint16_t sourceDevId;
byte sourceMeyPinId;
TargetPin target = TargetPin();
bool toggle;
bool inverse;
Rule *nextRule = NULL;
bool triggeredOnce = false;
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 SetLocalPinState(can_frame *frame);
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