May
20
Widget, it’s got a widget…
13 years ago, mid-May | Leave a Comment
John Smiths have a lot to answer for there I can tell you.
It’s been a busy few weeks at work while we launch our revamped online shop and how did I go about relaxing? I did more development work at home. Since we’ve moved into our house I haven’t really had a lot of time to do much development, more tiling grouting and renovating than anything else. This last week though, as we started to get on top of things, I took some time to put together a widget for Android. I’ve been collecting, storing and graphing data from various sensors around the house for some time now and while the graphs are pretty they aren’t really a quick or efficient way of reading the status at a glance.
Step forward the widget. Each widget requests XML data from the server and presents it on the widget, this allows an infinite number of widget variations since the only change is the data received. In other words, if it’s in the database it can be served. The widget itself has a number of coloured backgrounds which the server data can trigger if and it’s also capable of playing an alarm sound if required. I still need to fix this because the alarm sound triggers on each update and there’s currently no way to tell the widget to be quiet.
Update: Fixed this, tapping the widget will silence it until the next alarm trigger ie once the state returns to normal and then alarms once again.
Incidentally, since I only have a self signed certificate on my server but still wanted encrypted access I had to extend the DefaultHttpClient. By default Android will just refuse to connect to a server if the certificate isn’t signed by one of the ‘trusted’ certificate authorities – it wont tell you that it refused, it’ll just silently fail. You’d only ever really know if you’d connected to your device via adb and done a logcat. You can get round this by adding a keystore to your application, which is good enough for testing or personal applications.
If you want to do this you need to make sure you have the Bouncy Castle cryptography jar in your CLASSPATH. The first thing you’ll need is a copy of the certificate which I hope you’ve generated and installed on your server. If you need to get a remote server certificate you can use the following command (all one line).
echo | openssl s_client -connect your.server.goes.here:443 2>&1 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > mycert.pem |
Replace the “your.server.goes.here” with your server, obviously. Once you’ve done that export the CLASSPATH to the Bouncy Castle jar you downloaded replacing the path I’ve used with the location you downloaded it to:
export CLASSPATH=bcprov-jdk16-146.jar |
You can now use the following script, note that the keystore name is appkeystore.bks as on line 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/bin/bash CERTSTORE=appkeystore.bks if [ -a $CERTSTORE ]; then rm $CERTSTORE || exit 1 fi keytool \ -import \ -v \ -trustcacerts \ -alias 0 \ -file <(openssl x509 -in mycert.pem) \ -keystore $CERTSTORE \ -storetype BKS \ -provider org.bouncycastle.jce.provider.BouncyCastleProvider \ -providerpath /usr/share/java/bcprov.jar \ -storepass MyPaSsWoRd |
Replacing the MyPaSsWoRd on line 19 with a password of your choosing, you’ll need it later too. If you run the script you should get some output like this, obviously with your server information – remember to answer yes to the “Trust this certificate” prompt.
Owner: EMAILADDRESS=info@ automated.it, CN=www.automated.it, OU=Tech, O=Automated IT, L=Eye, ST=Suffolk, C=GB Issuer: EMAILADDRESS=info@ automated.it, CN=www.automated.it, OU=Tech, O=Automated IT, L=Eye, ST=Suffolk, C=GB Serial number: 4dce9c74 Valid from: Sat May 14 16:15:00 BST 2011 until: Sun May 13 16:15:00 BST 2012 Certificate fingerprints: MD5: 32:0F:33:0C:42:8D:FF:78:90:46:31:7A:4F:D3:33:23 SHA1: BD:A8:B8:21:B1:48:C3:53:BB:01:22:65:9E:00:6E:14:7B:DE:4E:F6 Signature algorithm name: SHA1withRSA Version: 1 Trust this certificate? [no]:yes Certificate was added to keystore [Storing appkeystore.bks] |
Create a directory called “raw” in your project’s ‘res‘ folder and copy the appkeystore.bks file to it.
In your Android application or widget you can now create a new class for the following code which will extend the original DefaultHttpClient class. You’ll want to change the package name on line 1 to match your application.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | package your.package.name.here import android.content.Context; import org.apache.http.conn.ClientConnectionManager; import org.apache.http.conn.scheme.PlainSocketFactory; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.conn.SingleClientConnManager; import java.io.InputStream; import java.security.KeyStore; public class myHttpClient extends DefaultHttpClient { final Context context; public String UserAgent="Android dataWidget (ScaredyCat 0014150511-0.1b) [http://blog.automated.it]"; public myHttpClient(Context context) { this.context = context; } @Override protected ClientConnectionManager createClientConnectionManager() { SchemeRegistry registry = new SchemeRegistry(); registry.register( new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); registry.register(new Scheme("https", newSslSocketFactory(), 443)); return new SingleClientConnManager(getParams(), registry); } private SSLSocketFactory newSslSocketFactory() { try { KeyStore trusted = KeyStore.getInstance("BKS"); InputStream in = context.getResources().openRawResource(R.raw.appkeystore); try { trusted.load(in, "MyPaSsWoRd".toCharArray()); } finally { in.close(); } return new SSLSocketFactory(trusted); } catch (Exception e) { throw new AssertionError(e); } } } |
Note that the password used in the script earlier should match the one on line 37– use your own different password in production for security purposes. You can now use the class as required in your application, for example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | myHttpClient httpclient = new myHttpClient(context); httpclient.getCredentialsProvider().setCredentials(new AuthScope(host, port), new UsernamePasswordCredentials(username,password)); BasicHttpContext localcontext = new BasicHttpContext(); BasicScheme basicAuth = new BasicScheme(); localcontext.setAttribute("preemptive-auth", basicAuth); httpclient.addRequestInterceptor(preemptiveAuth, 0); HttpHost targetHost = new HttpHost(host, port, scheme); HttpGet httpget = new HttpGet(url); httpget.setHeader("User-Agent", httpclient.UserAgent ); |
Once I’d got the SSL connection I could get the application to download a list of sensors from the database, this only happens the first time the first widget is added to the home screen. I need to sort a way of allowing the user to delete the list if more sensors are added. At the moment clearing the data for the widget application works but it erases the widget settings too.
When I’m at home I want to connect to a local server for the information for the widgets and when I’m out and about (using a 3G connection) I want to connect to an external server. I implemented the ability to automatically switch when my phone connected to my WiFi access point. One final thing I did was to add the ability to long press on a text field and then select ‘Save as default‘ allowing things like servers, Wifi MAC address, username and password to be saved as the defaults for all widgets.
Tagged with: 1-Wire • android • currentcost • opensource • software
May 20, 2011 21:10
Oct
20
I am an IAMS cat
14 years ago, mid-October | 1 Comment
After an eternity of waiting Current Cost have finally made their IAMS available to buy. One might have expected a fanfare, we’ve been waiting for these for over a year now, but there was nothing, no blog post, no tweet, nada. Thankfully Kevin Turner (@netcompsys) spotted them for sale. For those not familiar with the IAMS (Individual Appliance Monitors) when used in conjunction with a Current Cost monitor (compatible with Trec, Envi, EnviR ,EnviRW) an IAM allows you to measure the electricity usage for an appliance. Multiple IAMS can be used with a single monitor to give you an overview of your total usage.
As you can see from the graphs at the bottom of this post there’s clearly something not quite right with my fridge-freezer. Every hour for half an hour it uses 400 Watts. Lets do a couple of calculations and find out what this really means in electricity usage and how much money I’m frittering away.
400 / 2 == 200 (Watts per hour) - half 24 * 0.2 == 4.8 (kWh) 4.8 * 365.25 == 1753 (kWh per year)
You read that right. It’s using 4.8kWh a day! Most modern fridge freezers use around 300kWh a year, depending on their size, and I’m using nearly six (6) times that. Let’s say I’m paying 12.5 pence per kWh. In one year my current fridge-freezer is costing me £219.13 versus £39.50 if I were to buy a new one – that’s £179.63 difference. If I pick a new fridge-freezer that uses less than 300kWh a year the saving increases. I could almost buy a new fridge freezer each year with the money I’m wasting!
As you can see, being able to measure what’s going on by using the IAMS has highlighted that I really need to replace my existing fridge freezer with something much more efficient.
Taking another look at the graph you can see one other area that needs to be looked at. Those computers are eating a lot of electricity. Only this morning did I get round to plugging my laptop into an IAM to measure it’s power use. 45W .. all day .. every day.. Let’s just say that it’s prime for replacement but also that it does now get powered off when it’s not being used.
So, get measuring and get saving!
Tagged with: currentcost • electricity • iams
October 20, 2010 13:13
Current Electricity Use (15min)
iPhone/Webkit RSS Reader
Links
- automated home
- Automated It Technology News
- awooga!!!
- LinITX
- My Acer page
- My Asterisk pages
- My Work in progress (old)
- Noble Race Car
- openmoko / neo 1973 wiki
- planet openmoko
- Spadgecock Cumpants