An introduction to Node-RED

Node Red IconNode-RED started life as an IBM product designed as a middleware platform intended to wire together connected devices, now commonly referred to as “The Internet of Things” (IOT). Node-RED provides a browser-based editor within which “flows” can be created to connect devices from different manufacturers and often speaking different languages – Node-RED provides the middleware upon which these devices can communicate. Now an open source project hosted on Github, it’s free to download and use with no limitations.

The Node-RED platform is built upon Node.js which itself is a Javascript runtime engine built on top of Google’s incredibly powerful Javascript engine. Put simply, Node-RED is an open source, open standards platform to wire together all your home automation toys – and that’s exactly what I’ve used it for.

The editor itself will be familiar to anybody who has ever used any form of process flow designer tools, such as Microsoft Visio. Connecting devices is as easy as dropping the building blocks (known as “nodes”) onto the page (known as a “flow”) and connecting the nodes together.

Once your flows are wired together how you want them, you deploy them to your server and they become active.

Here’s a very basic flow, one which queries my Sony Bravia Android TV for its power status and posts the response back to my home automation platform (Domoticz) which in turn updates a virtual switch in Domoticz which is then made available to Homebridge, an open source implementation of Apple’s HomeKit platform – with all this hanging together, it’s possible to get and set the power status of the TV using Siri, e.g. “Siri, turn off the TV” gets used a lot in our house!

Simple Node-RED flow to query the power status of a Sony Bravia Android TV

Simple Node-RED flow to query the power status of a Sony Bravia Android TV. The output is also sent to a debug node (the green node at the end) so I can see what’s happening.


Overview of the Node-RED web-based editor and a selection of input nodes. The flow in this screenshot pings my domain controller and updates Domoticz with its status so I know if it disappears off line.


Node-RED switch node

The “switch” node which is used to apply logic to your flows. In this example, it gets the output from the Sony Bravia API call and decides which route to send the flow down based upon the output from the API.


Causes of and fixes for the “Invalid Parameter” error when replacing the root RDP certificate in Windows

If you use Microsoft Remote Desktop Services, you may well have come across a dreaded “Invalid Parameter” error when trying to replace the root RDP certificate. Replacing the root certificate gets rid of the issue of the default self-signed certificate causing security errors when connecting to a remote desktop session – this is an especially important task if you use RemoteApp with a Remote Desktop Gateway server, not doing so will cause a break in the login mechanism where Windows will prompt you to make a decision on the handling of the self-signed certificate – annoying when all you want to do is reach your desktop and/or app.

Updating the root RDP certificate is normally achieved by issuing the following command in an elevated command prompt or Powershell session;

wmic /namespace:\\root\cimv2\TerminalServices PATH Win32_TSGeneralSetting Set SSLCertificateSHA1Hash="Thumbprint"

“Thumbprint” is the SSL fingerprint from the SSL certificate you are trying to install as the root RDP certificate. You can get this by viewing the certificate in the Certificates snap-in (if you’ve got that far) or by double-clicking the certificate and checking its values. If you copy/paste from the certificate to something like Notepad, be sure to remove all spaces and any leading characters, there is a hidden character in the Certificates snap-in section for the thumbprint so be sure to strip it out as it’s invisible (leading whitespace).

Certificate thumbprint

The following error is common and having spent a while trying to fix this issue using online resources, there is a distinct lack of information on the actual cause of this error which I hope this post addresses.

The dreaded “Invalid Parameter” error

So, there’s a couple of reasons why this can happen – here’s what to check to ensure you can successfully update your root RDP certificate

Cause number 1: Missing certificate or certificate in the wrong location

The root RDP certificate must be stored in the local store of the computer account.

  • Open an elevated command prompt and type “mmc.exe” and press enter. Next click on “File” and “Add/Remove snap-in…” and add the Certificates snap-in
  • Choose “Computer Account” from the list and click “Next”
  • Choose “Local computer” (the default) and click “Finish”
  • Click “OK” to exit the wizard

