How to make Hubitat use API for Danfoss Ally

I have installet several Danfoss Ally Thermostats. I would like to control them via Hubitat using Danfoss Ally API.

I dont know much about API's but I have it working via the Danfoss API website. However, I dont know how to make Hubitat send the commands via HTTP (or another way?).

This is what I got:

I authorize OAuth2 by using my ClientID and ClientSecret.

I need to send commands like this using my specific DeviceID as parameter:

{
"commands": [
{
"code": "temp_set",
"value": 200
}
]
}

HTTP request fails
Danfoss Ally returns this error message when I use this HTTP command (Danfoss says this is the HTTP request):

"https://api.danfoss.com/ally/devices/{device_id}/commands"

However this just returns this error:

{
"type": "https://developer.danfoss.com/error-code-reference#header-information-missing",
"title": "One or more mandatory header parameters are missing from the request",
"status": 400,
"message_id": "rrt-4156407230370419063-c-geu1-22319-194202641-1"
}

Anyone knows how to do this?

Probably best directed in the developer section, if your one?

Im not a developer :slight_smile:

Then you need to ask a different question, you need to ask the developers if any would be interested in putting in the work to create a device or app to create the integration. you may find some have the same product. you can also look around to see if there was one before in smartthings or another hub as it may be able to be ported.

2 Likes

Do you have a link to the API documentation? Looks like they may be responding to HTTP GET so you’d want to use the asyncHttpGet command in a driver (or app if really complex). As part of the command you can specify the parameters, normally one of them is an authorization code that comes back from the login.

Also looks like the devices are zigbee 3.0 so it may be possible to find a local driver and cut the need for the cloud.

3 Likes

It says it accepts the HTTP GET command. However, I dont know how to send the commands. Can it be done by a simple HTTP request in a browser?

HTTP GET is the default for a browser, your issue will be that adding the authorization or other headers will require some coding - not difficult and it looks like they'll give you examples as you walk through their API, but ....

Had a few minutes to start an app:

https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossMstr.groovy

You’ll need to register the app with Danfoss (call it whatever you like) to get the API Key and Secret to fill in, and I don’t have any Danfoss devices so I can’t test past the initial authentication, but if this returns a list of your devices I could probably flesh it out into a full app and associated child devices.

4 Likes

Thank you so much!

I put in my key and secret from the app. When I pres check authentication it returns lots of letters below the button (something like hnlGy6xxxxxxxxxxVqAz5Sy) . When I pres get devices it returns with this:

Error: No signature of method: user_app_thebearmay_Danfoss_Master_687.paragraph() is applicable for argument types: (groovy.json.internal.LazyMap) values: [[result:[[active_time:1663423195, create_time:1663423195, id:bf7c1872db83e8d78ezmua, ...], ...], ...]]

Any thoughts? :slightly_smiling_face:

It didn't like me being lazy :sunglasses:

v0.0.2 out there, but it does look like it's pulling data. Probably shouldn't post the ID of anything, and I do need to suppress display of the secret come to think of it.

Bottom line, this looks to be doable.

:+1::+1::+1::+1::+1::muscle::muscle::muscle::muscle::muscle:

Fantastic - now I get lots of info, for instance My thermostat in the bathroom (Badeværelse v Hoveddør):

