Ecobee binding v2

Here’s the widget code, you’ll have to paste it into something that does carriage returns in order to understand it.

{
    "name": "MainFloor Ecobee Thermostat",
    "author": "RedOranges",
    "description": "Ecobee Thermostat Widget forked from Signal11",
    "settings": [
        {
            "type": "checkbox",
            "id": "sensors_onmain",
            "label": "Show Sensor Data on Main Panel?"
        },
        {
            "type": "checkbox",
            "id": "hide_units",
            "label": "Hide Units?"
        },
        {
            "type": "heading",
            "label": "Advenced Item overrides",
            "description": "All items below here you should not have to modify to get this widget to work. Theres are there if you wish to substitute items from the defaults"
        },
        {
            "type": "item",
            "id": "thermostat_name",
            "default": "MF_name",
            "label": "Name of the Thermostat"
        },
        {
            "type": "item",
            "id": "hvac_mode",
            "label": "HVAC Mode",
            "default": "MF_settings_hvacMode"
        },
        {
            "type": "item",
            "id": "use_celsius",
            "label": "Use Celsius?",
            "default": "MF_settings_useCelsius"
        },
        {
            "type": "item",
            "id": "temperature",
            "label": "Temperature",
            "default": "MF_runtime_actualTemperature"
        },
        {
            "type": "item",
            "id": "humidity",
            "label": "Humidity",
            "default": "MF_runtime_actualHumidity"
        },
        {
            "type": "item",
            "id": "desired_heat",
            "label": "Desired Heating Level",
            "default": "MF_runtime_desiredHeat"
        },
        {
            "type": "item",
            "id": "desired_cool",
            "label": "Desired Cooling Level",
            "default": "MF_runtime_desiredCool"
        },
        {
            "type": "item",
            "id": "user_cool",
            "label": "User Selected Cooling Level",
            "default": "MF_userCool"
        },
        {
            "type": "item",
            "id": "user_heat",
            "label": "User Selected Heating Level",
            "default": "MF_userHeat"
        },
        {
            "type": "item",
            "id": "running_event",
            "label": "Event Type",
            "default": "MF_runningEvent_Type"
        },
        {
            "type": "item",
            "id": "schedule",
            "label": "Schedule",
            "default": "MF_runningEvent_climate",
            "description": "Running event climate"
        },
        {
            "type": "item",
            "id": "heat_floor",
            "label": "Lowest heat",
            "default": "MF_settings_heatRangeLow",
            "description": "Lowest possible user heat temperature setting."
        },
        {
            "type": "item",
            "id": "heat_ceil",
            "label": "Highest heat",
            "default": "MF_settings_heatRangeHigh",
            "description": "Highest possible user heat temperature setting."
        },
        {
            "type": "item",
            "id": "cool_floor",
            "label": "Lowest cool",
            "default": "MF_settings_coolRangeLow",
            "description": "Lowest possible user cool temperature setting."
        },
        {
            "type": "item",
            "id": "cool_ceil",
            "label": "Highest cool",
            "default": "MF_settings_coolRangeHigh",
            "description": "Highest possible user cool temperature setting. (Change if using Celsius)"
        },
        {
            "type": "string",
            "id": "active_panel",
            "label": "Active Panel",
            "default": "ecobee-main",
            "description": "Do Not Change"
        },
        {
            "type": "heading",
            "label": "Remote Sensors",
            "description": "This widget supports multiple sensors as long as they are all added under the following group."
        },
        {
            "type": "item",
            "id": "remote_sensors",
            "label": "Remote Sensors Group",
            "description": "Each sensor needs two items. The temperature and it's occupancy.",
            "default": "gMFRemoteSensors"
        }
    ],
    "template": "<!-- Based off the work of @Signal11 including contributions from Natalie_Nielsen -->\n\n<!--\nVersion 2.0\n\n+ stop using groups due it indeterminite order\n+ cancel button missing\n\treplaced with svg\n+ can get get max and min heat from thermostat?\n  \tUse instead of  config.heat_floor etc\n\t\t\tsettings_heatRangeHigh \n\t\t\tsettings_heatRangeLow\n\t\t\tsettings_coolRangeHigh\n\t\t\tsettings_coolRangeLow \n  \tNeed to set \"step\": config.temp_step, to 0.5 if using C\n+ color occupied in sensor panel\n+ color occupied on main panel\n+ hide hamberger if main panel seonsors on\n* Use sensor icon\n+ blue slider and text\n-->\n\n\n<style type=\"text/css\">\n\t#ecobee {\n\t\tposition: absolute;\n\t\ttop: 0px;\n\t\tleft: 0px;\n\t\tdisplay: flex;\n\t\tflex-direction:column;\n\t\twidth: 100%;\n\t\theight: 100%\n\t}\n\t\n\t#ecobee .ecobee-content-panel {\n\t\theight: 100%;\n\t\twidth: 100%;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n\t\n\t.ecobee-flex-panel {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t}\n\t\n\t.ecobee-current-mode {\n\t\tflex: 1;\n\t}\n\t\n\t.ecobee-dialog {\n\t\tflex: 2;\n\t}\n\t\n\timg.ecobee-mode-icon {\n\t  height: 40px;\n\t}\n\t\n\t.ecobee-mode-off {\n\t\tcolor: #b0b4ba;\n\t\theight: 40px;\n\t}\n\t\n\timg.ecobee-humidity-icon {\n\t\theight: 12px;\n\t}\n  \n\t.ecobee-btn {\n\t\tbackground-color:rgba(0, 0, 0, 0.0);\n\t}\n\n\t.ecobee-btn-selected {\n\t\tbackground-color: white;\n\t\tcolor: black;\n\t}\n  \n\t.ecobee-btn-icon {\n\t\tborder:none;\n\t}\n\t\n\t.ecobee-btn-hvac {\n\t\tpadding: 10px 0px 5px;\n\t}\n\t\n\t.ecobee-hvac-btn-group button {\n\t\tborder: 1px solid white; \n\t\tpadding: 10px 15px; \n\t\twidth: 50%; \n\t\tdisplay: block; \n\t\tmargin:0 auto;\n\t}\n\n\t.ecobee-hvac-btn-group button:not(:last-child) {\n\t\tborder-bottom: none; /* Prevent double borders */\n\t}\n  \n\t.ecobee-hvac-btn-group button:first-child {\n\t\tborder-top-right-radius: 10px;\n\t\tborder-top-left-radius: 10px;\n\t}\n  \n\t.ecobee-hvac-btn-group button:last-child {\n\t\tborder-bottom-right-radius: 10px;\n\t\tborder-bottom-left-radius: 10px;\n\t}\n\t\n\t.ecobee-temperature-current { \n\t\tpadding-top: 10px;\n\t\tpadding-bottom: 10px;\n\t}\n  \n\t.ecobee-temperature-current h2 {\n\t\tfont-size: 3.0em;\n\t}\n  \n\t.ecobee-temperature-current h2 span {\n\t\tfont-size: 3.0em;\n\t}\n\t  \n\t.ecobee-temperature-current sup \n  {\n\t\tfont-size:40%; \n\t\tvertical-align: top; \n\t\ttop: 0.9em; \n\t}\n  \n\t.ecobee-sliders \n  {\n\t\tposition:absolute; \n\t\ttop: 60px; \n\t\tright:-5px;  \n\t\theight: 70%;\n\t\twidth: 120px;\n\t}\n  \n  .ecobee-sliders .ecobee-mode-slider \n  {\n\t\theight: 100%;\n\t\tpadding-top: 20px;\n\t} \n  \n\t.ecobee-resume-dialog \n  {\n\t\tposition:relative;\n\t\tborder: 1px solid white; \n\t\tborder-radius: 5px;\n\t\tdisplay:inline-block;\n\t\twidth:auto;\n\t\tmargin: auto;\n\t\tpadding: 7px 25px 7px 25px;\n\t}\n\t\n\t.ecobee-dialog-close \n  {\n\t\tpadding: 0px;\n\t}\n\t\n\t.ecobee-resume-dialog .ecobee-dialog-close \n  {\n\t\tposition: absolute;\n\t\ttop: -10px;\n\t\tleft: -10px;\n\t}\n  \n  .ecobee_sensors_main \n  {\n  \twidth: 50%;\n  }\n\n\t.ecobee-flex-panel .rzslider.rzvertical \n  {\n\t\theight: 100%;\n\t}\n\n\t.heat-slider .slider-content-vertical .slider-container,\n\t.cool-slider .slider-content-vertical .slider-container,\n\t.auto-heat-slider .slider-content-vertical .slider-container, \n\t.auto-cool-slider .slider-content-vertical .slider-container\n  {\n\t\ttext-align: right!important;\n\t\tpadding-right: 5px;\n\t}\n\t\n\t.heat-slider .rz-bubble,\n\t.auto-heat-slider .rz-bubble \n  {\n\t\tcolor: #FFAA00;\n\t\tfont-size: 1.3em;\n\t}\n\n\t.cool-slider .rz-bubble,\n\t.auto-cool-slider .rz-bubble \n  {\n\t\tcolor: #0DB9F0;\n\t\tfont-size: 1.3em;\n\t}\n\t\n\t.heat-slider .rz-bubble, \n\t.auto-cool-slider .rz-bubble \n  {\n\t\tbottom: -30px!important;\n\t}\n\t\t\n\t.cool-slider .rz-bubble, \n\t.auto-heat-slider .rz-bubble\n  {\n\t\tbottom: -30px!important;\n\t}\n\t\n\t.heat-slider .rzslider.rz-vertical .rz-bubble,\n\t.cool-slider .rzslider.rz-vertical .rz-bubble,\n\t.auto-heat-slider .rzslider.rz-vertical .rz-bubble, \n\t.auto-cool-slider .rzslider.rz-vertical .rz-bubble \n  {\n\t\tleft: -20px!important;\n\t}\n\n\t.heat-slider .rz-bubble .rz-limit .rz-ceil,\n\t.cool-slider .rz-bubble .rz-limit .rz-ceil,\n\t.auto-heat-slider .rz-bubble .rz-limit .rz-ceil, \n\t.auto-cool-slider .rz-bubble .rz-limit .rz-ceil \n  {\n\t\tbottom: 0px!important;\n\t}\n\t\n\t.heat-slider .rz-pointer,\n\t.heat-slider .rz-pointer.rz-active:after, \n\t.heat-slider .rzslider .rz-bar.rz-selection, \n\t.auto-heat-slider .rz-pointer,\n\t.auto-heat-slider .rz-pointer.rz-active:after, \n\t.auto-heat-slider .rzslider .rz-bar.rz-selection \n  {\n\t\tbackground-color: #FFAA00;\n\t}\n  \n    /*colour lowest element which some parts will be covered */\n    .cool-slider .rz-pointer,\n    .auto-cool-slider .rz-pointer,\n    .auto-cool-slider .rz-bar \n    {\n        background:#0DB9F0;\n\t\t\t\tbackground-color: #0DB9F0;\n    }\n  \n    /*colour inactive bar*/\n\t\t.auto-cool-slider .rzslider .rz-bar.rz-selection\n    {\n        background:#b0b4ba;\n\t\t\t\tbackground-color: #b0b4ba;\n    }\n  \n    /* set the long bar for auto heat to transparent (highest z order) */\n    .auto-heat-slider .rz-bar\n    {\n        background:#transparent;\n    }\n\n  \n\t.ecobee-mainmenu-item \n  { \n\t\tfont-size: 1.2em;\n\t\ttext-align: left;\n\t\tpadding-left: 20px;\n\t}\n\t\n\t.ecobee-menu-item \n  {\n\t\tpadding-top: 5px;\n\t\tpadding-bottom: 5px;\n\t}\n\t\n\t.ecobee-menu-topic \n  {\n\t\tfont-size: 0.9em;\n\t\ttext-align: left;\n\t\tpadding-left: 40px;\n\t}\n\t\n  .ecobee-menu-info \n  {\n\t\tcolor: #b0b4ba;\n  \tfont-size: 0.9em;\n  }\n  \n\t.ecobee-menu-data \n  {\n\t\ttext-align: left;\n\t\tpadding-left: 40px;\n\t}\n  \n  .ecobee-occupied \n  {\n    color: var(--primary-color);\n  }\n</style>\n\n<!-- floor and ceil need to be rounded to same unit as step  -->\n<div id=\"ecobee\" ng-init='heatmodel={\"name\": \"heat\", \"item\": config.user_heat, \"vertical\" : \"false\", \"hidelabel\" : \"true\", \"hidelimits\": \"true\",\n                                    \"floor\" : ((itemValue(config.heat_floor) * 2)| number : 0) / 2 ,\n                                    \"ceil\":  ((itemValue(config.heat_ceil) * 2)| number : 0) / 2 ,\n                                    \"step\": (itemValue(config.use_celsius) == \"ON\") ? 0.5 : 1}; \n                          \n                         coolmodel={\"name\": \"cool\", \"item\": config.user_cool, \"vertical\" : \"false\", \"hidelabel\" : \"true\", \"hidelimits\": \"true\",\n                                    \"floor\" : ((itemValue(config.cool_floor) * 2)| number : 0) / 2 ,\n                                    \"ceil\": ((itemValue(config.cool_ceil) * 2)| number : 0) / 2 ,\n                                    \"step\": (itemValue(config.use_celsius) == \"ON\") ? 0.5 : 1};'>\n  \n<!--------------------------------------------------------------- Ecobee Main Panel --------------------------------------------------------------->\n  <div class=\"ecobee-content-panel\" ng-show=\"config.active_panel == 'ecobee-main'\">\n  \t<div class=\"ecobee-thermostat-name\"><h4>{{itemValue(config.thermostat_name)}}</h4></div>\n\t\t<div class=\"ecobee-current-mode\">\n\t\t\t<!-- <div class=\"col-md-12\"> -->\n\t\t\t\t<div>\n\t\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon ecobee-btn-hvac\" ng-click=\"config.active_panel='ecobee-hvacselect'\">\n\t\t\t\t\t\t<img class=\"ecobee-mode-icon\" src=\"/static/images/ecobee/{{itemValue(config.hvac_mode) | lowercase}}.png\" ng-if=\"itemValue(config.hvac_mode) != 'off'\"/>\n\t\t\t\t\t\t<div class=\"ecobee-mode-off\" ng-if=\"itemValue(config.hvac_mode) == 'off'\">OFF</div>\n\t\t\t\t\t</button>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<img class=\"ecobee-humidity-icon\" src=\"/static/images/ecobee/drop.png\"/> {{itemValue(config.humidity)}}%\n\t\t\t\t</div>\n\t\t\t\t<div class=\"ecobee-temperature-current\">\n\t\t\t\t\t<h2 ng-if=\"itemValue(config.use_celsius) == 'ON'\">\n\t\t\t\t\t\t{{'%.1f' | sprintf:itemValue(config.temperature)}}\n\t\t\t\t\t\t<sup ng-if=\"!config.hide_units\">°C</sup>\n\t\t\t\t\t</h2>\n\t\t\t\t\t<h2 ng-if=\"itemValue(config.use_celsius) == 'OFF'\">\n\t\t\t\t\t\t{{'%.0f' | sprintf:itemValue(config.temperature)}}\n\t\t\t\t\t\t<sup ng-if=\"!config.hide_units\">°F</sup>\n\t\t\t\t\t</h2>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"ecobee-sliders\" ng-show=\"itemValue(config.hvac_mode) == 'heat' || itemValue(config.hvac_mode) == 'Heating'\">\n\t\t\t\t\t<widget-slider class=\"heat-slider\" ng-model=\"heatmodel\" />\n\t\t\t\t</div>\n\t\t\t\t<div class=\"ecobee-sliders\" ng-show=\"itemValue(config.hvac_mode) == 'cool' || itemValue(config.hvac_mode) == 'Cooling'\">\n\t\t\t\t\t<widget-slider class=\"cool-slider\" ng-model=\"coolmodel\" />\n\t\t\t\t</div>\n\t\t\t<!-- </div> -->\n\t\t</div>\n\t\t<div class=\"ecobee-dialog\">\n\t\t\t<div style=\"padding-top: 10px; margin: auto;\">\n\t\t\t\t<div class=\"ecobee-resume-dialog\" ng-if=\"itemValue(config.running_event) == 'hold'\">\n\t\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon ecobee-dialog-close\" ng-click=\"sendCmd(config.schedule, 'resume')\">\n            <svg >\n              <circle cx=\"10\" cy=\"10\" r=\"10\" stroke=\"gray\" fill=\"white\"  shape-rendering=\"geometricPrecision\"/>\n              <line x1=\"5\" y1=\"5\" x2=\"15\" y2=\"15\" stroke=\"black\" stroke-width=\"2\" shape-rendering=\"geometricPrecision\"/>\n              <line x1=\"5\" y1=\"15\" x2=\"15\" y2=\"5\" stroke=\"black\" stroke-width=\"2\" shape-rendering=\"geometricPrecision\"/>\n            </svg>\n\t\t\t\t\t</button>\n\t\t\t\t\t<font ng-if=\"itemValue(config.hvac_mode) == 'cool' || itemValue(config.hvac_mode) == 'Cooling'\" color=\"#0DB9F0\">\n\t\t\t\t\t\t\t{{itemValue(config.use_celsius) == 'ON'? '%.1f':'%.0f' | sprintf:itemValue(config.desired_cool)}}°\n\t\t\t\t\t</font>\n\t\t\t\t\t<font ng-if=\"itemValue(config.hvac_mode) == 'heat' || itemValue(config.hvac_mode) == 'Heating'\" color=\"#FFAA00\">\n\t\t\t\t\t\t  {{itemValue(config.use_celsius) == 'ON'? '%.1f':'%.0f' | sprintf:itemValue(config.desired_heat)}}°\n\t\t\t\t\t</font>      \n\t\t\t\t</div>\n\t\t\t\t<div class=\"ecobee-resume-dialog\" ng-if=\"itemValue(config.running_event) == 'resume'\">\n\t\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon ecobee-dialog-close\" ng-click=\"sendCmd(config.schedule, 'resume')\">\n            <svg >\n              <circle cx=\"10\" cy=\"10\" r=\"10\" stroke=\"gray\" fill=\"white\"  shape-rendering=\"geometricPrecision\"/>\n              <line x1=\"5\" y1=\"5\" x2=\"15\" y2=\"15\" stroke=\"black\" stroke-width=\"2\" shape-rendering=\"geometricPrecision\"/>\n              <line x1=\"5\" y1=\"15\" x2=\"15\" y2=\"5\" stroke=\"black\" stroke-width=\"2\" shape-rendering=\"geometricPrecision\"/>\n            </svg>\n\t\t\t\t\t</button>\n\t\t\t\t\tResuming your schedule\n\t\t\t\t</div>\n        <div style=\"padding-top: 20px; padding-bottom: 20px;\" ng-if=\"config.sensors_onmain\">\n          <div class=\"ecobee-menu-item\" ng-repeat=\"item in itemsInGroup(config.remote_sensors) track by $index\" ng-if=\"$index % 2 == 0\">\n\t\t\t\t\t\t<div class=\"ecobee-menu-topic\">\n              {{item.label}} \n              <br/>\n             \t{{itemValue(config.use_celsius) == 'ON'? '%.1f °C':'%.0f °F' | sprintf:item.state}} <span class=\"{{itemsInGroup(config.remote_sensors)[$index+1].state == 'ON' ? 'ecobee-occupied' : ''}}\">({{itemsInGroup(config.remote_sensors)[$index+1].state == 'ON' ? 'Occupied' : 'Unoccupied'}})</span>\n            </div>\n\t\t\t\t\t</div>\n        </div>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"ecobee-footer\" ng-if=\"!config.sensors_onmain\">\n\t\t\t<h4>\n\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon\" ng-click=\"config.active_panel='ecobee-menu'\">\n\t\t\t\t\t<i class=\"glyphicon glyphicon-menu-hamburger\"></i>\n\t\t\t\t</button>\n\t\t\t</h4>\n\t\t</div>\n\t</div>\n<!--------------------------------------------------------------- Ecobee HVAC Select Panel --------------------------------------------------------------->\n\t<div class=\"ecobee-content-panel\" style=\"display: table;\" ng-show=\"config.active_panel == 'ecobee-hvacselect'\">\n\t\t<div style=\"display: table-cell; vertical-align: middle;\">\n\t\t\t<div>\n\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon ecobee-btn-hvac\" ng-click=\"config.active_panel='ecobee-main'\">          \n\t\t\t\t\t<img class=\"ecobee-mode-icon\" src=\"/static/images/ecobee/{{itemValue(config.hvac_mode) | lowercase}}.png\" ng-if=\"itemValue(config.hvac_mode) != 'off'\"/>\n\t\t\t\t\t<div class=\"ecobee-mode-off\" ng-if=\"itemValue(config.hvac_mode) == 'off'\">OFF</div>\n\t\t\t\t</button>\n\t\t\t</div>\n\t\t\t<div class=\"ecobee-hvac-btn-group\">\n        <button ng-class=\"(itemValue(config.hvac_mode) == 'off') ? 'ecobee-btn-selected' : 'ecobee-btn'\" ng-click=\"sendCmd(config.hvac_mode, 'off'); config.active_panel='ecobee-main'\">Off</button>\n\t\t\t\t<button ng-class=\"(itemValue(config.hvac_mode) == 'heat') ? 'ecobee-btn-selected' : 'ecobee-btn'\" ng-click=\"sendCmd(config.hvac_mode, 'heat'); config.active_panel='ecobee-main'\">Heat</button>\n\t\t\t\t<button ng-class=\"(itemValue(config.hvac_mode) == 'cool') ? 'ecobee-btn-selected' : 'ecobee-btn'\" ng-click=\"sendCmd(config.hvac_mode, 'cool'); config.active_panel='ecobee-main'\">Cool</button>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n<!--------------------------------------------------------------- Ecobee Menu Panel --------------------------------------------------------------->\n\t<div class=\"ecobee-content-panel\" ng-show=\"config.active_panel == 'ecobee-menu'\">\n    <div><h4>Main Menu</h4></div>\n\t\t<div style=\"flex: 1; flex-grow: 1;\">\n\t\t\t<div class=\"ecobee-mainmenu-item\">Sensors</div>\n\t\t\t<div class=\"ecobee-sensors\" ng-init=\"sensors=[{tempItem:getItem('MF_mainThermostat_temperature'),occ:itemState('MF_mainThermostat_occupancy')},\n                                                    {tempItem:getItem('MF_Remote_1_temperature'),occ:itemState('MF_Remote_1_occupancy')},\n                                                    {tempItem:getItem('MF_Remote_2_temperature'),occ:itemState('MF_Remote_2_occupancy')}]\">\n\t\t\t\t<div class=\"ecobee-menu-item\" ng-repeat=\"item in sensors| filter:{occ: '!N/A'}\">\n\t\t\t\t\t<div class=\"ecobee-menu-topic\">{{item.tempItem.label}}</div>\n\t\t\t\t\t<div class=\"ecobee-menu-data ecobee-menu-info\">\n            {{itemValue(config.use_celsius) == 'ON'? '%.1f °C':'%.0f °F' | sprintf:item.tempItem.state}} <span class=\"{{item.occ == 'ON' ? 'ecobee-occupied' : ''}}\">({{item.occ == 'ON' ? 'Occupied' : 'Unoccupied'}})</span></div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t\t<div class=\"ecobee-footer\">\n\t\t\t<h4>\n\t\t\t\t<button class=\"ecobee-btn ecobee-btn-icon\" ng-click=\"config.active_panel='ecobee-main'\">\n\t\t\t\t\t<i class=\"glyphicon glyphicon-menu-hamburger\"></i>\n\t\t\t\t</button>\n\t\t\t</h4>\n\t\t</div>\n\t</div>\n\n</div>"
}

