Monday, October 31, 2016

DD-WRT update and Amazon dash

My router got updated and my initial experiments had all been on a tmpfs. As a reminder to my future self, JFFS2 should be enabled for persistent storage on flash (or use a USB drive of some kind).

Following https://www.dd-wrt.com/wiki/index.php/Journalling_Flash_File_System#Directions_for_.28normal.29_users:_using_Web-GUI_Interface worked for me.

I then created a script on the jffs2 mount point and updated DNSMasq settings (specifically "Additional DNSMasq Options") to point to this, e.g.:

dhcp-script=/jffs/dhcp_ha_post

Where /jffs/dhcp_ha_post is executable:

chmod a+rwx /jffs/dhcp_ha_post

Sunday, July 24, 2016

Home Assistant, custom events and Amazon Dash Button

Last post had high level over view of Amazon Dash hacking options that have already been discovered, along with an experiment with the Amazon Dash button with my router.

HA (like many home hub solution) offers custom events, docs/wiki for this are at https://home-assistant.io/getting-started/automation-trigger/

I was able to get a custom event/trigger created with the following config:

automation:
  - alias: Turn on a single light when custom event fires
    # curl -X POST http://localhost:8123/api/events/MY_CUSTOM_EVENT
    trigger:
      platform: event
      event_type: MY_CUSTOM_EVENT
    action:
      service: homeassistant.turn_on
      entity_id: switch.switch_name

The switch name can be either derived by scanning through your config or by copy/pasting from the web UI http://localhost:8123/devState (or what ever machie HA is running on). It could even be a group etc.

Triggering this can be easily achieved via the REST interface HA offer https://home-assistant.io/developers/rest_api/ 

As per the config example comment above, using curl is an easy way to send the event. This example is without any security, a password can be setup (presumably TLS over https too?).

My router is running dd-wrt and does NOT have curl so my terrible idea is to use netcat, and forgo security (i.e. anyone on the network can inject events) by updating the script that DNSMasq fires by manually sending an incomplete/minimal POST message:

#!/bin/sh

# To be called by/from DNSMasq as dhcp-script # More information, see http://somnambulistic-monkey.blogspot.com/2016/07/home-assistant-custom-events-and-amazon.html if [ -z "$2" ] then echo 'Missing param 2 (MAC address)' echo This script should be called by DNSMasq exit 1 fi HA_IP_ADDRESS=192.168.1.1 # Edit me! HA_IP_PORT=8123 # Send custom event to Home Assistant server # this really should use curl but it is not available # so make do with nc (netcat) { echo POST /api/events/MY_CUSTOM_EVENT_${2} HTTP/1.1.$'\r' echo Host: ${HA_IP_ADDRESS}$'\r' echo $'\r' } | nc ${HA_IP_ADDRESS} ${HA_IP_PORT}

This includes the MAC address of the Dash button in the event name (rather than making use of POST data payload, i.e. custom event parameter "event_data")

This means a custom trigger is created for each button and the HA config is the only place that needs updating, rather than the dns script.

I need to experiment with the range of the buttons now, so far all testing has been within 5m of the access point. But I'm now all setup for using these how I want :-)

One thing that other posts have mentioned is that uninstalling the Amazon store app may be desirable as it will remind you that the Dash button setup is not complete. This has been understated. I had about 15 notifications in just a few minutes!

Saturday, July 23, 2016

Yet Another Amazon Dash Button post

Searching for "amazon dash hack" yields a LOT of hits. There are some really great posts on this topic, and some less great posts. Pretty sure this post will fail in the later but this is probably mostly for me as a note taking exercise.

IMHO the definitive posts to read are:


I have the V2 button, you can read the above posts for more detail on them. I was NOT able to get this connected to my network without a mobile device. Using a laptop did NOT work. Once the Dash was hooked up to the network, I was able to change the WiFi network the Dash connected to by using a laptop but provisioning a fresh Dash can not be done this way without more digging/effort.  To change the Wifi network simply:
  1. Press and hold button for 4 secs (Amazon document 6 secs) until the led flashes blue
  2. Connect to the WiFi network the Dash is now serving on "Amazon ConfigureMe"
  3. Your device is almost certainly IP 192.168.0.100, the dash is on 192.168.0.1 and is running a webserver at http://192.168.0.1/
  4. Accessing the server will display the firmware version, DSN number (as printed on the box and on the back of the button) and more importantly the MAC address (sans ":") which is needed to identify the button
  5. You can change the Wifi network and WiFi password the Dash uses via curl:
curl "http://192.168.0.1/?amzn_ssid=SPECIFIED_SSID&amzn_pw=SPECIFIED_PASSWORD"


If you read from the webserver with a json content type, e.g.:

curl -H "Content-Type: application/json" http://192.168.0.1/

Get something like this (note this has been formatted for readablility):

{
    "amzn_devid":"DSN: printed on back of device and from QRCode",
    "amzn_macid":"MAC_DIFFERENT_FROM_ABOVE_MAC",
    "amzn_networks" :   [
                        {"ssid":"SID_HERE","bssid":"BSSID_HERE","security":"WPA AES PSK","rssi":"-72"},
                        ......
                        {"ssid":"SID_HERE","bssid":"BSSID_HERE","security":"WPA AES PSK","rssi":"-72"}
                        ]
}


As you might expect, the Dash will fail to configure if the access point it is connected to does not have Internet access.

When entering the WiFi password there is the option for Amazon to store this information. Whilst I was experimenting with this, I went through this process a lot and I must have forgotten one time to set this correctly and now Amazon has my WiFi password (for a sand boxed access point).

Matthew Petroff doesn't go into detail in how to then make use of the buttons for custom purposes but there are lots of links on that. But Ted Benson got into details on detecting the DNS/ARP connection that the Dash makes when getting its IP address for each button press at:

https://medium.com/@edwardbenson/how-i-hacked-amazon-s-5-wifi-button-to-track-baby-data-794214b0bdd8#.6gummiay2

 There is a more sophisticated approach where the Amazon web service itself is emulated https://mpetroff.net/2015/05/amazon-dash-button-teardown/#comment-246230 - from comments it is not clear if this works with V2 devices. This approach allows control over the LED to show some sort of state.


The V2 JK29LP has the same DHCP need as V1 (i.e. DHCP, not static address) so I explored the options there. The main options (and code samples in GitHub) I've seen are packet capture the ARP packet and then act on that, either using a framework or raw sockets

Raw socket access https://medium.com/@xtalker/hey-ted-i-got-this-working-on-my-raspi-without-all-the-scapy-overhead-thanks-to-http-e5704e4b16a9#.tdrzhe8xt - this only works under Linux (maybe Mac) and does not work under Windows, even when changing the type to IF_NET

Using a packet capture framework scapy under Linux as described by Ted Benson or under Winpcap under Windows https://medium.com/@gadberger/what-i-had-to-do-to-get-the-amazon-dash-hack-to-work-on-windows-fe06b272a788#.3xacxj5uj 

Buried in the comments at https://mpetroff.net/2015/05/amazon-dash-button-teardown/#comment-251428  Mohnish Chaudhary suggests making use of the dhcp-script that dnsmasq has.

I tried raw socket arp reading under Windows and could not get this to work, the OS errors out.
I tried raw socket arp reading under Linux and this does work (I think I had one occasion when the button press was not picked up), this was using a machine on the same WiFi network

Like Mohnish, I'm thinking packet sniffing is a little overboard for me. I have a dd-wrt router that is working fine and it uses DNSMasq. In the web interface there is a "Additional DNSMasq Options" config option, I simply set that to:

dhcp-script=/tmp/myscript

Which simply gets appended to the config file (i.e. this is not being provided via the command line parameter of the same name).

And then knocked up a quick and dirty script to see if it works:

#!/bin/sh
# usage dnasmasq.... --dhcp-script=/tmp/myscript
# in dd-wrt (etc.) add line:
#    dhcp-script=/tmp/myscript

logfile_name=/tmp/myscript.log

