Skip to content

Instantly share code, notes, and snippets.

@spawnrider
Created April 1, 2016 21:31
Show Gist options
  • Select an option

  • Save spawnrider/8c05572111c9259195e6f4d507918187 to your computer and use it in GitHub Desktop.

Select an option

Save spawnrider/8c05572111c9259195e6f4d507918187 to your computer and use it in GitHub Desktop.
My personal Arduino Domotic program
#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