File -- main.cpp:
#include "voodooapi.h"
#include "iostream"
#include "stdexcept"
using namespace std;
int main(int argc, char *argv[])
{
(void)argc; //suppress unused variable warning message!
(void)argv; //suppress unused variable warning message!
try {
VoodooAPI v; //create a VoodooAPI object on the stack
v.setUsernameAndPassword("yourname","yourpassword");
v.setDeviceID("FAAD4B:8E336A");
v.setDisplay("hello","there");
v.setTune("140,c5,1,c5,1,f5,3,p,2,c5,1,f5,1,a5,3");
v.execute(); //first call will force a login
v.setDeviceID("FF754A:E24C16");
v.setDisplay("here's","another");
v.execute(); //uses the same tune as above
v.setDeviceID("FB9915:C956FC");
v.setDisplay("and","another");
v.execute(); //change only those parameters that you need to
}
catch (invalid_argument e) {
cout << e.what() << '\n';
}
catch (runtime_error e) {
cout << e.what() << '\n';
}
return 0;
}
--------------------------------------------------------------------------------------------------------------------------------
File -- voodooapi.h:
#ifndef VOODOOAPI_H
#define VOODOOAPI_H
#include "string"
#include "stdexcept"
#include "curl/curl.h"
#include "iostream"
using namespace std;
class VoodooAPI
{
public:
enum operationType
{
display,
flash,
opStatic,
opStatic2,
location
};
VoodooAPI();
void setUsernameAndPassword(const string &u,const string &p);
void login(); //login method could be made private--your choice!
void execute();
void setDeviceID(const string &id);
void setOperation(const operationType ot);
void setDisplay(const string &l1, const string &l2);
void setTune(const string &t);
void setTime(short t);
void setTransactionID(const string &txn);
private:
const string base = "https://www.voodoodevices.com/";
string username;
string password;
string deviceID;
string line1;
string line2;
operationType op = display;
string tune;
short time = 10;
string txnID;
CURL * curly = NULL;
};
#endif // VOODOOAPI_H
--------------------------------------------------------------------------------------------------------------------------------
File voodooapi.cpp:
#include "voodooapi.h"
VoodooAPI::VoodooAPI()
{
//nothing needs to be done here in this example
}
void VoodooAPI::setUsernameAndPassword(const string &u, const string &p)
{
username = u;
password = p;
}
void VoodooAPI::login()
{
//make sure there is a username and password set
if (username=="") {
throw(invalid_argument("Username not set"));
}
if (password=="") {
throw(invalid_argument("Password not set"));
}
CURLcode res;
res = curl_global_init(CURL_GLOBAL_ALL);
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL curl_global_init failed: ")+curl_easy_strerror(res)));
}
curly = curl_easy_init(); //note that curl_global_init is called automatically in curl_easy_init if not called already
if (!curly) {
throw(runtime_error("CURL could not initialize"));
}
res = curl_easy_setopt(curly, CURLOPT_POST, 1); //use a post call to login
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL failed CURLOPT_POST: ")+curl_easy_strerror(res)));
}
string data="name="+username+"&pass="+password+"&form_id=user_login_block";
//note: user_login_block is found in the HTML of the homepage--check it out!
res = curl_easy_setopt(curly, CURLOPT_POSTFIELDS, data.c_str()); //make sure to pass the char *, not the string!
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL failed CURLOPT_POSTFIELDS: ")+curl_easy_strerror(res)));
}
res = curl_easy_setopt(curly, CURLOPT_COOKIEFILE, ""); //enables the cookie engine without initial cookies
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL failed CURLOPT_COOKIEFILE: ")+curl_easy_strerror(res)));
}
res = curl_easy_setopt(curly, CURLOPT_URL, base.c_str()); //goes to https://www.voodoodevices.com/
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL failed CURLOPT_URL: ")+curl_easy_strerror(res)));
}
//now that all the parameters are set, let's go...
res = curl_easy_perform(curly);
if (res!=CURLE_OK) {
throw(runtime_error(string("CURL post request failed: ")+curl_easy_strerror(res)));
}
}
void VoodooAPI::execute()
{
//make sure a deviceID has been set
if (deviceID=="") {
throw(invalid_argument("DeviceID not set"));
}
//set up the operation
string opWord;
switch (op) {
case display: opWord = "display";
break;
case flash: opWord = "flash";
break;
case opStatic: opWord = "static";
break;
case opStatic2: opWord = "static2";
break;
case location: opWord = "location";
break;
default: throw(invalid_argument("Bad operation"));;
}
//if there is no tune set, set it to none, which implies silence--not even a beep!
if (tune=="") {
tune = "none";
}
//are we already logged in? No need to log in twice.
if (!curly) {
login();
}
//if we get here and we're not logged in, there is some weird problem
//I don't think this could really happen, because if there is an error, the login above will
//throw an exception, and the code below will not execute.
if (!curly) {
throw(runtime_error("Login failed!"));
}
//okay, set up the whole url for the get request
//see: https://voodoorobotics.com/constructing-a-url/
string url = base+"api/"+deviceID+"/"+opWord+"/"+line1+"/"+line2;
switch (op) {
case display:
case flash:
url += "/"+tune+"/"+to_string(time);
break;
case opStatic:
case opStatic2:
case location:
; //do nothing!
}
//if there is a transaction ID for the closed loop, then add it here
//see: https://voodoorobotics.com/closed-loop-system/
if (txnID!="") {
url += "/"+txnID;
}
CURLcode res;
res = curl_easy_setopt(curly, CURLOPT_HTTPGET, 1L); //make sure we're doing a GET, not a POST
if (res!=CURLE_OK) {
curly = NULL;
throw(runtime_error(string("CURL failed CURLOPT_HTTPGET: ")+curl_easy_strerror(res)));
}
res = curl_easy_setopt(curly, CURLOPT_URL, url.c_str()); //don't pass just url. curl_easy_setopt expects a (char *)
if (res!=CURLE_OK) {
curly = NULL;
throw(runtime_error(string("CURL failed CURLOPT_URL: ")+curl_easy_strerror(res)));
}
res = curl_easy_perform(curly); //Finally, this is where the real action takes place.
if (res!=CURLE_OK) {
curly = NULL;
throw(runtime_error(string("CURL failed get request: ")+curl_easy_strerror(res)));
}
}
void VoodooAPI::setDeviceID(const string &id)
{
deviceID = id;
}
void VoodooAPI::setOperation(const operationType ot)
{
op = ot;
}
void VoodooAPI::setDisplay(const string &l1, const string &l2)
{
line1 = l1;
line2 = l2;
}
void VoodooAPI::setTune(const string &t)
{
tune = t;
}
void VoodooAPI::setTime(short t)
{
time = t;
}
void VoodooAPI::setTransactionID(const string &txn)
{
txnID = txn;
}