New User Interfaces

About 2 weeks ago I decided that something had to be done about the (number of) User Interfaces in our house. Especially for controlling the roller shutters from upstairs there was a need for a 2nd user interface. The touchscreen in the livingroom is being used a lot and we wanted the same convenience upstairs as well.

I’ve been tinkering with various touch screens on Arduino, FEZ Panda and the like, but I didn’t really like the size (~3″) and counting all the costs for a setup like that made me wonder if there could be a better choice. Why not buy a cheap 10″ Android tablet and make a web based interface? HTML5, websockets, ….

Setting Thermostat from smartphone

So I started looking around on the web for the right tools and I found jQuery Mobile.

The demos looked good, so I started creating some basic pages while keeping an eye open for a cheap tablet.

The first (test-)page I made was for changing the temperature setpoint of our central heating, just to see how hard it would be for me as a non-web-developer to create something that looked OK.

A slider, radiobuttons and an OK button were made very easy; it felt as if I’d done this before, but I haven’t – it’s very simple!

And if you look at the code (it’s great to create pages this way) I decided that jQuery Mobile will be it for the user interfaces I’m going to add.

And just look at the code; ain’t it sweet? 😉

<div data-role="page" id="tstat">
	<div data-role="header">
	  <h2>Thermostaat</h2>
	</div><!-- /header -->
	<div data-role="content">
	  <br />
    <label for="slider-1">Hoe warm wil je het hebben jochie:</label>
    <input type="range" name="slider-1"
    id="tstatslider" value="20" min="15" max="25" step="0.5"
    data-highlight="true" />
    <br />
    <fieldset data-role="controlgroup" data-mini="false">
    	<input type="radio" name="radio" id="radio-1"
    	value="choice-1" checked="checked" />
    	<label for="radio-1">Tijdelijk (tot volgend
    	  programma)</label>
    	<input type="radio" name="radio" id="radio-2"
    	value="choice-2"  />
    	<label for="radio-2">Continu</label>
    </fieldset>
    <br />
    <input type="submit" value="OK" onClick='do it;'
    data-icon="check" />
	</div><!-- /content -->

	<div data-role="footer" data-position="fixed">
  <div data-role="navbar">
		<ul>
			<li><a href="#home">Home</a></li>
			<li><a href="#">Weer</a></li>
			<li><a href="#">Cams</a></li>
			<li><a href="#luiken">Rolluiken</a></li>
		</ul>
	</div><!-- /navbar -->
	</div><!-- /footer -->
</div><!-- /page -->

Yep, this is definitely what I want and what I need!
So I created some more pages (lights, the roller shutters):

And right now I’m testing this user interface, cause I want to know how well it performs compared to our VB.Net touchscreen application in the living room, before I spend more time on it. First results are very good – 10 times faster than X10 😉

There are some issues I have to work on; things like the buttons not giving an audible feedback, making it secure so that this can also be used on our smartphones, etcetera.

But for now I’m happy with how this working out so far. A tablet has been bought too yesterday, so it looks like we’ll have our user interface upstairs real soon!

Testing drivers as Windows services

Now that my OpenTherm Gateway is operational, the interface to my Remeha Calenta has become almost obsolete; I could deactivate the whole Calenta driver now, cause the information from the OpenTherm Gateway is enough for me. But just shutting down the Calenta interface is not what I’m going to do – this is a great opportunity to test a driver while it’s running decoupled from the system – as a (Windows-) service.

I already did some small tests some time ago where I compiled a driver to a Console App; within minutes I had one running in my test-environment, but I didn’t go any further than that. And now that things are getting serious,  I decided to jump right to building a driver as a (Windows) service, which sounds like the best thing to do – I don’t see any benefit in having lots of drivers running as a Console App – a Service sounds much better.

So this evening I started reading on how to create a Service in Delphi, cause I’ve never done that before. Well with the TService class you’ve got a service installed in just a few steps.

The first thing I needed was some indicator to make the code service-aware. With all drivers built inside the ‘kernel’, it was very easy to get in- and outgoing data from driver to the event system, device objects, etcetera. That’s all gone when the driver is running as a service. So I had to alter some code so that the driver knows whether it’s running as a service or not; cause if so, it has to use MQTT to publish outgoing data instead of pushing it into a PC queue. Likewise, it has to subscribe to some relevant topics to be able to receive information from the outside world (e.g. the other Domotica system components).

Service-awareness was not that hard; it seems that checking the value of the Application.Mainform property is enough – if it’s nil, it’s safe to assume ‘service mode’ (probably Console mode as well, but didn’t check that).

Creating a MQTT equivalent for those internal queues won’t be that hard either; a single line of code has to be replaced so that the data is being published, instead of queued:


// 20121113
//DistributeToDevice(PhysicalAddress, copy(Buffer,1, PacketSize));

if gRunningAsService
then MQTTPublish(PhysicalAddress,copy(Buffer,1,PacketSize))
else DistributeToDevice(PhysicalAddress,copy(Buffer,1,PacketSize));

I also had to define whether a driver should be started from inside my Domotica system or that it was supposed to be running stand-alone as a service; for that I created an extra field in the driver table so that I wouldn’t end up with 2 running versions of the driver – the embedded one and the service instance.

Right now I have the Remeha Calenta driver running as a service – quick and dirty, just to see what happens and what has to be added and changed to make it reliable and most important: easy to work with.

Calenta Service

All that’s left to do is MQTT-enabling the Calenta driver and I can test this old-code/new-style driver without the fear of information loss, yet test as ‘live’ as much as possible 🙂

