The Dash Lid is the Amazon Container with a twist. It is designed to be a very low-friction device and method to use the Amazon Dash Replenishment Service.
The DashLid measures the remaining product in the container daily and requests a replenishment from Amazon if it is close to running out.
When a new shipment arrives from Amazon, the lid is simply placed on the new container.
Why Protein Powder?
Although the lid could work on many containers with a screw-type lid, protein powder makes a good use case right now because it typically takes awhile to deplete, it is easily and reliably measured, and has a higher price range than flour or sugar.
Thisr means that early adopters could find that it is worth the price of the sensor and software to acquire long-term customers.
The Customer's Point of View
The customer will use the lid in two scenarios:
1. Initial Setup
2. Recurring Use
For initial setup the customer will plug their lid into a computer, enter their WIFI credentials, and select the time to check for replenishment. The customer then runs an app that opens a web page to allow the customer to login to Amazon and select their product.
I believe that this is as easy as it can be. The device will likely need to charge before use, so plugging it into a computer has a dual purpose. The USB connection is also more secure than wireless when exchanging data with the device.
After the device is charged (on the MKR1000 the yellow light will stop flashing) it can be put on the new container.
When a new shipment arrives, the customer just moves the lid to the new container, optionally pouring in leftover product.
How it WorksThe client application is a Windows Forms application written in C# using Visual Studio. The basic operation is as follows:
- The Client presents a form for the user to fill in their WIFI SSID and Password. The user can also choose a time for the device to request replenishment. For example, at 3:00 AM the device can ping the product level and if it is below a predefined ordering level a replenishment request will be sent.
- The user is then prompted to plug in their device to charge it and set it up.
- The next step is to request the device specifications, such as Model and Serial Number.
private void GetDRSDeviceInfo()
{
MessageBox.Show("Please plug in your DashLid now.", "Plug in your DashLid.", MessageBoxButtons.OK, MessageBoxIcon.Information);
while (SerialPort.GetPortNames().Count() == 0);
string[] ports = SerialPort.GetPortNames();
string port = ports[0];
//foreach (string port in ports)
Console.WriteLine("Opening port " + port);
serialPort = new SerialPort(port, 9600, Parity.None, 8, StopBits.One);
//serialPort.PortName = port;
serialPort.Open();
string deviceInfo = serialPort.ReadLine();
System.Diagnostics.Debug.WriteLine(deviceInfo);
deviceSpecifications = Json.JsonParser.Deserialize<DeviceSpecifications>(deviceInfo);
}
- Next, using the device specs and client info stored in the client (the Windows Forms app) a URL is built to request a code grant.
private void BuildURL()
{
string scopeData = "{\"dash:replenish\":{\"device_model\":\"" + deviceSpecifications.model + "\",\"serial\":\"" + deviceSpecifications.serial + "\",\"is_test_device\":\"true\"}}";
string urlEncodedScopeData = WebUtility.UrlEncode(scopeData);
URL = "https://www.amazon.com/ap/oa?client_id=" + client_id + "&scope=dash%3Areplenish&scope_data=" + urlEncodedScopeData + "&response_type=code&redirect_uri=https%3A%2F%2Fwww.getpostman.com%2Foauth2%2Fcallback";
}
- The application then opens a browser with the URL to allow the user to login to Amazon.
private void UseWatinBrowser()
{
//Check url until the code is returned
WatiN.Core.IE ie = new WatiN.Core.IE(URL);
bool OkToContinue = true;
while (OkToContinue)
{
string currentURL = ie.Url;
System.Diagnostics.Debug.WriteLine(currentURL);
if (currentURL.Contains("code="))
{
returnURL = currentURL;
OkToContinue = false;
ie.ForceClose();
}
else
System.Threading.Thread.Sleep(1000);
}
}
- In the background the application checks for the browser URL to contain the code, which happens once every second. When the code is detected the browser closes.
private void ExtractCodeFromReturnURL()
{
//returnURL = "https://app.getpostman.com/oauth2/callback?code=cccccccooooooooodddddddeeeeee&scope=dash%3Areplenish";
int startString = returnURL.IndexOf("?code") + 6;
int endString = returnURL.IndexOf("&scope");
code = returnURL.Substring(startString, endString - startString);
//System.Diagnostics.Debug.WriteLine(code);
}
- Next the code is used to obtain the DRS Tokens.
private void ObtainDRSTokens()
{
var client = new RestClient("https://api.amazon.com/auth/o2/token");
var request = new RestRequest(Method.POST);
request.AddHeader("cache-control", "no-cache");
request.AddHeader("content-type", "application/x-www-form-urlencoded");
request.AddParameter("application/x-www-form-urlencoded", "grant_type=authorization_code&code=" + code + "&client_id=" + client_id + "&client_secret=" + client_secret + "&redirect_uri=https%3A%2F%2Fwww.getpostman.com%2Foauth2%2Fcallback", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
//System.Diagnostics.Debug.WriteLine(response.Content);
tokens = Json.JsonParser.Deserialize<Tokens>(response.Content);
}
- The tokens are sent to the DRS device through USB serial encoded as JSON.
private void SendDeviceInfo()
{
deviceData = new DeviceData();
deviceData.AccessToken = tokens.access_token;
deviceData.RefreshToken = tokens.refresh_token;
deviceData.WifiPassword = wifiPassword;
deviceData.WifiSsid = wifiSsid;
deviceData.ClientId = client_id;
deviceData.ClientSecret = client_secret;
deviceData.SlotId = slot_id;
deviceData.ReplenishHour = replenishHour;
DateTime dateTime = System.DateTime.Now;
deviceData.Year = (byte)(dateTime.Year - 2000);
deviceData.Month = (byte)dateTime.Month;
deviceData.Day = (byte)dateTime.Day;
deviceData.Hour = (byte)dateTime.Hour;
deviceData.Minute = (byte)dateTime.Minute;
deviceData.Second = (byte)dateTime.Second;
string json = Json.JsonParser.Serialize<DeviceData>(deviceData);
System.Diagnostics.Debug.WriteLine(json);
serialPort.WriteLine(json);
}
- The Arduino takes over and waits for the real-time clock to check the product level and possibly request replenishment.
- The application can optionally run after this to print out Arduino status in the Visual Studio debugging console.
private void ReadDeviceDebuggingInfo()
{
while (true)
{
if (serialPort.BytesToRead > 0)
{
System.Diagnostics.Debug.WriteLine(serialPort.ReadLine());
}
}
}
- Every 24 hours the ultrasonic sensor pings the product level. If the level is below the replenish threshold the product is ordered by the Dash Lid. The customer receives a replenishment email.
Getting Started with Dash Replenishment Service
A good place to start would be to look at the Amazon documentation here.
You will need to Create an LWA Security Profile, Create and SNS Topic, and Create your Amazon Dash Device.
For more detailed information on the process that is directly related to the AmazonDRS library used in this project, see the AmazonDRS Getting Started page.
Construction Note
Don't try to solder to LiPo batteries. You can make a simple connector out of solid wire like so:
Comments