After setting up OpenHAB, we are ready to run it. It’s exciting to see that it works. I imagine to control outlets, light switches and light bulbs from my phone.

OpenHAB isn’t tied to any specific devices or protocols. It talks to various devices by binding which is extensible. There’s a z-wave binding to communicate z-wave devices. So first thing to do is to add z-wave binding. After you add z-wave binding to your OpenHAB, you can use it to find your z-wave devices. There are two steps. First is to add a z-wave controller. Then include various z-wave devices.

First, install a z-wave controller. A z-wave controller acts like a bridge between your other z-wave devices and OpenHAB. The controller understands z-wave network and protocol. OpenHAB sends commands to and receives states from z-wave devices via the controller. Thing of it like a Bluetooth module. Without it, your computer won’t find any Bluetooth devices or use them. A z-wave controller is usually a stick or a module attached to your computer. I bought Aeotec Z-Stick Gen5. It’s straightforward to add it to OpenHAB. You can do it from Paper UI or HABmin. Go to “Extensions” and add “Z-Wave Binding”. The controller will then appear in Inbox and you can add it. You need to at least configure the serial port for your controller. This is to tell what device on your computer is the z-wave controller. You can list all /dev/tty* and find the one that’s added when you plug in your stick. Or you can find it from “dmesg”. Its name is /dev/ttyACM0 on my machine. Then you configure your controller and set the serial port.

Then you can include your other z-wave devices. I found that each device I bought came with the instruction about how to include it in a z-wave network. But there’re some tricky steps. I’ll only point out the tricky steps since otherwise it’s straightforward from the instruction.
1. Turn your z-wave controller into inclusion mode. The instruction usually says to press a button on the z-wave controller. You don’t need to do that. You turn it into inclusion mode from OpenHAB UI. Add a new thing and select “Z-Wave Binding”. OpenHAB will make your z-wave controller into inclusion mode for 30 seconds.You should have time to proceed to next steps.
2. OpenHAB may not actually initialize your devices even though it shows up in your thing list on UI, especially for battery devices. I still try to understand how it works. My guess is that OpenHAB needs to wake up the devices a couple times and get the information from the device. This is done at OpenHAB side. Even if you press wake up button on your devices, it may not help. Before it’s fully initialized, you may see “Unknown Device” for your device. Sometimes it’s showing the right type and name, but channels’ values are not available. One way to check whether it’s fully initialized is to check /openhab/userdata/zwave/. There’s should be an nodeXXX.xml file for your device. XXX is a number assigned to your device. If you turn on debug log when you add your z-wave device, you’ll find the node number.
3. Even if the nodeXXX.xml file is created, OpenHAB may still not be able to get device states or send commands to it yet. You may need to wait one day or two. I guess OpenHAB needs to wake up the devices a few times to be able to communicate with it.
4. Paper UI is created for Eclipse SmartHome. It’s not tailored for OpenHAB 2. You may find sometimes it’s not working as you expect. I suggest to use HABmin.
5. Turn on debug logging for z-wave binding. You can run /openhab/runtime/karaf/bin/client to get to karaf console. And run the command log:set debug org.openhab.binding.zwave.

I spent a couple days trying to figure out why I couldn’t add my device. It’s always showing “Unknown Device” or its state wasn’t updated. Then I first discovered that I didn’t need to press the button on the z-wave controller to be in inclusion mode. Then I learned that I may need to try to include/exclude the devices a few time to have the device added correctly. Last, the state may not update immediately, but it will in a day or two. The OpenHAB community is a great resource. There are friendly users and developers help to troubleshoot. It’s frustrating at first when things don’t work. Then it’s exciting when you see you can control from your phone. I encourage you not to be afraid of trying out and obstacles. It’s worth the efforts to learn and to improve.

OpenHAB is an open source home automation system. It’s vendor and technology agnostic and extensible. Every device is supported and communicated through corresponding addons and plugins. In theory, it supports most smart devices no matter whether its protocol is z-wave or ZigBee, etc. It’s now in 2.0 beta 4 which is based on Eclipse SmartHome which makes it easier to create new plugin and add new devices.

I like to use Docker too. It’s easier to manage production and development environment. As long as I create the Dockerfile, I can rapidly set up the exact same environment to run my OpenHAB. I don’t need to worry about differences on the OS, and the configuration is the same.

