KARPACH

WEB DEVELOPER BLOG

Google Home condo automation, Part 2 IFTTT

IFTTT

Google Assistant can be directly integrated with a variety of devices and services. However, it is not always convenient to say something like “Ok Google, ask Harmony to turn the TV on”, Luckily Google has shortcuts, so you can assign a short command and say something like “Ok Google, turn a TV on”. Lately, Google even added an ability to add up to two commands to one shortcut. Unfortunately with works only for basic scenarios. Here are some advanced scenarios that it is not possible to automate using built-in services:

  1. Add items to Google Keep shopping list
  2. Have a nighttime scene (dimmed lights, the specific song playing with a certain volume level)
  3. Skype parents
  4. Turn PC on/off

This is where IFTTT comes into the picture. IFTTT supports a lot of services and can be integrated with Google Assistant easily. IFTTT Platform can chain an unlimited number of services as well as the ability to send HTTP requests. I used the ability to send HTTP requests to solve all of the above-advanced scenarios. In the next part, I’ll describe how I automated a Google Keep scenario.

Posted on May 28, 2018 by

Google Home condo automation, Part 1 Hardware

Google Home

About a year ago I bought Google Home. Amazon Echo is more popular, but I already had a Google Music subscription, Chromecast and a bunch of Android phones. After a few months of playing with Google Home, I came up with a list of things that I want Google Home to be able to do:

  1. Control lights (everybody does that)
  2. Turn the TV on with different modes (TV, ChromeCast, HTPC)
  3. Add items to Google Keep shopping list
  4. Have a nighttime scene (dimmed lights, specific song playing)
  5. Skype parents
  6. Turn my PC on/off

Bonus features:

  1. Water plants
  2. Turn x-mas light on/off

Hardware

Control lights

Lutron Caseta

There is a big selection of smart switches, bulbs, and dimmers. I needed a physical smart light switch and my condo does not have a neutral wire. Most smart light switches must have a neutral wire. Lutron Caseta is the only one among popular brands which somehow does not need a neutral wire. Lutron Caseta has a broad spectrum of products that satisfy all my needs. Google Home and Harmony support them out of the box.

TV Control

Harmony Companion

Harmony is the absolute leader in TV remotes. I don’t care about the LCD screen since I’ll mostly control the TV using my voice, so I decided to buy Harmony Companion. It took some time to set it up, but finally, everybody in my family can do basic tasks switching between TV, ChromeCast, HTPC, and Bluetooth Music using a remote or voice.

HTPC

Intel NUC

I could buy Raspberry Pi + NAS, but I didn’t want to be limited by computing power. I also wanted to do Skype calls using my TV. This is why I bought Intel NUC + Logitech webcam. My Intel NUC supports both mSata and 2.5 HDD. I installed Windows on the small mSata SSD drive and used 2Tb old-fashioned hard drive for media storage.

Smart Wi-Fi Plug

I bought a WeMo switch when it was on sale. It works pretty reliably although every other day asks to update it.

Unfortunately, all this hardware out of the box does not solve my home automation scenarios and I had two write some code. I’ll cover those customizations in the next part of my blog.

Posted on May 17, 2018 by

How to sign assembly with as strong name in Visual Studio Team Services?

I have a self-generated password-protected key.pfx. That key.pfx file is used to sign some assemblies in my solution. I tried to build that solution in Visual Studio Team Services and it failed right away with the following error:

Error MSB3325: Cannot import the following key file: key.pfx. The key file may be password protected. To correct this, try to import the certificate again or manually install the certificate to the Strong Name CSP with the following key container name: VS\_KEY\_9000008CC1777

Quick googling shows that I need to run:

sn -i key.pfx VS_KEY_9000008CC1777

However this command will prompt a password, so this would not work for a build server. I tried to use an automated solution for the above command using the following PowerShell script:

param($PfxFilePath, $Password)

$absolutePfxFilePath = Resolve-Path -Path $PfxFilePath
Write-Output "Importing store certificate '$absolutePfxFilePath'..."

Add-Type -AssemblyName System.Security
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($absolutePfxFilePath, $Password, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]"PersistKeySet")
$store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "MY", CurrentUser
$store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::"ReadWrite")
$store.Add($cert)
$store.Close()

However, this didn’t work for Visual Studio Teams Services hosted build agent. I suspect that hosted build server has some kind of environment protection and the above certificate installation fails silently. Then I decided to extract key.snk file from key.pfx and use that file to sign assemblies. This approach works, but it is not secure, since I would need to store a private unprotected key file in source control. So, I came up with the idea to dynamically extract key.snk using the following PowerShell script:

Param(
	[Parameter(Mandatory=$True,Position=1)]
	[string] $PfxFilePath,
	[string] $PfxPassword
)

# The path to the snk file we're creating
[string] $snkFilePath = [IO.Path]::GetFileNameWithoutExtension($PfxFilePath) + ".snk";

# Read in the bytes of the pfx file
[byte[]] $pfxBytes = Get-Content $PfxFilePath -Encoding Byte;

# Get a cert object from the pfx bytes with the private key marked as exportable
$cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2(
	$pfxBytes,
	$PfxPassword,
	[Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable);

# Export a CSP blob from the cert (which is the same format as an SNK file)
[byte[]] $snkBytes = ([Security.Cryptography.RSACryptoServiceProvider]$cert.PrivateKey).ExportCspBlob($true);

# Write the CSP blob/SNK bytes to the snk file
[IO.File]::WriteAllBytes([IO.Path]::Combine([IO.Path]::GetDirectoryName($PfxFilePath), $snkFilePath), $snkBytes);

Then I added two variables to the build definition:

CertPath = $(Build.SourcesDirectory)\key.pfx
CertPass = password (clicked on a lock to secure value of variable)

After that I added a PowerShell task with the following arguments:

Sign assembly PowerShell task

This time the build passed and assemblies were signed successfully.

Posted on May 24, 2017 by