Category Archives: Smart House

Subscribing to Teams Presence with Graph API using Power Platform

Since the support for getting Teams Presence via Microsoft Graph API came into public preview earlier this year, https://docs.microsoft.com/en-us/graph/api/presence-get?view=graph-rest-beta&tabs=http, many where seeing interesting scenarios for automating Microsoft 365 using this presence status. In fact many, myself included, created different solutions for setting light bulbs etc to reflect the Teams presence. If busy, then red lights, if available green lights, and so on. I have this setup myself using Philips Hue lights, and have created a PowerApp using Flows to control my lights:

There has been one problem though, getting Teams Presence has only been possible by continuously querying the API to check if the status has changed. This can be scheduled of course, but running this every minute or so seems like an excessive way to achieve the goal: being able to see if the Teams Presence has changed!

Until just a few days ago that is, where I noticed that Teams Presence now is in Preview for subscribing to change notifications in Microsoft Graph: https://docs.microsoft.com/en-us/graph/webhooks#supported-resources

In this blog post I wlll show how to create a subscription for change notifications for Teams Presence for a specified user, and the requirements for doing this. And I will use Power Platform and Power Automate Flows to achieve this.

Let’s start with the Requirements..

First of all, to be able to set up a change notification for a resource, you need the same API permission as the resource require itself, for Teams Presence this is one of the following:

  • Presence.Read, for being able to read your own users presence status.
  • Presence.Read.All, for being able to read all users in your organization’s presence status.

Currently in the Beta endpoint, getting presence is only supported for Delegated permissions using work account, so you will have to to this with a logged in user.

The other important requirement is that you need a webhook uri for where the change notification can send a POST request for the resource that has been changed. This webhook uri can be on your preferred platform, many are using Azure Functions for this, but it can also be a third party platform. I will do it using Power Automate, another alternative could be using Azure Logic Apps also.

This webhook uri need to be able to:

  • Process the initial creation of the change notification subscription. Microsoft Graph expects a text response with a validation token for it to be successful.
  • Process every change to the resource that you subscribe to, in this example a Teams Users Presence Status.

We will get into the details on this, but for now, we will start explore using Graph Explorer.

Explore Presence and Subscriptions with Graph Explorer

Go to the Microsoft Graph Docs site and find Graph Explorer there, or just go to https://aka.ms/ge, and log in with your work account.

Type the following GET query: https://graph.microsoft.com/beta/me/presence

You need to be a Teams user to run this, but if permissions are consented, you should be able to see your own presence status like my example below. If you are getting a permission error, make sure that one of the permissions for Presence.Read or Presence.Read.All er consented. This can already been done by your administrator, if not you need to consent to them yourself.

Great, let’s check another users’ presence status. PS! The permissions don’t require admin consent, and using delegated permissions every user can check other users presence status, but you need Presence.Read.All to do that.

You need the other users id property, so you can check that first using for example <a href=”https://graph.microsoft.com/v1.0/users/https://graph.microsoft.com/v1.0/users/<someotherusersUpn>/?$select=id.

And then query for the other user’s presence: <a href=”https://graph.microsoft.com/beta/users/https://graph.microsoft.com/beta/users/<userid>/presence

Another way to query for your or other users presences, that are more aligned to the change notifications is using the /beta/communications/presences endpoint: <a href=”https://graph.microsoft.com/beta/communications/presences/https://graph.microsoft.com/beta/communications/presences/<userid&gt;:

If you can run all these queries successfully, then you are ready to proceed to change notifications subscriptions.

You can check if you have any active subscriptions for change notifications using a GET query to: https://graph.microsoft.com/v1.0/subscriptions or https://graph.microsoft.com/beta/subscriptions, depending on if you are working with preview resources. If you have no active subscriptions this should return a successful but empty response like below:

The next part would be to create a subscription for change notifications for presence, but first we need to prepare the Flow for receiving the webhook uri.

Create a Power Automate Flow for Change Notification Webhook

Log in with your work account to flow.microsoft.com, and create a new flow of type automated and blank, skip the first part of using pre-selected triggers. Search for the Request type trigger that is called “When a HTTP request is received”:

Next add a Initialize Variable action for setting the ClientState which we will use later for the creating the subscription. Set the variable to anything you want, give a name to the Flow and then save. When saved the HTTP POST URL will show the value you later will use as the webhook uri for the change notifications:

