Doorbell to send jsonrpc

Hi,

I have a couple of sparks on order, whenever the next run ships… but i just wanted to work a few things out so i can get it going as soon as they arrive.

the first project i have in mind is for my media center, XBMC. someone has written a neat little script for it so when i go into my browser and type the following, the video from my security camera at my front door slides in from the right hand side of the screen and displays for 10seconds

http://username:password@myipaddress:port/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22Addons.ExecuteAddon%22,%22params%22:{%22addonid%22:%22script.securitycam%22},%22id%22:%221%22}}

if i type this into my internet browser and hit enter it works perfectly and returns an ‘ok’ response. so i have read a few peoples posts and i think i need the following code to read if the doorbell button is pressed…

    int BTN = D0;
    int val = LOW;
    
    void setup() {
       pinMode(BTN, INPUT);
    
       digitalWrite(BTN, LOW);
    }
    
  
    
    void loop() {
    
      val = digitalRead(D0);
    
      if(val == HIGH) {
    
What do i need to put here to make this work?
     }
    
    }

but i have no idea how to send the command.

once i get this working i would like to set up something that sends a push notification to my phone, that way i can look at the camera when i’m not home and see who it is and even talk to them too

Hi @Hootie81,

Sounds cool! I expanded on a previous post where I talked about making http POST / http GET requests, here’s a nicer version with http basic auth (from your url):

//how to call
httpGetRequest("192.168.1.10", 80, 
    "/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22Addons.ExecuteAddon%22,%22params%22:{%22addonid%22:%22script.securitycam%22},%22id%22:%221%22}}",
    "username","password");
}

//the wrapper
void httpGetRequest(char *hostname, int port, char *url, char *username, char *password) {
  TCPClient client;
  client.connect(hostname, port);
  client.print("GET ");
  client.print(url);
  client.println("HTTP/1.0");
  client.print("Host: ");
  client.println(hostname);

  if (username != NULL) {
    //NOTE! make sure username and password are already base64 encoded here!
    client.print("Authorization: Basic ");
    client.print(String(username) + String(":") + String(password));
  }
  client.println("Content-Length: 0");
  client.println();
  client.flush();
  client.stop();
  delay(250);
}

Thanks! :smiley:
David

THANKS! @Dave I really cant wait to receive the sparks now.

that makes it much clearer, i can see how the main part works now. How does the base64 encoding part work?

when i do this in firefox i get

{"id":"1","jsonrpc":"2.0","result":"OK"}

is there a way to read this to make sure it worked? maybe a green flash of a led for result ok?

Hi @Hootie81,

Totally! You’d just want to read back what you got from the server and either check to see that it contains a success string, or actually parse out the HTTP response status code. I wonder if anyone in the community is actively working on an HTTP client library or if that is something we should add to the backlog.

Thanks!
David

What is that delay for? Why 250?

I think I added it after seeing a corresponding commit in the firmware when closing sockets. There may have previously been an issue that occurred without a pause, so it might just be old superstitions. I also tend to put small delays in between multiple requests so I don’t hammer the server I’m hitting. :smile:

Ok, so i got an email saying my core is about to ship, so i decided to put a bit more time into this again.

When i try and get @Dave code to compile i get errors, with the line below,

  client.println("Host: " hostname);

am i right in assuming i can split this into 2 lines, as below?

client.print("Host: ");
client.println(hostname);

i changed ‘println’ to ‘print’ on the first line so it doesn’t carriage return between.

Here is the code that will hopefully do the job,

int doorbell = D0; // Doorbell button connects to D0 on the core
unsigned long Lockout; // used to stop flooding 
        
void setup() {
    
    pinMode(doorbell, INPUT_PULLUP); // other side of doorbell will connect to ground to pull low
    Lockout = millis();

}

void loop() {
    if (millis() >= Lockout){  // check how long its been since last pushed
        if(digitalRead(doorbell) == LOW) {  //read the doorbell button
            delay(50);
            if(digitalRead(doorbell) == LOW) {  // debounce check again to make sure 
                Lockout = millis() + 15000; // set up the lockout period 15 seconds before it will run again
                httpGetRequest("192.168.1.10", 80, 
    "/jsonrpc?request={%22jsonrpc%22:%222.0%22,%22method%22:%22Addons.ExecuteAddon%22,%22params%22:{%22addonid%22:%22script.securitycam%22},%22id%22:%221%22}}",
    "username","password");  // opens up a script in xbmc that displays an ip camera 
            }
        }
    }

}


void httpGetRequest(char *hostname, int port, char *url, char *username, char *password) {
  TCPClient client;
  client.connect(hostname, port);
  client.print("GET ");
  client.print(url);
  client.println("HTTP/1.0");
  client.print("Host: ");
  client.println(hostname);

  if (username != NULL) {
    //NOTE! make sure username and password are already base64 encoded here!
    client.print("Authorization: Basic ");
    client.print(String(username) + String(":") + String(password));
  }
  client.println("Content-Length: 0");
  client.println();
  client.flush();
  client.stop();
}

@Hootie81 this can work too:

client.println("Host: " + String(hostname));

Thanks for catching that! My mistake, I edited the code above to (hopefully) work properly :slight_smile: