Ecobee binding v2

TIP: Under Configuration>System>Regional Settings you need to click [Show More] to make the Measurement System preference appear.

2 Likes

Thanks. I never knew that was there.

Guys,
I’m currently transitioning to the ecobee binding v2, and obviously need to rewrite my action rules.
Right now, the temperature hold (for setting a new temperature, simple as that) is not working as expected.
The programming example relies on a proxy switch and values for that:
Switch SetTemperatureHold "Set Temperature Hold [%s]"
Number:Temperature UserCool "User Selected Heat [%.1f %unit%]"
Number:Temperature UserHeat "User Selected Cool [%.1f %unit%]"

In the example, the value from UserCool/UserHeat is sent to the ecobee, so far, so good.

val ecobeeActions = getActions("ecobee","ecobee:thermostat:account:103778713388")
ecobeeActions.setHold(UserCool.state as QuantityType, UserHeat.state as QuantityType)

However, it does not get updated itself. When one just changes the temperature, that is fine, but when some other mechanism (like a schedule) changes setpoints, it’s not reflected.

That’s why with the v1 binding I used not a proxy, but an item tied to the “desiredHeat” and “desiredCool” channels. I’d increment them, the change would go to the ecobee and be read back on the next update.

Now, however, it seems that the desired temperatures are read back from the thermostat before writing new ones, is that the case? What happens is that on a change the “desired” temperature reflects my change for a moment, but then flips back to its old value.

Any idea (or code snippets) on how you guys implement that? What exactly does the “getActions” do other than set which thermostat to use?

Thanks!

The desiredHeat and desiredCool channels are defined as read-only because that’s how they are defined in the Ecobee API spec. Therefore, you cannot send commands to those channels.

If you send a command to the desiredHeat and desiredCool channels, I suspect that’s why it’s “flipping back” to the old value.

Yes, it simply gets a handle to the thing for the purpose of invoking it’s action(s).

I’m not sure I follow this. Are you setting a hold using the setHold action? If so, the hold will be in effect until it’s canceled.

I think I found the problem, I needed to have the rule wait a second before issuing the action, then it works.

Ok, to go into details on how I do it:
In the items file, I define the (read-only) items for desiredCool and desiredHeat. For the ecobee, that clearly is a read-only value, but for openhab it’s not. So I can map it on a dashboard and change the value.
When that happens, the rule kicks in:
when
Item ecobee_mbr_setpoint_heat received command or
Item ecobee_mbr_setpoint_cool received command
then
val ecobeeActions = getActions("ecobee","ecobee:thermostat:account:number")
Thread::sleep(1000)
ecobeeActions.setHold(ecobee_mbr_setpoint_cool.state as QuantityType<Number>, ecobee_mbr_setpoint_heat.state as QuantityType<Number>, null, null, null, "nextTransition", null)

So it takes the new value for desiredCool (ecobee_mbr_setpoint_cool in my case) and sends it to the ecobee as a hold (in this case I only want it to hold until the next transition kicks in, like the schedule. That’s why I need to use the whole definition of the setHold).

So now when my schedule or an away hold changes the desiredCool setpoint, it is reflected in ecobee_mbr_setpoint_cool. That would not be the case if I were to use the proxy.

With the proxy, say I change the desired.Heat temperature to 75 and leave it there, but then the schedule changes that to 65 for the night, the proxy would still show 75 because it does not get updated.

Or do I have a wrong train of thought somewhere here?

1 Like

This is a good solution. Thanks for posting.

I do see a very slight timing issue. If there’s a schedule change after you change the item, but before the action executes, it’s possible that the wrong setpoint will be used in the call to setHold. In practice, I expect this would occur rarely, if ever.

Also, the reason you need the delay is because you’re accessing the state of the item before it’s been updated by openHAB. This could be avoided by using triggeringItem, but you’d need some extra rule logic to determine which item is the triggering item.

Yes, that’s right. This could be avoided by updating the proxy item whenever desiredHeat and desiredCool changes.

In general, though, it looks like you have a good, workable solution.

Indeed, one could update the proxy based on the “desired” temperatures, but that would still leave you with twice the number of items than necessary.
As my solution works now, I’ll stick with it.

I see the timing issue, but as it would only apply for one second at each schedule change, I don’t think it has any practical influence on functionality.

Makes sense. It’s a good solution?

Agreed. Likelihood of it occurring is extremely rare. You probably could reduce the sleep amount, as it’s probably just a couple 10s of milliseconds for those item updates to occur.

Yes, works perfectly.
One might think about updating the programming example in the binding’s documentation to get away from the proxy items.
I could probably reduce the wait period, but I don’t mind waiting a second until my thermostat updates the temperature :wink:

@mhilbush
Mark,

First off, thank you for the work in v2. I upgraded my install from 2.5.4 to 2.5.5 over the weekend, and took the opportunity to update the Ecobee binding from v1 to v2. The efforts have been minimal, and so far everything seems to run smoothly. There is a one thing I noticed that I want to bring to your attention. Not sure if this is a bug on my side.

