Issues creating Ecobee vacations with sensible setpoints

Hi all,
I am having issues successfully creating vacations within Ecobee javascript rules.
OH 4.2.1 on Windows 10.

I think I am having issues properly defining the QuantityType values for the heat and cool setpoints. Below is my Javascript rule:

var push = actions.thingActions("pushover", "pushover:pushover-account:8418ffd5d7");
try {
  // Import necessary Java classes
  var QuantityType = Java.type('org.openhab.core.library.types.QuantityType');
  var ZonedDateTime = Java.type('java.time.ZonedDateTime');
  var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
  var Date = Java.type('java.util.Date');
    
  var ecobeeActions = actions.thingActions("ecobee","ecobee:thermostat:beb50b877a:412870797948");
  //var coolTarg = 81|°F
  //var heatTarg = 55|°F
  var coolTarg = new QuantityType("82 °F");
  var heatTarg = new QuantityType("54 °F");
  var nowDT = ZonedDateTime.now();
  
  if(items.MQTT_HMI_VacationEnd_DateTime.state.toString() == "NULL") {
    push.sendMessage("Vacation end time is NULL, cannot begin Ecobee vacation period, you must do this manually.", "Liberty OpenHAB");
  } else {
    var dtEndVacationStr = items.MQTT_HMI_VacationEnd_DateTime.state.toString();
    // Define the format pattern that matches the incoming DateTime string
    var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
    var parsedEndVacDateTime = sdf.parse(dtEndVacationStr);
    console.log("Ecobee vacation test", "parsed end date: " + parsedEndVacDateTime)

    // Add 2 days to the current datetime
    //var nowDTplus2 = nowDT.plusHours(48);

    console.log("Setting Ecobee vacation with coolTarg: " + coolTarg + " and heatTarg: " + heatTarg);
    result = ecobeeActions.createVacation("OH-Vacation", coolTarg, heatTarg, nowDT, parsedEndVacDateTime, 'auto', 0);
    if(result == false) {
      console.log("Ecobee vacation test", "Ecobee vacation creation failed")
      push.sendMessage("Ecobee vacation creation FAILED, please investigate.", "Liberty OpenHAB");
    } else if(result == true) {
      console.log("Ecobee vacation test", "Ecobee vacation creation SUCCEEDED")
      push.sendMessage("Ecobee vacation created successfully, ending " + dtEndVacationStr, "Liberty OpenHAB");
    }
  }
  
} catch(err) {
  console.error("Something bad happened in Ecobee vacation creation: " + err.message); 
}

This runs successfully, a vacation is created in the Ecobee account, but I always get cool and heat setpoints showing up improperly in the Ecobee app, sometimes as 8 degF and 6 degF, respectively, and sometimes as 65 degF and 45 degF.

The console.log comment directly above the vacation creation line prints out:

2024-09-09 17:05:52.348 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Setting Ecobee vacation with coolTarg: 82 and heatTarg: 55

Am I defining the QuantityType values improperly?
When the vacation name says it needs to be ‘unique’ in the docs, what does that actually mean? Do I need to define and save a truly unique UUID? or does it just need to be unique compared to any other currently-existing Ecobee vacations?

Thanks for any help.

Is this Nashorn or JS Scripting?

Your rule looks like Nashorn which really you probably shouldn’t be using any more. It’s a very old version of JS, the code you have to write is excessively long and the JS Scripting code comes with a helper library that makes the code much easier to readr, write and maintain.

I don’t see anything obviously problematic except I don’t see why coolTarg and heatTarg are not showing the units in the logs. I haven’t used Nashorn JS in quite some time and you are having to deal with differences between JS and Java and the weirdness that comes from that.

But you are also using console.log and I can’t remember if that existed in Nashorn or not so :man_shrugging:

I JS Scripting the rule would/should look like this:

var push = actions.thingActions("pushover", "pushover:pushover-account:8418ffd5d7");
try {
  // It is not necessary to import *any* Java classes
  var ecobeeActions = actions.thingActions("ecobee","ecobee:thermostat:beb50b877a:412870797948");
  var coolTarg = Quantity('82 °F');
  var heatTarg = Quantity('54 °F');
  var nowDT = time.toZDT();

  if(items.MQTT_HMI_VacationEnd_DateTime.isUninitialized) {
    push.sendMessage("Vacation end time is NULL, cannot begin Ecobee vacation period, you must do this manually.", "Liberty OpenHAB");
  }
  else {
    var dtEndVacationStr = items.MQTT_HMI_VacationEnd_DateTime.state; // .state is already a String
    // The date format already looks like an ISO8601 string so no need for the parser.
    var parsedEndVacDateTime = time.toZDT(dtEndVacationStr);
    console.log("Ecobee vacation test", "parsed end date: " + parsedEndVacDateTime);

    // Add 2 days to the current datetime
    //var nowDTplus2 = time.toZDT('P2D'); // ISO8601 Duration String

    console.log("Setting Ecobee vacation with coolTarg: " + coolTarg + " and heatTarg: " + heatTarg);
    var result = ecobeeActions.createVacation("OH-Vacation", coolTarg, heatTarg, nowDT, parsedEndVacDateTime, 'auto', 0); // this variable was never declared in your original code

    if(result == false) {
      console.log("Ecobee vacation test", "Ecobee vacation creation failed")
      push.sendMessage("Ecobee vacation creation FAILED, please investigate.", "Liberty OpenHAB");
    } else if(result == true) {
      console.log("Ecobee vacation test", "Ecobee vacation creation SUCCEEDED")
      push.sendMessage("Ecobee vacation created successfully, ending " + dtEndVacationStr, "Liberty OpenHAB");
    }        
  }
 
} catch(err) {
  console.error("Something bad happened in Ecobee vacation creation: " + err.message); 
}

