Code review of a Publish/Subscribe Architecture using SignalR in Home Automation – Part 4
Previously, I covered an example of synchronizing webpages across multiple devices in the context of a Home Automation application which can control lights in a house using any internet connected device. I also covered the architecture and went into some detail around using a publish/subscribe approach to connecting the browsers, web application, and the agent that controls the lights in the home together.
In this post, I am going to go into some more detail around the code to connect the use case together.
First, let us cover rendering the initial html page.
Let’s start with the MVC viewmodel and show it is maps to the screenshot of the rendered page.
The viewmodel is nice and simple, to collections of objects that will be used to generate a list of push buttons and a list of toggle buttons. Below you can see the mapping of the collections to each column in the page.
This shows how the ViewModel maps to the User Interface
The controller is pretty straight forward as well. This is an example and for simplicity I am new’ing up the two repositories ...Don’t do this in your project, use constructor injection. The Index action, calls to the repositories and maps the two collections to the view model. Simple .
Here is how the controller populates the ViewModel
The mvc view to create the page using knockout
Let’s dissect the markup by library.
This view has three vectors we can discuss here.
jQuery Mobile html tags and css classes
ASP.Net MVC Razor markup to generate the Scene buttons, server side
KnockoutJS client side templating to create the toggle buttons and support synchronization across browsers
jQuery Mobile specific code underlined
In the figure above, the jQuery Mobile css classes have been underlined. These classes are used with the html tags by jQuery Mobile framework to make style the form and elements to match the screen shot. The jQuery mobile uses a combination of class values and some html5 data- attributes, that are specific to the jQuery Mobile framework. In this view the only additional attribute we need for the jQuery Mobile is the data-role.
ASP.Net MVC Razor syntax highlighted underlined
This code shows that a razor foreach loop is used to generate the html for the Scene buttons. This code is used to create the buttons server side, because the buttons do not need to be synchronized across the browsers. So writing this code using server side generation is the simplest way to create this portion of the page.
KnockoutJS specific markup is underlined
KnockoutJS uses more of the data- attributes to implement its databinding. For this view all the attributes that we use for the KnockoutJS functionality are all the same attribute, data-bind. It does have some nested syntax, for example we use a foreach loop to loop over all the Devices and create the toggle switch for each device in the collection. Another interesting feature that was needed was the attr construct using in the select html tag. The gist of what knockout is doing is just mapping html attributes to properties values on the model. This feels similar to the Razor server side syntax but it varies just a little bit since the binding code is run in the browser rather than on the server.
The KnockoutJS specific code is underlined
The jQuery Mobile constructs are underlined.
In the handlers for the toggle button and the push buttons, the hub is called and this is where we send the address of the x10 device and the scene to execute on the agents. We use the jQuery data function to pull a piece of application state data that is unique to each button. This is stored in the data-x10 element in the markup. Using signalR here makes the code clean because we just publish the message to the server and we do not need to handle a response as part of this method. We handle the response in the event handler we hook up in the hub.broadcastDeviceState message. The anonymous function takes two values, there are defined in the server side portion of the signalR code (I will show that in the next post). We setup a handler for the broadcastHeartbeat message as well. Similar to the previous function.
In the next post I will show the server side SignalR hub.
Follow me on RSS and Twitter