The Certificates snap-in is displayed. To import the certificate;

  • Expand the “Certificates” node then “Personal”
  • Click on “Certificates” under “Personal”, right click and select “All Tasks” then “Import…”
  • Click “Next” and browse to the location of your certificate
  • Enter any additional information required by the wizard (i.e. the password for the private key, if applicable)
  • On the Certificate Store page, leave the default certificate store (“Personal”) and finish the wizard.

My SSL certificate in the correct location

Run the import command and check the output again, if everything is OK, you’ll see the following, if you get “Invalid Parameter”, continue reading…

A successful root RDP certificate update

Cause number 2: Lack of private key information

This one caught me out; despite having my certificate in the correct location, it had been imported from a .crt file which did not have private key data stored in it. To remedy this, I imported a .pfx version of my certificate that I’d created previously – the .pfx had both public and private key data and so fulfilled the requirement of making the private key data available. If you have a .crt and .key combo (public and private certificate data) then there are tools online that can convert them into a single file with both public and private data (e.g. the .pfx certificate I used) or if you have OpenSSL installed that can be used too.

Cause number 3: Inappropriate SSL certificate

Not all SSL certificates are created equal – to be up for the task of authenticating servers (as is necessary here) the SSL certificate must have the “Server Authentication (” Enhanced Key Usage type. To find out if your certificate has this type, you can either refer to the “Intended Purposes” column in the Certificates snap-in (see the screenshot above – it shows “Server Authentication” as one of the intended purposes) or double-click the certificate, switch to the details tab and find the “Enhanced Key Usage” section. Without “Server Authentication (” – the certificate is not suitable for this purpose.

SSL certificate showing Server Authentication (

That’s it – if you have these things checked off, you should have no issues using your certificate as the root RDP certificate and pass-through authentication in your RDS environment should work with no issues.

Tagged with: , , , , , , , ,

Passing audio stream from TVHeadend to Sonos

The latest development (read: unstable) version of TVHeadend merged a new feature from fellow developer Hyper which allows TVHeadend to extract (and transcode) the audio stream of any source that is configured in TVHeadend (e.g. a DVB-S or DVB-T stream). This is an exciting feature as it allows you to set up “stations” on devices such as Sonos and play the audio directly from TVHeadend on the Sonos device(s) – this also applies to other audio platforms such as Squeezebox etc.

To get started on this how-to, you need to ensure you are running at least version 4.1-2267~g6efcfd2 from the TVHeadend github site (or from the official “unstable” repository).

First up, lets create a streaming profile to pass only an audio stream to the receiving device.

Navigate to Configuration > Stream Profiles > Add and select “Transcode/av-lib” as the type


Next, configure the stream profile as per the screenshot below, only the following settings need amending, leave everything else as per the defaults;

Enabled:        True
Profile Name:   Audio (or whatever you like)
Container:      Raw Audio Stream
Video Codec:    Do not use
Audio Codec:    AAC or Vorbis
Audio Bitrate:  128 (or whatever you like)


Click “Create” to finish setting up the profile.

Next, we need to configure a user that will be used to identify the client(s) (i.e. the Sonos receivers) to TVHeadend so that TVHeadend sends the stream in the correct format to the receiver.

Navigate to Configuration > Users > Access Entries and click “Add”

Next, configure the user as per the screenshot below, only the following settings need amending, leave everything else as per the defaults;

Enabled:               True
Username:              *
Streaming:             True
Advanced Streaming:    True
Allowed Networks:,,
Streaming Profiles:    audio (or whatever you called your new profile above)

Setting the username to asterisk (*) means any or no user, we then limit who (or what) can access the user profile by setting the appropriate network settings. In my example above, I allow my 3 Sonos devices (, and to access TVHeadend. The /32 at the end of the address simply means “only this IP address” in CIDR network notation. Amend the network settings to suite your environment.


The last part is client-specific, so the example below is relevant only to Sonos, but the principle will be the same regardless of which client you are using.

First, grab the URL of the channel you want to add as a stream in your client. Navigate to Configuration > Channel / EPG > Channels, find the channel you want to stream, right click on the playicon icon and copy the URL to the clipboard. The URL will look similar to the below;


We need to remove the parameter at the end of the URL (the bit from the question mark onwards) to give us


You now have your streaming URL. Next, go to your client (in my case Sonos), find the option for adding a stream (or radio station) and paste the URL into the dialog box.

That’s it – if you try and play the stream, your client should connect to TVHeadend and start streaming only the audio element of the stream. You can check that your client is connected to TVHeadend and using the right stream by navigating to Status > Subscriptions and checking for a client using your “Audio” profile (or whatever you named it in the first step above)


Tagged with: , , ,

systemd script for OSCam

OSCam Logo

OSCam as it stands uses the old sysinit (/etc/init.d/oscam) script to control its daemon. I wanted to leverage a bit of functionality within systemd, the ability to automatically start a crashed process, so decided to convert the “old” init.d script into a systemd script. Starting and stopping the OSCam daemon is no different to the old sysinit scripts, as most distros are guiding people towards systemd by outputting the equivalent systemd command when you start or stop a service. For example, if I run the following on my Debian box;

/etc/init.d/oscam stop

Systemd intervenes and shows me how I should control the daemon;

systemctl restart oscam

So even though no systemd script exists for OSCam on my box, Debian treats the sysinit script as a systemd script, but only as far as starting and stopping the script goes – it does not give the extra benefits of systemd which as above include automatic restart of failed services.

So, below is a systemd script which can control OSCam – you might need to change the binary and PID file paths but this works on my system. Simply create a new systemd script;

sudo nano /etc/systemd/system/oscam.service

…and add the following content…


ExecStart=/usr/local/bin/oscam -b -B /var/run/
ExecStop=/usr/bin/rm /var/run/


This will start OSCam in daemon mode (the -b flag) and then create a PID file for the deamon (-B) at /var/run/ – as mentioned above, you might need to alter the paths but this is the basic systemd service required to control OSCam.

Once you’ve created the service, you need to reload the systemd daemons by issuing;

sudo systemctl daemon-reload

…then you can simply start the OSCam daemon by issuing;

sudo systemctl start oscam

You can check OSCam is running by visiting the web interface or by running;

sudo systemctl status oscam

…where you should see something like this;

 oscam.service - OScam
   Loaded: loaded (/etc/systemd/system/oscam.service; disabled; vendor preset: enabled)
   Active: active (running) since Fri 2016-09-30 11:40:30 BST; 10min ago
  Process: 21828 ExecStop=/usr/bin/rm /var/run/ (code=exited, status=203/EXEC)
  Process: 24126 ExecStart=/usr/local/bin/oscam -b -B /var/run/ (code=exited, status=0/SUCCESS)
 Main PID: 24131 (oscam)
   CGroup: /system.slice/oscam.service
           ├─24130 /usr/local/bin/oscam -b -B /var/run/
           └─24131 /usr/local/bin/oscam -b -B /var/run/

One final thing is to ensure OSCam starts on boot, to do that, issue the following command;

sudo systemctl enable oscam.service

And that’s it!

Happy viewing!

Tagged with: , , , , ,

Fixing Outdated or Corrupted Exchange ActiveSync Device Partnership in Exchange 2013

I recently upgraded from an iPhone 6S Plus to an iPhone 7 Plus, having gone through other iterations of iPhone upgrades with no issues connecting to my Exchange 2013 server, but this one was different. On restoring from iCloud, my iPhone could not connect to my Exchange 2013 server (hosted on-premise). A fair bit of Googling revealed varying solutions, most of which centered around enabling permission inheritance for my Active Directory users (which I’ve already done previously for an unrelated error).

Having double-checked that permission inheritance was turned on, I set about looking in the Event Viewer logs on my Exchange 2013 VM and noticed a recurring error every time my new device attempted to sync;


An exception occurred and was handled by Exchange ActiveSync. This may have been caused by an outdated or corrupted Exchange ActiveSync device partnership. This can occur if a user tries to modify the same item from multiple computers. If this is the case, Exchange ActiveSync will re-create the partnership with the device. Items will be updated at the next synchronization.


So off to my Windows Server 2012 R2 Domain Controller to take a look at the Active Directory Administrative Center. One quick global search for ‘iphone‘ revealed an Active Directory sync partnerships for the user I was interested in, once I’d confirmed it was the right container for the right user, I deleted the container, re-tried the sync and monitored the Event Viewer on the Exchange 2013 box. No change, the sync was still failing and the error still appeared.


I noticed that the stack trace related to the error log specifically mentioned deleting the ‘ExchangeActiveSyncDevices‘ container if it was empty (which it was now I’d deleted the only sync partnership contained within) so another global search for ‘ExchangeActiveSyncDevices‘, ensuring I chose the container for the right user, the container was deleted and my new iPhone sprung in to life. After refreshing the results in Active Directory Administrative Center, I could see the container had been re-created.



So it appears it was a permissions issue all along but the fix turned out to be deleting the ‘ExchangeActiveSyncDevices‘ container (and anything beneath it) for the affected user.

Tagged with: , , , , , ,

Building the closed source TBS DVB drivers for Ubuntu/Debian

This is a brief guide on how to download, compile and install the closed TBS drivers for Debian derivative linux distributions. These drivers are released by the manufacturer and contain closed source/proprietary code. We have a separate guide catering for the open source TBS drivers here.

Install the required tools

First we need to install some packages to enable us to build the drivers.

sudo apt-get install build-essential unzip
sudo apt-get install linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,')


sudo aptitude install build-essential unzip
sudo aptitude install linux-headers-$(uname -r|sed 's,[^-]*-[^-]*-,,')

Grab the latest source code

The driver package names often change so visit the TBS website ( for the latest version. The version included below is current as of the publication of this guide (July 2016)

mkdir /tmp/tbs
cd /tmp/tbs

Unzip the drivers


Untar the driver package

tar xjvf linux-tbs-drivers.tar.bz2

Go into the driver directory

cd linux-tbs-drivers

Configure the build environment for the correct archicecture


…for 32bit environments or…


…for 64bit environments. Only run ONE of these commands.

Build the driver source

make -j 4

Assuming the drivers build correctly, you can install them using

sudo make install

Reboot to make the drivers take effect.

sudo shutdown -r now

If the modules error for some reason even after a reboot, it may be because there are other drivers clashing with the newly built/installed ones. The simply way to resolve this (providing you don’t have other vendors DVB cards in the same machine) is to;

sudo rm -rf /lib/modules/`uname -r`/kernel/drivers/media/*

…and then run…

sudo make install

…again from the source directory.

Tagged with: , , , , ,

Building the open source TBS DVB drivers for Ubuntu/Debian

This is a brief guide on how to download, compile and install the opensource TBS drivers for Debian derivative linux distributions. These drivers are based upon the excellent Linux Media project and tailored specifically for TBS digital TV cards. We have a separate guide catering for the official TBS drivers here.48 законов власти. Часть 2

Install the required tools

First we need to install some packages to enable us to build the drivers.


Now lets grab the source code

If the build fails with something about Proc::ProcessTable then issue the following command;

…and try the build again.

Assuming the drivers build correctly, you can install them using

…and load them using…

…for CX23885 based cards or…

…for SAA716X based cards.

Alternatively, just reboot.

If the modules error for some reason even after a reboot, it may be because there are other drivers clashing with the newly built/installed ones. The simply way to resolve this (providing you don’t have other vendors DVB cards in the same machine) is to;

…and then run…

…again from the media_build directory.

That’s all there is to it – the DVB cards should show up in a couple of places;

By issuing…


…or simply by checking in your DVB application (such as TVHeadend).

Tagged with: , , , ,

How to integrate OScam with TVHeadend

OScamThis guide details how to integrate OScam with TVHeadend to enable decryption of pay TV channels within TVHeadend. The guide does not deal with the configuration of cards (local or otherwise) on the OScam side and is in no way intended to promote piracy of pay TV. You should use this guide to decrypt channels for which you have a legitimate subscription for.

Configuring OScam

The first part of the guide deals with setting up OScam to allow TVHeadend to request decryption keys for encrypted channels.

Create a new user to allow TVHeadend to talk to OScam

Click on the Users tab at the top of the OScam screen
Click on the ‘Add Users’ link
Configure a user similar to below;

user                          = tvheadend
pwd                           = tvheadend
monlevel                      = 4
group                         = 1
max_connections               = 99

Configure DVBAPI

DVBAPI allows TVHeadend to communicate with OScam over TCP

Click on the Config tab at the top of the screen
Click on the DVB-Api link
Configure DVBAPI as per the below;

enabled                       = 1
pmt_mode                      = 0
listen_port                   = 9001 # or whatever port you want if 9001 is taken
ecminfo_type                  = 4
user                          = tvheadend # user should match the user created above
read_sdt                      = 1
boxtype                       = pc

Before leaving OScam, you should configure at least one card to provide the decryption keys to TVHeadend. This is outside of the scope of this guide but you will need one card for each CAID that you wish to decrypt in TVHeadend. If you use multiple providers, you will need at least one card for each providers channels you wish to decrypt.

Configuring TVHeadendTVHeadend CA Client

Next we switch to TVHeadend to make the link back to OScam.

Log in to TVHeadend with a user with admin permissions
Navigate to Configuration > CA’s
Click on the Add button
Select CAPMT (Linux Network DVBAPI) from the drop down list
Configure the client as per the below;

Enabled: True
Client name: OSCam # or whatever you like
Mode: OSCam net protocol (rev >= 10389)
Camd.socket filename / IP Address (TCP mode): # the IP address of the machine running OScam - is localhost so if both OScam and TVHeadend are on the same machine, this is fine
Listen / Connect port: 9001 # must match the port number above

Click the Create button

The icon to the left hand side of the newly created CA client should show a green tick – if this isn’t the case, go back and double check your settings. Also make sure that port 9000 isn’t blocked on the machine running OScam.

Tagged with: ,

Cross-compiling TVHeadend for Raspberry Pi

This guide details how to set up a chroot environment to enable you to build TVHeadend for Raspberry Pi (which uses the arm architecture) on an x86_64 Debian distribution.

Setting up the chroot

A chroot is essentially an installation of the linux operating system that exists within the host version but is (or can be) completely isolated from the outside host. This means that it’s possible to build packages for completely different versions of linux than the one running the chroot and indeed even different architectures. This guide specifically details setting up a chroot which runs the armhf version of Debian (as used by the Raspberry Pi) to enable you to build and optionally package a version of TVHeadend for distribution and use on the Raspberry Pi.

Installing the required tools

sudo apt-get install qemu-user-static dchroot schroot debootstrap wget


sudo aptitude install qemu-user-static dchroot schroot debootstrap wget
cd /tmp
sudo dpkg -i raspbian-archive-keyring_20120528.2_all.deb

Creating your chroot

sudo mkdir -p /var/chroot/raspbian-armhf/
sudo qemu-debootstrap --keyring /usr/share/keyrings/raspbian-archive-keyring.gpg --arch armhf jessie /var/chroot/raspbian-armhf

If you want to use a different version of Debian other than jessie – substitute jessie for your preferred version (i.e. wheezy) in the command above

sudo echo raspbian-armhf | sudo tee /var/chroot/raspbian-armhf/etc/debian_chroot
sudo ln -s ../proc/mounts /var/chroot/raspbian-armhf/etc/mtab
sudo cp /etc/passwd /etc/group /etc/shadow /var/chroot/raspbian-armhf/etc
sudo nano /etc/dchroot.conf

Enter the following in the newly created file;

raspbian-armhf /var/chroot/raspbian-armhf
sudo nano /etc/schroot/schroot.conf

Enter (or add to the end of the file) the following. Again substitute jessie for your preferred debian variant (i.e. wheezy)

description=raspbian jessie armhf

Entering the chroot

sudo dchroot -d -c raspbian-armhf

The following commands all happen inside of the chroot – ensure that your bash prompt says ‘raspbian-armhf’ before continuing as this confirms you are inside of your chroot environment.

Installing the required tools

sudo apt-get install git build-essential pkg-config libssl-dev bzip2 wget libavahi-client-dev zlib1g-dev libavcodec-dev libavutil-dev libavformat-dev libswscale-dev libavresample-dev python gettext cmake libdvbcsa-dev liburiparser-dev debhelper libcurl4-gnutls-dev curl

If you get an error whilst trying to install these packages, check your sources.list to ensure it has not been replaced by another mirror other than the raspbian one;

sudo nano /etc/apt/sources.list

It should look like this;

deb jessie main
deb-src jessie main

If it doesn’t, delete any lines in the file (CTRL+K) then replace them with the above lines and try installing the packages again.

Downloading the TVHeadend source code

Change to the root directory;

cd /root

To download the latest stable (4.0) source code then running

git clone -b release/4.0

If you want to get the very latest (4.1) source code (which is considered unstable) then running

git clone

Packaging the source code into a redistributable .deb package

As the intention of this guide is to install the package on a different machine, we have skipped the ‘build’ step as it is incorporated into the packaging instructions below.

From the TVHeadend source directory, run;

AUTOBUILD_CONFIGURE_EXTRA='--prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libexecdir=${prefix}/lib/tvheadend --disable-maintainer-mode --disable-dependency-tracking --enable-libffmpeg_static --enable-hdhomerun_static --enable-dvbcsa --enable-bundle' ./ -t debian

Installing packaged version of TVHeadend

The autobuild command will produce a .deb file (named something like tvheadend_v4.1-2141~g01c26fc_amd64.deb) in the directory above the source directory. Copy the debian package (either by using a USB disk or using scp to copy it to your target host) and run the following to install it;

sudo dpkg -i YourPackageName.deb

You will more than likely hit failed dependencies here so after running the above, run the following to fix the missing dependencies;

sudo apt-get install -f

That’s it! You should be able to view the TVHeadend web interface at http://RaspberryPiIPAddress:9981/

Tagged with: , , , , ,

Packaging TVHeadend for distribution

Once you have built TVHeadend, you may want to create a redistributable debian package to enable you to distribute and install the package on a system other than the one you built the package on (this works hand-in-hand with our ‘Cross-compiling TVHeadend for Raspberry Pi’ guide).

Installing dependencies

Packaging TVHeadend has the same core dependencies ans building from source so ensure you install those dependencies before attempting to package TVHeadend.

Additional dependencies

As well as the build dependencies discussed above, the following are required to build a redistributable package for TVHeadend;

sudo apt-get install debhelper libcurl4-gnutls-dev curl


sudo aptitude install debhelper libcurl4-gnutls-dev curl

Building TVHeadend package

From the TVHeadend source directory, run;

AUTOBUILD_CONFIGURE_EXTRA='--prefix=/usr --includedir=${prefix}/include --mandir=${prefix}/share/man --infodir=${prefix}/share/info --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libexecdir=${prefix}/lib/tvheadend --disable-maintainer-mode --disable-dependency-tracking --enable-libffmpeg_static --enable-hdhomerun_static --enable-dvbcsa --enable-bundle' ./ -t debian

Installing packaged version of TVHeadend

The autobuild command will produce a .deb file (named something like tvheadend_v4.1-2141~g01c26fc_amd64.deb) in the directory above the source directory. To install it, you should run;

sudo dpkg -i <tvheadend_output_file>.deb
Tagged with: ,