That just sets up the interface to display like the ecobee interface.

I also noticed that when the rules are loaded I get the following errors:

Type cannot be derived
The method setHold(ThingActions, QuantityType<Object>, QuantityType<Object>, Number) from the type EcobeeActions refers to the missing type Object
The method setHold(ThingActions, QuantityType<Object>, QuantityType<Object>, String, Date, Date, String, Number) from the type EcobeeActions refers to the missing type Object

(Offtopic)
Good that’s working for you. I’m with you here and I tried that to get air through the High-MERV filters, but sadly it had no effect on my suffering :frowning:

The binding keeps “loosing” authorization and requires the pin to be entered again. The only way I know this happened is that my automation scripts stop firing. I then go look at the log and it is telling me “USER INTERACTION REQUIRED” and to enter a pin. Nothing happened that would seemingly cause this – no reboot, not power outage, not lose of internet, etc. Why does it keep loosing the pin or why does it keep requiring one to be entered? Is there a way to stop this from happening?

I’ve had this happen on 2 separate installations at about the same time. I don’t think that can be a coincidence. Others have reported the issue, as well. Right now I only can assume this is something Ecobee is doing on their end. t certainly wouldn’t be the first time this has happened. :wink:

1 Like

Finally upgraded to OH 3, and this binding still does not work to set the temperature.
I’m still getting Script execution of rule with UID 'ecobee-5' failed: temperature is not a QuantityType in ecobee

This is my rule:

rule CoolHold
when
 Item desiredCool received command
then
 logInfo("CoolHold", "Setting cool setpoint to " + receivedCommand.toString)
 val desiredCoolTemp = new QuantityType<Temperature>(receivedCommand.toString)
 var QuantityType<Temperature> desiredHeatTemp
 if (desiredHeat.state == UNDEF && hvacMode.state.toString == "cool") {
   desiredHeatTemp = desiredCoolTemp
 } else {
   desiredHeatTemp = new QuantityType<Temperature>(desiredHeat.state.toString)
 }
 logInfo("CoolHold", "receivedCommand: "+ receivedCommand.getClass().toString)
 logInfo("CoolHold", "desiredCoolTemp class: "+ desiredCoolTemp.getClass().toString)
 logInfo("CoolHold", "desiredHeatTemp class: "+ desiredHeatTemp.getClass().toString)
 val ecobeeActions = getActions("ecobee","ecobee:thermostat:fe065f15:316561513825")
 Thread::sleep(1000)
 ecobeeActions.setHold(desiredCoolTemp as QuantityType<Temperature>,desiredHeatTemp as QuantityType<Temperature>, null, null, null, 'nextTransition', null)
end

I may have posted this before, but this is my rule, working in OH3:

rule "Ecobee Set Temperature"
when
  Item ecobee_setpoint_heat received command or 
  Item ecobee_setpoint_cool received command
