-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDigitalInputRTU.cpp
83 lines (74 loc) · 2.26 KB
/
DigitalInputRTU.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <DigitalInputRTU.hpp>
DigitalInputRTU::DigitalInputRTU()
{
this->iot = nullptr;
this->size = 0;
this->callbackCount = 0;
for (int i = 0; i < 16; i++)
this->inputBuffer[i] = false;
}
DigitalInputRTU::~DigitalInputRTU()
{
}
void DigitalInputRTU::begin(char *remoteBaseTopic, uint8_t remote_card_slot, ESPMegaIoT *iot)
{
this->remoteBaseTopic = remoteBaseTopic;
this->remoteBaseTopicLength = strlen(remoteBaseTopic);
this->cardSlot = remote_card_slot;
this->iot = iot;
}
void DigitalInputRTU::subscribe()
{
// Subscribe to all pins
for(uint8_t i = 0; i < 16; i++)
{
char* topic = (char*)calloc(this->remoteBaseTopicLength + 6, sizeof(char));
sprintf(topic, "%s/%02d/%02d", this->remoteBaseTopic, this->cardSlot, i);
this->iot->subscribe(topic);
free(topic);
}
}
bool DigitalInputRTU::digitalRead(uint8_t pin)
{
return this->inputBuffer[pin];
}
uint8_t DigitalInputRTU::registerCallback(std::function<void(uint8_t, bool)> callback)
{
this->callbacks[callbackCount] = callback;
return callbackCount++;
}
void DigitalInputRTU::unregisterCallback(uint8_t handler)
{
this->callbacks.erase(handler);
}
void DigitalInputRTU::mqttCallback(char *topic, char *payload)
{
// First trim base topic from topic
char* topicWithoutBase = topic + this->remoteBaseTopicLength;
// Then check if topic is in format /cardSlot/pin
// Example trimmed topic: /01/00
// Card slot range from 00 to 99
// Pin range from 00 to 15
// Note that both card and pin are padded with 0 if they are less than 10
if(strlen(topicWithoutBase) != 6)
return;
if(topicWithoutBase[0] != '/')
return;
if(topicWithoutBase[3] != '/')
return;
// Extract card slot and pin
uint8_t cardSlot = (topicWithoutBase[1] - '0') * 10 + (topicWithoutBase[2] - '0');
uint8_t pin = (topicWithoutBase[4] - '0') * 10 + (topicWithoutBase[5] - '0');
// Check if card slot is correct
if(cardSlot != this->cardSlot)
return;
// Extract value
bool value = strcmp(payload, "1") == 0;
// Update input buffer
this->inputBuffer[pin] = value;
// Call callbacks
for(auto const& callback : this->callbacks)
{
callback.second(pin, value);
}
}