Amazon Pricing Notifier

Made by Kami Chin, Ryan Stinebaugh and Samuel Lee

This project is an ambient device which will open a chest when an item on the user's personal wishlist goes under a target price

Created: February 15th, 2018

0

Intention:

This project is designed to display personal data in a public way. We chose to create a device that shows when something on the user's Amazon wish list goes on sale. The device uses the Amazon API to get data about the user's personal wish list and what is currently on sale at Amazon. This information is shown to the user by opening an old amazon box automatically through the use of servo motors.

0

Parts:

1. 2 Servo Motors 

2. Particle Photon

3. 7 x Jumper Cables

4.  2 x Alligator Clip Heads

5. Cardboard Box

6. String

7. Duct tape

0

Procedure Overview:

1. Modified the code found on http://diotlabs.daraghbyrne.me/6-controlling-outputs/servo/ to control 2 Servo motors. Code is listed below.

2. Created the code to access the Amazon API. Our code can be found below.

2. Used the Amazon API to alert our Particle when a target item on Amazon is on sale. 

3. Attached two Servo motors to the insides of a box using string and duct tape to automatically open the box when triggered by the Particle.

0

Process:

We considered different methods of opening a box. As illustrated below, we thought about opening the box via a "sliding door" method, drawing a curtain, or using a front flap. Ultimately, we chose to open the box using the two top flaps of the box because it was simple, easy to implement with two Servo motors, and the most noticeable state change.

0

Wiring:

Once we decided on the method in which we were going to open the box, could then start wiring the physical components into the Particle Photon. Our wiring is shown below, and requires 7  jumper cables along with the two servo motors.

0

We started making the self opening box by poking two holes for the servo motor. We then threaded the wires through for the motor making sure to leave enough slack in the line to re position the motors. We first tried mounting the servos inside on the bottom surface of the box and ran thin wire outside of the box to "pull" the box open. Our hope was that we could hide the motors with a false bottom, so it would look like a more finished produce. After struggling to get this working, we changed the design by moving the motors higher.

0

The new design placed the motors centered directly below the "hinge" of the box flaps. The motors were held in place by duct tape and string, but this can be replaced by a stronger form of joining such as glue or screws.  Since the included servo fin was not long enough to open the box entirely, we used two alligator clip heads to extend the length of the lever arm. The alligator clips sometimes fell out of place so we added duct tape to the connection point as well.

0

Code:

The code below is made to go on to the particle device, and does not need to be updated if the user wants to change the item they are tracking. The purpose of this code is to check for an update in the particle cloud for a push from the Amazon API code and to tell the two servo motors to open and disengage after a set amount of time.

0
Code below controls the servo motors hooked up to the Particle Photon. Pins D0 and D1 are used for the 2 servo motors.
// Code for particle servo control

/*
 * Project Ambient
 * Description: Detects amazon price changes and opens a treasure box
 * Author: Samuel Lee, Ryan Stinebaugh, Kami Chin
 * Date:
 */

int servo_pin_1 = D0;
int servo_pin_2 = D1 ;
int device_on = HIGH ;
int box_open = 0 ; //should be closed in natural state
Servo myServo1 ;
Servo myServo2 ;


//function will be exposed to cloud. args not used
//called when wave is to be performed
int servoWave(String args) {
  //perform wave
  if(device_on == LOW) {
    return 0 ;
  }
  const int leftAngle = 0 ;
  const int rightAngle = 100 ;
  const int delayPeriod = 500 ;
  int numWaves = 4 ;
  for(int w =0; w < numWaves ; w++) {
    if(w%2) {
      //odd iteration
      myServo1.write(leftAngle)  ;
    }
    else {
      myServo1.write(rightAngle) ;
    }
    delay(delayPeriod) ;
  }
  //reset position
  myServo1.write(leftAngle) ;
  delay(delayPeriod) ;
  return 1;
}

//called asynchronously
int servoOpenBox(String args) {
  if(device_on == LOW || box_open) {
    return 0 ;
  }
  const int closedAngle = 0 ;
  const int openAngle = 100 ;
  const int delayPeriod = 3000 ;
  //assumes closed
  myServo1.write(openAngle) ;
  myServo2.write(openAngle) ;
  box_open = 1 ; //signal box is open
  delay(delayPeriod) ;
  //reset position
  myServo1.write(closedAngle) ;
  myServo2.write(closedAngle) ;
  box_open = 0 ; //closed box
  return 1;

}


// setup() runs once, when the device is first turned on.
void setup() {
  // Put initialization like pinMode and begin functions here.
  myServo1.attach(servo_pin_1);
  myServo2.attach(servo_pin_2);
  //ensure it's at 0 position
  myServo1.write(0) ;
  myServo2.write(0) ;
  //test servo
  myServo1.write(100) ;
  myServo2.write(100) ;
  delay(500) ;
  myServo1.write(0) ;
  myServo2.write(0) ;
  Particle.function("servoWave", servoWave) ;
  Particle.function("servoOpenBox", servoOpenBox) ;

}