The next part is the most important one, and that require a little knowledge of the creation process for change notifications subscriptions. This is documented here https://docs.microsoft.com/en-us/graph/webhooks#managing-subscriptions, but the high level steps are:

  1. When the Subscription is created, a POST request is sent with Content-Type text/plan and a query parameter that contains a validationToken. Microsoft Graph expects a 200 OK response and a text/plain body that contains the validationToken to be able to successfully create the subscription.
  2. Immediately after creation, and for every change notification, a POST request is sent with Content-Type application/json. Microsoft Graph expects a 202 Accepted response to this, if not it will continuously try to send the same change notification. You should also check the ClientState for verification, and of course include your own business logic for what to do in the Flow for when changes occur.

So your Flow needs to address these requirements, and there can be different ways to achieve this, but this is how I did it in my setup:

After the initialize variable, I created a Switch control action, using Content-Type from the HTTP Request trigger. In this way I can separate the logic in my flow for the initial creation and validation, and for the updates.

Validating the Subscription

If the Content-Type is text/plan; charset=utf-8, I will try to get the validation token sent by Microsoft Graph, and create a response that returns status 200 OK and the validation token back in a text/plain body.

I used the Compose data operation, and a custom expression that retrieves the validationToken from the query parameters. The expression I use is: @triggerOutputs()[‘queries’][‘validationToken’].

The Request Response action returns a status code of 200, set the Content-Type to text/plain and for Body select the Output from the Compose Validation Token.

The above steps should be sufficient for creating the subscription, it is recommended to validate the ClientState also, in my case I have done that in the next step.

Processing and Responding to Change Notifications

The change notifications will come as Content-Type “application/json; charset=utf-8”, so I add a case for that under my Switch. Microsoft Graph expects a 202 Accepted Response, it is recommended to respond this early in your flow, so that any later actions or your own business logic generates errors that prevents this response.

In the Response action I just return 202 Accepted. I have then added a Parse Json action to make it easier to reference the values later in the flow:

You can generate the schema from an existing sample, from the Microsoft Graph docs, referred above, or you can just use the following sample from me here:

{  “value”: [    
{      “subscriptionId”: “<subscriptionid>”,      
“clientState”: “MyGraphExplorerSecretClientState”,      
“changeType”: “updated”,      
“resource”: “communications/presences(‘<userid>’)”,      
“subscriptionExpirationDateTime”: “2020-07-11T20:04:40.9743268+00:00”,      
“resourceData”: {        
“@odata.type”: “#Microsoft.Graph.presence”,        
“@odata.id”: “communications/presences(‘<userid>’)”,        
“id”: null,        
“activity”: “Away”,        
“availability”: “Away”      },      
“tenantId”: “<tenantid>”    }  
]}

Now I can begin my business logic. As the value from the notification body is of type array, an Apply to each block will be needed, it will be automatically added if you select any of the attributes in the resulting actions. I will first verify that the clientState is matching the variable i defined in the beginning of the flow. This is a safestep that only the Graph subscription I created can call this Flow.

In the next part I have added a new Switch control, where I retrieve the presence status that have changed.

And this is where you add your own business logic, so I will stop here. In my own example (see PowerApp for Hue Lights above) I will control my lights based on presence updates, but this is a theme for a upcoming blog post.

With the Flow ready, we can now create the Subscription.

Creating Microsoft Graph Change Notification for Teams Presence

I will now create the Subscription in Graph Explorer, using a POST request to https://graph.microsoft.com/beta/subscriptions. In this POST request you will need a request body that contains the following:

Here is a quick explanation of the above values:

  • changeType: can be “updated”, “created”, “deleted”. Only “updated” is relevant for presence changes.
  • clientState: For verification in the webhook that the call is coming from the expected source, consider this a sensitive value.
  • notificationUrl: This is the webhook uri, and for my Flow this will be HTTP POST URL shown earlier.
  • resource: This is the user I want to get presence updates from. Note that you can get multiple user presences also using /communications/presences?$filter=id in ({id},{id}…) (https://docs.microsoft.com/en-us/graph/api/resources/webhooks?view=graph-rest-beta)
  • expirationDateTime: Every subscription only lasts for a specific time depending on resource type. The subscription needs to be renewed before expiry. For Teams Presence subscriptions only last one hour, same as chatMessage. See details for different types of resources: https://docs.microsoft.com/en-us/graph/api/resources/subscription?view=graph-rest-beta#properties. If you select an expiry time that is larger than supported, it will reset to one hour max.

Let’s run this query to create the subscription, if everything works, I will now get a 201 response that the subscription is created. Note the expiration time that is one hour from now:

This wouldn’t work if my Flow had failed, so let’s look into the run history on that. I see that I have 2 recent successful runs:

Let’s look into the first one. I see that the request is coming in as a text/plain with a validationToken, which I then return to MIcrosoft Graph:

Let’s look into the second run. This returns the first presence update, I can see that the user is “away”:

Now, let’s test this. With my user I go to Teams client, it should automatically change my presence from away to available or busy depending on my calendar, or I can set the status manually myself:

Checking the Flow runs again, I can indeed see that the Flow has been triggered via the Change Notification:

If I look into the details, the status update is Available:

If I bring up the Flow in a bigger picture I can indeed see that my logic ends up where the switch case checks for available status:

My Flow will now be triggered for every change as long as the subscription don’t expire.

Summary

In this blog post I have shown how you can create a Microsoft Graph Subscription for Change Notifications to selected users Teams Presence, using Power Automate to validate subscriptions and process the changes.

There are more work to do, as I need some logic for renewing and managing my subscriptions. But that will be the topic for the next blog post coming soon!

Thanks for reading, hope it has been useful 🙂

Remote Authentication and Controlling Philips Hue API using Postman

A while back I bought my first starter kit of Philips Hue lights and bridge, and since then I’ve bought several more bulbs, lamps, lights strips and more. One of the things I quickly got interested in was how to use the very well developed Hue API (https://developers.meethue.com/develop/hue-api/). You need to register and login with a Hue Developer Account, which is free, to be able to explore the API documentation, and for following the steps I describe in this blog post.

If you want to have a very quick look at the Hue API, you can start with this link which does not require a Hue Developer Account: https://developers.meethue.com/develop/get-started-2/. If you are familiar with Postman for exploring API’s, which may have brought you to this blog post to begin with, you should read on as I will describe and share some of the work I have been doing.

When I started exploring the API, I did what most people do: I searched online for tips and how-to’s. I found the following useful Postman Collection on GitHub: https://github.com/moldedbits/philips-hue-postman. So I downloaded that collection, and after configuring my Postman environment with the IP address to the bridge, and pushed the linked button to create a username, all described above on the get started link, I was good to go!

However, this let’s me explore the API only locally, requiring me to run the commands from a local device. This is where I should let you know my real reasons for wanting to use the Hue API, as I work with Microsoft and Cloud solutions daily. I wanted to look into scenarios where I can manipulate my Hue Lights dependent on events from the Microsoft Platform. It could be updating the lights to reflect my presence in Teams, it could be blinking the lights if some alerts happened, and so on. I want to be able to use Azure Functions, Power Platform, PowerShell etc. for controlling my Hue API.

To be able to do that, I need to be able to run Hue API commands remotely, and luckily the Hue API support that as well: https://developers.meethue.com/develop/hue-api/remote-api-quick-start-guide/.

Before I go into the details of this blog post on how I set up remote authentication and control of my Hue API using Postman, I first wanted to share a proof and sneak peak of a coming blog post that I have succeeded in what I’ve wanted, I can now authenticate and control my lights using for example Power Platform:

It was really the foundation of what I learned using Postman to do Remote Authentication to Hue API that made me able to create the solution above, so lets get into the details.

Create a New Remote Hue API app

The first thing you need to do after you have create a Hue Developer account, is to create a new Remote Hue API app here: https://developers.meethue.com/my-apps/.

You need to specify the following required fields:

  • App name: A display name for your remote app
  • Callback URL: This is needed for the Oauth2 consent and returning an authorization code. Specify https://app.getpostman.com/oauth2/callback here.
  • Application description: A short description for your remote app.
  • Optionally you can specify contact details.

After submitting your new app is ready, and also an AppId, ClientId and ClientSecret will be provided, for example:

You are now ready to start setting up your Postman client. If you don’t have Postman installed you can get it at https://www.postman.com/downloads/.

Create Postman Environment and Collection

In the Postman client I have saved all my variables and requests against the Hue API in an environment and collection. At the end of this blog post, I will share with you the link to a GitHub repository where you download these samples for you to start with yourself.

As I will be using several variables with my Postman queries against the Hue API, I’ve created an environment like the following:

Most of these variables are empty to begin with, but you can start by filling out:

  • ClientId: From the app registration at your Hue Developer Account.
  • ClientSecret: From the app registration.
  • AppId: From the app registration.
  • DeviceId: This is the id of the client you will be running queries from. It could be anything like the name of the computer, or the environment you are running from. I just chose my surname and postman.
  • DeviceName: Anything Display Name for the device you run the queries from.

The rest of the variables will be empty for now, but they will be calculated and updated based on responses later.

Also, since collections and variables can be synced and shared with other users or devices, I keep the sensitive variables like client id and secret only in current value column.

After creating my environment, I’ve created a collection with folders for my requests, for example like the following:

We can now proceed to start with Remote Authentication to Hue API.

Remote Authentication to Hue API

Hue Remote API use Oauth2 authorization code flow to get an access token that has to be included in the HTTP Authorization Header for every request to the API. We will use the app registration we did earlier to authenticate with the developer account and grant application access, and with the resulting authorization code we can request the access token to be used in the requests.

The documentation for Remote API is here: https://developers.meethue.com/develop/hue-api/remote-authentication/, and I will walk through the following requests in my Postman Collection:

Get Authorization Code

To get an Authorization code you need to construct an Url like the following:

https://api.meethue.com/oauth2/auth?clientid=ClientId&response_type=code&state=anystring&appid=AppId&deviceid=DeviceId&devicename=DeviceName

You can use Postman to construct the Url like the following, but you cannot really run the query from here as the Postman browser does not support the response:

You can use the code view on the right to get a preview of the request, and the copy it from there and paste it to your browser:

When you execute the authorization code url in your browser, you will be asked to log in with your Hue Developer account, if you aren’t already, and then you need to grant permission to your app registration:

After successfully granting permission, you will be redirected to the Callback Url you specified earlier, and from there you can get the authorization code:

Copy that code and paste it in the environment variable for AuthorizationCode as shown below:

Now that we have the Authorization Code, we can proceed requesting the Access Token. There are two methods for getting an access token:

  • Basic Authentication, which sends your client id and secret as base64 encoded strings in the authorization header.
  • Digest Authentication, which use a more secure challenge-response handshake that handle the credentials more securely.

See documentation for more details on whether to use basic or digest. I will show both in the following.

Get Access Token with Basic Authentication

To get an access token with basic authentication, create a POST request to the token endpoint, specifying the following query parameters:

  • code=authorization code you received in the previous step, using the environment variable
  • grant_type=authorization_code

In addition to that you need to set the Authorization Header to type Basic Authm and specify the ClientId and ClientSecret as shown below:

Postman has this great feature called tests that you can use to run javascript commands before (pre-request) or after queries. You can use this to save response details and update your environment variables. In my example I’m saving the response which would include the access and refresh tokens, and update my environment variables with that:

If I now run this request (and you haven’t waited to long to the authorization code to expire), you should get a successful response:

These tokens expire after the specified amount in seconds. For the Access Token this is 168 hours = 7 days. The Refresh Token expire after 112 days.

This means that after 7 days, you will need to use the refresh token to get a new access token. And when you do that, you will get a new access token valid for 7 more days, and a new refresh token again valid for another 112 days. This means in theory that as long as you refresh the access token regularly, this can last “forever” for your client.

You can also verify that the environment variables for access token and refresh token has been updated based on my javascript from above:

Refresh Token with Basic Authentication

If your access token has expired, you will get a response like the following:

To refresh the access token, you need to use the oauth2/refresh endpoint and with the query parameter grant_type?refresh_token:

The same as getting access token with basic authentication, also when refreshing you need to specify the authorization header to use basic auth, and with client id and secret as username and password:

In Headers, specify that the Content-Type is application/x-www-form-urlencoded:

And in the Body of the request, specify the environment variable for refresh token as form parameter like this:

Under Tests I have the same javascript as shown earlier, which lets me save the refreshed access token and refresh token to my environment again. When I run the request to refresh the access token, I should get a successful response like the following:

Now that I have an access token and refresh token, I’m all set for doing the necessary remote config for getting a username to use in the requests, but first I will show how to do Digest Authentication. If you want you can skip right to the Remote Configure Link Button and Create User section below.

Get Access Token with Digest Authentication

When you want to get an access token using Digest Authentication, you will need to start over again with getting an authorization code as described earlier. After that I will just request an access token with a POST request to the oauth2/token endpoint with the query parameters of code=authorization code & grant_type=authorization_code. This is basically the same request as I used with basic authentication, but with one important difference: I will not specify the Authorization Header to be basic auth.

When I run this request without a authorization header, I will get a 401 unauthorized response like the following. In the response Header and the WWW-Authenticate key I will get the first part of the challenge-response needed for Digest Authentication, the value called Nonce:

As with previous requests, I run a javascript test that extracts the response, in this case it is a little more complicated as i need to examine the response header and split so that I can get the Nonce value. This is so saved to the Nonce environment variable like this:

Now that I have the Nonce I can proceed requesting an access token with Digest Authentication. This time I go to the request Headers and add an Authorization Header with a value as shown below:

This requires a little more explanation. The Authorization header consist of the following:

Digest username=”{{ClientId}}”, realm=”oauth2_client@api.meethue.com”, nonce=”{{Nonce}}”, uri=”/oauth2/token”, response=”{{ResponseMD5Hash}}”

, where Nonce is the value I retrieved from the WWW-Authenticate response header in the first request, and the response is a calculated MD5 Hash as explained in the documentation linked earlier from Hue Remote API. But how did I get this value calculated? This time around I’m using a pre-request script to calculate that, based on the formula from the documentation (marked in green comment below):

So this little pre-request script calculates and sets the ResponseMD5Hash environment variable, so that I have that available when constructing the Authorization Header for Digest authentication.

Before I proceed with requesting an access token using Digest Authentication, I need to put together a Test script that do 2 tests:

  1. Check if there is a WWW-Authenticate response header, and if so save the Nonce to environment variable.
  2. Check if there is a successful json response and if so save the access and refresh tokens to environment variables.

My script now looks like this:

This means that I will need to run the request twice in succession, the first time I will get a 401 Unauthorized response, in which I will get the Nonce:

The second time I will get the 200 OK and a JSON response:

I now have an access token using Digest Authentication:

Refresh Token with Digest Authentication

When the Access Token expire, I will need to use the Refresh Token to get a new Access Token with Digest Authentication. Refreshing using Digest is based on the same challenge-response flow as getting the access token.

First I need to construct a POST request to the oauth2/refresh endpoint like below:

Then I have to add to the Header Content-Type: application/x-www-form-urlencoded, and the Authorization using Digest like shown below:

This Digest Authorization Header is the same as with requesting the access token, with one important difference, uri is “/oauth2/refresh“.

Next, in the Body I need to specify the refresh token:

In the Pre-request Script, make sure to use “/oauth2/refresh” when calculating the md5 hash:

And the Tests scripts are the same as with getting an access token:

Remember that refreshing the access token using Digest will follow the same pattern as getting the access token, you will need to run the refresh request twice in succession for getting a 401 Unauthorized and then 200 OK like shown above.

Get Access Token with Postman Oauth2 Authorization

With the collection of requests shown above, you should now be able to use the access token and refresh when needed for as long time as you need to. Before I proceed to configuration and accessing my lights, I will add one more method of getting access token with Postman: Using the built-in Oauth2 Authorization method.

Lets start by creating the following GET request, this is just a simple request to get configuration from my HUE bridge:

Next, go to Authorization, select Oauth 2.0 and add Authorization data to Request Headers as shown below. Then click on the Get New Access Token button:

In the following dialog, give a name for your Token, and make sure that grant type is Authorization Code. Select Authorize using browser, and note the Callback URL. You need to copy this URL. Construct an Auth URL using your environment variables like I have shown below, the Access Token URL, specify ClientId and ClientSecret variables, type any string for state, and make sure that Client Authentication is Basic Auth header:

Now, before you click on Request Token, you need to go back to your Hue Developer Account and change the Callback URL to the one above:

When you have done that, you can click on Request Token, which will launch you default browser:

You need to be logged in with your Hue Developer account and grant permission:

After that you will get the following message when redirected:

You might have some issues with pop up blocker or redirects:

If everything works as expected, your Postman client will receive the callback and complete then authentication:

And you should receive your Access Token:

Note the little warning about partially support:

Click the Use Token button, which should fill in the Access Token field. Now click Send on the request:

This should now response with some config details of your Hue Bridge, like the name and versions. If you go to Headers and show the hidden Headers you will see that Authorization Header has been set with Bearer and your Access Token.

So going forward, and for the rest of this blog post, you now have two options for using Access Token:

  1. Use the Access Token from environment variables that I have shown how you can retrieve with Basic or Digest Authentication, and Refresh when needed.
  2. Use the Oauth2 Authorization for every request (or set it on the parent level of your collection of requests). When the Access Token expire, it won’t refresh automatically, so you need to Request a new one.

Remote Configure Link Button and Create User

Now for the next part we will have to remote configure the link button, so that the bridge will accept creating a new user for us to be able to control the lights.

Enable Link Button

Users of Hue will remember that you from time to time that you need to push the link button on your bridge when adding new users. With Remote API we can do this without having to run around the house 😉

Create a PUT request like the following. On Headers specify Authorization and value to be Bearer {{AccessToken}}, which will get your environment variable from the previously retrieved access token. PS! For all the following requests: Always include this Authorization: Bearer {{AccessToken}} header!

Specify Content-Type: application/json:

Next, set the Body to {“linkbutton”: true}:

And then Send the Request, you should get a success response like below:

You now have 30 seconds to add your user..

Add Whitelist Identifier

Next, create a POST request to the Bridge endpoint that specify devicetype in the Body, like shown below, where devicetype is a named description of your client and app, for example:

Run the request, but if 30 seconds have passed, you will get this response:

In that case, just run the PUT request again to enable the link button, and try again. When successful you should get a response like the following:

This username have to be included in every Hue Remote API request later, so make sure to save it in your environment variables:

Get All Configuration

Your starting point now for all requests are https://api.meethue.com/bridge/{{username}}/ (and remember to include the Authorization: Bearer {{AccessToken}} header always).

If I want to list all configuration, I can run this GET request:

Which will provide me with all the configuration details of my Bridge:

We are now ready to start controlling the Lights and more!

Control Lights Remotely

If will now show you some sample requests for controlling lights via Hue Remote API:

List All Lights

If I want to list all my lights, I can just run a GET request: https://api.meethue.com/bridge/{{username}}/lights/:

The response will show all lights, numbered from 1 to count of lights connected to your bridge. I’ve collapsed some details in the response above, but you can see from my light number 12 that the state is “on”, you can see the brightness, color and more.

PS! Every light is a new typed object, and not an array, which I find a bit unfortunate, so you need to be aware of that if you want to loop through your lights for example.

If you want to get a specific light, just add the light number at the end of the GET request URI, like this: https://api.meethue.com/bridge/{{username}}/lights/12

Turn a Light On/Off

You can control the state of a specific light by doing a PUT request to your specified light number, for example light number 12: https://api.meethue.com/bridge/{{username}}/lights/12/state

You need a Request Body that tells what the light state should be. For example to turn the light off, just include a body with {“on”:false}, the response will confirm success (and you should be able to visually confirm as well ;):

Likewise, to turn on again:

Controlling Light State and Colors

Now you can really start playing with your lights with custom states, you can change brightness, go from cold white to warm white, or maybe set a color scene for the millions of colors available if your light supports color. More info can be found here:

https://developers.meethue.com/develop/get-started-2/core-concepts/#controlling-light

Light color are primarly controlled by the CIE color space, where you specify an array of two values between 0 and 1 expressed as x and y.

Source: https://developers.meethue.com/develop/get-started-2/core-concepts/#controlling-light

Here is an example where I both control brightness (1-254) and a custom color:

Now, you can just experiment and learn for yourself. A good tip is to use your Hue App on your mobile phone to set the color you like, and then use GET to get the light state color settings.

Summary and Github Repo

I hope you have learnt a lot about Hue Remote API when reading this, I certainly learnt a lot exploring and documenting this via Postman. This understanding has provided me with the knowledge and tools to look into automation and integration scenarios with the Microsoft solutions I use daily in my job. I’ve already been doing this with PowerShell, Azure Functions, Logic Apps and Power Automate to name a few. There is a blog post coming soon on Power Platform and how I did that to control my lights based on Teams Presence and more.

So whether you are a developer that loves to write code, or maybe you are more into the low-code, no-code solutions, I hope this has been helpful.

I promised I will share my Postman Collection and Requests for Hue Remote API, so here it is: https://github.com/JanVidarElven/HueRemoteAPI-Postman-Collections

Knock your self (or your lights) out, and please feel free to comment or contribute 🙂