Notice all the Java stuff is gone, it’s all pure JS. I’ve removed a lot of unnecessary converstions as well and used time.toZDT() which is your swiss army knife for manipulating date times.

Thanks @rlkoshak , this is helpful.

Unfortunately, even after these improvements, I still wasn’t successful in getting the proper heat/cool setpoints to appear in the Ecobee app. The values continued to show up in Ecobee as 65 cool / 45 heat. I did use a different vacation name string, with no improvement.

I see the following in the log, though, which seems to indicate the QuantityTypes are working:

2024-09-10 00:48:25.226 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Ecobee vacation test parsed end date: 2024-09-11T17:00-04:00[SYSTEM]
2024-09-10 00:48:25.227 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Setting Ecobee vacation with coolTarg: 84 °F and heatTarg: 54 °F
2024-09-10 00:48:25.335 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Ecobee vacation test Ecobee vacation creation SUCCEEDED

I did try hardcoding the values into the createVacation call, with no better results. I tried Celsius values, too, with no improvement.

var result = ecobeeActions.createVacation("abcdefg", Quantity('84 °F'), Quantity('54 °F'), startDate, endDate, 'auto', 0);    // was coolTarg, heatTarg

I tried to see if I could get a RulesDSL version of this method to work as expected, but then I banged my head against a wall with date/time formats for too long…

Any additional suggestions?

At this point I’m not sure that the problem is the rule at all. This looks like an ecobee binding problem.

What happens if you send just a plain number instead?

Just substituting numbers instead of Quantities like this:

var result = ecobeeActions.createVacation("abcdefg", 84, 54, startDate, endDate, 'auto', 0);    // coolTarg, heatTarg

yields this error:

2024-09-11 09:35:39.267 [ERROR] [nhab.automation.script.ui.d779c6e43b] - Something bad happened in Ecobee vacation creation: invokeMember (createVacation) on org.openhab.binding.ecobee.internal.action.EcobeeActions@1b9d09df failed due to: Cannot convert '84'(language: Java, type: java.lang.Integer) to Java type 'org.openhab.core.library.types.QuantityType': Unsupported target type.

So it really does want QuantityTypes.

Should I create an issue here with the relevant context?

I don’t know if this is supported but try coolTarg.rawQtyType. Quantity is a JS wrapper around the Java QuantityType and based on the code we should be able to get the Java Object that way.

The add-on is supposed to convert between the JS Objects and the Java Objects in cases like this (this is why you can use a JS number in places that expect a Java number or a time.ZonedDateTime in places that expect a java.time.ZonedDateTime, but it might not work correctly with a Thing action and Quantity perhaps.

var result = ecobeeActions.createVacation("abcdefg", coolTarg.rawQtyType, heatTarg.rawQtyType, startDate, endDate, 'auto', 0);

If that doesn’t work, definitely create an issue on the echobee binding. Something is up.

No joy, unfortunately. I ran this:

console.log("Setting Ecobee vacation with coolTarg: " + coolTarg.rawQtyType + " and heatTarg: " + heatTarg.rawQtyType);
var result = ecobeeActions.createVacation("abcdefghi", coolTarg.rawQtyType, heatTarg.rawQtyType, startDate, endDate, 'auto', 0);

which generated these logs:

2024-09-11 10:22:27.922 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Ecobee vacation test parsed end date: 2024-09-12T16:00-04:00[SYSTEM]
2024-09-11 10:22:27.923 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Setting Ecobee vacation with coolTarg: 84 and heatTarg: 54
2024-09-11 10:22:28.047 [INFO ] [nhab.automation.script.ui.d779c6e43b] - Ecobee vacation test Ecobee vacation creation SUCCEEDED

but the vacation created in Ecobee still has incorrect and fixed heat/cool setpoints.

(for anyone confused about the post date vs. the log date, I did the testing way back in September but forgot to press GO on the post until I just came back to this.)

I’ll get an issue created.

For anyone who comes across this, the issue here was that Ecobee’s API expects setpoints to be submitted in units of “0.1 degF”, meaning the values need to be multiplied by 10, but the Ecobee binding was not performing this x10 multiplication. Thanks to @mhilbush for tracking this down. See this Github issue for more details.

Mark has implemented a fix that will be in Openhab 5.0+ and possibly a patch release, but in the meantime you can just multiply your heat/cool setpoints in vacation creation rules by 10 and you should get vacation events being created as expected.