then
  val ecobeeActions = getActions("ecobee","ecobee:thermostat:xxxxx:yyyyyyyyyy")
  Thread::sleep(1000)
  ecobeeActions.setHold(ecobee_setpoint_cool.state as QuantityType<Number>, ecobee_setpoint_heat.state as QuantityType<Number>, null, null, null, "nextTransition", null)
end

where the triggering items are linked to the “runtime#desiredHeat” and “runtime#desiredCool” channels.
The “next transition” means that the set values get overridden when the ecobee changes them according to the schedule. You can change that, of course.

And yes, the 1-second-sleep is necessary, otherwise the set temperatures don’t “stick”.

That delay is necessary because your rule runs off of receiving a command, so the state isnt updated when the rule is triggered. You should be using receivedCommand.

If I use your exact rule, I get a casting error:
Script execution of rule with UID 'ecobee-5' failed: Could not cast 78.98 to org.openhab.core.library.types.QuantityType; line 62, column 25, length 39 in ecobee

Now I’m confused, I do use “received command”. Did you mean I should use “when item received update”?

receivedCommand is an implicit variable set by the rule:

Ah, ok, you mean to use the implicit variable instead of the item’s state for the Ecobee Action.

Not sure if that would be practical as the rule is triggered by either one of the items, and receivedCommand would only contain one of them. And I’m not sure how to differentiate between the two for the EcobeeAction.

But, admittedly, it works well the way it is.

To make things clear, here are my items:

Hope that helps.

Number:Temperature ecobee_setpoint_heat "Heat Setpoint [%.1f °F]"    <temperature>   { channel="ecobee:thermostat:xxx:yyy:runtime#desiredHeat" }
Number:Temperature ecobee_setpoint_cool "Cool Setpoint [%.1f °F]"    <temperature>   { channel="ecobee:thermostat:xxx:yyy:runtime#desiredCool" }

Yeah, you dont have much choice when you have them both trigger the same rule. The easy solution is to have separate rules, but there’s no sense in changing it if it works for you.

1 Like

I finally figured this out. The problem is that receivedCommand is dimensionless, so I had to explicitly create a QuantityType with a dimension:


val ecobeeActions = getActions("ecobee","ecobee:thermostat:xxxx:xxxxxxx")
val mode = EcobeeThermostatHome_HVACMode.state.toString
if (mode == "heat") {
  ecobeeActions.setHold(EcobeeThermostatHome_DesiredCool.state as QuantityType<Temperature>,new QuantityType<Temperature>(receivedCommand.toString+" °F"), null, null, null, 'nextTransition', null)
} else if (mode == "cool") {
  ecobeeActions.setHold(new QuantityType<Temperature>(receivedCommand.toString+" °F"),EcobeeThermostatHome_DesiredHeat.state as QuantityType<Temperature>, null, null, null, 'nextTransition', null)
}
1 Like

