Tag: English

  • My Attempts to Integrate Home Assistant with ADT UK

    TL;DR. In the UK, you cannot connect the ADT alarm panel with any other devices or services that aren’t ADT-certified.

    Z-Wave Secondary Controller

    This is the first solution that I tried. Now I no longer say it doesn’t work in other regions than the UK, but I also can’t verify that myself. Full disclaimer that my experience is limited to the UK market, I managed to put my SmartThings Hub v3 Z-Wave into the learner mode, and was able to use the ADT mobile app to add it as a secondary controller (IIRC, it asked for a code, and I just gave 2222 which seems to be the generic installer’s code that ADT engineers use). Afterwards, I have 5 Z-Wave “Dimmer Switches” shown in the SmartThings app (I have 4 motion sensors, 1 door/window sensor, which I assume that’s why I have 5 Z-Wave devices shown up), but none of them would transmit any data. Later on, they went into the state of “disconnected” perpetually.

    To make things worse, the ADT panel would then display a warning saying my SmartThings Hub is an unknown device in the “Smart Devices” section. I was also not able to remove it myself using neither the panel nor the mobile app.

    In the end, over a phone call with an ADT technician, they were able to remotely remove my SmartThings Hub from the devices. Now my SmartThings Hub is just in a broken state as a secondary Z-Wave controller. Of course, I could reset my SmartThings Hub but then I’d also need to reconnect my 15 ZigBee devices. Instead of going through that hassle, I managed to use the SmartThings web app to remove these zombie Z-Wave dimmer switches, which is enough to hide them from the SmartThings app.

    Qolsys Gateway

    I then checked out https://github.com/XaF/qolsysgw which seemed to be the only working integration according to some HomeAssistant posts. Unfortunately, I’m not able to see “Installation” in the Advanced Settings in my Qolsys IQ Panel 4.

    Over a phone call with an ADT technician, I’ve been told that menu is reserved for ADT engineers only, and that connecting to other systems such as Google Home, Alexa is not allowed in the UK (but he admitted it is something that customers can do in the US for example). This might explain why some people is able to use Z-Wave secondary controller, yet I’m not able to (though the error is much less obvious).

    I do feel a bit conflicted on their approach to this matter, as this effectively breaks my smart home setup into two disconnected worlds: one with SmartThings and HomeAssistant that’s relatively well connected, and one with just ADT alarm system. Hopefully they’ll update their policies in the UK in the coming years, and we could use more competition in this space and someone should provide a solution that integrates with other smart home systems in the UK.

  • Citrix Receiver UK Keyboard Layout Issue on Linux and Chrome OS

    I have this weird issue where my employer’s remote virtual desktop is configured in English (UK), and it works well in Windows with UK keyboard layout. However, if I try to connect to the same instance from Linux (or Chrome OS), with the same hardware, it would appear as if I’m typing from a US keyboard. To make it more bizarre, if I configure a US keyboard in the remote Windows session and switch to it, it would appear as if I’m typing with the UK keyboard layout.

    Googling this yields a few frustrating customers, but probably the combination of using a UK keyboard in Linux and accessing a Windows VDA is not that common? I’m surprised that hacks need to be applied… The bizarre symptoms made me wonder what if I just tell the Citrix receiver (or workspace) application to simply use whatever the keyboard layout the remote VDA configured? Bingo! That solves the problem (for me at least). Changing the keyboard layout to (Server Default) in the [WFClient] configuration section did the trick for me in Linux. The configuration file should be in ~/.ICAClient/wfclient.ini

    However, I have yet to find where the configuration is stored for Chrome App (in Chrome OS), nor whether it’s even possible to update the default setting there. In the meantime, I found a workaround by editing the ICA file. Open it with a text editor, and add

    KeyboardLayout=(Server Default)

    to the [WFClient] section.

    Reference: https://support.citrix.com/article/CTX328177/keyboardlayoutserver-default-cannot-take-effect-on-citrix-workspace-app-for-linux

  • Home Assistant Core Setup on Banana Pi M5

    There is no support for BananaPi M5 from Home Assistant OS, which leaves me either the container or the core version. Originally I was going to use the container image, however, it needs too much disk space (7GB was not enough as it maxed out my onboard storage). I went for Home Assistant Core instead, and this post records my journey setting it up.

    1. Install uv (a Python environment manager)
    2. Install latest Python (3.13 at the time of writing), because Home Assistant Core has deprecated the support for older versions of Python
    3. Install Home Assistant Core (official documentation as a reference). I’m using uv to manage the virtual environment (note that I’ll enable ISAL for better performance).
    cd /srv/homeassistant/
    uv venv pyenv --python 3.13
    source pyenv/bin/activate
    uv pip install homeassistant==2024.12.3
    uv pip install isal  # ISAL for faster gzip and zlib
    1. Install and configure Cloudflare Zero Trust Tunnel (official documentation for remote tunnel). To expose my Home Assistant access to the public Internet, so that I can access it everywhere. Besides, some cloud-based services require that access because they use callbacks (the alternative is to pay for Nabu Casa which is a subscription-based service). Configure the access control in Cloudflare Zero Trust so that only verified emails from a restricted list have access (additional policies can be set for a new application that bypasses any control for cloud services callbacks)
      • Worth noting that the cloudflared add-on cannot be used because Home Assistant Core doesn’t support add-ons.
    2. Setup a new service in systemd for Home Assistant’s hass so that it starts on boot and restarts on failures. I created this file /etc/systemd/system/ha@homeassistant.service (systemctl enable and systemctl start afterwards):
    [Unit]
    Description=Home Assistant
    After=network-online.target
    After=network.target
    
    [Service]
    Type=simple
    User=homeassistant
    ExecStart=/srv/homeassistant/pyenv/bin/hass
    Restart=on-failure
    RestartSec=5s
    
    [Install]
    WantedBy=multi-user.target
    
  • Chrome OS Flex on Samsung Galaxy Book Pro 360 Dual Boot

    Happy Chinese New Year (Year of Dragon/Loong) to you all!

    A New Year’s surprise from Google. The latest version of Chrome OS Flex finally supports Samsung Galaxy Book Pro 360 to an extent that can be used as a daily driver.

    (more…)
  • Banana Pi M5 Pro Quick Review

    My old ODROID-U3 has been giving me quite some headaches. Its old USB 2.0 ports and 100Mbps Ethernet port are also very limiting in 2023. Its power supply is not the best (not an uncommon issue with HardKernel’s products, certainly not uncommon among the older generation of single board computers). A hardware upgrade is therefore necessary.

    I don’t really use it for anything else other than a humble home server to stream videos, music, and sometimes photos. Generally used as a private file share system at home. I already bought an 1 TB USB 3.0 HDD, so I definitely need a device that supports USB 3.0 at least. To not have a limiting network I/O, it should also have 1Gbps Ethernet port.

    Why not buying a popular Raspberry Pi 4? Well, I tried, but it’s out of stock everywhere. That’s why I turned to its alternatives, initially I was going to buy another HardKernel’s ODROID product, but its pricing in Europe is just way too high than the price on its website. Unfortunately, (not sure if this has anything to do with Brexit), there is a minimum order requirement to ship to the UK. I’m building a cluster or something, so looking again…

    Ta-da! I found Banana Pi, the name is a bit.. knock-off, and the manufacturer is in China, I’ll let you connect the dots. Banana Pi M5 is not the newest model, but it’s comparable to Raspberry Pi 4 and ticks all of my boxes. Long story short, I bought it from Ali-Express where it’s much cheaper than Amazon or other local retailers here. They were also running some sales on bundles, so I ended up buying it with a metal case, yet paying less.

    On paper, it provides even better performance than Raspberry Pi 4! More importantly, it’s readily available! One thing I did pay extra attention to is the availability of upstream Linux images, having suffered quite a bit there with HardKernel’s products. Thankfully, Banana Pi has Armbian support (rated platinum for Banana Pi M5, whatever platinum means). To save even few more pennies, it comes with an onboard 16GB eMMC storage!

    It’s been faithfully serving its purpose on the shelf next to the router for a couple of weeks now. Reliable little machine that’s fast and responsive! If you’re thinking of buying a single-board computer like Raspberry Pi, but couldn’t find available stocks, Banana Pi might fit in.

  • Chrome OS, Linux Containers and Application Launchers

    So I installed the great brunch framework on my laptop after a hiatus of a couple of months. I still dislike the fact that the Linux containers are running under a VM on Chrome OS. Sure it is more secure as the containers won’t be able to access the host hardware directly etc. It is also slightly inefficient. So I tried both chromebrew and brioche. Note that brioche only supports brunch (thus half of this post won’t apply to official Chrome OS builds).

    (more…)
  • Number Rounding Business

    Rounding numbers is probably one of the topics in primary school. In school, we’ve learned that half rounds up, anything less than half rounds down. For example, 0.5 rounds to 1, but 0.4 rounds to 1. Duh, I’m stating the obvious you think. It only came to my attention that this is NOT really the default behaviour in a very popular programming language: Python.

    Here, is a simple example to try in your own Python console.

    (more…)
  • Merge Pandas DataFrame with Nested Dictionary

    Not an avid Pandas or Numpy user myself, but I had to spend some time lately to optimise probably a fairly common process: looking up a nested dictionary (2 or more levels) to find the right values element-wise for a column in a Pandas DataFrame. If it’s not clear, the problem I’m trying to solve here is to optimise a look-up function that can be done with .apply() to something more performant.

    You might say, why not using .map()? Because the look-up function is not y = f(x), no, it is more like y = f(x, a) or even y = f(x, a, b), depending on the level of nestedness.

    As mentioned earlier, this can be implemented with .apply() by supplying a Python function that does the look-up. However, .apply() is very slow (it’s not vectorised). The solution here is actually straightforward (I’m very new to Pandas and it took me some time to get here so I decided to make a note here for this). We first flatten the nested dictionary to have different levels of keys as tuples, which allows us to create a DataFrame with MultiIndex. With MultiIndex, we can easily apply .merge to join the DataFrame objects.

    Hopefully the code snippet is more understandable.

    import pandas as pd
    
    nested_dict = {
        "A": {
            "Apple": "Red",
            "Banana": "Green",
        },
        "B": {"Apple": "Green", "Banana": "Yellow"},
    }
    df = pd.DataFrame.from_dict(
        {
            "Fruit": {0: "Apple", 1: "Banana", 2: "Banana"},
            "Price": {0: 0.911, 1: 1.734, 2: 1.844},
            "Bucket": {0: "A", 1: "B", 2: "A"},
        }
    )
    
    # Method 1: .apply()
    # Apply Python function element-wise, as slow as a regular for loop
    df1 = df.copy()
    df1["Color"] = df1.apply(
        lambda row: nested_dict.get(row["Bucket"], {}).get(row["Fruit"]), axis=1
    )
    print(df1)
    
    # Method 2: .merge()
    # Vectorized, much faster (even though the big O is the same)
    df2 = df.copy()
    # The only overhead is to construct a dataframe with 'MultiIndex'
    nested_df = pd.DataFrame.from_dict(
        {
            (inner_key, outer_key): value
            for outer_key, outer_value in nested_dict.items()
            for inner_key, value in outer_value.items()
        },
        orient="index",
    )
    nested_df.index = pd.MultiIndex.from_tuples(nested_df.index)
    nested_df.rename(columns={0: "Color"}, inplace=True)
    df2 = df2.merge(nested_df, how="left", left_on=("Fruit", "Bucket"), right_index=True)
    print(df2)
    
  • Building KDE Frameworks on Windows from Source

    Some notes on how to build KDE Frameworks packages from source on Windows using Visual Studio tools.

    To do so, you need to first have a version of Qt compiled by MSVC installed. Some system environment variables to be set, using Qt 5.15.2 as an example:

    • PATH needs to add C:\Qt\5.15.2\msvc2019_64\bin
    • Qt_DIR needs to be set to C:\Qt\5.15.2\msvc2019_64

    Example instructions for building CMake-based projects (all KDE projects), the command below should be executed in x64 Native Tools Command Prompt.

    mkdir build && cd build
    cmake .. -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX="C:\Qt\5.15.2\msvc2019_64"
    nmake && nmake install
    

    This will install the compiled KDE module into the Qt installation path. You can install it elsewhere, but if you do, make sure you update PATH environment variable accordingly.

  • A New Termux Mirror

    TL; DR. https://termux.librehat.com is a new Termux packages mirror! Maintained by me, synchronised every six hours, located in the United Kingdom, hosted by Oracle Cloud.

    In the full article below, I’ll write up how to set up a Termux mirror (or in general, a Debian packages repository mirror).

    (more…)