-
zmote configuration with REST APIs in Windows Powershell
11/27/2015 at 13:42 • 0 commentsFirst thing you need to do with a new zmote is to connect it to your Wi-Fi router. Every time zmote is powered ON, it configures itself as Wi-Fi access point (AP) so that one can connect to it (no password required) and configure it for connection with your router. Accesspoint (aka. hotspot) willshow up as zmote_*******. In this example it is zmote_00f2e958.
Power on zmote and Connect your pc/laptop to zmote_******** access point (hotspot)
When connected to zmote through its AP interface, zmote can be accessed at 192.168.4.1 IP.
Let us find out its MAC address, which we will need later:
> Invoke-RestMethod -Uri 192.168.4.1/api/wifi/mac ap_mac sta_mac ------ ------- 1a-fe-34-f2-e9-58 18-fe-34-f2-e9-58
Now, let's configure zmote to connect to our Wi-Fi router with SSID router and password sample.
> Invoke-RestMethod -Uri "192.168.4.1/18-fe-34-f2-e9-58/api/wifi/connect" -Method Put -ContentType 'application/json' -Body "{""ssid"":""router"",""password"":""sample""}" status ------ OK
Note that we have used sta_mac from earlier API here. This value is required in many APIs to make sure that our commands reach intended zmote (in case there are dynamic changes in IP by DHCP server).
After above command, zmote will configure itself to connect to router, will restart and get an IP from the DHCP server running on router. It may take 15-30 seconds for it to get connected and register itself with zmote.io server.
Power off and power on zmote. Disconnect pc/laptop from zmote_******** access point (hotspot).
After this point, you are ready to use zmote with www.zmote.io or looking at the rest of rest REST API.
Thank you Dougles for the time saving tip on complex double quotes needed http://douglastarr.com/using-powershell-3-invoke-restmethod-with-basic-authentication-and-json/
-
Using zmote with Home Remote
10/26/2015 at 04:39 • 1 commentSo we found this Android App called Home Remote that looks like it was made for hardware like zmote. It lets you design your own remote controller app for your phone (it supports Android, iOS and even WIndows Phone) with fine grained control over button placement and functionality. What really makes it unique is the remote "Designer" that it comes with, a PC based app that lets you create your own customized remote that you can then take to your phone.
Sound interesting? Head on over to our intsructable that explains it all.
http://www.instructables.com/id/Configuring-Home-Remote-for-use-with-zmote/?ALLSTEPS
-
REST control over zmote
10/25/2015 at 04:57 • 0 commentsNOTE: This log is applicable to older, v1 version of zmote. If you bought a zmote recently (or planning to buy one) and are planning to control through REST APIs, please contact us by email for latest APIs.
zmote is an open-source, Wi-Fi enabled IR blaster / receiver widget that offers full control through simple REST APIs.
We will go through important APIs and learn how to configure a zmote, how to send, receive and analyze IR signals using a zmote, as well as sending IR signals to it remotely, through internet using its REST-to-MQTT bridge.
This project will be useful to any one who wants to
- integrate IR transmission / monitoring features into a home automation project
- analyse IR signals from a remote for hacking or study purpose
- find hidden (discrete) IR codes for a given IR-controlled device
- create a web front-end or a mobile app for IR-controlled devicesConfiguring SSID / password
First thing you need to do with a new zmote is to connect it to your Wi-Fi router. Every time zmote is powered ON, it configures itself as Wi-Fi access point (AP) so that one can connect to it (no password required) and configure it for connection with your router.
When connected to zmote through its AP interface, zmote can be accessed at 192.168.4.1 IP.
Let us find out its MAC address, which we will need later:
$ curl http://192.168.4.1/api/wifi/mac {"ap_mac": "1a-fe-34-f2-e9-58", "sta_mac":"18-fe-34-f2-e9-58"}
Now, let's configure zmote to connect to our Wi-Fi router with SSID router and password sample.
$ curl -X PUT -H 'Content-Type: application/json' -d '{"ssid":"router","password":"sample"}' http://192.168.4.1/18-fe-34-f2-e9-58/api/wifi/connect {"status":"OK"}
Note that we have used sta_mac from earlier API here. This value is required in many APIs to make sure that our commands reach intended zmote (in case there are dynamic changes in IP by DHCP server).
After above command, zmote will configure itself to connect to router, will restart and get an IP from the DHCP server running on yout router. It may take 15-30 seconds for it to get connected and register itself with zmote.io server.
Registering as a client
zmote supports a special feature of ability to control over internet without any special user authentication. It does that by authenticating client (web browser or mobile app). In order to control a zmote through internet, a client must authenticate with zmote.io server when in the same local network (actually, same public IP as seen by the server) as the zmote.
For example, once zmote is connected to your home router and you visit app.zmote.io from your PC browser, your PC browser will automatically get access to your zmote without any special pairing. Then, even if your PC goes out of home network, let's say it connects through your office network, it will be able to send commands to your zmote through zmote.io server.
This is achieved by a client by first registering itself with v1.zmote.io, which is very simple:
$ curl http://v1.zmote.io/client/register {"_id": "5629dc538b1a4a0e005323b4", "secret": "I5UBVi42afQ0uIxTPoFcF4SAo1wnMPI4" }
The _id and secret returned by this API are important and are required in the next step, authentication.
Authentication requires cookies so that authentication token need not be passed manually to APIs that require it. Let's authenticate our client now:
$ curl -c zmote-cookies http://v1.zmote.io/client/auth -X POST -d '{"_id":"5629dc538b1a4a0e005323b4","secret":"I5UBVi42afQ0uIxTPoFcF4SAo1wnMPI4"}' -H 'Content-Type: application/json' {"extIP":"180.151.117.39"}
Note that we save cookies to a file for future use. The extIP value shows client's public IP as seen by zmote.io server. Any zmotes with the same public IP are now accessible to us.
Discovery of zmote (local or remote access)
Now that we have registered and authenticated our client, let's find out zmotes accessible to us. We will need the cookies we saved in last step.
We refer a zmote as a 'widget' internally:
$ curl -b zmote-cookies http://v1.zmote.io/widgets [{ "_id": "5607e785bacb1f187a71a9c2", "chipID": "00f2e958", "extIP": "180.151.117.39", "connected": true, "localIP": "192.168.1.7", "name": "zmote_f2e958", }]
Note that this API returns a JSON array with one entry for each zmote we have access to. The reply shows that we have access to only one zmote, having widget id 5607e785bacb1f187a71a9c2. We will need this widget id later, when we want to access our zmote remotely.
Note that it has same external IP as ours and it is connected to zmote.io server right now. So, it is very likely that we will find it in our local network at its reported localIP.
Let's check it out...
$ curl http://192.168.1.7/api/wifi/mac {"ap_mac": "1a-fe-34-f2-e9-58", "sta_mac":"18-fe-34-f2-e9-58"}
Surely, there it is.
Since it is available locally, we can directly control it without having to go through zmote.io server.
Sending IR codes
zmote requires IR code specification in a specific JSON format, as described in comments below:
{ // Modulation frequency "frequency": 38000, // Sequence of ON and OFF times, described in number of cycles // for the given modulation frequency "seq": [76,1064,15,60,15,136,15,2401], // Number of entries in 'seq' "n": 8, // Repeat code specification: [,,] // count: number of times to send repeat code // start: start index in 'seq' for repeat code // end: 1 + end index in 'seq' for repeat code "repeat": [0,0,8] }
Above code is to trigger shutter for a Nikon DSLR camera. We can send it to our zmote as:
$ curl -X POST -H 'Content-Type: application/json' -d '{"frequency":38000,"seq":[76,1064,15,60,15,136,15,2401],"n":8,"repeat":[0,0,8]}' http://192.168.1.7/18-fe-34-f2-e9-58/api/ir/write {"status":"ok"}
Note that we do not need authentication when accessing a zmote locally, but we need its MAC address.
Return status of ok indicates that code is accepted and that zmote has started transmitting it.
We may get return status as busy. A busy status indicates that zmote is busy transmitting earlier code and cannot accept a new code right now. That can happen with a long code or a code with many repeats. In such cases, we should wait for some time and then try sending again.
We also may get return status as badformat, which means that the IR code we sent is not in acceptable format.
Sending IR codes remotely
In case when zmote is not available locally, but it is connected to zmote.io server, we can send IR codes to it through the server. Yes, as you guessed, this API requires an authenticated client. It is time to use authentication cookies we saved in a file in earlier steps.
Note that we will also need widget id that we got during zmote discovery.
$ curl -b zmote-cookies -X POST -H 'Content-Type: application/json' -d '{"frequency":38000,"seq":[76,1064,15,60,15,136,15,2401],"n":8,"repeat":[0,0,8]}' http://v1.zmote.io/widgets/5607e785bacb1f187a71a9c2/api/ir/write { "status": "pending", "_id": "562a04548b1a4a0e005323b8" }
Since it may take some time for our command to reach zmote through MQTT, this API returns without waiting for a response from zmote, with a pending status.
We also get a command id, which we can use to query status of our pending request:
$ curl -b zmote-cookies http://v1.zmote.io/widgets/5607e785bacb1f187a71a9c2/command/562a04548b1a4a0e005323b8 {"status":"ok"}
Return status can still be pending or one of ok, badformat or busy as with sending IR codes locally.
Recording IR codes
zmote has an IR receiver (in front), so it can also be used to record IR signals.
First, we need to trigger recording of IR signals:
$ curl http://192.168.1.7/18-fe-34-f2-e9-58/api/ir/trigger {"status":"ok"}
Then, we need to poll zmote at regular intervals for any received IR signals:
$ curl http://192.168.1.7/18-fe-34-f2-e9-58/api/ir/read {"status":"ok","trigger":[236,51994,144,1387,8487,4155,567,1547,569,1545,572,486,566,494,570,488,571,488,569,489,568,491,569,489,568,491,570,1544,570,1544,564,1551,571,487,571,487,566,492,569,23969,569,1544,568,1546,568,492,564,494,567,491,565,493,566,492,567,491,568,491,565,493,568,1547,570,1545,571,1543,566,493,567,491,542,516,567]}
In the return message, trigger is a sequence of ON and OFF times, in micro-seconds, recorded by zmote.
Since the IR receiver may catch noise, partial or false signals, this recorded sequence needs to be validated before use. There are many free and paid tools available for such analysis. Server at zmote.io has such a tool accessible online for developers and hackers to use it.
Let's analyse above received sequence. The JSON obtained above API can directly be POSTed to zmote.io server for analysis:
curl http://v1.zmote.io/irp/decode -X POST -H 'Content-Type: application/json' -d '{"trigger":[236,51994,144,1387,8487,4155,567,1547,569,1545,572,486,566,494,570,488,571,488,569,489,568,491,569,489,568,491,570,1544,570,1544,564,1551,571,487,571,487,566,492,569,23969,569,1544,568,1546,568,492,564,494,567,491,565,493,566,492,567,491,568,491,565,493,568,1547,570,1545,571,1543,566,493,567,491,542,516,567]}' {"protocol":"JVC{2}","device":3,"obc":28,"misc":"no repeat"}
Our analysis shows that the recorded sequence matches JVC protocol with device = 3 and obc (or function) = 28.
It is possible for analyser to not find any valid sequence, in which case, it will return not found error.
It is also possible for analyser to wrongly classify a given sequence. It is recommended to record a sequence two or three times, analyse them independently and only then conclude about its correct protocol / format.
Once we are sure about signal format, we may want to convert it to the format zmote expects and save it so that it can be sent to zmote at a later time whenever required. Server at zmote.io offers an API for that as well:
$ curl http://v1.zmote.io/irp/encode -X POST -H 'Content-Type: application/json' -d '{"protocol":"JVC","device":3,"obc":28}' {"frequency":37900,"n":36,"repeat":[0,2,36],"seq":[320,159,20,60,20,60,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,60,20,60,20,60,20,20,20,20,20,20,20,899]}
It is recommended to test this code at least once with actual device before saving it for future use.
Note that some IR protocols (e.g. RC5) use a toggle bit, which is to be toggled on successive key presses, to distinguish it from repeat code (long press). For such protocols, there are two IR codes, one with toggle = 0, other with toggle = 1. Such codes can be generated using misc field as follows:
$ curl http://v1.zmote.io/irp/encode -X POST -H 'Content-Type: application/json' -d '{"protocol":"RC5","device":2,"obc":8,"misc":"T=0"}' {"frequency":36000,"n":22,"repeat":[0,0,22],"seq":[32,32,64,32,32,32,32,32,32,64,64,32,32,32,32,64,64,32,32,32,32,3264]} $ curl http://v1.zmote.io/irp/encode -X POST -H 'Content-Type: application/json' -d '{"protocol":"RC5","device":2,"obc":8,"misc":"T=1"}' {"frequency":36000,"n":22,"repeat":[0,0,22],"seq":[32,32,32,32,64,32,32,32,32,64,64,32,32,32,32,64,64,32,32,32,32,3264]}
Conclusion
In this project, we covered most important zmote APIs that a user / hacker / learner may need.
Information provided here can be used to control IR-controlled gadgets from a script, a web page or an automation system.
We also saw how IR codes can be sent remotely when zmote is not available in local network. This feature alone can open up a lot of IoT / home automation applications.
In the end, we saw how IR signals can be captured from a physical IR remote, analysed for correctness and re-sent using zmote. This method is useful for learning more about IR signals and their format, as well as to find out discrete (hidden) IR codes for many devices.
-
Using zmote with your own MQTT broker
10/12/2015 at 08:06 • 0 commentszmote is typically controlled via a REST API when you are on the same network as zmote. You can get more details about the REST API here.
zmote does support MQTT as well, but we intended this to be used when controlling the zmote from outside its network. There's usually no other way to get through your router's firewall when you are outside of your home network without having to do additional configuration. And it wouldn't be very safe anyhow.
MQTT makes the process safe and painless. The zmote connects to our MQTT broker and authenticates itself. It can then be controlled via the broker by sending messages as described here.
But perhaps that is not you want. Say you have your own MQTT broker and you want zmote to connect to it instead. Turns out you can do this easily enough without having to modify zmote's firmware.
Step 1: Determine your zmote's IP and MAC
There is a way to determine your zmote internal IP address by querying zmote.io (again, ourAPI document has all the details). But I'll assume you know how to get it IP on your own (by checking your router's web interfac, say, or simply by guessing and pinging). First, check that you are right:
curl http://<zmote_ip>/api/wifi/mac
This should return something like this:{"ap_mac": "1a-fe-34-f3-b4-6e", "sta_mac":"18-fe-34-f3-b4-6e"}
Step 2: Save the default MQTT Broker IP and Port
Next query the zmote for the default MQTT broker it is connecting to:
$ curl http://192.168.0.100/18-fe-34-f3-b4-6e/api/config/mqtt_server {"mqtt_server":"104.154.71.241"} $ curl $http://192.168.0.100/18-fe-34-f3-b4-6e/api/config/mqtt_port {"mqtt_port":"2883"}
Keep these written down somewhere for when you need to go back.Step 3: Change it to your MQTT Broker IP and Port
You can change this via corresponding `POST` commands
$ curl -X POST -H 'Content-type: application/json' -d '{"mqtt_server":"xxx.yyy.zzz.nnn"}' http://192.168.0.100/18-fe-34-f3-b4-6e/api/config/mqtt_server $ curl -X POST -H 'Content-type: application/json' -d '{"mqtt_port":"nnn"}' http://192.168.0.100/18-fe-34-f3-b4-6e/api/config/mqtt_port
Step 4: Reboot
Reboot your zmote using
curl http://192.168.0.100/18-fe-34-f3-b4-6e/api/wifi/reset
When the zmote come back up, it should connect to your broker instead of its default. You can then issue it your commands via your own broker.Hold On
Changing the MQTT broker will break your ability to control your zmote via http://zmote.io, our web app.
I'd still recommend the REST API over MQTT for several reasons.
- The REST API is easier to use -- you post to a particular URL a JSON object as command and you get a JSON response back telling you if all went well.
- It is faster -- there is no round tripping through an intermediary. You client speaks one-to-one with the zmote
- It works from any client that can do simple HTTP (a browser or even another network-connected IoT device)
But if you are comfortable with MQTT and have your own infratructure that makes that simple for you, you can use it by all means. If you think we have gotten our MQTT API all wrong and, in fact, it is better than the REST API, we'd like to hear from you.