It’s been a while since the last post here, but I hope someone is still reading this.
Since ecobee only allows a schedule to be in half-hour increments and that doesn’t fit my needs anymore, I want to have OH send the schedule changes to the thermostat instead of programming a schedule in the thermostat it self.

Now sending holds for setpoints for heating/cooling is clear, does anyone know how to set the sensor that will be used to hold the temperature? I have two external sensors I use at different times during the day.

Is there an action for that? Maybe define “climates” within the thermostat and assign sensors to them, and then switch to that climate and override the setpoints?

Thanks!

Just in case someone is interested, I have it working now by issuing ecobeeActions with a ClimateRef like “home” and “sleep”, which I defined on the Ecobee dashboard to reflect the temperatures and sensors I want.

It is to note that one needs to use the ClimateRef ID’s. Those are nowhere to be found except for the standard ones “home”, “away” and “sleep”. Any custom ones do not use the name you give them, but go by “smart1”, “smart2”, etc.

I’m not sure if this is ecobee-related, but lately my actions fail rather strangely. Meaning that when I choose a switch as the trigger, the action works. When I choose cron, it does not. The error is:

[ERROR] [internal.handler.ScriptActionHandler] - Script execution of rule with UID 'ecobee-schedule-1' failed: null in ecobee-schedule

The rule is exactly like the example in the binding description:

val officeActions = getActions("ecobee","ecobee:thermostat:xxxxx:yyyyyyy") //Office

rule "Ecobee-Schedule-1 06:30 Weekday Office"
when 
        Time cron "0 30 06 ? * MON,TUE,WED,THU,FRI *"
then
                officeActions.setHold("home")
                }
end

Does anyone have an idea why that is? Needless to say, any other cron-based rules work flawlessly.

Thanks!