#include <UIPEthernet.h>
#include <EEPROM.h>
EthernetClient client;
EthernetServer server = EthernetServer(1337);
const byte mac[6] = { 0x46, 0x72, 0x69, 0x74, 0x7A, 0x21 }; // Fritz! (in hexadecimal)
const PROGMEM char dataPost[] = "POST /igdupnp/control/WANCommonIFC1 HTTP/1.1\n";
const PROGMEM char dataHost[] = "Host: fritz.box:49000\n";
const PROGMEM char dataConnection[] = "Connection: keep-alive\n";
const PROGMEM char dataUserAgent[] = "User-agent: FritzbackDevice/1.0\n";
const PROGMEM char dataContentType[] = "Content-Type: text/xml; charset=utf-8\n";
const PROGMEM char dataAction[] = "SOAPAction: \"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1#GetAddonInfos\"\n";
const PROGMEM char dataLength[] = "Content-Length: 426\n";
const PROGMEM char dataPacketA[] = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope ";
const PROGMEM char dataPacketB[] = "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" ";
const PROGMEM char dataPacketC[] = "xmlns:ns1=\"urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1\" ";
const PROGMEM char dataPacketD[] = "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" ";
const PROGMEM char dataPacketE[] = "xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" ";
const PROGMEM char dataPacketF[] = "SOAP-ENV:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">";
const PROGMEM char dataPacketG[] = "<SOAP-ENV:Body><ns1:GetAddonInfos/></SOAP-ENV:Body></SOAP-ENV:Envelope>\n";
char sendBuffer[100];
long curRates[2] = { 0L, 0L };
long maxRates[2] = { 0L, 0L };
const int PIN_PUMP[2] = { 6, 5 };
const int ROM_PUMPS = 0;
const int ROM_MAXRATES[2] = { 2, 6 };
byte cfgPumps = 0;
void setup() {
// Pin Modes
pinMode(PIN_PUMP[0], OUTPUT);
pinMode(PIN_PUMP[1], OUTPUT);
// Ethernet
Ethernet.begin(mac);
server.begin();
// EEPROM
maxRates[0] = EEPROM_ReadLong(ROM_MAXRATES[0]);
maxRates[1] = EEPROM_ReadLong(ROM_MAXRATES[1]);
cfgPumps = EEPROM.read(ROM_PUMPS);
}
void loop() {
if (client.connect(Ethernet.gatewayIP(), 49000)) {
while (client.connected()) {
client.print(getString(dataPost));
client.print(getString(dataHost));
client.print(getString(dataConnection));
client.print(getString(dataUserAgent));
client.print(getString(dataContentType));
client.print(getString(dataAction));
client.print(getString(dataLength));
client.print("\n");
client.print(getString(dataPacketA));
client.print(getString(dataPacketB));
client.print(getString(dataPacketC));
client.print(getString(dataPacketD));
client.print(getString(dataPacketE));
client.print(getString(dataPacketF));
client.print(getString(dataPacketG));
client.print("\n");
//
unsigned long timeout = millis() + 5000;
while (client.available() == 0) {
if (millis() > timeout) {
break;
}
delayLoop(1);
}
char limiter[] = "<>";
timeout = timeout = millis() + 5000;
while (true) {
char dataBuffer[255] = { 0 };
client.readBytesUntil('\n', dataBuffer, 255);
setRate("NewByteReceiveRate", 18, dataBuffer, 0);
setRate("NewByteSendRate", 15, dataBuffer, 1);
char *fin = strtok(dataBuffer, "<>");
if ((strncmp(fin, "/s:Envelope", 11) == 0) || millis() > timeout) {
break;
}
}
delayLoop(250);
}
}
delayLoop(5000);
}
void delayLoop(int wait) {
unsigned long timer = millis() + wait;
while (millis() < timer) {
if (EthernetClient control = server.available()) {
while (server.available() > 0) {
int cmd = control.read();
switch (cmd) {
case 'R':
maxRates[0] = 0L;
maxRates[1] = 0L;
EEPROM_WriteLong(ROM_MAXRATES[0], 0L);
EEPROM_WriteLong(ROM_MAXRATES[1], 0L);
break;
case 'P':
cfgPumps = 1;
EEPROM.update(ROM_PUMPS, 1);
break;
case 'p':
cfgPumps = 0;
EEPROM.update(ROM_PUMPS, 0);
analogWrite(PIN_PUMP[0], 0);
analogWrite(PIN_PUMP[1], 0);
break;
}
control.println(curRates[0]);
control.println(curRates[1]);
control.println(maxRates[0]);
control.println(maxRates[1]);
control.println(cfgPumps);
control.println();
control.stop();
}
}
}
}
void setRate(const char* value, int vsize, char* origBuffer, int mr) {
char dataBuffer[255];
strcpy(dataBuffer, origBuffer);
char* tag = strtok(dataBuffer, "<>");
if (strncmp(tag, value, vsize) == 0) {
long data = atol(strtok(NULL, "<>"));
curRates[mr] = data;
if (data > maxRates[mr]) {
EEPROM_WriteLong(ROM_MAXRATES[mr], data);
maxRates[mr] = data;
}
if (cfgPumps == 1) {
if (map(data, 0, maxRates[mr], 0, 100) > 3) {
analogWrite(PIN_PUMP[mr], map(constrain(data, 0, maxRates[mr] * 0.7), 0, maxRates[mr] * 0.7, 100, 255));
} else {
analogWrite(PIN_PUMP[mr], 0);
}
}
}
}
char* getString(const char* str) {
strcpy_P(sendBuffer, (char*) str);
return sendBuffer;
}
void EEPROM_WriteLong(int address, long value) {
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
EEPROM.update(address, four);
EEPROM.update(address + 1, three);
EEPROM.update(address + 2, two);
EEPROM.update(address + 3, one);
}
long EEPROM_ReadLong(int address) {
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}