I have 2 items defined as follow:

DateTime Ecobee_lastModified_UTC { channel=“ecobee:thermostat:account:xxxxxxxxxxxx:info#lastModified” }
DateTime Ecobee_runtime_lastModified_UTC { channel=“ecobee:thermostat:account:xxxxxxxxxxxx:runtime#lastModified” }

When I looked at the event log, I noticed a behavior where Ecobee_lastModified_UTC is changed back and forth at the same time. No issues were observed with Ecobee_runtime_lastModified_UTC.

2020-06-06 14:40:28.510 [INFO ] [smarthome.event.ItemStateChangedEvent        ] - Ecobee_lastModified_UTC changed from 2020-06-06T19:37:11.000-0000 to 2020-06-06T16:41:50.000-0000
2020-06-06 14:40:28.510 [INFO ] [smarthome.event.ItemStateChangedEvent        ] - Ecobee_lastModified_UTC changed from 2020-06-06T16:41:50.000-0000 to 2020-06-06T19:40:11.000-0000
2020-06-06 14:40:28.510 [INFO ] [smarthome.event.ItemStateChangedEvent        ] - Ecobee_runtime_lastModified_UTC changed from 2020-06-06T19:37:11.000-0000 to 2020-06-06T19:40:11.000-0000

So, I did a curl to pull data directly from the Ecobee API. As you can see below, there are 2 “lastModified” time return.

thermostatList → lastModified: “2020-06-06 16:41:50” (The last modified date time for the thermostat configuration.)
runtime → lastModified: “2020-06-06 19:40:11” (The UTC date/time stamp of when the thermostat was updated.)

It appears the binding initially updated Ecobee_lastModified_UTC with “thermostatList → lastModified”, then overwrote it with “runtime → lastModified”. Appreciate if you can take a look and see if you are also seeing the same behavior.

Thanks in advance!

{
    "page": {
        "page": 1,
        "totalPages": 1,
        "pageSize": 1,
        "total": 1
    },
    "thermostatList": [{
        "identifier": "xxxxxxxxxxxx",
        "name": "My ecobee",
        "thermostatRev": "200606164150",
        "isRegistered": true,
        "modelNumber": "nikeSmart",
        "brand": "ecobee",
        "features": "Home,HomeKit",
        "lastModified": "2020-06-06 16:41:50",
        "thermostatTime": "2020-06-06 14:42:49",
        "utcTime": "2020-06-06 19:42:49",
        "runtime": {
            "runtimeRev": "200606194011",
            "connected": true,
            "firstConnected": "2018-10-19 02:49:51",
            "connectDateTime": "2020-06-03 15:11:45",
            "disconnectDateTime": "2020-06-02 07:06:51",
            "lastModified": "2020-06-06 19:40:11",
            "lastStatusModified": "2020-06-06 19:40:11",
            "runtimeDate": "2020-06-06",
            "runtimeInterval": 234,
            "actualTemperature": 755,
            "actualHumidity": 51,
            "rawTemperature": 755,
            "showIconMode": 0,
            "desiredHeat": 700,
            "desiredCool": 750,
            "desiredHumidity": 36,
            "desiredDehumidity": 60,
            "desiredFanMode": "auto",
            "desiredHeatRange": [
                450,
                790
            ],
            "desiredCoolRange": [
                650,
                920
            ]
        }
    }],
    "status": {
        "code": 0,
        "message": ""
    }
}

Thanks for the investigation @jakdock. I’ll have a look.

@jakdock I didn’t turn up anything unusual after my first quick look at the code.

It updates the info#lastModified channel here.

And it updates the runtime#lastModified channel here.

Those are the only 2 places where the lastModified channels are updated.

@mhilbush

I restarted OpenHAB, and I am no longer seeing the behavior that I saw earlier. Appreciate you taking a look at this so quickly. I will keep an eye out on it, and will reply back if I see anything unusual.

Thanks again!

Thanks. I had a feeling that a restart might resolve the issue.

OTOH, I found what might be the cause. I have lastModified defined as a channel type twice here and here. I’ll correct this next time I do a release. If the problem reoccurs for you, post back here and I’l push the fix more quickly.

Thanks, Mark.

On a different topic, I finished converting all of my items over from v1 to v2 last night. I am only using 20 or so items (mostly in “info”, “runtime”, and “settings”), and everything is working great. The items are all updating as expected and matching the API I manually curl. However, I have not been able to get the weather forecast group to work. I defined them exactly like the other items, but all of them are showing up as NULL. Below are a few examples of how I defined the items.

Number:Temperature   Weather_Temperature "Temperature [%.0f %unit%]" { channel="ecobee:thermostat:account:xxxxxxxxxxxx:forecast0#temperature" }
Number:Dimensionless Weather_Humidity    "Humidity [%d %unit%]"      { channel="ecobee:thermostat:account:xxxxxxxxxxxx:forecast0#relativeHumidity" }
Number:Speed         Weather_Wind_Speed  "Windspeed [%.0f %unit%]"   { channel="ecobee:thermostat:account:xxxxxxxxxxxx:forecast0#windSpeed" }

This appears fairly straightforward, so I am really not sure what I am doing wrong. I am also seeing no activities for items I defined in the forecast group in “events.log”. I also checked “openhab.log” and did not see anything unusual. I also did a curl and can confirm the API is returning weather forecast data (below). Any advice is appreciated. Thanks again.

{
    "page": {
        "page": 1,
        "totalPages": 1,
        "pageSize": 1,
        "total": 1
    },
    "thermostatList": [{
        "identifier": "xxxxxxxxxxxx",
        "name": "My ecobee",
        "thermostatRev": "200607030058",
        "isRegistered": true,
        "modelNumber": "nikeSmart",
        "brand": "ecobee",
        "features": "Home,HomeKit",
        "lastModified": "2020-06-07 03:00:58",
        "thermostatTime": "2020-06-07 14:49:53",
        "utcTime": "2020-06-07 19:49:53",
        "weather": {
            "timestamp": "2020-06-07 19:33:36",
            "weatherStation": "FI:KPIA",
            "forecasts": [{
                    "weatherSymbol": 0,
                    "dateTime": "2020-06-07 14:33:36",
                    "condition": "Clear",
                    "temperature": 881,
                    "pressure": 1014,
                    "relativeHumidity": 34,
                    "dewpoint": 559,
                    "visibility": 15000,
                    "windSpeed": 8,
                    "windGust": -5002,
                    "windDirection": "ESE",
                    "windBearing": 111,
                    "pop": 0,
                    "tempHigh": 891,
                    "tempLow": 618,
                    "sky": 1
                },
                ... (abridged)
           ]
        }
    }],
    "status": {
        "code": 0,
        "message": ""
    }
}

Hmm. That’s strange. I was pretty sure this was working. Let me have a look.

@jakdock I just tested it here and it’s working fine for me. Isn’t that the way it always goes… :roll_eyes:

Can you try putting the binding into TRACE mode? If at least one item is linked to a forecast channel, you should see a log entry that looks like this.

2020-06-07 17:57:01.539 [TRACE] [andler.EcobeeThermostatBridgeHandler] - ThermostatBridge: Thermostat thing 'ecobee:thermostat:server:XXXXXXXXXX' including object 'includeWeather' in selection

Also, in TRACE mode, you should see the request and response JSON.

Mark,

I think I have discovered the issue. After turning on trace, this is what it shows:

2020-06-07 20:00:39.227 [TRACE] [hab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler] - ThermostatBridge: Thermostat thing 'ecobee:thermostat:account:411977279982' including object 'includeEquipmentStatus' in selection
2020-06-07 20:00:39.227 [TRACE] [hab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler] - ThermostatBridge: Thermostat thing 'ecobee:thermostat:account:411977279982' including object 'includeProgram' in selection
2020-06-07 20:00:39.227 [TRACE] [hab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler] - ThermostatBridge: Thermostat thing 'ecobee:thermostat:account:411977279982' including object 'includeRuntime' in selection
2020-06-07 20:00:39.227 [TRACE] [hab.binding.ecobee.internal.handler.EcobeeThermostatBridgeHandler] - ThermostatBridge: Thermostat thing 'ecobee:thermostat:account:411977279982' including object 'includeSettings' in selection
2020-06-07 20:00:39.227 [TRACE] [penhab.binding.ecobee.internal.handler.EcobeeAccountBridgeHandler] - AccountBridge: Thermostat ecobee:thermostat:account:411977279982 selection: selectionType=registered,selectionMatch=null,includeAlerts=null,includeAudio=null,includeDevice=null,includeElectricity=null,includeEnergy=null,includeEquipmentStatus=true,includeExtendedRuntime=null,includeHouseDetails=null,includeLocation=null,includeManagement=null,includeNotificationSettings=null,includeOemCfg=null,includePrivacy=null,includeProgram=true,includeReminders=null,includeRuntime=true,includeSecuritySettings=null,includeSensors=null,includeSettings=true,includeTechnician=null,includeUtility=null,includeVersion=null,includeWeather=null
2020-06-07 20:00:39.227 [TRACE] [org.openhab.binding.ecobee.internal.api.EcobeeApi                ] - API: Get Request json is '{"selection":{"selectionType":"thermostats","selectionMatch":"411977279982","includeAlerts":true,"includeEquipmentStatus":true,"includeEvents":true,"includeProgram":true,"includeRuntime":true,"includeSensors":true,"includeSettings":true}}'`

The API request did not include: “includeWeather”:true. Accordingly, the API response does not include weather information. Is there something I need to pass onto the binding to turn on weather?

Thanks again.

You just need to have at least one item linked to a weather channel.

Mark,

It is working perfectly now. Thanks a lot !!