check_and_truncate()
{

    touch ${logfile_name}  # ensure file exists on first run
   
    #file_size=`du -k ${logfile_name} | cut -f1`
    #max_file_size=4  # Kb

    file_size=`ls -al ${logfile_name} |awk '{print $5}'`
    max_file_size=2048  # bytes
    max_file_size=1024  # bytes

    # Simple truncation/rotation
    # NOTE this will break any `tail -f ...` usage
    if [ ${file_size} -gt ${max_file_size} ];
    then
        mv ${logfile_name} ${logfile_name}_trunc
        echo truncated `date` > ${logfile_name}
        #tail -20 ${logfile_name}_trunc >> ${logfile_name}
        grep -v '^truncated' ${logfile_name}_trunc | tail -20 >> ${logfile_name}
        rm ${logfile_name}_trunc
    fi
}

check_and_truncate



echo ------------------
>> ${logfile_name}
env | grep \^D >> ${logfile_name}
echo `date` $0 ${*} >> ${logfile_name}

This works and shows the MAC address. dd-wrt includes both nc (netcat) and wget so this could proxy somewhere else without needing to packet sniff. I've yet to hook this piece up.... I'm trying to avoid writing a custom server to to receive the payload (which is usually my goto answer) and see if it can be delivered directly to https://home-assistant.io/

Is it worth going through the time to set this up? Dunno. But I had a fun morning playing with this :-)

Continued http://somnambulistic-monkey.blogspot.com/2016/07/home-assistant-custom-events-and-amazon.html

Saturday, December 26, 2015

Homage for the Holidays - meets Star Wars

A buddy of mine had an interesting idea for the holidays, https://medium.com/homage-for-the-holidays I’m not planning on attempting new projects every week but one seems manageable.

Like most people I’d been tentatively waiting for the new Star Wars movie, The Force Awakens to come out. I only have to hear the theme tune and I’m pumped and ready to watch Star Wars Episode IV: A New Hope :-) I only had one wish for the new movie, “please don’t let it be bad”.

In the run up to the new movie coming out, it has been amusing to see the various merchandising tie-ins going on, from coffee creamer
 to soup
  One of the (unofficial) pieces of merchidise I saw was a shirt http://shirt.woot.com/offers/the-storm with a cool piece of art work on it - not something I was thinking I’d wear but cool!

A while later, when the movie was released and I was organizing to see it with friends, I thought about creating a watch face for the Pebble watch to enhance the viewing experience :-)

I’ve put some time into https://github.com/clach04/watchface_framework/ to help create (digital) watch faces for the Pebble easily and quickly. This seemed like a good time to use it with a deadline, I had about an hour before we were going to the movie theater!

First thing was to get an image suitable for the Pebble Time, I cropped and edited an image from Woot using The Gimp then resized and reduced the colors to match the Pebble Time color palette.

Once that was ready the watch config needs some tweaking to pick where/how the image is displayed along with the time. The results of this initial attempt resulted in:


Which was as far as I got before needing to leave to meetup with friends and to take the watchface out for a road test.

Later after seeing the movie (all I’ll say, so as to avoid any chance of spoilers is; not awesome but a fun and enjoyable Star Wars movie), I spent some time fine-tuning and adding features that I personally want in a watchface. Viz. date information, battery power levels, and displaying an image when the bluetooth connection to the phone is lost. The results of this was:



Finally, whilst the time was readable, a large font can be faster to read so the image was resized a little smaller and a larger font used:




As with many projects, there was one part that took up a disproportionate amount of time, creating a useable bluetooth logo suitable for the Pebble (and the code to go along with it). I spent some time in a small dead end attempting to convert a Bluetooth logo from SVG into a vector format (PDC) that the Pebble understands. Whilst the current version is usable now, it still isn’t pretty enough to use yet due to some limitations with the Pebble vector format. In the end I cut my losses and exported to bitmap (PNG) format.

I’ve been using this watchface for a week now, whilst I do like the result, the thing I really like about the original hires source image (the clouds and lightning) by Skylar Hoga is not as clearly visible on the Pebble (due to a much lower resolution and color depth). I spent some time using a vector storm trooper helmet (converted to bitmap, conversion to PDC also hit problems with the current Pebble svg2pdc tool) this looks cleaner on the Pebble rather than The Storm. It would be interesting to see what the original looks like on a Samsung Gear S2 or Apple Watch.

Here is the current vector screen shot for https://github.com/clach04/watchface_storm_trooper/tree/vector_opaque:



First post

Who'd have thought that picking a new and unique blog name for a platform that started 16 years ago would be difficult :-p

Welcome to another blog which will have single digit number of posts and then never be updated again.