The official docker image for OpenHAB is based on Ubuntu and it always gets the latest successfully built OpenHAB snapshot which means it may change nightly. Whenever you run the command to create such a container, the OpenHAB version may be different. Besides, I prefer CentOS to Ubuntu. So I decide to create a new Dockerfile for myself. First, it’s based on CentOS. second, it always installs the same OpenHAB version unless you change that. It’s straightforward to create a new Dockerfile for OpenHAB since I could copy most from the current official docker image. But I did find some nuances that broke the whole things. Below are the changes I made and the workarounds to the problems.

  1. Download OpenHAB 2.0 beta 4.
    • You can find the download link for the version from here.
  2. Install Oracle Java
      • I don’t find Oracle Java in CentOS repository and I cannot use yum to install it. Fortunately, I found this Stack Overflow question and used wget to download the rpm from Oracle Java website. Here’s the command to download 8u102:
        wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u102-b14/jre-8u102-linux-x64.rpm"
  3. Problems in setting up the user and permissions.
    • The official docker image creates a few groups and the user openhab. It’s running the daemon as the user openhab. First, some gids of the new groups in the official docker image conflicts the built-in groups in CentOS. Second, For some reason, it seems to me running as the user openhab doesn’t have access to /dev/ttyACM0 which is the z-wave device. Even though I set the right groups and permissions in the docker and the permissions in the host. I ended up running everything as root in docker. It’s a potential security issue. The process running on docker is running on the host as root too.
  4. Setting up Eclipse in Docker. This is to allow you to develop on the docker image.
    • Eclipse is a GUI. How to work with the GUI? One way of doing it is to pass $DISPLAY to the container and run “xhost +” on the host. This will allow the docker to use the host x server. But doing that is a security concern since you open up your host.
  5. Install maven and ant.
    • Don’t install them via yum. That’ll pull in OpenJDK. Remember we need Oracle Java to run. So I download the tar files from the websites and set up the $PATH.
  6. Run it.
      • If you don’t need to do development, you can keep the command from the original Dockerfile. That is,
        ENTRYPOINT ["/openhab/entrypoint.sh"]
        CMD ["server"]

    Otherwise, you can just comment out ENTRYPOINT and CMD and start shell from the docker image. Remember, to expose all the ports from your docker container via the option “-P” when you start your container.

That’s how I set up the docker image. It took a few trial and error. Most were spent on setting up the user and permissions. It’s mysterious to me. I think I already set up the permissions right but I still ended up using root. But it works fine in that approach. Development is fine. I hope you can explore OpenHAB world and enjoy it.

I’m sure you’ve used data binding in WPF. There are five BindingMode: Default, OneTime, OneWay,  OneWayToSource, and TwoWay.

OneWay is best for read-only property. But if it’s not done correctly, it’ll break the binding and the target won’t be updated.

Here’s how it’s broken: call SetValue on the control to set the target directly. What happens here is that WPF will set the value of the target to the one passed in SetValue. That will overwrite the binding. Since the binding is OneWay, WPF cannot set the source, so it need to remove the binding to set the value. After that, even if the source is updated, the target sill stay the same. With that in mind, we must not throw exceptions in the setter of the source and the converter if that exists.

This is something we need to take into account when we set up OneWay binding. Always update the source, instead setting the target. If you’re creating a library and set a dependency property on the control directly, you’re setting the trap to your library users. This is rather difficult to debug.

