I want to do some normal validation of the UI (normal for people other than Fibaro which doesn't seem to understand the finer things of the user interface concepts). My immediate desire is to take two values from the UI and pass them both to the API where they will be processed. The device is a thermostat and is using the com.fibaro.hvacSystemAuto device type. This presents the user a heating setpoint and a cooling setpoint when the thermostat is in Auto mode. But when the "Set" button is pressed, it sends the heat setpoint as an action, then it sends the cool setpoint. But the API expects both setpoints when the device is in Auto. Further, it burps if the heat setpoint is hotter than the cool setpoint. Even worse, the device control is in the cloud so the round trip is quite slow. It appears that the heat setpoint property I retrieve using fibaro.getValue(self.id, "heatingThermostatSetpoint") doesn't appear to be the value which was just sent (and passed to the cloud) during the heat setpoint onAction() method [remember, BOTH values are sent to the API on each call]. My original idea was to adjust the current setpoints so that the cooling setpoint was 2° higher than the heating setpoint when that setpoint is about to be set if they are not already in a valid state. Then, during the cooling setpoint adjustment, I would change the heating setpoint to be 2° cooler than the cooling setpoint if they are not already in a valid state.
Of course an even better solution would be to be able to peek at the other setpoint in the UI and send it. And ideally, I would like to be able to keep the state of the two setpoints in a valid state at all times. The app used by the thermostat adjusts the heating down if the cooling setpoint is adjusted down too much or it adjusts the cooling up if the heating setpoint is adjusted up too much. So it would be good practice to do something similar in the Fibaro UI. 🙄 But that's not likely to happen anytime in my lifetime or my children's lifetimes either.
The code I'm using is:
elseif (self.properties.thermostatMode == "Auto")
then
self:debug('Original coolingThermostatSetpoint ' .. self.properties.coolingThermostatSetpoint)
-- The coolingThermostatSetpoint must be greater than the heatingThermostatSetpoint.
-- Since both the heating and cooling setpoints are updated individually but the
-- API must be adjusted for both values at the same time, there are problems when
-- the heating setpoint is hotter than the cooling setpoint. Solution (for now) is to
-- adjust the coolingThermostatSetpoint to be 2° higher than the new heatingThermostatSetpoint.
-- **Note: If the user has not set these two setpoints correctly, the actual heating and cooling
-- setpoints will reflect a 2° difference from whichever setpoint has been called last.
local coolValue = fibaro.getValue(self.id, 'coolingThermostatSetpoint')
self:debug(string.format("getValue() returned %f", coolValue))
if coolValue <= roundedHeatValue then
coolValue = roundedHeatValue + 2
end
My first pass used the self.properties.coolingThermostatSetpoint value. Then I tried the call to fibaro.getValue() but that didn't seem to help either.
The code to set the cooling setpoint is a duplicate of the above except the heating setpoint is adjust downward by 2 vs. the cooling setpoint being adjusted upward.
So what am I doing wrong?
Thanks in advance to any ideas or solutions.
Peter
PS: After working on this some more I FINALLY recognized this is a symptom of the async nature of web communication. Both setpoints are called back to back (duh). But the first call gets all the way to sending the API command out and then yields while that happens asynchronously. Then the other setpoint is changed and does the same thing. EXCEPT, the original heating setpoint has not been updated in the hub because that process is not executed until the success of the API call. I know how basic this is to people but I'm something of a dinosaur and cannot get it through my pea-sized, dinosaur brain that things have to happen asynchronously because of the latency of internet communications. Ok....now I'm back on board with all of this and I must find some elegant solution to resolve this.
Forgive me for showing my ignorance but I learned a valuable lesson (again, but maybe it will stick this time).