Created
April 1, 2016 21:31
-
-
Save spawnrider/8c05572111c9259195e6f4d507918187 to your computer and use it in GitHub Desktop.
My personal Arduino Domotic program
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <b64.h> | |
| #include <HttpClient.h> | |
| #include <SPI.h> | |
| #include <Ethernet.h> | |
| #include <RCSwitch.h> | |
| #include <DHT.h> | |
| // To send RF commands | |
| RCSwitch mySwitch = RCSwitch(); | |
| #define DHTPIN 3 // what pin for DHT humidity/temperature sensor | |
| //#define DHTTYPE DHT11 // DHT 11 | |
| #define DHTTYPE DHT22 // DHT 22 (AM2302) | |
| //#define DHTTYPE DHT21 // DHT 21 (AM2301) | |
| // Initialize DHT sensor for normal 16mhz Arduino | |
| DHT dht(DHTPIN, DHTTYPE); | |
| // NOTE: For working with a faster chip, like an Arduino Due or Teensy, you | |
| // might need to increase the threshold for cycle counts considered a 1 or 0. | |
| // You can do this by passing a 3rd parameter for this threshold. It's a bit | |
| // of fiddling to find the right value, but in general the faster the CPU the | |
| // higher the value. The default for a 16mhz AVR is a value of 6. For an | |
| // Arduino Due that runs at 84mhz a value of 30 works. | |
| // Example to initialize DHT sensor for Arduino Due: | |
| //DHT dht(DHTPIN, DHTTYPE, 30); | |
| #define STRING_BUFFER_SIZE 128 | |
| char buffer[STRING_BUFFER_SIZE]; | |
| EthernetServer server(80); | |
| void setup() { | |
| Serial.begin(9600); | |
| // Enter a MAC address and IP address for your controller below. | |
| byte mac[] = { | |
| 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; | |
| // The IP address will be dependent on your local network: | |
| IPAddress ip(192,168,0,9); | |
| //Serial.println("Init RF services"); | |
| // Transmitter is connected to Arduino Pin #10 | |
| mySwitch.enableTransmit(9); | |
| // Optional set pulse length. | |
| mySwitch.setPulseLength(700); | |
| // Optional set protocol (default is 1, will work for most outlets) | |
| mySwitch.setProtocol(2); | |
| mySwitch.setRepeatTransmit(10); | |
| //Serial.println("Init DHT services"); | |
| dht.begin(); | |
| // start the Ethernet connection and the server: | |
| Ethernet.begin(mac, ip); | |
| server.begin(); | |
| //Serial.print("Init ethernet server at "); | |
| //Serial.println(Ethernet.localIP()); | |
| mySwitch.enableReceive(0); // Receiver on inerrupt 0 => that is pin #2 | |
| //Serial.println("Card initialized"); | |
| } | |
| void send404(EthernetClient client) { | |
| //Serial.println("Send404"); | |
| client.println("HTTP/1.1 404 OK"); | |
| client.println("X-Powered-By: domoserver"); | |
| client.println("Connnection: close"); | |
| client.println("Content-Type: application/json"); | |
| client.println(""); | |
| client.println("{\"status\":\"ko\", \"error\":\"not found\"}"); | |
| } | |
| void sendStatus(EthernetClient client) { | |
| //Serial.println("Send Status"); | |
| // Send a standard http response header | |
| client.println("HTTP/1.1 200 OK"); | |
| client.println("X-Powered-By: domoserver"); | |
| client.println("Connnection: close"); | |
| client.println("Content-Type: application/json"); | |
| client.println(""); | |
| client.print("{\"status\":\"ok\", \"uptime\":"); | |
| client.print(millis()); | |
| client.println("}"); | |
| } | |
| void sendReceivedRFCode(unsigned long decimal, unsigned int length, unsigned int delay, unsigned int protocol) { | |
| EthernetClient client; | |
| const char kHostname[] = "192.168.0.6"; | |
| String command = "GET /apireceive"; | |
| command += "?value="; | |
| command += decimal; | |
| command += "&bit="; | |
| command += length; | |
| command += "&delay="; | |
| command += delay; | |
| command += "&protocol="; | |
| command += protocol; | |
| //Serial.print("Send comamnd : "); | |
| //Serial.println(command); | |
| // Connect to Node-Red | |
| if (client.connect(kHostname, 1880)) { | |
| //Serial.print("-> Connected to "); | |
| //Serial.println(kHostname); | |
| // Make a HTTP request: | |
| client.print(command); | |
| // Read humidity | |
| float h = dht.readHumidity(); | |
| // Read temperature as Celsius | |
| float t = dht.readTemperature(); | |
| // Check if any reads failed and exit early (to try again). | |
| if (isnan(h) || isnan(t)) { | |
| //Serial.println("Failed to read from DHT sensor!"); | |
| } | |
| else { | |
| client.print("&temperature="); | |
| client.print(t); | |
| client.print("&humidity="); | |
| client.print(h); | |
| } | |
| client.println( " HTTP/1.1"); | |
| client.print( "Host: " ); | |
| client.println(kHostname); | |
| client.println( "Connection: close" ); | |
| client.println(); | |
| client.println(); | |
| client.stop(); | |
| } | |
| else { | |
| // you didn't get a connection to the server: | |
| //Serial.println("--> connection failed/n"); | |
| client.stop(); | |
| } | |
| } | |
| /** | |
| * Parse the string and return an array which contains all path segments | |
| */ | |
| char** parse(char* str) { | |
| char ** messages; | |
| messages = (char**)malloc(sizeof(char *)); | |
| char *p; | |
| p = strtok(str, " "); | |
| unsigned int i = 0; | |
| while (p != NULL) { | |
| p = strtok(NULL, "/"); | |
| char *sp; | |
| boolean last = false; | |
| sp = strchr(p, ' '); | |
| if (sp != NULL) { | |
| *sp++ = '\0'; | |
| last = true; | |
| } | |
| messages[i] = p; | |
| i++; | |
| if (last) { | |
| break; | |
| } | |
| messages = (char**)realloc(messages, sizeof(char *) * i + 1); | |
| } | |
| messages[i] = '\0'; | |
| return messages; | |
| } | |
| void handleCommand(EthernetClient client, char* cmd, char* param) { | |
| if (strcmp(cmd, "status") == 0) { | |
| //Serial.println("status"); | |
| sendStatus(client); | |
| } | |
| else if(strcmp(cmd, "dht") == 0) { | |
| // Read humidity | |
| float h = dht.readHumidity(); | |
| // Read temperature as Celsius | |
| float t = dht.readTemperature(); | |
| // Check if any reads failed and exit early (to try again). | |
| if (isnan(h) || isnan(t)) { | |
| //Serial.println("Failed to read from DHT sensor!"); | |
| return; | |
| } | |
| //Serial.print("Humidity: "); | |
| //Serial.print(h); | |
| //Serial.print(" %\t"); | |
| //Serial.print("Temperature: "); | |
| //Serial.print(t); | |
| //Serial.println(" *C "); | |
| // Send a standard http response header | |
| client.println("HTTP/1.1 200 OK"); | |
| client.println("X-Powered-By: domoserver"); | |
| client.println("Connnection: close"); | |
| client.println("Content-Type: application/json"); | |
| client.println(""); | |
| client.print("{\"status\":\"ok\", \"temperature\":\""); | |
| client.print(t); | |
| client.print("\", \"humidity\":\""); | |
| client.print(h); | |
| client.println("\"}"); | |
| } | |
| else if (strcmp(cmd, "ov") == 0) { | |
| mySwitch.setProtocol(2); | |
| mySwitch.setPulseLength(700); | |
| sendCode("XXXXXX", 32); | |
| sendStatus(client); | |
| //Serial.println("ov"); | |
| } | |
| else if (strcmp(cmd, "cv") == 0) { | |
| mySwitch.setProtocol(2); | |
| mySwitch.setPulseLength(700); | |
| sendCode("XXXXXX", 32); | |
| sendStatus(client); | |
| //Serial.println("cv"); | |
| } | |
| else if (strcmp(cmd, "alarmoff") == 0) { | |
| mySwitch.setProtocol(1); | |
| //mySwitch.setPulseLength(550); | |
| sendCode("XXXXXX", 24); | |
| sendStatus(client); | |
| //Serial.println("alarmoff"); | |
| } | |
| else if (strcmp(cmd, "alarmprotect") == 0) { | |
| mySwitch.setProtocol(1); | |
| //mySwitch.setPulseLength(550); | |
| sendCode("XXXXXX", 24); | |
| sendStatus(client); | |
| //Serial.println("alarmprotect"); | |
| } | |
| else if (strcmp(cmd, "alarmon") == 0) { | |
| mySwitch.setProtocol(1); | |
| //mySwitch.setPulseLength(550); | |
| sendCode("XXXXXX", 24); | |
| sendStatus(client); | |
| //Serial.println("alarmon"); | |
| } | |
| else if (strcmp(cmd, "send") == 0) { | |
| mySwitch.setProtocol(1); | |
| //mySwitch.setPulseLength(550); | |
| sendCode(param, 24); | |
| sendStatus(client); | |
| //Serial.print("send: "); | |
| //Serial.println(param); | |
| } | |
| else { | |
| send404(client); | |
| //doAnHTTPcall(); | |
| } | |
| } | |
| void sendCode(char* param, int bytes) { | |
| //Serial.print("Sending code : "); | |
| //Serial.println(param); | |
| //mySwitch.send(param); | |
| long paraml = atol(param); | |
| mySwitch.send(paraml, bytes); | |
| } | |
| int countSegments(char* str) { | |
| int p = 0; | |
| int count = 0; | |
| while (str[p] != '\0') { | |
| if (str[p] == '/') { | |
| count++; | |
| } | |
| p++; | |
| } | |
| // We don't want to count the / in 'HTTP/1.1' | |
| count--; | |
| return count; | |
| } | |
| void loop() { | |
| // listen for incoming clients | |
| EthernetClient client = server.available(); | |
| if (client) { | |
| // an http request ends with a blank line | |
| boolean currentLineIsBlank = true; | |
| while (client.connected()) { | |
| if (client.available()) { | |
| char c; | |
| int bufindex = 0; // reset buffer | |
| buffer[0] = client.read(); | |
| buffer[1] = client.read(); | |
| bufindex = 2; | |
| // Read the first line to determin the request page | |
| while (buffer[bufindex-2] != '\r' && buffer[bufindex-1] != '\n') { | |
| // read full row and save it in buffer | |
| c = client.read(); | |
| if (bufindex<STRING_BUFFER_SIZE) { | |
| buffer[bufindex] = c; | |
| } | |
| bufindex++; | |
| } | |
| // Clean buffer for next row | |
| bufindex = 0; | |
| // Parse the query string | |
| int nSegments = countSegments(buffer); | |
| char **pathsegments = parse(buffer); | |
| int i = 0; | |
| for(i=0; i<nSegments; i++) { | |
| //Serial.println(pathsegments[i]); | |
| } | |
| if (c == '\n' && currentLineIsBlank) { | |
| handleCommand(client, pathsegments[0], pathsegments[1]); | |
| break; | |
| } | |
| if (c == '\n') { | |
| currentLineIsBlank = true; | |
| } | |
| else if (c != '\r') { | |
| currentLineIsBlank = false; | |
| } | |
| } | |
| } | |
| // Give the web browser time to receive the data | |
| delay(1); | |
| // Close the connection: | |
| client.stop(); | |
| //Serial.println("Client disonnected"); | |
| } | |
| // Send RF data | |
| if (mySwitch.available()) { | |
| //output(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedRawdata(),mySwitch.getReceivedProtocol()); | |
| sendReceivedRFCode(mySwitch.getReceivedValue(), mySwitch.getReceivedBitlength(), mySwitch.getReceivedDelay(), mySwitch.getReceivedProtocol()); | |
| mySwitch.resetAvailable(); | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment