Thursday 23 February 2017

Arduino Uno Light switch

Update: I have since built the $16 nRF24 wireless serial controlled light switch and the ESP8266 based WiFi to nRF24 bridge.  Please see the above links for project write-up.

I made a serially controlled light switch by combining a $3 servo, a $4 Arduino Uno and an old laptop...
I used some mounting tape and hot glue to keep the servo on the switch plate, and the servo stays in neutral position when not activated so the light switch (decora style) can be operated by hand for ease of use.

I've got a Wi-Fi shield on the way and I plan on getting rid of the laptop and will probably re-write the sketch at that point... Stay Tuned for more details and pictures!!

Raspberry Pi Water Sensor



Since I'm already using my Raspberry Pi as a radius and Amazon button server I figured I may as well start learning some hardware hacking and I've had water in the basement before so I want to know about it before it happens again...

I already had a 4 conductor wire running from my automation area to my utility room for a previously failed washing machine detector project (replaced with a Wemo Insight now fully functional)

I made 3 detection areas, 1 for fun and 2 practical...

One right under the hot water tank, one on the floor and right behind the washing machine and one inside the drain of the washing machine.

For the hot water tank I took 2 pieces of wire and stripped them bare and ran them along the under side of the tank spaced fairly close together but not touching... On either end I put in a few conductive wood screws and wrapped the wire around the threads.

I did the same thing near the floor and behind the washing machine, I had multiple wire/contacts on a single sensor so if either one gets wet it will trip the system.

The final one is a pair of bare wires going down the drain, this can tell me when the washing machine is draining in it's cycle and confirm the whole thing is still working.

On the Pi, I connected GPIO 23, 24 and 25 and a common ground which one of each of the wire pairs was connected to and tied together with a wire nut.

I then wrote a little python script that would periodically poll those GPIOs and send me an alert if one went low (was using internal pull up) or switched states for more than 10 seconds (this would stop it from toggling back and forth as it dried out, and stop nuisance alerts)

This was a super easy project and a great start to working directly with hardware...

RDING Temper in Python on Windows



I got this device for a few bucks on eBay:
http://www.ebay.ca/itm/USB-Thermometer-Sensor-Temperature-Data-Logger-Tester-For-PC-Laptop-Mac-Computer-/272558575206?hash=item3f75c1ce66:g:gugAAOxy8QZST4PN

And it seems to work decently... It came with really awful windows software and the only real way to get data from it (short of using the HID keyboard typing excel) was to get their pretty awful software to write out a CSV every second and then compile and delete the data files it made... The software would also do weird things, crash, and leave weird dialogs on the screen...  I built a program to deal with most of these issues until I had a chance to get the data from USB properly.

I found info on using pywinusb.hid to grab info from HID devices and I also found this module which did not seem to work... I think it's meant for Linux, I did not troubleshoot it very much..

As I was playing with the pywinusb raw example I found out that it was able to get temperature readings while the temper application was running, so I decided to see if I could make this work, and I did...

Here is the code if anyone wants to read the temperature from your module.

This is my first time doing any direct USB stuff so it may not be perfect, but it seems to work... If you have any suggestions leave them in the comments.

======================= temper.py ===========================
#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
"""
Handling raw data inputs example
"""
from time import sleep
from msvcrt import kbhit

import pywinusb.hid as hid

def sample_handler(data):
    # For debugging purposes or getting data from other sensors
    #print("Raw data: {0}".format(data))
    temp = str(data).split(',')
    temp = int(temp[3]) + int(temp[4])/256.0
    temperature = round(temp,2)
    print temperature
    # You can put your own code here to do whatever you want with the temp readings!



def raw_test():
    # locate the proper device based on it's Vendor and Product ID
    temper = hid.HidDeviceFilter(vendor_id = 0x0c45, product_id = 0x7401).get_devices()
 
    # Only continue if the device is found, otherwise return an error below
    if temper:
        while True:
        device = temper[0]
        try:
            device.open()
            #Setup the callback for when data comes in from the device
            device.set_raw_data_handler(sample_handler)
            # Keep going at this main loop until the device is unplugged
            while device.is_plugged():
                # Keep device open and rx new events...
                # We have to make a request for the temperature from the device
                report = device.find_output_reports()[ 0 ]
                # This is the command to request temperature
                report[ 0xff000001 ].value = 0x01,0x80,0x33,0x01,0x00,0x00,0x00,0x00
                # Send the command
                report.send()

                # Wait this long between requests... You can make this shorter or longer based on your needs
                sleep(1)
            return
        finally:
            # close the device if it's been removed
            device.close()
    else:
        # The device wasn't found, return an error and exit
        print("Can't find a Temper device")
#
if __name__ == '__main__':
    # first be kind with local encodings
    import sys
    if sys.version_info >= (3,):
        # as is, don't handle unicodes
        unicode = str
        raw_input = input
    else:
        # allow to show encoded strings
        import codecs
        sys.stdout = codecs.getwriter('mbcs')(sys.stdout)
# Start the main loop/listener
raw_test()
=================================== SNIP ==================

Dash Button Update (How to change the battery)


Well it finally happened! After only about a month my Dash battery died!  I got the red light of death!!

Since I can't get these easily or cheaply since I don't live in a dash "friendly" area I decided to see if I can put new batteries in...

I took my utility knife in it's shortest blade form as to not touch the board inside and cut and pushed along the seam, after a little cutting it was clear it had broken free enough to put my blade under it and wedge it up.  The bottom popped off cleanly! Yay!

The second one did not come apart as nicely, but it eventually yielded and I was able to get at the battery without damaging the unit.

I removed an replaced the AAA battery and now I'm getting a red error light like it's not registered....
I ran the Amazon app and got it to go through registration (even with my prime subscription over) it still worked just fine, except it would fail at registering.. Then I remembered I had it blocked from the internet, so I removed that temporarily so it could talk to Amazon's server and, bam It's back to normal again!!  I can even almost get the case to "snap" shut, though it will never be perfect again..

UPDATE: I had to change the batteries again and go through setup again... I was trying ot figure out how to do this without having to re-configure the WiFi settings and it turns out you can pull and replace the battery without it loosing anything.  The problem seems to arise when the device boots in a low battery condition and you get the "red light of death" instead of the happy white light.  I started logging clicks so I can tell approximately how many I get from a battery and I will add a low battery message to tell me to check the battery before it goes dead.

Things to note:
- WiFi settings seem to be on battery backed ram, not fash.. If you want to keep your WiFi settings keep the juice flowing while you change the battery, otherwise prepare to go through setup again
- Make sure you change the batteries before you get the read light of death or your settings will be erased
- Opening the case is less difficult that I thought it would be, just be careful as there are bits and bobs around the edges, don't go too deep
- The top half with the button is mounted to the PCB with screws I believe, the bottom is just a big empty shell and they will separate as the score line (where the clip attaches)
- The clip will probably never work again after you open it and you will need to tape it back together, it doesn't snap back together in any meaningful way.

Amazon Dash Button Hacking


If you are in the US or UK  (Amazon hates Canada) and you have an Amazon Prime account you can buy these Dash buttons for $5 each (I've heard they go on sale for even cheaper too)  and if you buy one that has a product you actually want they will credit your account $5 on your first order.

If you know someone in the USA or have a reshipping address you should be able to get one anywhere in the world though.

First thing to know is there are two generations of this button...

The old generation had no site survey and the internal web server would allow you to setup the button via a laptop or phone, the new button requires the Amazon Shopping App until someone figures out the setup process. I believe they also changed some SSL stuff.

If you want to see the tear-downs and detailed write ups on these buttons visit Matthew Petroff's sites below.

Original buttons:
https://mpetroff.net/2015/05/amazon-dash-button-teardown/
Newest Rev:
https://mpetroff.net/2016/07/new-amazon-dash-button-teardown-jk29lp

I will be talking about the second revision as this is the one I have.

By holding the button down for 6 seconds it will go into setup mode... It will broadcast a WiFi network "Amazon ConfigureMe" and it will also be discoverable via Bluetooth.

If you connect to the WiFi it will give you an IP in the 192.168.0.1/24 subnet and the button will be 192.168.0.1.  You can go to it's webpage to view model, firmware and battery status.

There is not currently a manual setup procedure.

It uses a single AAA battery but the case is sealed so you will need to cut it open to change the battery.

To setup the WiFi network:
1) Download and install the Amazon Shopping App.
2) Select the menu and select "Settings" with your countries Flag
3) Select Country & Language
4) Set your country to United States or United Kingdom (supported areas)
5) Hit Done
6) Hit the menu button and select "My Account"
7) Scroll down (it's a couple screens down) You should see Dash Devices
8)  Choose Setup New Device
9) Follow instructions to enter your WiFi settings
10) When it gets to the point where it says select your product you can exit out of the process so your button won't order anything

At this point your Dash should have got an address from DHCP so check your leases, you can then decide if you want it online or not... If you don't block it at the router*  If it has internet access it may get firmware updates and other nasty things from Amazon so there may be good reason not to let it online.

* If you have a higher end router that lets you do DNAT, you should DNAT the device to a HTTPS server somewhere on the internet, it will realize the cert doesn't match and go back to sleep within seconds... If it's packets are just dropped or it's sent to a closed port it will spend about 20 seconds trying to make DNS, DHCP and HTTPS requests before giving up killing the battery faster.

The unit stays in a deep sleep until the button is pushed... It takes about 3 seconds between the time you push the button for the device to wake up, connect to WiFi and send several (for some reason) DHCP requests.    This device would not be ideal for realtime requests (like a light switch) where you expect instant gratification.

Here are the approximate times for press detection based on the detection method:
DNAT to a remote web server:                ~10 seconds
ARP for gateway:                                      ~8 seconds
DHCP broadcast:                                     ~3 seconds

Keep in mind none of these methods care what the button has to say, it just detects the fact that it's coming online, it really only does one thing anway so there's no need to get into the nitty gritty of it's protocol... Either it's there (been pushed within the last few seconds) or it's not.

DNAT can be setup on a high end router based on the MAC or IP address of the device in question.  You then just need a script that can accept a connection on a port and then do whatever action you want when that button is pressed.  This is the slowest and would require a different port/server for each button you own.

ARP has been used by a lot of button hackers online... There is a simple scapy script that will detect the buttons ARP request.  You get the MAC of the button in this request so you only need the one script which can uniquely identify each button and run commands based on that.  This is pretty quick but not the fastest way as the button sends 3-4 DHCP requests before looking for the gateway.

DHCP sniffing is the fastest way you can trigger an event off the button.  I have written a simple python script that takes stdin from tcpdump and looks for the MAC of the buttons and then runs a command when it sees the first one.   The request is noted within 3 seconds of hitting the button... This is as fast as you will be able to get with this tech as it takes a while to wake up and connect to WiFi.

All these methods will generate mutliple requests per press so you should ignore anything but the first press within about 5-10 seconds. This will stop it from sending multiple commands.

I have this simple script running on my Rasberry Pi:

*************************************************************

import urllib2,time,sys

# Watches DHCP requests via TCPdump and looks for Amazon buttons
# Will call automation server via HTTPs to call actions.

# Run with the following command:
# nohup tcpdump port 67 or port 68 -e -n -l | python button.py &
#
# nohup keeps it running after you log out
# port 67 or 68 is to filter for DHCP traffic
# -e Prints the link-level header on each dump line
# -n Doesn't attempt to resolve DNS names
# -l Make stdout line buffered for piping it to this script
# python button.py ME!
# & Run in the background

# Allows button to be pressed right after script starts
timeout = time.time()-15
# Downside is using the same timeout for all buttons is that only 1 press of any button can happen in a 10 second period.
# You can add a timeout for each button if you feel the need.


while 1:
    # Read data from tcpdump via stdin
    name = sys.stdin.readline()

    # One block for each button. Change the ac:63 mac to your buttons MAC
    # ff:ff:ff etc is broadcast, leave this part alone.
    if name.find('ac:63:be:xx:xx:xx > ff:ff:ff:ff:ff:ff') != -1:
        # Button 1
 
        # Enforce minimum 10 second delay between pushes so this doesn't activate more than once
        if time.time() > timeout+10:
        # In my case make a web request to my automation server
            req = urllibequest('https://www.myserver.com/buttons/button1.py')
            response = urllib2.urlopen(req)

            # Update the last pressed time
            timeout = time.time()

*********************************************************

Put the above script in a file called button.py, update the MAC address to match your button (and copy the if block multiple times if you want more than 1 button) and finally alter the web request to either your server, or you can have the script run your code directly for quicker response.

Then start it up with the following command:
nohup tcpdump port 67 or port 68 -e -n -l | python button.py &

It's either going to have to run as root or you will need to give a non-root user access to tcpdump.  Since the script is so simple I don't think there's really any possibility to exploit it as it stands.  If anyone sees a problem please let me know in the comments.

The sticky stuff on the back is basically useless. Mine fell off the wall after 15 minutes.  I used some mounting tape to hold it up.  It also comes with a removable hook you can hang it from.

If you want to spend a LOT more money there are other buttons out there that will probably preform much better.  I am also looking at getting a CHIP (like the Pi Zero but with WiFi) and wiring in a bunch of buttons to that for a future project...

It seems most of the hacker community has moved on from these things, so getting any more info on writing new firmware, or adding new features or setting up without the app is unlikely to come.

TL;DR
- Cheap and maybe even free (if you live in the USA or UK and already have Prime)
- Easy to setup via the Amazon App
- MINIMUM of 3 seconds between push and detection so not great for real time applications
- Single use, you can't detect multiple presses within a wake cycle long presses or anything else
- You will have to wreck it to change the battery, it's sealed shut. However It does take a regular AAA if you get in.
- Battery may die quickly if you press it a couple times a day...
- Can also order you cat food while turning your lights on and off :P
- Sticky stuff on the back is useless


Home Automation On A Budget

I've been on a multi-year journey to get the best bang for my buck and build a home automation, security and entertainment system.

Each piece of hardware has a specific Python module that takes care of it, and there is a large main web module that allows user interaction with the system as a whole.

The idea was to spend as little as possible on each item so there will be ups and downs to each item and you will either needs to build your own controller software or have a very flexible HA controller that allows custom modules to use all this stuff within your own system.

I will start by writing up a list and a review of each piece of hardware I use in my system.

Filtrite 3M-50:
This is a rebadged RadioThermostat  CT50 and often sold for much less.
This was the first thing I got and probably one of the most useful.

Pros:
- Low cost  $80-100 USD
- Large backlit touch screen (black and white)
- Supports multi stage systems
- Connects directly to 2.4 GHZ WiFi networks via included U-Plug module
- Easy to use free app that gives detailed stats and talks directly with thermostat
- Works like a normal thermostat locally
- Well documented local API

Cons:
- No local web interface (just a page to change the wifi settings)
- Can be a little slow to respond
- Uses Ad-Hoc network for initial setup
- Requires a "C" wire to work at all
- Asks for battereis yearly but you don't need them
- No local security

The 3M-50 is a pretty nice thermostat.   Most functions can be controlled via the touch screen, the worst part is the mode and fan physical buttons on the side look and feel the same so you need to remember which is which.  Other than that the interface is very straight forward and feature rich... It supports most heating and cooling systems* including multi-stage systems and heat pumps.  It also has settings for swing and other things most people don't need.   It also has 2 stages of local locking where you can lock out advanced and setup modes but allow local adjusting of temperature or you can lock all the controls on the thermostat and manage it only via WiFi.
Schedule programming locally is a little non-intuitive as it is with most thermostats with a fixed display, however I have never had to use it since they provide such a nice user interface via the app or website.

* Many systems don't have a "C" or common wire which is needed to power up the U-Plug module.   The thermostat part will work on batteries, but the WiFi will not.  Make sure you have or can run a common wire before buying this unit!  Also since this unit is generally "wall powered" via your furnace, it will run fine even without batteries.

The U-Plug module is a little cartridge that plugs into the side of the thermostat.  This is basically a WiFi radio and a microcontroller that can talk to the thermostat over some kind of serial interface.  (They also make ZWave U-Plug modules).   Without the U-Plug module the thermostat is just a standard touch screen thermostat with an extra connector.

Initial setup of the U-Plug module can be tricky as it requires a device that can connect to an Ad-Hoc WiFi network.   My Windows 10 laptop nor my smartphone would do this, I use an old Windows XP laptop to set it up, however once it's setup you can access it's web interface to change any WiFi and LAN settings.   Beyond that there is no other controls in the web interface and it's pretty slow to respond.

The API is JSON based via it's web server but it's API only so don't expect to go to it's IP to do anything. That being said the iPhone and Android app is very nice and they even have a web based interface on the radiothermostat website.  You can change modes, settings, temperatures, build your 7 day, 4 period schedules (one for heat one for cool), view current temperature and status, view hourly and daily graphs of runtime, and set low and high temp alerts though these two options.   The app when connected to the same network as the thermostat will communicate with it directly via API calls and when you are away from it, it will communicate via the cloud albeit with a 5 minute delay between check-ins.

The API is very easy to find online and pretty easy to implement if you need to write your own code.

AlarmDecoder (Formerly known as AD2USB):
This unit was the only one of it's kind when I got it, it allowed users to integrate their home security system with their automation system generate alerts and remotely control it.  This is now avail as a service through your monitoring provider if you want to pay a monthly fee but that will not integrate with your automation system.

This will work with a Honeywell Vista or DSC Power series panel, however I think the Eyezon Envisalink-4 which is only about $20 more is a better option as it is self contained and does not require a PC.

Pros:
- Small and easy to wire (as simple as adding a keypad)
- Well documented by manufacturer (this is a developers product)
- Acts as a USB serial port and starts giving data as soon as you connect it
- Can act as virtual zones and trigger events on your physical system
- Will show all RF events if you have a receiver even if they aren't programmed in your panel (sniffer mode)
- No monthly fees

Cons:
- You need something that can talk USB to use it
- User interface software provided is sketchy at best
- Third party product not supported by manufacturer of panel
- You will need your installer code and the know-how to program your system somewhat

I've found this unit to be a very useful and reliable addition to my system.   It allows me to get notices when sensors are triggered, send commands to my system when I am away from home and even have automation events triggered via my key fobs.

This unit was built for developers so there is a forum to ask questions and a full API on their website.

It hooks up with 4 wires from your panel and is configured the same way a keypad is configured. If you have a GSM or network communicator already it can sniff communications with your central station and if you don't it will emulate one so it can get detailed event messages.

It starts dumping raw data to the COM port (every few seconds a specific status string is dumped) and events such as relays, RF and communicator events are sent with a special prefix as they happen.  Numbers typed are sent as keypresses and there are special characters you can use to send messages for virtual zones.

The developer offers a local keypad emulator program that you can download that will show your alarm events and allow you to press keys but it's fairly simplistic and I have never used it.

The Envisalink-4 (about $120 USD) is a better option however as it can go inside your panel, connect directly to your LAN and has a built in web server.. They also have a user friendly, free portal interface at eyezon.com that allows you to get alerts and control your system remotely and they even have an option to pay a few bucks a month to have your system professionally monitored.  It also has a local API built in so you can write your own code.

X10:
I have been slowly phasing this stuff out as it's not reliable across phases (I don't have a coupler) it's one way, sometimes randomly turns on or off and there are way better things out there.

At the moment I only have a single X10 wall switch left and a CM-11a serial and a USB RF interface as well as a few RF transceivers around the house.

Pros:
- Can be bought wholesale super cheaply ($3 - $8 USD per device)
- May be the cheapest option for "lick and stick" switches and motion detectors
- Decently documented API online for PC interfaces

Cons:
- Does not pass phases very well (some plugs will not work)
- 99% of devices are one way so you can't confirm if they turned on/off
- Can be unreliable and can switch from noise on the line
- Software is abysmal
- Slowwwwww
- No security

The only hardwired device I still have is a bathroom wall switch which allows me to use a stick a switch inside the bathroom to control the lights as well as an X10 motion detector to turn the lights on/off during the evening.  I also have a few RF transceivers around the house since the RF range isn't that great.

I have many stick a switch units and palm pad controllers around my house to remote control my automation system, I also have several eagle eye motion sensors to tell where people are and where they are going in combination with my home alarm systems motion and door sensors.

Most similar solutions are way too expensive so I will probably be using the RF part for many years to come.

I don't recommend X10 modules or switches for most applications unless you need to control a ton of things and have a very tight budget.  If you are looking to control just 1 or 2 plugs and a bunch of lights there are better options for a little more money.

The serial PC interface can take up for 5 seonds to process and respond to a command so if you are looking for instant response this may not be a good option for you. (The newer USB interface is much faster at around 1 second but it's an RF device so it has to be within RF range of your RF devices)

Wemo:
These devices made by Belkin are pretty handy and can be extremely reliable.  There are a ton of these type devices on the market but I only own the Wemos.

They cost about $35 USD and come in many different types.  You can even find some appliances with built in Wemo controllers.

Pros:
- Fast response
- Full load supported (120v @ 15a)
- Local interface (button and light)
- Free app with remote access (if you want it)
- Two way so you can poll device state
- Expandable: power monitors, motion detectors, etc.
- Built in schedule system
- ITTT support

Cons:
- Relatively expensive
- You need a smartphone to use it (app)
- API is not well documented
- Range isn't great
- 2.4 Ghz only, no Ethernet jack
- No local security

I currently own a Wemo Switch, two Insight Switches and a Wemo Light Switch.  The switch plugs into a socket and you can plug a device into it, the light switch is hard wired and replaces an existing switch to make it into a smart switch. The insight switches work just like the Switch but have power monitoring, more on this later.

You can long press the light switch to trigger another Wemo device if you so choose in the latest firmware.

The app is OK, it can be a little slow and clunky but it does what it says on the tin.    The devices switch almost instantly when a command is sent, and when you turn the device on locally the app will almost instantly show that it's been powered on or off.

New devices broadcast an open SSID which you connect to and then open the app which walks you through naming and giving your network settings after which the device will connect and show up in your app.   You can choose to enable remote control which sets up a connection to Belkin's cloud so you can control it away from home.  The devices DO broadcast an open hidden network but Belkin support says you cannot connect to this network while it's associated with your network.. My testing has shown this to be true.

I believe the API is SOAP based, I have a python module calle Ouimeaux that allows me to control it via software but I have had issues with modules disappearing or being not reachable, though I think I have fixed that (see my Wemo offline post).

I can't seem to find any documented API for setting up a new device without the app and the few details for switching and reading status out there are out there are pretty sketchy, inside code and scattered around at best.

I may eventually document the whole API but it's pretty low on my priority list.

Update: The Insight switches are pretty neat.  They are about half the size of the standard Wemo Switch, and the whole top of the device is touch sensitive (there is no physical button).   The app adds a new pull down for the device and new options.  The pulldown will show the current power usage in Watt Minutes, as well as average usage, it also shows the run time for the day (reset at midnight), and and approximate daily and monthly cost.  It will also show if the device is ON, in Standby.

You program the minimum current for ON so you can tell if your TV for example is switched off but in standby or actually powered on.  The default is a few watts.  You can also program your current electric rate and it will give you more accurate cost calculations.

The Ouemeaux module supports polling all this data directly from the switch so you can find out exactly how much power something is drawing in milliwatt minutes. Current run/standby time, last run/standby time, etc.

Connected by TCP:
This is a connected lighting system that USED to be made by a relatively large Technical Consumer Products bulb producer.
They decided to completely scrap the Connected line after some internal changes.
This means if you can find the bulbs in store they are likely being sold off for a few dollars and you can still buy whole kits online for less than the cost of a single Hue bulb.

Make sure you have spare bulbs because they could become hard to find in a few years.

Pros:
- One of the cheapest connected bulb systems just got cheaper
- Two way, control dimming and power states
- Different form factor of bulbs including CFL and LED in different shape and socket types
- 800 lumen (60w equiv) are the most common bulb
- Supports use of internet gateway or RF remote control or both
- Fully documented API by me
- Mfgr and 3rd party apps work with system
- Had a nice web interface ***
- High local security on newest firmware
- Bulbs form mesh network for extended range
- Can act like a normal light bulb
- Other companies are selling gateways that will support these bulbs
- Timers and scenes
- Many bulb support 200+

Cons:
- Not made anymore could be hard to find
- Nice local interface has been removed in latest firmware
- Range can suck depending on layout and number of bulbs
- No WiFi on the gateway, it has to plug into your router or switch (or get a WiFi bridge)
- Jennet-IP isn't a popular protocol (so it won't work with a z-wave controller or anything)
- Cloud service discontinued, but other companies are picking up the slack


This system is pretty nice for the money.  If you read the Pros and Cons you'll notice a lot of contraditions, let me cover those first.

The oldest firmware had a very nice insecure http interface with pretty pictures and Javascript and animations and all by browsing to the devices IP... It also had an SSH server with a root password of thinkgreen.   The API did not check tokens and everyone was happy.

Then they decided they wanted to be super secure so they shut down the SSH server, killed off the HTTP server, switched to HTTPs, started checking tokens and required that you press the button on the device to actually get a token.  In my case this update completely broke their app and I have had to work around it.   That left me with few options for controlling it, so I just fixed my code to use the new token system and have since made their app work again.

The other thing is range... I have found the gateway needs to be pretty close to the bulbs you are using... They will form a mesh network so if you have a bunch of bulbs they will pass messages to each other but they have to all be powered on (not lit up though).   This means you can technically have unlimited range but you need a bunch of relay stations between the gateway and the final bulb.

You can poll in real-time the state of each bulb and what brightness level it's at, if it's powered on and reachable by the gateway and a whole pile of other useful data.  You can also setup groups of bulbs into a virtual fixture and put different bulbs and fixtures into up to 10 different "rooms"

You can also build timers and scenes which can be accessed with the push of a button.

There are other manufacturers which are picking up the slack in the software department left when TCPi decided to leave the connected market so you aren't SOL if you buy this system or already own it and still want cloud and product support and these devices are multi protocol hubs so you can add other smart bulbs and devices by adding them.

If you can find old stock at Home Depot you can get 70-90% off the original prices!

These devices also will come on at full brightness after a power off (min 1.5 seconds) so you can use them as a regular light bulb too if you don't always want to use the app.  Just keep in mind if you switch the power off you can't control them anymore.

I have documented the full API of the TCP gateway in another post here for anyone looking to develop software of an interface for these devices.

MiLight:
This is another connected bulb system but it's a cheap Chinese system.  The main advantage is they have mutli-color bulbs similar to the Hue system but a whole kit costing much less than a Hue bulb.

Pros:
- Very cheap
- WiFi only gateway (2.4ghz)
- No web interface except for setup
- Many 3rd party apps are better than OEM
- Decent range
- Has local security on the configuration interface
- Supports stand alone remote
- Works as a normal light bulb
- Virtually limitless sized bulb groups

Cons:
- RGB bulbs are only at full brightness in "white" mode
- RGB is stepped, can't produce any color
- No local security for controlling the bulbs
- Limited number of separate bulbs (4 groups of 1 or more bulb [x2 - One RGB, One White] Max 8 groups per gateway)
- One way communication
- No cloud service
- API isn't well documented but there are python modules out there that work
- WiFi Only (2.4 Ghz).

This system is great if you want to feel like you have a Hue system but also want to feel like your wallet isn't empty.  I paid around $40 USD for a WiFi gateway and an RGB bulb.  I also got a Warm White/Daylight bulb for another $8.

All the bulbs are dimable via the software and they all do at least 2 colors.  The WW/D does a yelowish warm white at full brightness and a blueish daylight color at full brightness and can be switched, dimmed and turned on and off via the app.

The RGB can be set to a soft white or any of 16 or so colors, it also has many "effect" modes such as disco where it flashes on and off in different colors and rainbow where it slowly fades between colors.  There is a slider within the app that you can move along a color gradient but it's much more stepped as opposed to fluidly switching between the colors... There is one color of red and one color of orange, etc.

Soft white will be at the full brightness you purchased, however when you switch to a color mode you loose about 1/3 of the brightness... I'd say the 65w equiv bulb is about 40w equiv in RGB mode but don't quote me on this I haven't measured.

You can dim from anywhere to 100% to 0% as well as turn the bulb on or off.  They also have a super low brightness mode called night light.

The app allows you to select your gateway (if you have more than one) and then it gives you a choce of about 6 different remote control styles.  These aren't labeled and are a little hard to understand.  You also will note the color the non color remotes will only work with color and non color bulbs.. ie you can't use a color remote with a white bulb.

Each remote has 4 buttons to select the group of bulbs you want to control... When you add a bulb the gateway programs the bulb with it's group number and the gateway's ID. This means you can have an unlimited number of bulbs per group since the bulbs aren't aware of each other, nor is the gateway aware of each individual bulb.

You are however limited to a max of 4 single RGB bulbs and 4 single white bulbs per controller.

Since these are one way you can't confirm they switched on or off or accepted the color change command so if that's important to you avoid these.   For the most part I have never had a problem with these doing as they were told since the devices are never switched off and are within range of the gateway.

I don't have the API for this but I found a python module that lets me do all the functions the app can.  I did not look into it further.

Generic USB Relay Board:
I have a ceiling fan with a factory remote that controls the fan speed and light... I got a 8 port USB relay board and wired the remote into it so I could control my fan and lights... This is more of a project than a off the shelf product however.


That's it for now... I'll add more another time.

Connected by TCP API (The Lightbulbs made by TCPI)


TCPi is no longer making their app or their devices and the cloud service is dead so this means you can get it even cheaper now but I've had issues with their app not working so this is some details on how to talk to their gateway running the newer locked down firmware.

The older firmware has a very nice web interface with no authentication on HTTP you can juse use in your browser it's all graphical and pretty.  You can also ssh into it on port 22 with the username root and password thinkgreen.  The API calls are the same but the old version will accept ANYTHING in token. Both of these access methods are insecure and should not be exposed outside of your LAN.

The device WILL auto update if it has internet access. If you like the web/ssh make sure you keep it on your LAN only.  Once it updates the app may stop working (may not be able to detect the AP), and it may loose authentication every time you close it so you need to press the button to use it which makes their APP pointless aside from setup.  There are 3rd party apps that you can get that work however.

If you want to keep using the OEM app and you are having these problems a small proxy could be written to give the app a valid token each time it starts.

The API should work with the older firmware (where port 80 is open) but you don't need to provide a valid token in your strings.

I have written a python module if anyone is interested contact me, this entry will just detail the raw calls you can make to the device and how you can convince the OEM app it's talking to a gateway when it's actually talking to your web server.

This article is written for developers and experienced IoT hackers that know how to setup a SSL web server and make XML calls via HTTP(s).   You will not find this useful if you aren't at least mildly experienced with these things.

All API calls are XML over HTTP(s) and the gateway will accept GET or POST requests as long as the form data is correct.
There are only 2 fields used:
cmd - The command you are calling
data - All the XML data for the request

You can specify the server IP by hitting the little gear in the lower right hand corner of the app.

The App starts by sending an auth request. All requests are done via HTTPs on port 443.  Again new firmware only. Old firmware uses port 80 standard http.

*** Auth request will be greeted by a 404 message unless the gateway is in auth mode (press the button, blinking lights etc) ***

/gwr/gop.php?cmd=GWRLogin&data=<gip><version>1</version><email>dummy username</email><password>dummypassword</password></gip>

The username and password do not matter. It will only accept them in auth mode... This will return a token.. Make sure you write this down :P

<gip><version>1</version><rc>200</rc><token>YOUR TOKEN GOES HERE</token></gip>

You will need to included the <token>YOUR TOKEN GOES HERE</token> with EVERY subsequent interaction with this server.   As far as I can tell they never expire.

Next up the client requests the following:
/gwr/gop.php?cmd=GatewayGetInfo&data=<gip><version>1</version><token>YOUR TOKEN</token></gip>
And gets back:
<gip><version>1</version><rc>200</rc><gateway><gid>A NUMBER</gid><online>0</online><primary>1</primary><fwversion>3.0.80</fwversion><mac>D4:A9:28:XX:XX:XX</mac><serial>111-1111-11111</serial><lastreboot></lastreboot><lastseen></lastseen><lanip>192.168.XXX.XXX/24</lanip><externalip></externalip><gipserver>tcp.greenwavereality.com</gipserver><type>Apollo3</type><modelno>not set</modelno></gateway></gip>

Online will reflect if it can get to the WAN or not... Mine is blocked at the router... Since their server is down, who cares anyway right?

The next 2 requests aren't supported by my gateway but you need to return the error code so the client doesn't freak out
/gwr/gop.php?cmd=AccountGetDetails&data=<gip><version>1</version><token>TOKEN AGAIN</token></gip>

So give it:
<gip><version>1</version><rc>500</rc></gip>

/gwr/gop.php?cmd=AccountGetPreferences&data=<gip><version>1</version><token>YOU GUESSED IT</token></gip>

And I got this back, and the client seems OK with it...
<html><head><title>400 Bad Request</title></head><body><h1>400 Bad Request</h1><p>Unknown GOP command: AccountGetPreferences</p></body></html>

The following command gets your room list, the easiest way to get the response is to send the command to your gateway...
/gwr/gop.php?cmd=RoomGetCarousel&data=<gip><version>1</version><token>TOKE TOKE</token><fields>name,power,product,class,image,imageurl,control</fields></gip>

The response is super long and will be different for each system... If you can't send this request to your gateway yourself this document isn't for you.... FYI you don't need to do all the prior stuff to run this command, you just need a valid token.

Then this command gets the list of Scenes/Smart Control settings... Mine are default and the list isn't too long so I'll post the response.
/gwr/gop.php?cmd=SceneGetList&data=<gip><version>1</version><token>TOKENS FOR ALL</token><fields>detail,imageurl,bigicon</fields><islocal>1</islocal></gip>

And you will get back:
<gip><version>1</version><rc>200</rc><enable>1</enable><scene><sid>1</sid><active>1</active><name>Home</name><desc></desc><order>0</order><type>manualcustom</type><icon>images/scene/home.png</icon><device><id>216510933483966411</id><type>D</type><cmd><type>power</type><value>1</value></cmd><cmd><type>level</type><value>100</value></cmd></device><device><id>359879170926881236</id><type>D</type><cmd><type>power</type><value>1</value></cmd><cmd><type>level</type><value>100</value></cmd></device><device><id>360160645903591892</id><type>D</type><cmd><type>power</type><value>1</value></cmd><cmd><type>level</type><value>100</value></cmd></device></scene><scene><sid>2</sid><active>1</active><name>Away</name><desc></desc><order>1</order><type>manualcustom</type><icon>images/scene/away.png</icon><device><id>216510933483966411</id><type>D</type><cmd><type>power</type><value>0</value></cmd><cmd><type>level</type><value>100</value></cmd></device><device><id>359879170926881236</id><type>D</type><cmd><type>power</type><value>0</value></cmd></device></scene><scene><sid>3</sid><active>1</active><name>Night</name><desc></desc><order>2</order><type>manualcustom</type><icon>images/scene/night.png</icon><device><id>216510933483966411</id><type>D</type><cmd><type>power</type><value>0</value></cmd><cmd><type>level</type><value>100</value></cmd></device><device><id>359879170926881236</id><type>D</type><cmd><type>power</type><value>0</value></cmd></device></scene></gip>

Then it tries to get room information:
/gwr/gop.php?cmd=RoomGetInfoAll&data=<gip><version>1</version><token>I'LL TOKE THAT</token><rid>0</rid><fields>name,power,product,class,image,imageurl,control,other</fields></gip>

Again this response is large and unique to your setup/devices, please get your own and look at it, it's fairly self explanitory...

Then the app will try and grab the images of the devices on the current page (you will be at your first room by this point)
/gwr/gop.php?fmt=image&cmd=DeviceGetImage&data=<gip><token>THAT SILLY TOKEN</token><did>Device ID (DID) OF YOUR LIGHT BULB OR FIXTURE</did></gip>

This will return an actual PNG file in the flesh!  Try it yourself!

The app will also call this function while flipping pages, it also has a super long unique response:
/gwr/gop.php?cmd=RoomGetList&data=<gip><version>1</version><token>JRRTOLKEN</token></gip>

The bulb info response can be fetched with the following call:
/gwr/gop.php?cmd=DeviceGetInfo&data=<gip><version>1</version><token>T</token><did>Device ID of the bulb</did><fields>name,power,product,class,image,control,realtype,other,status</fields></gip>

This retuns XML data about the bulb, how it's setup, etc. and even has a BASE 64 encoded ASCII version of the PNG in it!

You can make a bulb go into identify mode where it flashes bright and dim with the following call:
/gwr/gop.php?cmd=DeviceSendCommand&data=<gip><version>1</version><token>T</token><did>Device ID</did><type>identify</type><val>1</val></gip>

Of course the same command with val set to 0 will turn it off.

The response for this as with most commands that don't give you any data is just a 200 as follows: <gip><version>1</version><rc>200</rc></gip>   You will see this a lot.

To find out what bulbs/dids belong to a fixture (a group of bulbs) you can use the following command.
/gwr/gop.php?cmd=DeviceVirtualGetList&data=<gip><version>1</version><token>T</token><did>FIXTURE VIRTUAL DID</did><fields>name,image,imgs,imageurl,realtype</fields></gip>

To add/remove a bulb from a fixture use these commands:
DeviceVirtualDeviceAdd and DeviceVirtualDeviceDelete.  The syntax is the same as the other commands with the initial <did> tag being the DID of the virtual device and then having a <device><did> pair for the bulb to be added or removed.  I don't know if this command supports more than one bulb at a time, I wouldn't push it :P


This again gives a long long long XML response which will contain the <did> and <name> elements of each bulb within that fixture.
Each bulb will be within it's own <device> tag.  Keep in mind you can't directly address a bulb that's linked to a fixture but this can be useful for removing it later.

To rename a lightbulb:
/gwr/gop.php?cmd=DeviceSetInfo&data=<gip><version>1</version><token>T</token><did>DID of the bulb, names aren't used here</did><name>FRIENDLY NAME OF THIS BULB</name><color>THIS IS THE ROOM IT BELONGS TO 0-9</color><other><rcgroup>YOU CAN PUT A CSV OF 1-4 IN HERE TO LINK THIS TO A PHYSICAL REMOTE CONTROL</rcgroup></other></gip>

The above command can be called with or without any of these params you just need the DID.. You can change the "color" or rcgroup without changing the name, etc.  Just leave the fields out you don't want to change.

Also if you put a bulb into a "color" of 10 or above it will lock up your gateway.

To rename a room you use the following.  Keep in mind if there's no bulb in a room things can get weird.
/gwr/gop.php?cmd=RoomSetInfo&data=<gip><version>1</version><token>T</token><rid>0</rid><name>MY ROOOMMMM</name></gip>
You'll get the usual 200 OK from these guys

You can also delete a device or virtual device with the following call:
/gwr/gop.php?cmd=DeviceDelete&data=<gip><version>1</version><token>T</token><did>BULB/FIXTURE ID TO DELETE</did></gip>

You can create a virtual device/fixture with this call:
/gwr/gop.php?cmd=DeviceVirtualCreate&data=<gip><version>1</version><token>T</token><color>ROOM #</color><name>NAME OF THE FIXTURE</name><image>BASE 64 ENCODED ASCII STRING OF A PNG YOU CAN LEAVE THIS TAG OUT COMPLETELY</image><producttype>159</producttype><device><did>DID of bulb 1</did></device><device><did>DID of bulb 2</did></device></gip>

FYI product type 159 is a virtual fixture and you can have as many <device><did></did></device> items as you want in a fixture (up to whatever the actual software limit is)

You will get back a special 200 message with the DID the gateway assigned your new virtual fixture.  You don't need to remember this though, you can easily get it from the room list.

<gip><version>1</version><rc>200</rc><did>123456781234567890</did></gip>

There is a GWRBatch command but I think it just allows you to run multiple queries within one, I have all but ignored it as it is not important.

The magic auth mode / search mode:
If you have a valid token you can put the device back into "auth" mode so you can add a new client or get a new token... This command is the EXACT SAME function as pushing the button..

/gwr/gop.php?cmd=GatewayInclusionStart&data=<gip><version>1</version><token>T</token></gip>

The unit will accept auth requests as well as learn any new bulbs within range.
If you get a 401 from this your token is no good.

If you want to check on the progress of a scan you can use this command, it will also tell you if it's still in auth mode:
/gwr/gop.php?cmd=GatewayInclusionProgressGet&data=<gip><version>1</version><token>T</token></gip>

The result is this:
<gip><version>1</version><rc>200</rc><gateway><gid>NUMBERS HERE</gid><state>1</state><progress>0</progress><start>0</start><end>0</end></gateway></gip>

I didn't have a bulb to learn with this so I'm not sure what will change if it finds one but the <state> will change from 1 to 0 when it's stopped scanning and left auth mode.

If you want to run a scene use the following call:
/gwr/gop.php?cmd=SceneRun&data=<gip><version>1</version><token>T</token><sid>1</sid></gip>

The SID is the ID of the scene you want to run, If you look up a whole bunch near the beginning the client requested all the Scenes, the SIDs are all listed there.

Scenes can be a little tricky to create so I'll break the code down more here... You will still need all the standard headers <gip><version> <token> when making this call, I have left them off to make this readable.

CMD = SceneCreateEdit  You can also use SceneDelete with the <sid> tag to delete a scene.

<sid>0</sid> # ID of the scene.  If you use 0 here the system will generate you an SID.  If you want to edit an existing entry specify it's SID
<active>1</active> # Enabled. Set to 0 if you want to disable this item
<name>test</name> # Name... Call it whatever you want
<type>manualcustom</type> # manually triggered. Use "schedulecustom" instead if you want to enable time/day schedules
<islocal>1</islocal> # always yes

### SCHEDULES ### SEE ABOVE
<every>0,1,2,3,4,5,6</every> #  0=Sun thru 6=Sat
<starttime>15:07</starttime> # Begin at (sunset, sunrise or mil time)  Zero padded digits please!
<stoptime>02:11</stoptime> # End at (sunset, sunrise or mil time)  Zero padded digits please! (not 1:3 but 01:03)

####################

<icon>tv.png</icon> # See below for a list

### DEVICES SECTION ### You can have any number of <device> items in here ####
<device><id>DID of the bulb you want to control</id> # DID of the bulb.
<type>D</type> # D here tells the gateway the above ID is a DEVICE and not a ROOM .Virtual devices/fixtures are D type as well.
<cmd><type>power</type><value>0</value></cmd></device> # This device is off, see below for dimming options
<device><id>3</id> # DID of second device in this case room/color #
<type>R</type> # This tells the gateway your above item is a ROOM and not a DEVICE
<cmd><type>power</type><value>1</value></cmd><cmd><type>level</type><value>80</value></cmd></device>   # This turns the device ON and sets the dim level to 80%