name:Badeværelse v. hoveddør, online:true, device_type:Danfoss Ally™ Radiator Thermostat, id:bfaXXXXXXXXXX26a39rlmo, time_zone:+02:00, status:[[code:switch, value:true], [code:mode, value:manual], [code:work_state, value:NoH.........

But how do I send the commands to it? :slightly_smiling_face::slightly_smiling_face::slightly_smiling_face:

I need to build that section yet. What I'll do is have the app query the device list and then build a child device for each device it sees. You'll be able to control each real device through the virtual child device when I'm done.

Sounds absolotely great! :grin:

Do you need anything from me?

I have a little bit of coding to do to get to the next phase of this, and then I'll push it up for you test (24-48 from now hours if I don't hit any major snags). We'll probably go through a couple iterations until we get it right, and if you see anything along the way that you'd changed let me know and we'll see what we can do.

Fantastic. I am very grateful :slightly_smiling_face::slightly_smiling_face::slightly_smiling_face:

1 Like

New version out there, plus a device driver.

App:
https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossMstr.groovy
Device Driver:
https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossThermostat.groovy

At this point, you should only need to:

  1. Go to the Drivers Code section and create a new driver by importing the Device Driver link above
  2. Go to the App code section and re-import the app code
  3. Go to the app and hit Get Devices

If everything is working correctly you should end up with a child device for each of the thermostats you have defined to Danfoss. Only saw 2 commands temp_set and possibly mode. By default each thermostat is set to poll every 5 minutes, but can be set by child device.

You are fast!

When I his get devices i get tis Error message (I have deletet sensitive info) :slight_smile:

Danfoss Master
settings
Unexpected Error
An unexpected error has occurred trying to load the app. Check Logs for more information.
Error: expecting '}' or ',' but got current char 'r' with an int value of 114 The current character read is 'r' with an int value of 114 expecting '}' or ',' but got current char 'r' with an int value of 114 line number 1 index number 1 {result=[{active_time=1663423195, create_time=1663423195, id=bf7c1872dzmua, name=Danfoss Ally™ Gateway, online=true, status=[], sub=false, time_zone=+02:00, update_time=1663424521, device_type=Danfoss Ally™ Gateway}, {active_time=1663424096, create_time=1663424096, id=bfa15fa9941rlmo, name=Badeværelse v. hoveddør, online=true, status=[{code=switch, value=true}, {code=mode, value=manual}, {code=work_state, value=Heat}, {code=temp_set, value=150}, {code=upper_temp, value=350}, {code=temp_current, value=193}, {code=window_state, value=close}, {code=lower_temp, value=50}, {code=child_lock, value=false}, {code=battery_percentage, value=91}, {code=factory_reset, value=false}, {code=fault, value=0}, {code=ViewingDirection, value=false}, {code=LoadRadiatorRoomMean, value=-500}, {code=Load_estimate, value=-11}, {code=leavinghome_temp, value=170}, {code=pause_temp, value=60}, {code=SetpointChangeSource, value=Schedule}, {code=leave_home_fast_heat, value=50}, {code=at_home_fast_heat, value=50}, {code=manual_mode_fast, value=200}, {code=holiday_temp, value=150}, {code=window_toggle, value=true}, {code=window_state_info, value=close}, {code=at_home_setting, value=210}, {code=leaving_home_setting, value=170}, {code=pause_setting, value=50}, {code=holiday_setting, value=150}, {code=heating_mode_VC, value=Heating}, {code=switch_state, value=false}, {code=last_click_time, value=}, {code=data_logger, value=}, {code=motor_step_counter, value=0}, {code=vertical_mounting, value=Horizontal}, {code=sync_preheat_time, value=0}, {code=battery_level, value=0}, {code=banner_ctrl, value=false}, {code=boiler_relay, value=true}, {code=room_sensor, value=false}, {code=sensor_avg_temp, value=-800}, {code=mounting_mode_active, value=false}, {code=sw_build, value=}, {code=battery_voltage, value=0}, {code=ext_measured_rs, value=-32768}, {code=radiator_covered, value=false}, {code=ctrl_alg, value=1}, {code=heat_available, value=false}, {code=heat_supply_request, value=false}, {code=load_balance_enable, value=false}, {code=etrv_configuration, value=0}, {code=rh_temp_meau, value=0}, {code=local_temperature, value=-5000}, {code=pi_heating_demand, value=0}, {code=OccupiedSetpoint, value=-32768}, {code=operation_mode, value=0}, {code=open_window, value=0}, {code=adaptation_runstatus, value=0}, {code=sw_error_code, value=0}, {code=moto_step_counter, value=0}, {code=ControlDiagnostics, value=}, {code=CtrlDiagFrequency, value=0}], sub=true, time_zone=+02:00, update_time=1663424140, device_type=Danfoss Ally™ Radiator Thermostat}], t=1663836276324} .^

Can you turn on the debugging and try it again - should be the same result, but I want to see what format the data came back in before I hit the error. Let’s start doing the exchange via PM at this point so that we don’t clog the thread with detail that no one else will read.

There are a few more tweaks that may be needed to clean things up a wee bit, but these appear to be ready for general use:

App:
https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossMstr.groovy

Thermostat Driver:
https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossThermostat.groovy

Room Sensor Driver:
https://raw.githubusercontent.com/thebearmay/hubitat/main/danfoss/danfossSensor.groovy

I’ll be creating a Release post to track bug and enhancement requests over in the Developers section, and adding these to HPM later today.

Edit: Release post at:

Fantastic work! Fantastic to be able to include all these sensors and thermostats in Hubitat while on the same time be able to use the Danfoss Ally app to update the devices make detailed settings etc.