There’s a problem in touching a select element on Microsoft Edge or on Windows 10 Phone app.
When you touch the select element, it won’t open the options or the options are open twice.
It seems to be interfered with Ionic Framework’s tapping (http://ionicframework.com/docs/api/page/tap/).
The solution is simple: disabling the tab system.
For select element, I use

<select data-tap-disabled="true" ...></select>

That solves the problem. Tapping on the select element will open the options correctly.

I use ui-router (https://github.com/angular-ui/ui-router) to route the url to state. For each state, we can specify the controller and the view. When transitioning from one state to another, we need to pass some data.

The way to specify a state is

$stateProvider.state('StateName', {
    url: 'request url',
    templateUrl: 'html file path'
})

There are a few ways to pass data to the state.

  1. Set the parameter in the url. For example, “contacts/{contactId}”.  And use $stateParams to get the value. For example, $stateParams.contactId.
  2. In some cases, we don’t want to specify parameters in url. Then we still can specify parameters in the state. e.g.
$stateProvider.state('StateName', {
    url: 'request url',
    params: {
       param1: null,
       param2: null
    },
    templateUrl: 'html file path'

Then you still can use $stateParams.param1 or $stateParams.param2 to get the values.
The way to set the parameter is:

$state.go('StateName', {param1: 'params Value'});

That’s it. We can pass various parameters to the same url and the state should be able to handle it.

I developed a mobile app recently. VS is an excellent tool in managing the project and debugging. I would like to start from setting up the project in VS, followed by my experience in my mobile development journey.

The app is a bookkeeping of your investment. Your investment can be in the brokerage account, retirement account or HSA. Besides bookkeeping, it also calculates the rate of investment.

First of all, I use Visual Studio 2015 Community with Apache Cordova Tool. I chose to install Windows phone 10 SDK. You can install the Android emulator and the Android SDK. It’s up to your target platform.

VS.Installtion

Note that even though you just want to target Windows 10 and Windows Phone 10, you still need to install Windows Phone 8.1 Tools and SDKs. Otherwise you won’t be able to debug it on your Windows 10 Phone. It complains that bin/arm/dbghelp.dll is not found and it comes with Windows Phone 8.1 Tools.

Framework can improve productivity and accelerate development. It provides the backbone of the application and glue all major parts together. I just need to follow the pattern and fill in the parts. I chose Ionic framework.

What UI is suitable for this app? Ionic provides some templates: simple, tabs and side menu. I think side menu provides the largest real estate on the screen, while flexible in navigation.

It’s easy to create an Ionic project in VS. In the “New Project” dialog, search Ionic in the Online tab, then download the one you like.

VS.searchIonic

After the template is downloaded, you need to re-open “New Project” dialog, and Ionic project templates are in the Installed tab.

VS.newIonic

Since it’s bookkeeping, it needs to persist the data. Sqlite is suitable in the mobile application. I found a plugin at GitHub (https://github.com/litehelpers/cordova-sqlite-ext.git).

In VS, open config.xml (View Designer), then add a custom plugin. Use the git repository and install it. VS.addPlugin

So far, I’ve set up the project.  The journey has started.

I recently noticed my VPS is slow. The blog takes a long time to show me any content. When I log in vis SSH, I usually don’t see what I type in immediately. The command is echoed a few minutes later.

I started my investigation. I ran ‘top’. CPU doesn’t run crazily. Memory isn’t loaded heavily. There’s no suspicious process. Everything looks good. But the connection is still slow! I asked the VPS provider. Hey, why is my VPS slow to respond when CPU and memory aren’t overloaded? The support team took a look and responded to me with one IP address 191.96.249.54 that established many connections to my VPS. I then searched the IP address online and found this StackOverflow question (http://serverfault.com/questions/778831/how-to-block-an-attack-on-wordpress-using-ufw-on-ubuntu-server). It’s an attack! Somebody suggested to use ipsest to add a blacklist. Probably that’s the way to go, because when I looked at Apache log, there’s also connection from 191.96.249.53. They’re from the same organization.

I found the solution. I installed ipset to find out that it didn’t run. I got this error:

ipset v6.11: Cannot open session to kernel.

Some articles online say it needs kernel patching. But I don’t control kernel on my VPS. So I contacted my VPS provider again. We couldn’t just upgrade the kernel. But they suggested me an alternative solution: CSF (http://www.configserver.com/cp/csf.html).

CSF can do what ipset does. I just need to use the blacklist. Besides, it can monitor user log in and inform you when somebody tries to log in in a short time to figure out the password. There are other protections too. All are documented in the readme file. The configuration file contains explanation for all options. It is a lot of information to digest and you have to make your own choice. I’ll just put down some basic points:

  1. Set TESTING to 1 first. The value 1 will have CSF stop itself 5 minutes  after it’s started. So when you accidentally lock yourself out, you still can gain access to your VPS after at most 5 minutes.  Remember to set it back to 0 when you’ve tested your configuration file.
  2. TCP_IN and UDP_IN are the ports that incoming connections are allowed to connect to. At least, put your SSH port number in TCP_IN so that you still can access  to your VPS.
  3. On my system, CSF can’t find /usr/bin/host. It’s in its log file. Remember to check the log file for any errors and fix them.
  4. csf.deny contains a list of IPs from where the incoming connection are dropped. It supports CIDR notation (https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing#CIDR_notation). I put the suspicious IP addresses in this file.

After CSF starts to run. There is no connection from the suspicious IPs any more from Apache log file. The connection to my VPS is fast again.

I’m using angular-translate and angular-translate-loader-partial to translate an AngularJS application. angular-translate provides directives, filters and a service to get texts translated. It provides a few ways to load translation files. angular-translate-loader-partial is one loader that allows you to load the necessary translation files when you need them. This is what I’m using right now. The document from https://angular-translate.github.io/ covers all of them. But there’s a gap in the end to end scenario. The translation fails.

Here’s the summary of what need to be done from the document:

    1. Tell the translate provider to use the partial loader and the translation file path pattern.
      $translateProvider.useLoader('$translatePartialLoader', {
          urlTemplate: '/i18n/{part}/{lang}.json'
      });

      urlTemplate tells the loader how to find the translation file. In this example, it’s in /i18n/ directory. {part} will be provided later. {lang} is the language you use. It’s set later too.

    2. Set the preferred language and fall back languages in your module configuration function. e.g.
      $translateProvider.preferredLanguage('zh_CN').fallbackLanguage('en_US');

      That tells the translate provider to look for translation for Simplified Chinese, and fall back to English if it’s not found. This will set the {lang} for the loader.

    3. Load the translation file and refresh translation tables. This is done by
      $translatePartialLoader.addPart('contact');
      $translate.refresh();

      The translation file for ‘contact’ will be loaded. It sets the {part} in urlTemplate. So the translation file path is /i18n/contact/zh_CN.json.

      $translate.refresh() must be called every time a part is added. The document also suggests to refresh translation tables in event $translatePartialLoaderStructureChanged.

      app.run(function ($rootScope, $translate) {
        $rootScope.$on('$translatePartialLoaderStructureChanged', function () {
          $translate.refresh();
        });
      });
      

That seems straightforward. Everyone can add those code and start to use directives, filters or the service to translate their own applications. But that won’t just work.

Both $translatePartialLoader.addPart() and $translate.refresh() are asynchronous. When you use directives, filters or the service to ask for translation for a given id, the translation table may not be loaded! This is what happens in my application. The document doesn’t warn it, and doesn’t present a solution either. The solution is simple, however. Both loadPart() and refresh() return promises. You have to ask $translate to get the translation after the promise refresh() is resolved.  So you can do something similar to:

$translate.refresh().then(function() {
    $translate('TRANSLATE_ID').then(function(data) {
        $scope.SomeLabel = data;
    });
});

This is tedious. Every time when you try to translate something, you have to double check whether the translation table is ready. And you cannot use directives and filters. Because when the translation table becomes ready, it won’t update the directives and filters. Here’s an example to demonstrate the solution: http://plnkr.co/edit/MrliEBMed17f3yqeRqz3

angular-translate is flexible in loaders and how to do translation (directives, filters or services). But there are some undocumented limitations (or bugs). When you use partial loader, you cannot use directives and filters. But at least, there’s always another way of doing it. angular-translate still doesn’t fail at getting the work done.

In C#, covariant and contravariant allow implicit conversion for generic type arguments. But they’re not applied to struct or other value types including primitive type (except string) and enum.

Only an interface declaration can contain covariant and contravariant generic parameters.

A covariant allows to assign an object that is instantiated with a more derived type argument to an object that is instantiated with a less derived type argument. It’s declared with keyword out with the generic type parameter. For example, this declares an interface with a covariant generic parameter: interface ICovariantInterface<out T>.

A contravariant does the reversed. It allows to assign an object that is instantiated with a less derived type argument to an object that is instantiated with a more derived type argument. It’s declared with keyword in with the generic type parameter. For example, this declares an interface with a contravariant generic parameter: interface IContravariantInterface<in T>.

There are some built-in covariant and contravariant generic interfaces in C#, such as IEnumerable, IComparable.

Usually I would think that covariant in analogy to class hierarchy. It’s similar to that a derived class can be assigned to a base class/interface. For contravariant, it’s done in the opposite direction.

But we cannot use struct or other value types in covariant and contravariant. Both covariant and contravariant are applied to reference types. And reference types and value types have different memory layout.

So this is not allowed: IEnumerable<object> baseGeneric = new List<int>();.

This Guillaume Rouchon’s post illustrates how to add a custom IntelliTraece event. Mine is to complement it with an enum type and updates in Visual Studio 2015 Update 2.

Let me summarize how to add a custom IntelliTrace event. The file you have to change is in a sub folder of Visual Studio installation folder, <VS installation folder>\Common7\IDE\CommonExtensions\Microsoft\IntelliTrace\14.0.0\en\collectionplan.xml. You need to have admin privilege to do that. This file only affect F5 debugging in Visual Studio. If you are using IntelliTrace standalone collector, you have to pass the collection plan file to the command line.  So you can modify default one that comes with the standalone collector or write your own one.

What you need to do to add a custom event is

  1. Add a category under TracepointProvider/Categories
  2. Add an assembly under TracepointProvider/ModuleSpecifications
  3. Add your own diagnostic event specification under TracepointProvider/DiagnosticEventSpecifications
There are two ways of querying parameter values and returned values. The first is DataQuery. It’s a simple declarative way using dot notation to get values of the parameter or the field in the parameter. It only supports primitive types. The other way is ProgrammableDataQuery. You have to provide your own IProgrammableDataQuery implementation to query a complex type.
For enum, we’re going to use DataQuery.
We need to specify a type in the data query for enum. Intuition tells us we can use the enum type. But that’s not working. The right type should be the underlying integral type. For example, int. The value is also an integral value too.
Let me illustrate it here.
I create a sample console application
using System;
namespace ConsoleApplication1
{
    enum Color
    {
        Red,
        Green,
        Blue
    }
    class Program
    {
        static void Main(string[] args)
        {
            PrintColor(Color.Blue);
        }
        static void PrintColor(Color color)
        {
            Console.WriteLine("Color: " + color);
        }
    }
}

Let’s change the collection plan.

1. Add a new category.

<Category Id="enumSample" _locID="category.enumSample">Enum Sample</Category>

2. Add a new module

<ModuleSpecification Id="sample">ConsoleApplication1.exe</ModuleSpecification>

3. Add a diagnostic event specification
We’re going to query the parameter color in the method PrintColor.

      <DiagnosticEventSpecification>
         <CategoryId>enumSample</CategoryId>
         <SettingsName _locID="settingsName.ConsoleApplication.PrintColor">PrintColor (Color)</SettingsName>
         <SettingsDescription _locID="settingsDescription.ConsoleApplication.PrintColor">Print the color</SettingsDescription>
         <Bindings>
            <Binding>
               <ModuleSpecificationId>sample</ModuleSpecificationId>
               <TypeName>ConsoleApplication1.Program</TypeName>
               <MethodName>PrintColor</MethodName>
               <MethodId>ConsoleApplication1.Program.PrintColor(System.Int32):System.Void</MethodId>
               <ShortDescription _locID="shortDescription.PrintColor.Color">Print Color "{0}"</ShortDescription>
               <LongDescription _locID="longDescription.PrintColor.Color">Going to print the color in integral value "{0}"</LongDescription>
               <DataQueries>
                 <DataQuery index="0" type="Int32" name="color" query="" _locID="dataquery.PrintColor.Color" _locAttrData="color"></DataQuery>
               </DataQueries>
            </Binding>
          </Bindings>
      </DiagnosticEventSpecification>

Save the file and restart VS. The custom event shows in Tools/Options/IntelliTrace/IntelliTrace Events

IntelliTraceEventOptions

When I debug the program, the custom event appears in the Events table. Look at the description! It shows me the integral value of the enum value.IntelliTraceCustomEvent

How simple it is to add a custom IntelliTrace event! This is helpful to diagnose a piece of code path that’re prone to error in changes. When you have your own collection plan for the program, you can just debug the program and let it run, and spot the error from the Events table.