Here is a full list of icons:
tv.png - A TV
heart.png - Heart
sensor.png - Like an EKG
zroom_00.png - Black Room
zroom_01.png - Green Room
zroom_02.png - Blue Room
zroom_03.png - Red Room
zroom_04.png - Yellow Room
zroom_05.png - Purple Room
zroom_06.png - Orange Room
zroom_07.png - Aqua Room
zroom_08.png - Pink Room
zroom_09.png - Gray Room
clock.png - A clock
away.png - Person running away
light.png - Light bulb
lamp.png - Floor lamp
fan_cool.png - Blue fan
fan_heat.png - Red fan
star.png - Star
vacation.png - Plane
home.png - House
night.png - Partial Moon
target.png - Gun sight
washing_machine.png - Washing machine
music.png - Music note
dim.png - Contrast symbol
off_to_work.png - Briefcase
rainy.png - Umbrella
e_car.png - Car
tree.png - Xmas tree
thermostat.png - Thermometer
coffee.png - Mug
bolt.png - Lightning
eat.png - fork and knife

And finally the stuff you can find almost anywhere on how to get status, switch and dim bulbs/fixtures:

Status:
cmd is GWRBatch data is as follows to get multiple data:
<gwrcmds><gwrcmd><gcmd>RoomGetCarousel</gcmd><gdata><gip>\n<version>1</version><token>1234567890</token><fields>name,control,power,product,class,realtype,status</fields></gip></gdata></gwrcmd><gwrcmd><gcmd>UserGetListDefaultRooms</gcmd><gdata><gip><version>1</version><token>1234567890</token></gip></gdata></gwrcmd><gwrcmd><gcmd>UserGetListDefaultColors</gcmd><gdata><gip><version>1</version>\n<token>THIS TOKEN MATTERS!</token></gip></gdata></gwrcmd></gwrcmds>

This will return a huge amount of data about the rooms, colors, and devices. I suggest you use an XML parser library to deal with the output.

This will allow you to tell what bulbs/fixtures are part of your system and if they are on or off, what their dim level is and if they are marked as offline by the <offline>1</offline> tag which means the gateway cannot currently talk to it (out of range or switched off)

To Switch a bulb on or off use the cmd DeviceSendCommand with the <did> of the bulb/fixture and <value> of 1 or 0 for on or off.
The dim comand is exactly the same except you would add <type>level</type> to your data field and your value would be from 0% to 100%.

I think that covers everything the app can do. This should help you get going with this wacky and weird interface.  If this helped you please drop a comment below and if you have any questions please comment or contact me and I will gladly answer them.

Bonus:
Here is a simple Python script you can put on a web server that support SSL (made for Windows). It will proxy your app and give it a valid token you can specify.

It's slower than talking directly to the gateway but if your app is broken this will make it work at least...

The blog has removed my tabs I put spaces in, hopefully it still works.

#!c:\python27\python.exe -W ignore


import cgi, sys, urllib2, urllib, msvcrt, os


# Put your valid token & gateway IP in here and don't change anything else.

token = "YOURTOKENHERE"
gateway = "192.168.xx.xxx"

###############################################################################


# Header is always HTML even when it's an image -.-
print "content-type: text/html\n"

form = cgi.FieldStorage()

image = 0

# read all the keys and put them into a urlencoded var
data = ""
for key in form.keys():
 if key == "fmt" and form[key].value == "image": image = 1 # if they requested an image

data += urllib.urlencode({key : form[key].value}) + "&"

# chop off last extra &
data = data[:-1]



url = 'https://%s/gwr/gop.php' % gateway



# Give the users token for the login request, this is really the ONLY thing this script does -.-
if str(form).find('GWRLogin') != -1:
 print "<gip><version>1</version><rc>200</rc><token>%s</token></gip>" % token
 sys.exit(0)



try:
# All non login requests will be sent to the gateway
 content = urllib2.urlopen(url=url, data=data).read()

# If it's a raw image we need the output format to be binary
 if image == 1:
  msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)

# Output the data from the gateway to the client
 sys.stdout.write(content)


except:
 pass  



Reverse Engineering VstarCam C95


I got this cheap little toy from eBay to replace an older dedicated LCD system that wasn't working right.  It automatically makes a reverse proxy into your network and it's running a bunch of sketchy services and it's another IoT device I did not trust on my LAN with internet access.  (In case you haven't noticed a trend I don't like IoT devices to connect to the internet)

I connected and setup this unit with the Eye4 application via the "playing a sound method" (where your WiFi SSID and password are encoded into an audio clip the device can interpret) to add it.  The device would not support a hidden SSID nor would it support a WPA2 PSK with any symbols in it (It took me an hour to figure this out as it acted like everything was fine but it just would not accept the WiFi settings when the sound played)

After it was online everything worked great.  I could access the camera and intercom and the doorbell button would sometimes play a ringing on my phone.  I wanted to do more with this device and I wanted it off the internet however.

The device runs a telnet server but Vstar will not give the root password and none of the usual suspects work but the fact that it has a hardcoded "secret" root password is bad, who knows what else this thing is doing behind your back...

It did not want to work reliably if it couldn't setup it's tunnel and it would not do anything when you pressed the button on it, something had to be done!

It will also try to use google's public dns at 8.8.8.8 but having it's gateway as a server instead of the router will stop it from getting to the internet.

After some Wireshark I logged into the unit's HTTP interface and set the DNS and Gateway (Setup -> Basic Network) to one of my servers.

I setup a maraDNS server on said server with the following configuration:

mararc:
csv2["eye4.cn."] = "eye4.txt"
csv2["vstarcam.com."] = "vstar.txt"
csv2["baidu.com."] = "baidu.txt"
csv2["windows.com."] = "windows.txt"

eye4.txt:
s2.% 192.168.x.xxx ~
device-abnormal.% 192.168.x.xxx ~
authentication.% 192.168.x.xxx ~
ntp2.% 192.168.x.xxx ~
ntp.% 192.168.x.xxx ~
push.% 192.168.x.xxx ~

vstar.txt:
s3.% 192.168.x.xxx ~

windows.txt:
time.% 192.168.x.xxx ~

baidu.txt:
www.% 192.168.xx.xxx ~

This would direct all the standard DNS queries to my server instead of their internet counterparts, however it's INITIAL query is a HTTP request to a webbased DNS resolver with a hard-coded IP address which would thwart the whole process...

So I added the IP of that DNS resolver (119.29.29.29) to my servers network card.

I added this to my Apache config as it uses a few different ports:
Listen 8087
Listen 119.29.29.29:80
Listen 808

# =================================================
# Fake Web to DNS Server thing for doorbell
# ===============================================
NameVirtualHost 119.29.29.29:80
<VirtualHost 119.29.29.29:80>
DocumentRoot "c:/doorbell"
<Directory "c:/doorbell">
Allow from all
Order allow,deny
</Directory>
</VirtualHost>

# =================================================
# Doorbell Alarm Port
# ==============================================
NameVirtualHost *:808

<VirtualHost *:808>
DocumentRoot "/doorbell"
AliasMatch ^/(.*)$ c:/doorbell/push.py
<Directory "c:/doorbell">
Allow from all
Satisfy Any
Options Includes ExecCGI
</Directory>
</VirtualHost>

NameVirtualHost *:8087
<VirtualHost *:8087>
DocumentRoot "/doorbell"
<Directory "c:/doorbell">
Allow from all
Satisfy Any
</Directory>
</VirtualHost>      

You will also need an SSL site setup with the following entry:

<Directory "c:/www/GetToken">
Allow from all
Satisfy Any
</directory>


