Ubiquiti UniFi WiFi and Haiku Big A** Fans Wall Controllers

If you’ve purchased either a UniFi access point or a Haiku/Big A** Fan recently, you may encounter a problem with wall controllers failing to control the associated fan. While the setup nearly works, the final verification step for the wall controller always fails from the app. Further, and confusingly, if you look at the clients list in the Ubiquiti controller, it’s very likely that you’ll see the wall controller listed with a valid IP address. However, that’s not enough to make everything work as expected.

There are two settings that seem to enable the wall controller to work properly. I discovered these after reading an article about setting up a Google Home/Chromecast. You don’t necessarily need to setup a new SSID and VLAN for your wall controller. That’s up to you. However, you will need to enable IGMP Snooping and MulticastDNS for the Wifi that the wall controller and the fan use.

IGMP Snooping / multicast enhancement is found here: Settings > Wireless Networks> WIRELESS NETWORK [EDIT] > Advanced Options and at the end, Enable multicast enhancement (IGMPv3).Edit Wifi Settings to Enable ICMP

Next, enable multicast DNS: Settings > Services > MDNS > [ON]

Enable Multicast DNS

As soon as I enabled these, the two wall controllers we have for two Haiku fans began to operate nearly immediately.

 

 

Visual Studio 2017 Anaconda Prompt Fix

For some reason, if you install the Python Tools for Visual Studio 2017, you’ll end up with an Anaconda command prompt that won’t work. It apparently is due to a path length limitation where the total target path exceeds some ridiculously small number in Windows for a shortcut.

Thankfully, the fix isn’t painful — it’s just frustrating that it needs to be done.

I’ve seen suggestions to use the old-school DOS 8.3 file paths, but I prefer to use something that still reads well and maps to other dev command line tools on my workstation.

I created a directory junction in an existing folder C:\Dev:

mklink /d c:\Dev\Anaconda3_64 "c:\Program Files (x86)\Microsoft Visual Studio\Shared\Anaconda3_64"

Specifically, I created:

C:\Dev\Anaconda3_64

which is a junction to:

c:\Program Files (x86)\Microsoft Visual Studio\Shared\Anaconda3_64

You can use any junction directory you want, but remember that it can’t be too long, or you’ll have the same problem with a different name/path. :) When using mklink, be sure to quote the path for the Anaconda install in the Visual Studio directory as shown above in the mklink example.

Next, I updated the command prompt with the new path:

c:\Dev\Anaconda3_64\pythonw.exe C:\Dev\Anaconda3_64\cwp.py C:\Dev\Anaconda3_64 %windir%\system32\cmd.exe /k c:\Dev\Anaconda3_64\Scripts\activate.bat c:\Dev\Anaconda3_64

Of course, you’ll need to substitute the path you used (just copy and paste into Notepad and do a quick search and replace with the full path I used).

It should start up without issue now.

Class Decorator with TypeScript and React

The syntax for creation and use of a class decorator written in TypeScript that works with a React.js component wasn’t obvious …, so I thought I’d document it here.

The decorator takes a constructor/class which could be used how ever you’d like (or substituted for something else entirely).

 

TS2688 with TypeScript, React Native, and MobX

To preserve my sanity if I should run into this again…. 

I created a React Native project, ejected it, and then converted it to use TypeScript. Things were going well until I started to use MobX. The following error occurred:

node_modules/mobx/lib/utils/utils.d.ts(1,23): error TS2688: Cannot find type definition file for 'node'.

Something as simple as:

import { observable } from "mobx";
may cause the error shown above. If you look at the utils.d.ts file mentioned in the TS2688 error line, you’ll see what’s causing the error:
/// <reference types="node" />
It seems like a harmless error and easily resolved. Usually when there are missing types, your first step should be to add them to your project. My first attempt was to add the @types/node to the project.
yarn add -D @types/node
Bzzt. That produces a whole new batch of errors due to duplicate definitions. There are quite a few classes and functions that are duplicates when React Native and Node declarations are both imported.
Apparently, this needs a stub for node so that the error can be bypassed (without changing or using other compiler switches like –skipLibCheck).
I created a new folder in the src tree called typings. In that folder, I created another folder, this time called node. And finally, in that folder, I created a nearly empty file called index.d.ts (the file contains a comment about why I created the file and a link to this blog post).
Folder structure
The project now compiles without issue. The declaration types that were needed by MobX are already included elsewhere, but the pesky reference directive forces the compiler to try to locate the types.

Flutter Demo application linking to BoardGameGeek.Com’s Hot Game List

I’ve built a slightly more interesting application using Flutter.  Using an XML feed from BoardGameGeek’s API, the application displays a list of the current hot games complete with thumbnail images.

Android Screen

Here‘s the code. I used a standard Flutter app template and also added a few packages to the project.

I’ve coded a substantial amount of Windows Presentation Foundation (WPF) and Silverlight code over the years. One of the concerns that often came up was the UI tree …, the more complex it was, the slower the app often was without lots of tricks. Using the new inspector for Flutter apps, I selected one of the images in the UI. Needless to say, there are a few objects created to represent the UI tree. In fact, I had trouble capturing the image for this blog post. :)


Flutter Nesting

I don’t have evidence that this generally will be a performance problem. Maybe with relatively simple mobile applications, a deep rich object based UI hierarchy won’t affect performance as much as it might in a desktop application of reasonable complexity. Regardless, it’s worth considering as you build a UI.