Opentherm Gateway operational

Opentherm Gateway and SimpleCortex side by sideToday I finished the monitoring part of the OpenTherm Gateway. The code running on the Simplecortex had proven to be reliable enough to start using it, so why not do just that 🙂

The OpenTherm Gateway you see on the right is my older one, built earlier this year and will be replaced by the new one once it’s finished.

Before I could start on the OpenTherm Gateway, I had to fix some issues which were the result of what I did last week. The MQTT driver was not as stable as I hoped; it worked fine for several hours, but it never made it longer than 48 hours, so I rearranged some code and it has been running fine since then.

Another thing I had to fix was that the Touchscreen, which was transformed to an MQTT client, was disconnected from the broker by the time I came home from work. The reason: the Touchscreen goes into hibernation when nobody’s at home to save energy, which leads to the broker closing the connection! Didn’t think of that one.. before, the touchscreen was a UDP listener, in which case there is no real connection… so I added a timer to the Touchscreen application that periodically checks the connection and re-establishes it when needed.

Back to the OT Gateway. The largest part of the work that still had to be done was preparing my Domotica system. The MQTT topics were already being received, but I had to do something about the payloads. The Opentherm Gateway produces a lot of bit values like for instance CH mode (Central Heating mode); payload ‘0’ means not active, ‘1’ means active. Well, I’m not going to pester users with terms like ‘ch_mode 1’ or ‘dhw_mode 0′; Central Heating mode active’ or ‘Hot water not active’ sounds more like it, right… But again, one of my goals is not to put texts like those hard-coded in any piece of code – not on the Simplecortex which publishes the information, nor in a Touchscreen app, or webpage or whatever.

So I felt really lucky that I started thinking about those things a long time ago and introduced so-called ‘Informationtypes‘ in my system in a very early stage. In a few words, an informationtype can transform a value that represents whatever to something a human can understand. For example with a door sensor, ‘0’ will be translated to ‘closed’ and 1 becomes ‘open’; but the same ‘0’ becomes ‘off‘ in the case of an appliance module. My Domotica system already does that for me and exposes both the ‘raw’ values (0/1 in case of booleans, unformatted data in case of numeric values, etc.) as the ‘formatted’ values (on/off, open/closed, floats with the right number of decimals). Raw data is nice, for computers. But not for humans! Currently, there are 150 informationtypes in my system (in the database, of course) ranging from on/off for a switch to the selected input on my AV receiver (0=”BD/DVD”, 1=”CBL/SAT”…).

So all I had to do was publishing those formatted values as well and I could present those values on a webpage and display something really meaningful … a new MQTT root hierarchy was born: /value.

And doing things this way, enabled me to reduce the code for the OpenTherm Gateway Device class to (almost) nothing more than this (the rest is all constants and type defs):

  case DataInfo.Format of
    flag8: Pin(iTopic).AsBoolean:=(Payload='1');
    u8,s8,u16,s16: Pin(iTopic).AsInteger:=StrToInt(Payload);
    f8_8: Pin(iTopic).AsFloat:=StrToFloatX(Payload);
    dowtod:begin
      { TODO : Finish }
    end;
  end;  //case

So now, when the central heating starts working, there’s (my system being the point of view) “/sensor/OTGW/flame 1” coming in and “/value/OTGW/flame Yes” going out. Now I can make a webpage without displaying meaningless numbers or having to translate those numbers locally that don’t (have to) mean anything to a human.

And here’s the result, showing parts of the information gathered with the OpenTherm Gateway.

 

Putting it all together

Today the time had come to implement some things I wrote about during the last weeks/months.

My Domotica system did already have a MQTT client for some time, but not in the right way. I added a MQTT client some time ago, but since life without MQTT has become unthinkable, I felt it was time to transform the client into a MQTT driver. The way I do things, each driver lives in its own thread, not the main VCL thread so to speak. This has several advantages and it also allows me to (re)start the MQTT driver when I need or want to. And I get some statistics about the amount of bytes going in and out, the number of events that occurred and so on. Finished that yesterday.

While working on the Simplecortex Opentherm Gateway code, I improved the code that automatically reconnects the Simplecortex to the MQTT broker. This is a very important aspect, cause I really don’t like resetting/rebooting things when the machine on which the MQTT broker runs, has rebooted for some reason; all clients should reconnect as if nothing has happened.. the new Simplecortex code had to be implemented in the Simplecortex code for my Smart meter as well.

Another thing I’ve been working on recently is the TFTP bootloader. I tested it numerous times, but didn’t implement it yet. With the second Simplecortex almost ready for action, the time had come to work on that too. So I changed both the Smart meter and Opentherm Gateway projects so that the resulting binary file was suitable to be downloaded by the TFTP bootloader and flashed the TFTP bootloader to my Smart meter Simplecortex.

And today I upgraded the VB.Net app running on our Asus EEE Top touch screen in the living room.

Touch screen

Until today, this DDMC Touch application got its information from my Domotica system by means of UDP broadcast and I changed that UDP part to MQTT subscriptions.  Since the way the information arrives is not that different actually, I managed to transform this touch application from UDP to MQTT in less than 2 hours. Commands sent from the touchscreen back to the system are still done the XML-RPC way, but that will be changed too.

And so today I’ve started using a new version of my Domotica system, updated the Smart meter code on the Simplecortex and updated the touch application. Enough changes in one day to give it some time and see if there are any serious bugs present – so the next few days, all I will do is watch, clean my office and do nothing else….

No wait… now I can spend some time on some other unfinished projects!