When the unit boots the first thing is does is makes two HTTP requests:
GET http://119.29.29.29/d?dn=authentication.eye4.cn
GET http://119.29.29.29/d?dn=push.eye4.cn
Therefore c:\doorbell\d contains the IP address of my server 192.168.x.xxx and nothing else this will then direct the camera to connect to my server for it's web and auth requests.

The next stage of the process is to request a token from "the authentication server". Since it's using my server for DNS and HTTP DNS I have given my servers IP as the answer to those DNS entries.

And it then sends this HTTPS request to my server (where XXXX will be unique to your camera and account you setup when you added it to eye4:
GET https://authentication.eye4.cn/GetToken/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXC95/VSTC/VSTXXXXXXXXXXXX/48.61.72.75/1

I created the path for /GetToken/XXXXX.../VSTC/VSTXXX/etc but you can use an aliasmatch if you want to do it the easy way.  The only part of that path that will ever change is the number at the end it could be 1 or 2 or 3, I've never seen it go above 5 so I made the files 1-5 in that directory with all the same contents:

# = digit, L = Letter. It shouldn't matter what you put in here, this is telling the camera what token and user ID it will use when sending data to the remote server. I included the formatting just incase the camera cares.  You can also use the GetToken string your camera sends you to get your actual Token by browsing to the URL on your PC and then putting the response in a text file.

{"token":[{"class":"E","access_token":"VSTB######LLLLL:##LL##L###LLL###L#L#L##
##LL#L#"}],"errcode":0,"push":[{"user":"#######","name":"Doorbell1"}]}

At this point the camera is happily registered and will occasionally send UDP packtes to your server which will just get dropped. This doesn't seem important...

The Eye4 app will still work locally at this point and you can integrate it with your own DVR software that supports ONVIF or MJPEG.

Now for the fun part, when someone presses the Doorbell button...
The unit will connect on port 808 and make a HTTP request to some long string including the token given above.
The alias match will force rediect it to run push.py which is the script shown below.
My script uses the Pushover API as it is way more reliable than their built in app, however the script will show you how to register to their API server and send push messages to the Eye4 app running on your phone.  You can add whatever other events you want to the code when someone pushes the button like turn on a porch light, send a text or anything.
I have added comments in-line to explain what it is doing.

If you don't want to use the eye4 server at all (meaning their app) your push.py script is very simple:

push.py:
#!c:\python27\python.exe -W ignore

import urllib2, time

# This will tell the camera/doorbell unit that the request was processed correctly.
print "Content-type: text/html\n\n"
print '{"message":"OK","errSubCode":"200","errCode":200}'

# this is where you would execute anything you want to happen when the doorbell is rung.
# You can do this very simply in PHP as well as you just need to return a string to the camera so it doesn't have an error.

If you do want to use the eye4 app and their push server this code will do that...
push.py:
#!c:\python27\python.exe -W ignore

# This program is called when someone presses the doorbell button on my front door
# Eye4 subroutine will use the eye4 server to relay the message so the Eye4 app will ring

import urllib2, time


def eye4():
# use eye4 server to send doorbell notice

# Get token - You will need to replace the # and L with your cameras ID by looking at your HTTPD logs when it calls GetToken on startup.
req = urllib2.Request('https://authentication.eye4.cn/GetToken/#LL#L#LLL####L#L#######LL#L#LLL##L###C95/VSTC/VSTL######LLLLL/48.61.72.75/1')
response = urllib2.urlopen(req)
the_page = response.read()

# The VSTL## etc should match the VSTL## in the GetToken.  This parses out the token used for requests.
token = the_page.split('VSTL######LLLLL:')[1].split('"')[0]

# Generate the current time/date stamp that will show up on your phone.  This uses real-time but you can make up your own as long as it's in the correct format.
datestr = str(time.localtime()[0])+str(time.localtime()[1])+str(time.localtime()[2])+str(time.localtime()[3])+str(time.localtime()[4])+str(time.localtime()[5])

# create the GET request to send the message to the server so it can push to your phone
# Again you need to edit the VSTL######LLLLL part with the info from above.
# the ####### at the end of the request will be the account user ID. You can find this in the Token file at ("user":"#######")
# You can change Front%20Door to anything you want this will show up under the bell on the Eye4 app.

url = 'http://push.eye4.cn:810/push/VSTC/'+datestr+'/10/20/0/0/VSTL######LLLLL:'+token+'/Front%20Door/#######/0'

# Send Ring notice
req = urllib2.Request(url)
response = urllib2.urlopen(req)
the_page = response.read()
if the_page.find('OK') != -1:
return 0
else:
print the_page




# This will tell the camera/doorbell unit that the request was processed correctly.
print "Content-type: text/html\n\n"
print '{"message":"OK","errSubCode":"200","errCode":200}'

# This is where you can call any other scripts you want when someone rings the bell.
try:
# Send the message via eye4 app
eye4()
except:
pass


If for some reason the camera gets a message that's abnormal it will make a HTTP request to your server to the abnromal script to report an error.  The request will contain the problem.  I don't have a sample of this handy as the above should stop it from ever entering an abnormal state.  If however it should get there you need to fix the problem before it will send alarm/push requests and there may be issues accessing the camera with Eye4 on the network.

You can also use webcam viewer apps on your phone to access this unit even ones that are not Eye4, however you may not be able to talk to the unit unless you use Eye4.  The profile VStarcam C7816 works best if your app supports it that will get you video and listen and talk will work but it will not sound right.

I have yet to work out how the audio part works, I may at some point in the future work on that...

Hopefully this helps anyone that wants to do more with this neat little camera or wants to use it locally with a DVR rather than have it make holes in your network.

As a site note the App makes you change the admin password after installation (I believe it's 888888 by default) The web interface has a bug in the code that will only allow your password to be 3 characters consisting of a letter and 2 numbers. I have written a proxy server that will remove that Javascript code while leaving the rest of the interface intact if anyone wants it post a comment.  This will allow you to change the password without Eye4 and will allow you to add the Operator and Visitor users.

Don't want your Wemo online?


The IoT world is full of weird and wonderful security holes. I don't trust most of my IoT devices as far as I can throw them and for the most part I don't want them talking to the internet and creating tunnels into my network. Wemo does allow you to disable remote access but even then if someone did manage to get into a device somehow they could enable it and I don't completely trust Belkin's code won't try something sneaky in the middle of the night so I decided to block it's access to the internet at the router... This simple action that seems to not affect most other devices had a major impact on the Wemo, every 30 seconds or so it would stop responding for 3 seconds and would constantly fall off the network with a flashing orange light. I noticed when I had enabled internet access for a firmware update that both of my devices never missed a ping while they were online so I started running packet captures on them. It turns out the Wemo is pinging the gateway IP every 30 seconds or so and when it doesn't get a response it will time out for a few seconds (not sure what it's actually doing when this happens). I added a rule to allow ICMP responses from the gateway IP (the internal IP of the router) and blocked all other traffic with a reject rather than a drop and now they are both staying online steadily without being able to talk to the internet. They also respond much faster in the app and more reliably too.

Freeblog SUCKS!

My first blog site sucked, I am trying something new, HERE!

Freeblog is awful if you don't want to give them money and even if you do their editor and stuff is really limited.

This will be the place I will document my hacks, technology stuff, projects, etc.

I like to tinker and hopefully this information will be helpful to someone out there :)