Back to what I built. When a user taps on a board game in the list, I’ve wired the code to call the _showGameItem below. I appreciate that there’s an easy way to navigate to a new page on the stack and show a UI, all within a single function. Of course, I could have split it into multiple builder functions if needed.

To register an event callback for the onTap, I’d tried finding a Widget that exposed it directly. I’m accustomed to elements having events (often bubbling events) that would have exposed something like onTap. However, with the exception of specialized widgets like Buttons for example, it’s not exposed on most Widgets (even those that have UI). So, at the outer layer of the items being shown in the ListView, I used a GestureDetector to capture the tap event:

I would have preferred that the Container to have the event available. Maybe it’s not as pure, but, meh. I’d like to reduce the noise of building a UI and adding yet another layer just to capture an event is a distraction.

Architectural elegance does not always lead to a framework that is easy or friendly.

While I wasn’t really concerned about performance of my application or the possible impact from hitting the BoardGameGeek API a few times, I used application storage to cache a copy of the XML data that’s retrieved from BoardGameGeek just to get some experience with the APIs. Further, I added code to store the next time the file can be updated to the SharedPreferences object instance (to prevent it from being updated too frequently). I liked the simple exception handling in Dart as it’s relatively low impact to handle a specific exception type without caring about the details by using the on clause (just by dropping the catch(e)).

I noticed that the exception handler can specify one or two parameters. The first is always the exception and the second is the stack trace (StackTrace).  I’m not sure why the stack trace isn’t part of the exception object though.

When the file is cached completely and successfully, the Widget state is updated, which triggers an application refresh, which is what happens on lines 29-32.

Had Flutter been an option in the earlier days of Android, it would have been a strong contender in the application building space, especially that it runs on Android and iOS. From reading some of the issues on Github, the general consensus is that the cross-platform Flutter competitor to beat is React Native. In fact, I’m surprised that it has taken Google this long to produce a potentially viable alternative to the Java Android development tools. I’d honestly thought they’d announce something several years ago (I’ve watched Google I/O for many years for the announcement).

If Android devices were upgraded more routinely (as are iOS devices), web technologies such as installed progressive web applications could be a serious contender and alternative for many application types. But, modern Android operating system versions are very slow to roll out (if ever) to the majority of devices.  Over half of Android devices are running Android 6.0 or earlier.

Android Developer Version Distribution

Until the Android OEM ecosystem delivers timely updates to all phones newer than 5 years, solutions like Flutter (and competitors) remain a potentially reasonable way to reach a large variety of devices without needing to update to recent OS releases. However, it may be that the hardware hosting older versions, such as 6.0/Marshmallow and earlier are not capable of adequately executing a modern app built with technology like is used by Flutter.

Continued concerns

I still find the syntax of building a UI to be cumbersome and frustrating for several reasons:

  1. Using code to describe the UI is not effective for me. I can’t as quickly look at a block of code and determine what the UI is likely to be. It’s just too noisy.
  2. I’m constantly frustrated by getting the right number of closing parentheses to match the open parentheses. Using the auto formatting tools of Android Studio for Dart doesn’t make it easier. There are 10 lines that are marking the closing of some block. I’ll add an example below of how messy it starts to look if they’re combined in a way that the auto formatter suggests.
  3. In fact, if it were easy, I’d want to lines to start with the Widget type rather than child: new WidgetName(. But, there’s not an obvious way to format the code that way as the named parameters (child) are needed to provide the widget instance.
  4. Layout is a mess of classes and initialization. The examples on the web site make general sense, but when I’ve tried to innovate on my own and understand how to build other UI patterns, I’ve struggled to find the right combination of Widget classes that represent a desired layout. I imagine that with practice I’d get better, but I also would likely create multiple stateless Widgets to make some of the common patterns I’d expect to use routinely.

Hulk Smash Layout

Does Flutter have a future? Would you want to build an app that you wanted to still be building on 3-4 years from now? As it’s still in Alpha form, I wouldn’t do anything but explore.

Then, there’s Dart. The strength of many development options for mobile and web development is the ability to concentrate on one programming language and have it work on client and server. With Flutter and Dart, if you don’t have a serverless-style architecture in place, you’ll need to use a second programming language. And that may limit its adoption. Of course, developers that work on multiple app platforms today have accepted this is just the price they have to pay, so maybe that’s not a big deal. If you’ve got a development shop that can have developers specialize, then this may be a non-issue entirely. For startups and very small teams, it’s a potential obstacle that must be considered.

 

Notes

If you try the code as I’ve put it on GitHub, you may encounter an error with a codec. This is actually a bug in the Flutter framework and apparently is fixed already and will be available generally at some point in a mainline branch. You’ll just need to rerun it.

Example of Auto Formatting

Note the parentheses on lines 20 and 21. That style causes me to just keep adding closing parentheses until the syntax is correct or the error is different. They’re very difficult to count.

Android Studio

Android Studio is an acquired taste from a theme and style perspective. With a few adjustments, it’s tolerable.

Android Studio Font and Color Settings

I’m not sure why Keywords in the Darcula theme are bright, bolded orange. While keywords are important, they’re unnecessarily vibrant, especially in code blocks describing the UI:

Bright Bold Orange Code Block

I turned off the bold minimally and changed the color of class names as an experiment … it’s better, but not right yet.

Android Studio with custom class name