Unable to select Azure subscription in Visual Studio Logic Apps deployment

From time to time (or what seems like VERY often), you might not get the option for selecting your Azure subscription/resourcegroup in Visual Studio Logic Apps Designer, when you open a Logic Apps project. This happes even when you are logged into an Azure account.

Continue reading “Unable to select Azure subscription in Visual Studio Logic Apps deployment”

Differentiate between Multiple triggers in a Logic App

In some cases, you might want to use more than one trigger in a Logic App. This can for instance be when you hook up to a D365 CE environment and use the “Common Data Service” Connector in Logic Apps to subscribe to changes

Here, it might make sense to have two triggers (one for the event “When_a_record_is_created” and one for the event “When_a_record_is_updated”) since both can often be handled similarly – at least if you are inserting or updating them in a SQL-server.
This is easy to do, since you in the following actions always can refer to “@triggerbody()” no matter which trigger has fired.

But what can you do, if you also would like to include the “When_a_record_is_deleted” trigger in the same Logic App. It potentially could be handled by the same Stored Procedure (for instance), but where the data from CDS is similar whether it is a “created” or an “updated” event, CE only sends the CE record GUID when it triggers the “deleted” event. This would probably make it less obvious to use the same handling for all 3 triggers.

You can actually query the logic app, for which trigger was in fact triggered. You can use the “@trigger()?[‘name’]” in a condition to compare it with trigger-names and behave differently depending on the trigger.

It can very well be argued, if it is a good idea to pack both INSERT, UPDATE and DELETE handling into one single Logic App, but in our case we are having a LOT of Logic Apps already, and it clutters the view the more Logic Apps are added. Also, the CE tables in question are small, seldom-updated tables.

Automatically created objects by a Philips Hue v1 App

These are the scenes that are created automatically by a Philips Hue v1 (bridge v1) App. They look suspiciously simple.