//main logic controlled by external server
void loop() {
  //TODO add logic to change device_on based on digital input
}
Click to Expand
0

This code works with the Amazon API to track a desired item on their website. A target price is set by the user to determine when they would like to be notified, and once that threshold is passed, a notification is sent through the particle cloud to tell the designated particle device to run the function to open the motors

0
The code below is used for accessing the amazon API and is written in python. In order for it to work, the user must have an amazon_associates product advertising account and the corresponding access tokens for it. Also the following package is required. Details for installation are in the link provided: - python-amazon-simple-product-api 2.2.11 (https://pypi.python.org/pypi/python-amazon-simple-product-api)
from amazon.api import AmazonAPI
import time,  threading
import requests

access_key = "YOUR AMAZON PRODUCT ADVERTISING ACCESS KEY" 
secret_key = "YOUR AMAZON PRODUCT ADVERTISING SECRET KEY" 
associate_id = "YOUR AMAZON PRODUCT ADVERTISING ASSOCIATE ID"
amazon = AmazonAPI(access_key, secret_key, associate_id, region="US")

device_id = "YOUR PARTICLE DEVICE ID"
particle_access_token = "YOUR PARTICLE ACCESS TOKEN"
check_freq = 60 # in seconds
item_id = 'AMAZON PRODUCT ID FOR DESIRED PRODUCT TO PURCHASE'
item_price = 59.99 # set this to the current market price for the item 
target_price = 47.99 # set this to desired purchase price



def servoOpenBox():
	global device_id, particle_access_token
	url = "https://api.particle.io/v1/devices/{}/{}".format(device_id, "servoOpenBox")
	res = requests.post(url, data={"arg":"", "access_token":particle_access_token})
	if res.status_code != requests.codes.ok:
		print "Bad POST request. Error {}".format(res.status_code)
	else:
		# print  "Good Request"
		print ""  


def alertPriceDrop():
	if item_price <= target_price:
		# servoWave()
		print "Price Dropped Target = {} Current = {}".format(target_price, item_price)
		servoOpenBox()

def update_price():
	global check_freq, item_price, item_id, amazon
	print time.ctime()
	item = amazon.lookup(ItemId=item_id)
	item_price = float(item.price_and_currency[0])
	alertPriceDrop()


# for simulation purposes
def simulate_update_price():
	global item_price, target_price
	# simulate_check_freq = 10 #in seconds
	high_price = 59.99
	low_price = target_price
	if item_price <= low_price:
		item_price = high_price
	else:
		item_price = low_price
	alertPriceDrop() 
	# threading.Timer(simulate_check_freq, simulate_update_price).start()


class UpdateThread(threading.Thread):
	def __init__(self, update_func, period):
		threading.Thread.__init__(self)
		self.update = update_func
		self.period = period
		self.event = threading.Event()

	def stop(self):
		self.event.set()

	def run(self):
		while not self.event.wait(self.period):
			self.update()


def setup():
	global amazon, item_id
	item = amazon.lookup(ItemId=item_id)
	# print "{}".format("abc")
	print "Name = {}, price = {}".format(item.title, item.price_and_currency)
	item_price = float(item.price_and_currency[0])
	print item_price


def run():
	setup()
	updateThread = UpdateThread(update_price, check_freq)
	updateThread.start()
	while 1:
		cmd = raw_input()
		if cmd == "stop":
			print "stopping..."
			updateThread.stop()
			break
	return




if __name__ == "__main__":
	run()
Click to Expand
0

Product video:

0
Amazon price notifier - ambient projet
Kami Chin - https://youtu.be/yu2M1QjEIj4
0

Future Concept Ideas:

If we were to make this concept into a product fit for market, we would need to add a way for the user know which item on their list was on sale. This could be done through a inside of the box, so the user would have to look inside to get the information. Currently our prototype follows one product, which is defined by putting the amazon item number in the code that accesses the Amazon API. We would also need to simplify this experience for the user, and one way this could be done is through a mobile application or even creating an IFTTT widget for what we produced through our code. I think we also would want to redesign the box so that the motors are hidden. This could be done through adding an inner box where the motor could sit in between the layers. This would also protect the motor from being broken when the user is reaching inside the box.

x
Share this Project

Courses

49313 Designing for the Internet of Things (Undergrad)

· 22 members

A hands-on introductory course exploring the Internet of Things and connected product experiences.


About

This project is an ambient device which will open a chest when an item on the user's personal wishlist goes under a target price