Specifies an API call on our server.
Pick-to-Light QueryString URL Sections
Our Pick-to-Light technology works with your existing ERP or WMS or even Microsoft Excel. A simple URL request, sent to our server on the Amazon Cloud, causes the associated Pick-to-Light device to light up with the operator’s name, SKU and quantity to pick, barcode, QR-Code, icon – or any five lines of text!
For more powerful interfaces consider using our REST API instead of the QueryString API.
Code Samples
These code samples will help you integrate the Pick-to-Light devices with your WMS or ERP. Need a closed-loop system (to confirm picks)?
Very Simple Perl Example using LWP
# use strict; use warnings; use LWP 5.64; my $browser = LWP::UserAgent->new; $browser->cookie_jar({}); my $host = 'https://www.sku-keeper.com/'; # the host $browser->post( $host, [ 'name' => 'yourusername', # the log-in ID 'pass' => 'yourpassword', # the password for the above ID 'form_id' => 'user_login_block' ], ); $browser->get($host."api/E8D787:72D9D7/pick/hello/there/15,c5,4/10"); $browser->get($host."api/FFFE81:A42B35/pick/hello/there/15,c5,4/10"); $browser->get($host."api/FAAD4B:8E336A/pick/hello/there/15,c5,4/10"); $browser->get($host."api/FF754A:E24C16/pick/hello/there/15,c5,4/10"); $browser->get($host."api/FB9915:C956FC/pick/hello/there/15,c5,4/10");
Java Example with exceptions
File Demo.java public class Demo { public static void main(String[] args) { try { VoodooAPI v = new VoodooAPI(); //create a VoodooAPI object v.setUsernameAndPassword("yourusername","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 (IllegalArgumentException e) { System.out.println ("Illegal Argument Exception, Result = " + e); } catch (RuntimeException e) { System.out.println ("Runtime Exception, Result = " + e); } catch (Exception e) { System.out.println ("Exception, Result = " + e); } } } File VoodooAPI.java import java.util.*; import java.net.*; import java.io.*; public class VoodooAPI { enum operationType { display, flash, opStatic, opStatic2, location }; private final String base = "https://www.sku-keeper.com/"; private String username; private String password; private String deviceID; private String line1; private String line2; private operationType op = operationType.display; private String tune; private short time = 10; private String txnID; private boolean loggedIn = false; private List cookies; public void VoodooAPI() { } public void setUsernameAndPassword(final String u, final String p) { username = u; password = p; } public void login() throws Exception { //make sure there is a username and password set if (username=="") { throw(new IllegalArgumentException("Username not set")); } if (password=="") { throw(new IllegalArgumentException("Password not set")); } URLConnection connection = new URL(base).openConnection(); HttpURLConnection httpConn = (HttpURLConnection)connection; httpConn.setInstanceFollowRedirects(false); connection.setDoOutput(true); // Triggers POST. connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); String data="name="+username+"&pass="+password+"&form_id=user_login_block"; try (OutputStream output = connection.getOutputStream()) { output.write(data.getBytes()); } InputStream response = connection.getInputStream(); cookies = connection.getHeaderFields().get("Set-Cookie"); loggedIn = true; } public void execute() throws Exception { //make sure a deviceID has been set if (deviceID=="") { throw(new IllegalArgumentException("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(new IllegalArgumentException("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 (!loggedIn) { 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 (!loggedIn) { throw(new RuntimeException("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+"/"+ Integer.toString(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; } try { URLConnection connection = new URL(url).openConnection(); for (String cookie : cookies) { connection.addRequestProperty("Cookie", cookie.split(";", 2)[0]); } InputStream response = connection.getInputStream(); //response discarded in this demo! } catch(Exception e) { loggedIn = false; //if there was a problem, make sure that I'm logged out. throw e; } } public void setDeviceID(final String id) { deviceID = id; } public void setOperation(final operationType ot) { op = ot; } public void setDisplay(final String l1, final String l2) { line1 = l1; line2 = l2; } public void setTune(final String t) { tune = t; } public void setTime(final short t) { time = t; } public void setTransactionID(final String txn) { txnID = txn; } }
C++ Example using libcurl and exceptions
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.sku-keeper.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.sku-keeper.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; }
PHP Example using libcurl
function init() { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,"https://www.sku-keeper.com/api"); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_USERAGENT, 'PHP script'); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt"); curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt'); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, "name=yourname&pass=yourpassword&form_id=user_login_block"); ob_start(); // prevent any output curl_exec ($ch); // execute the curl command ob_end_clean(); // stop preventing output curl_close ($ch); unset($ch); } function lightDevice($devID,$line1,$line2,$time = 10,$flash = TRUE) { if ($flash) { $cmd = 'message'; } else { $cmd = 'pick'; } $ch = curl_init(); curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt"); curl_setopt($ch, CURLOPT_URL,"https://www.sku-keeper.com/api/$devID/$cmd/$line1/$line2/15,c5,4/$time"); $buf3 = curl_exec ($ch); curl_close ($ch); } init(); lightDevice('E8D787:72D9D7','hell','yeah'); lightDevice('FFFE81:A42B35','hell','yeah'); lightDevice('FAAD4B:8E336A','hell','yeah'); lightDevice('FF754A:E24C16','hell','yeah'); lightDevice('FB9915:C956FC','hell','yeah');
Python Example using requests
import requests session = requests.Session() def init(): postData = { 'name': 'yourusername', 'pass': 'yourpassword', 'form_id': 'user_login_block', 'op': 'Log in' } loginUrl = 'https://www.sku-keeper.com/api' response = session.post(loginUrl, data=postData) def lightDevice(devID,line1,line2): newUrl = 'https://www.sku-keeper.com/api/'+devID+'/message/'+line1+'/'+line2+'/15,c5,4/10' response = session.get(newUrl) init() lightDevice('E8D787:72D9D7','hell','yeah') lightDevice('FFFE81:A42B35','hell','yeah') lightDevice('FAAD4B:8E336A','hell','yeah') lightDevice('FF754A:E24C16','hell','yeah') lightDevice('FB9915:C956FC','hell','yeah')
Javascript Example using XMLHttpRequest
var xhr = new XMLHttpRequest(); function init() { xhr.open('POST', 'https://www.sku-keeper.com/api', false); xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhr.withCredentials = true; xhr.send('name=yourname&pass=yourpassword&form_id=user_login_block'); } function lightDevice(devID,line1,line2,time = 10,flash = TRUE) { var cmd = ''; if (flash) { cmd = 'message'; } else { cmd = 'pick'; } xhr.open('GET','https://www.sku-keeper.com/api/'+devID+'/'+cmd+'/'+line1+'/'+line2+'/15,c5,4/'+time); xhr.send(); } init(); lightDevice('E8D787:72D9D7','hell','yeah'); lightDevice('FFFE81:A42B35','hell','yeah'); lightDevice('FAAD4B:8E336A','hell','yeah'); lightDevice('FF754A:E24C16','hell','yeah'); lightDevice('FB9915:C956FC','hell','yeah');
Google App Script Example using UrlFetchApp
function init() { var formData = { 'name': 'yourname', 'pass': 'yourpassword', 'form_id': 'user_login_block', }; var options = { 'method' : 'post', 'payload' : formData, 'contentType': 'application/x-www-form-urlencoded', 'muteHttpExceptions': false, 'followRedirects':false }; var response = UrlFetchApp.fetch('https://www.sku-keeper.com/api', options); return response.getAllHeaders()['Set-Cookie']; } function lightDevice(devID,line1,line2,time,flash,cookie) { var cmd = ''; if (flash) { cmd = 'message'; } else { cmd = 'pick'; } var options = { 'muteHttpExceptions': false, 'headers': {'Cookie':cookie}, }; UrlFetchApp.fetch('https://www.sku-keeper.com/api/'+devID+'/'+cmd+'/'+line1+'/'+line2+'/15,c5,4/'+time,options); } function go() { var cookie = init(); lightDevice('D8927E:C752D3','hell','yeah',10,false,cookie); lightDevice('FFFE81:A42B35','hell','yeah',10,false,cookie); lightDevice('FAAD4B:8E336A','hell','yeah',10,false,cookie); lightDevice('FF754A:E24C16','hell','yeah',10,false,cookie); lightDevice('FB9915:C956FC','hell','yeah',10,false,cookie); }
Visual Basic for Applications Example (Excel Spreadsheets)
' For Excel be sure to enable 'Microsoft WinHTTP Services' under Tools->References Global oRequest As WinHttp.WinHttpRequest Sub Mainsheet_UpdateURL() If ([typ] = "Plain") Then tp = "pick" Else If ([typ] = "Flash") Then tp = "message" Else tp = "static" End If End If Dim tid As String tid = Application.WorksheetFunction.VLookup([LocationName], Worksheets("TagIDs").Range("A2:B9999"), 2, False) Dim tun As String tun = Application.WorksheetFunction.VLookup([Tune], Worksheets("Tunes").Range("A2:B9999"), 2, False) [Constructed_URL] = "https://www.sku-keeper.com/api/" & tid & "/" & tp & "/" & [line1] & "/" & [line2] If Not ([typ] = "Static") Then [Constructed_URL] = [Constructed_URL] & "/" & tun & "/" & CStr([theSeconds]) End If End Sub Sub Mainsheet_Change(ByVal Target As Range) Dim keycells As Range Set keycells = Range("c6:c16") If Not (Application.Intersect(keycells, Range(Target.Address)) Is Nothing) Then Call Mainsheet_UpdateURL End If 'Changes in UserName or Password resets the connection Set keycells = Range("c2:c4") If Not Application.Intersect(keycells, Range(Target.Address)) Is Nothing Then Set oRequest = Nothing End If End Sub Sub Button2_Click() 'Static oRequest As WinHttp.WinHttpRequest 'On Error GoTo Err_DoSomeJob If ([theUser] = "") Then MsgBox "Username is required!" Exit Sub End If If ([thePassword] = "") Then MsgBox "Password is required!" Exit Sub End If If ([theSeconds] = "") Then MsgBox "Please set the number of seconds!" Exit Sub End If If (oRequest Is Nothing) Then loginURL = "https://www.sku-keeper.com/user/login" nm = [theUser] ps = [thePassword] loginBody = "name=" & nm & "&pass=" & ps & "&form_id=user_login&op=Log+in" sz = Len(loginBody) Set oRequest = New WinHttp.WinHttpRequest With oRequest .Open "POST", loginURL, False .SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" .SetRequestHeader "Content-Length", CStr(sz) .Send loginBody '.WaitForResponse 'sResult = .ResponseText End With End If sUrl = [Constructed_URL] With oRequest .Open "GET", sUrl, False .SetRequestHeader "Content-Type", "application/x-www-form-urlencoded" .Send "" '.WaitForResponse 'sResult = .ResponseText End With End Sub
VBA Example modified to use VBA-Web to get through corporate firewalls
' This code does not use WinHTTP. Instead, it uses a free library called VBA-Web. ' See https://github.com/VBA-tools/VBA-Web ' Calls from this code should get through most company firewall setups. Sub SKUCall(ByVal sUrl As String) If (Client Is Nothing) Then Set Client = New WebClient Client.BaseUrl = "https://www.sku-keeper.com/" Client.EnableAutoProxy = True Client.FollowRedirects = False Dim Request As New WebRequest Request.Resource = "user/login" Request.Method = WebMethod.HttpPost Request.AddHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" Request.Format = WebFormat.FormUrlEncoded Request.RequestFormat = WebFormat.FormUrlEncoded If ([Username] = "") Or ([Password] = "") Then MsgBox ("Username or Password not set!") Set Client = Nothing End End If Request.AddBodyParameter "name", [Username] Request.AddBodyParameter "pass", [Password] Request.AddBodyParameter "form_id", "user_login" Request.AddBodyParameter "op", "Log+in" ' Make the request Dim Response As WebResponse Set Response = Client.Execute(Request) ' Handle the response If (Response.StatusCode = 200) Then MsgBox ("Login failed! Sorry. Too many bad login attempts--maybe? Wait a while and try again.") Set Client = Nothing End End If If Not (Response.StatusCode = 302) Then MsgBox ("Login failed! Sorry. Error: " & CStr(Response.StatusCode)) Set Client = Nothing End End If Set Cookies = Response.Cookies End If Dim GetRequest As New WebRequest GetRequest.Resource = Replace(sUrl, "https://www.sku-keeper.com/", "") GetRequest.Method = WebMethod.HttpGet Set GetRequest.Cookies = Cookies GetRequest.AddHeader "User-Agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)" ' Make the request Dim GetResponse As WebResponse Set GetResponse = Client.Execute(GetRequest) ' Handle the response If Not (GetResponse.StatusCode = WebStatusCode.Ok) Then MsgBox ("API call failed! Sorry. Error: " & CStr(GetResponse.StatusCode)) Set Client = Nothing End End If End Sub
C# Example using HttpWebRequest with exceptions
using System; using System.Collections.Generic; using System.Net; using System.Text; // for class Encoding using System.IO; // for StreamReader System.Net.ServicePointManager.SecurityProtocol = System.Net.ServicePointManager.SecurityProtocol Or SecurityProtocolType.Tls11 Or SecurityProtocolType.Tls12; namespace CDDDemo { public class IllegalArgumentException: Exception { public IllegalArgumentException(string message): base(message) { } } public class RuntimeException: Exception { public RuntimeException(string message): base(message) { } } class Program { static void Main(string[] args) { try { VoodooAPI v = new VoodooAPI(); //create a VoodooAPI object v.setUsernameAndPassword("yourusername","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 (IllegalArgumentException e) { Console.WriteLine("Illegal Argument Exception, Result = " + e); } catch (RuntimeException e) { Console.WriteLine("Runtime Exception, Result = " + e); } catch (Exception e) { Console.WriteLine("Exception, Result = " + e); } } } public class VoodooAPI { public enum operationType { display, flash, opStatic, opStatic2, location }; private string baseurl = "https://www.sku-keeper.com/"; private string username; private string password; private string deviceID; private string line1; private string line2; private operationType op = operationType.display; private string tune; private short time = 10; private string txnID; private bool loggedIn = false; CookieContainer cookieContainer; public VoodooAPI() { cookieContainer = new CookieContainer(); } public void setUsernameAndPassword(string u, string p) { username = u; password = p; } public void login() { //make sure there is a username and password set if (username=="") { throw(new IllegalArgumentException("Username not set")); } if (password=="") { throw(new IllegalArgumentException("Password not set")); } HttpWebRequest request = (HttpWebRequest)WebRequest.Create(baseurl); request.CookieContainer = cookieContainer; string postData="name="+username+"&pass="+password+"&form_id=user_login_block"; var data = Encoding.ASCII.GetBytes(postData); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.ContentLength = data.Length; using (var stream = request.GetRequestStream()) { stream.Write(data, 0, data.Length); } var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); response.close(); loggedIn = true; } public void execute() { //make sure a deviceID has been set if (deviceID=="") { throw(new IllegalArgumentException("DeviceID not set")); } //set up the operation string opWord; switch (op) { case operationType.display: opWord = "display"; break; case operationType.flash: opWord = "flash"; break; case operationType.opStatic: opWord = "static"; break; case operationType.opStatic2: opWord = "static2"; break; case operationType.location: opWord = "location"; break; default: throw(new IllegalArgumentException("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 (!loggedIn) { 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 (!loggedIn) { throw(new RuntimeException("Login failed!")); } //okay, set up the whole url for the get request //see: https://voodoorobotics.com/constructing-a-url/ string url = baseurl+"api/"+deviceID+"/"+opWord+"/"+line1+"/"+line2; switch (op) { case operationType.display: url += "/"+tune+"/"+ time.ToString(); break; case operationType.flash: url += "/"+tune+"/"+ time.ToString(); break; case operationType.opStatic: case operationType.opStatic2: case operationType.location: default: break; //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; } try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.CookieContainer = cookieContainer; var response = (HttpWebResponse)request.GetResponse(); var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd(); //response discarded in this demo! response.close(); } catch(Exception e) { loggedIn = false; //if there was a problem, make sure that I'm logged out. throw e; //rethrow the error } } public void setDeviceID(string id) { deviceID = id; } public void setOperation(operationType ot) { op = ot; } public void setDisplay(string l1, string l2) { line1 = l1; line2 = l2; } public void setTune(string t) { tune = t; } public void setTime(short t) { time = t; } public void setTransactionID(string txn) { txnID = txn; } } }
REST API PHP Example using libcurl
Please refer to our REST API description.
Unboxing and & Setup
Unboxing Your Order
Voodoo Robotics CEO, Trevor Blumenau, goes through each item that may be included in your order. (An update with our Modern devices is coming soon!)
Pick-to-Light Devices
Everything you ever wanted to know about batteries, (low) voltages, devices, mounting, device IDs, etc.
Check for the latest in AAA battery prices at Slickdeals.
Double-sided tape can be purchased from Home Depot.
Talk to us about other mounting options.
(An updated video with our Modern devices is coming soon!)
Turbos
Turbos connect the pick-to-light devices to the cloud. They are very easy to set up: just set your connection information and add your username and password. Turbos have a very useful GUI that does a great job helping you debug your system, check radio ranges, test communications, and see device parameters.
Using Pick-to-Light with Spreadsheets
Our Pick-to-light system is so flexible and easy to use that you don't have to integrate with a WMS/ERP - if you're a small company you can integrate with your Microsoft Excel Spreadsheets or Google Sheets. (If you're running Google Sheets, you're probably already aware that it can, at times, be much slower than Excel.)
Microsoft Excel
Just for demonstration purposes, we've constructed an Excel Spreadsheet that is tightly integrated with our Devices. Please contact us for a copy. The VBA source code is included.
We do not anticipate that customers will use this spreadsheet in their actual operations, but rather, copy and paste the VBA code into the spreadsheets they're already using.
You May Also be Interested in:
Using the QueryString or REST API is a snap for setting up locations and static information on devices. In this video, we show how you can do it from Excel.
How easy is that?!
Pickers get tired (or perhaps they're lazy!). Do they really need to push a button on a device to dismiss a pick request? The answer is, no--they can use a barcode scanner instead.
Trevor Blumenau, CEO of Voodoo Robotics, demonstrates with our Demo Excel Spreadsheet.
Constructing a Sequence of Messages
Oftentimes, pickers or other warehouse/manufacturing workers need to perform a specific sequence of steps. Perhaps they're assembling a kit, or mixing a recipe/formula.
Operations must be performed in order and only proceed when the previous operation is completed.
In this video, we demonstrate using Devices to deliver a sequence of operational messages in a particular order. The code is written in VBA and runs in our Demo Excel Spreadsheet.