{
 "scenes": {
 "C2gX9ZsFSLMydOt": {
 "name": "Relax",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "cU9We_r01_d01"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:52",
 "version": 2
 },
 "R-tUrp2kHUfVJWS": {
 "name": "Read",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "W2dMg_r01_d02"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "h-RPB4RxcyrQDCI": {
 "name": "Concentrate",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "Droce_r01_d03"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "kWUGFVk5Gkg-XET": {
 "name": "Energize",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "tQhCU_r01_d04"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "LnVW3KduPhXCJlU": {
 "name": "Bright",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "CoTkg_r01_d05"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "fvS98qg-kFYxs2u": {
 "name": "Dimmed",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "AsAn0_r01_d06"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "8kz7tFP9mqkRyg2": {
 "name": "Nightlight",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "zF0lY_r01_d07"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "McJwqpyji8vD7OS": {
 "name": "Savanna sunset",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "jhaQr_r01_d15"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "MMPiGjG4skqYWI1": {
 "name": "Tropical twilight",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "AEgR2_r01_d16"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "eHtlKrxQ8QJY50C": {
 "name": "Arctic aurora",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "zWOx5_r01_d17"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 },
 "kLbjwM-78e8Eawz": {
 "name": "Spring blossom",
 "lights": [
 "1"
 ],
 "owner": "xxx",
 "recycle": false,
 "locked": false,
 "appdata": {
 "version": 1,
 "data": "io4hD_r01_d18"
 },
 "picture": "",
 "lastupdated": "2019-12-16T17:33:54",
 "version": 2
 }
 }
}

as well as the rules created for a Philips Hue Tap

{
 "rules": {
 "1": {
 "name": "Tap 2.3",
 "owner": "xxx",
 "created": "2019-08-06T18:10:07",
 "status": "enabled",
 "recycle": false,
 "conditions": [
 {
 "address": "/sensors/2/state/lastupdated",
 "operator": "dx"
 },
 {
 "address": "/sensors/2/state/buttonevent",
 "operator": "eq",
 "value": "17"
 }
 ],
 "actions": [
 {
 "address": "/groups/1/action",
 "method": "PUT",
 "body": {
 "scene": "LnVW3KduPhXCJlU"
 }
 }
 ]
 },
 "2": {
 "name": "Tap 2.1",
 "owner": "xxx",
 "created": "2019-08-06T18:10:07",
 "status": "enabled",
 "recycle": false,
 "conditions": [
 {
 "address": "/sensors/2/state/lastupdated",
 "operator": "dx"
 },
 {
 "address": "/sensors/2/state/buttonevent",
 "operator": "eq",
 "value": "34"
 }
 ],
 "actions": [
 {
 "address": "/groups/1/action",
 "method": "PUT",
 "body": {
 "on": false
 }
 }
 ]
 },
 "3": {
 "name": "Tap 2.2",
 "owner": "xxx",
 "created": "2019-08-06T18:10:07",
 "status": "enabled",
 "recycle": false,
 "conditions": [
 {
 "address": "/sensors/2/state/lastupdated",
 "operator": "dx"
 },
 {
 "address": "/sensors/2/state/buttonevent",
 "operator": "eq",
 "value": "16"
 }
 ],
 "actions": [
 {
 "address": "/groups/1/action",
 "method": "PUT",
 "body": {
 "scene": "LnVW3KduPhXCJlU"
 }
 }
 ]
 },
 "4": {
 "name": "Tap 2.4",
 "owner": "xxx",
 "created": "2019-08-06T18:10:07",
 "status": "enabled",
 "recycle": false,
 "conditions": [
 {
 "address": "/sensors/2/state/lastupdated",
 "operator": "dx"
 },
 {
 "address": "/sensors/2/state/buttonevent",
 "operator": "eq",
 "value": "18"
 }
 ],
 "actions": [
 {
 "address": "/groups/1/action",
 "method": "PUT",
 "body": {
 "scene": "LnVW3KduPhXCJlU"
 }
 }
 ]
 }
 },
 "sensors": {
 "2": {
 "state": {
 "buttonevent": 34,
 "lastupdated": "2019-08-06T18:11:03"
 },
 "config": {
 "on": true
 },
 "name": "Living switch",
 "type": "ZGPSwitch",
 "modelid": "ZGPSWITCH",
 "manufacturername": "Philips",
 "uniqueid": "00:00:00:00:00:45:01:02-03"
 }
 }
}

Looking inside a Hue E27 bulb

I just stumbled upon this site, where fred27 have disassembled a White E27 bulb.

Part of his findings (everything below is his):

Onboard you’ll find the largest IC is a SAM21R21E18A. This is a nice 32-bit ARM microcontroller with built-in Zigbee. It’s the brains and communications for the device.

There are a number of test point accessible on the underside of the PCB. It took a fair bit of following traces, checking continuity with a multimeter and probing with an oscilloscope, but I managed to work out what many of these were for. This is what I found:

TP1 – Ground
TP2 – SWCLK
TP3 – SWDIO
TP4 – Serial TX
TP5 – Serial RX
TP6 – LED output (about 32V)
TP7 – Regulated 3.3V power to microcontroller
TP8 – RESET
TP11 – Ground
TP25 – power supply to LM2204 regulator

So there a number of interesting signal here. TP1 and TP11 are the signal ground for the microcontroller and logic circuitry. TP7 is the regulated supply voltage.

SWCLK (TP2), SWDIO (TP3) and RESET (TP8) are interesting. You’d need these if you want to load new firmware onto the microcontroller or debug it. Interesting stuff, but this is arguably starting to head over the ethical line of hacking. It’s more complicated than we need anyway.

The serial port (TP4 and TP5) are also interesting. You see some debug output on TP4 as the device powers up. Nothing as you use the device and switch the bulb on and off so not much use to us. Once again, more complicated than we need. If you want to take a look, it’s 3.3V TTL 115200 8N1.

I told you it was possible to play around with the device safely, and it is. NEVER power your device from the mains whilst poking around. If you have a clean 3.3V supply you can connect that to TP7 and power the device that way. Better still is to supply a slightly higher voltage to TP25. It’s usually at about 24V but even 5V (e.g. from a USB charger) will do the job. You might not be able to light up the LED board but it will connect to you Hue hub. At this voltage but you will be able to look at signals, but most importantly you’ll be able to do it safely.

Setting up a Hue Tap Switch

Update 2019-12-08: While the bridge until now has ignored all attempts from me to pair the Tap Switch, it suddenly changed its opinion after it was restarted recently.

After the restart, the bridge paired with the Tap Switch immediately (empty POST to /sensors, press button on Tap Switch according to Zigbee-channel for 10+ seconds while monitoring pairing via GETs to /sensors/new)

The bridge detected the Tap

{
 "8": {
 "name": "Hue tap switch 1"
 },
 "lastscan": "2019-12-08T12:01:29"
}

and added this config to /sensors

{
 "state": {
 "buttonevent": null,
 "lastupdated": "none"
 },
 "config": {
 "on": true
 },
 "name": "Hue tap switch 1",
 "type": "ZGPSwitch",
 "modelid": "ZGPSWITCH",
 "manufacturername": "Philips",
 "uniqueid": "00:00:00:00:00:45:xx:xx-xx"
}

After it was added, it detected the first buttonpress without issues (event 34), but since then absolutely NO buttonpresses on the Tap switch have been registered on the bridge. No idea why.

I have tried pressing hard and softer (always click’ing), long and doubled – all to no effect.


Original pairing instructions

I tried to follow instructions from here

Reddit

Following instructions, holding button down for 10+ seconds, then click again to “verify the switch works” and nothing happens.

On this video, it works

Which button to hold depends on your ZigBee channel:

  • ZigBee channel: 11 = button 1
  • ZigBee channel: 15 = button 2
  • ZigBee channel: 20 = button 3
  • ZigBee channel: 25 = button 4

Any device has to initially be within 1 metre of the bridge to first pair it.

and from here

Reddit
Button 3 depressed for 10 seconds puts them in pairing mode.
The TAP switch doesn’t need to be reset, it is using Zigbee Green Power protocol and to reconnect it with another Hue bridge you just have to follow the commision instuctions in the Hue app to pair it with another Hue bridge……

It cannot connect directly to Smart Things Hub, because that one doesn’t support Zigbee Green Power protocol (yet?).


9to5mac
Cnet
huetips


Dissecting the Hue Tap Switch


No constant connection and some Zigbee discussions


https://huetips.com/tutorials/how-to-add-a-hue-tap/#b57845a1eb852f4b2

Press and hold for 10 seconds the button it tells you to on the screen. The button will be different every time you connect a new Hue Tap. Make sure you press down hard enough to where the Tap makes a click sound.

The hue tap uses a zigbee transmitter like your bulbs, make sure you are within a few feet of your bridge and are pressing down the button all the way until it clicks and hold it for 10 or 12 seconds.


.NET – ThreadSafe updating controls from a non-gui thread

Thread-safe updating of controls from another thread

https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread

Another method (from BB)

private void buttonOk_Click(object sender, EventArgs e)
{
Cursor = Cursors.WaitCursor;
buttonOk.Enabled = false;
int count = 0;
SaveSettings();
for (int i = 0; i < (int)NoOfMessages; i++)
{
new Thread(new ThreadStart(() =>
{
Stopwatch watch = new Stopwatch();
watch.Start();
var message = PerformWork(.........);
watch.Stop();
var tempCount = ++count;

Invoke(new MethodInvoker(() =>
{
textBoxLog.Text += "Message " + (tempCount) + " done." + Environment.NewLine;
if (tempCount == (int)NoOfMessages)
{
Cursor = Cursors.Default;
buttonOk.Enabled = true;
}
// Console.WriteLine("DONE " + tempCount);
}));
})).Start();
}
}

 

Processing Excel files in Biztalk

Using the ‘Microsoft OpenXml SDK’

http://www.dispatchertimer.com/tutorial/how-to-create-an-excel-file-in-net-using-openxml-part-1-basics/

https://docs.microsoft.com/en-us/office/open-xml/spreadsheets

Main download

Older method using ODBC etc

https://social.msdn.microsoft.com/Forums/en-US/5ce981f2-d5b7-41f6-b553-c717c565529d/reading-and-processing-excel-file-xlsx-in-biztalk-2010?forum=biztalkgeneral

https://social.msdn.microsoft.com/Forums/en-US/477c7de5-9f0c-4e84-b006-71c8cced2295/reading-excel-file-in-biztalk?forum=biztalkgeneral

http://biztalk.stottcreations.com/2007/12/biztalk_excel_xls_pipeline_component/

MSDN installation files

I just learned, that MSDN installation files (at least for Windows) are not full installation files, but (apparantly) crippled ones.

If for instance, you need a Windows 10 installation media, you should not normally use the one from MSDN, but download it from microsoft.com instead.

My specific problem, was that the package from MSDN would not accept the product-key which was embedded in BIOS, whereas the installation media from microsoft.com used the embedded key without any complaints at all.

I have no idea if this is also the case beyond Windows installations.