#include "MeyRule.h" #include "MeyCan.h" #include #include ; RemotePinInfo remotePinInfo = RemotePinInfo(); Rule *rules = NULL; void PutRule(Rule *rule) { if (rules == NULL) rules = rule; else rules->AddRule(rule); } void AddSimple(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) { Rule *rule = new Rule(); rule->sourceDevId = sourceDevId; rule->sourceMeyPinId = sourceMeyPinId; rule->targetDevId = targetDevId; rule->targetMeyPinId = targetMeyPinId; rule->toggle = false; rule->inverse = false; rule->lastPinState = false; PutRule(rule); } void AddToggle(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) { Rule *rule = new Rule(); rule->sourceDevId = sourceDevId; rule->sourceMeyPinId = sourceMeyPinId; rule->targetDevId = targetDevId; rule->targetMeyPinId = targetMeyPinId; rule->toggle = true; rule->inverse = false; rule->lastPinState = false; PutRule(rule); } void AddToggleInverse(uint16_t sourceDevId, byte sourceMeyPinId, uint16_t targetDevId, byte targetMeyPinId) { Rule *rule = new Rule(); rule->sourceDevId = sourceDevId; rule->sourceMeyPinId = sourceMeyPinId; rule->targetDevId = targetDevId; rule->targetMeyPinId = targetMeyPinId; rule->toggle = true; rule->inverse = true; rule->lastPinState = false; PutRule(rule); } void CheckRule(uint16_t deviceId, uint8_t dt, uint8_t state, Rule *rule) { RemotePinInfo *currentRemotePinInfo = remotePinInfo.FindOrAdd(rule->targetDevId); if (currentRemotePinInfo == NULL) return; // check the new state with the last one. Needs to be done, as the UP switch might // send it multiple times like "01 01" "01 01" for a single tip.(antibeat) bool lastPinState = rule->lastPinState; bool pinState = dt > 0; if (rule->triggeredOnce && lastPinState == pinState) return; rule->lastPinState = pinState; rule->triggeredOnce = true; if (rule->inverse) pinState = !pinState; if (rule->toggle) pinState = (currentRemotePinInfo->getPinState(rule->targetMeyPinId) ^ true); BroadcastTriggerMeyPinCanPackage(rule->targetDevId, rule->targetMeyPinId, pinState); currentRemotePinInfo->setPinState(rule->targetMeyPinId, pinState); } void HandleTriggered(can_frame *frame) { if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) { RemotePinInfo *currentPinState = remotePinInfo.FindOrAdd(GetDeviceId(frame->can_id) ); if (currentPinState == NULL) return; currentPinState->setPinState(frame->data[0], frame->data[1]); } } void HandleRules(can_frame *frame) { HandleTriggered(frame); if (rules == NULL) return; if (GetPackageType(frame->can_id) == SWITCH_TRIGGERED_CAN_ID) { uint16_t deviceId = GetDeviceId(frame->can_id); uint8_t dt = frame->data[1]; uint8_t state = frame->data[0]; rules->Traverse(deviceId, dt, state, CheckRule); } }