mkmer / AIOSomecomfort

AsyicIO client for US models of Honeywell Thermostats
GNU General Public License v3.0
6 stars 2 forks source link

Honeywell Humidity Control #8

Open xinde1989 opened 1 week ago

xinde1989 commented 1 week ago

Please add humidity control as Total Comfort allows this on the app and on the website.

Control Logs from webpage: Humidifier Request (This POST file popped up after I submitted the request to change humidity) Request: {"Mode":1,"LowerLimit":10,"UpperLimit":60,"Setpoint":45,"DeadBand":null,"DeviceId":xxxxx,"IndoorHumidity":48,"IndoorHumidityAvailable":true,"IndoorHumidityValue":"48%","SetpointValue":"45%"} Response: Nothing

POST /portal/Device/Menu/Humidifier HTTP/2 Host: mytotalconnectcomfort.com

Humidifier Confirmation ( This POST file popped up a few seconds after I hit the submit button, confirming the humidity change) Request: Nothing Response: {"DeviceId":xxx,"UpperLimit":60,"LowerLimit":10,"Deadband":null,"Mode":1,"Setpoint":45,"IndoorHumidityAvailable":false,"IndoorHumidity":0}

POST /portal/Device/Menu/Humidifier HTTP/2 Host: mytotalconnectcomfort.com

Off/Auto Log: Off: Request: {"Mode":0,"LowerLimit":10,"UpperLimit":60,"Setpoint":50,"DeadBand":null,"DeviceId":xxxx,"IndoorHumidity":49,"IndoorHumidityAvailable":true,"IndoorHumidityValue":"49%","SetpointValue":"50%"}

Response: {"DeviceId":xxxx,"UpperLimit":60,"LowerLimit":10,"Deadband":null,"Mode":0,"Setpoint":50,"IndoorHumidityAvailable":false,"IndoorHumidity":0}

Auto: Request: {"Mode":1,"LowerLimit":10,"UpperLimit":60,"Setpoint":50,"DeadBand":null,"DeviceId":xxxx,"IndoorHumidity":49,"IndoorHumidityAvailable":true,"IndoorHumidityValue":"49%","SetpointValue":"50%"}

Response: {"DeviceId":xxxxxx,"UpperLimit":60,"LowerLimit":10,"Deadband":null,"Mode":1,"Setpoint":50,"IndoorHumidityAvailable":false,"IndoorHumidity":0}

xinde1989 commented 1 week ago

The GET message generated right after I submitted the change doesn't have any request or response data.

It looks like the POST message with the "indoorhumidityavailable: false" message get posted every 10-15 seconds or so automatically. It might just be how the website is setup to refresh the information automatically?

mkmer commented 1 week ago

Maybe there is more data included in the "standard" message with the info we need. On the thermostat control page, there are GET messages every 10 seconds. The response has a latestData json structure. The non humidifier version looks like this:

{
    "success": true,
    "deviceLive": true,
    "communicationLost": false,
    "latestData": {
        "uiData": {
            "DispTemperature": 68,
            "HeatSetpoint": 68,
            "CoolSetpoint": 76,
            "DisplayUnits": "F",
            "StatusHeat": 0,
            "StatusCool": 0,
            "HoldUntilCapable": true,
            "ScheduleCapable": true,
            "VacationHold": 0,
            "DualSetpointStatus": false,
            "HeatNextPeriod": 56,
            "CoolNextPeriod": 56,
            "HeatLowerSetptLimit": 40,
            "HeatUpperSetptLimit": 76,
            "CoolLowerSetptLimit": 74,
            "CoolUpperSetptLimit": 99,
            "ScheduleHeatSp": 68,
            "ScheduleCoolSp": 76,
            "SwitchAutoAllowed": false,
            "SwitchCoolAllowed": true,
            "SwitchOffAllowed": true,
            "SwitchHeatAllowed": true,
            "SwitchEmergencyHeatAllowed": false,
            "SystemSwitchPosition": 1,
            "Deadband": 0,
            "IndoorHumidity": 43,
            "DeviceID": 1234567,
            "Commercial": false,
            "DispTemperatureAvailable": true,
            "IndoorHumiditySensorAvailable": true,
            "IndoorHumiditySensorNotFault": true,
            "VacationHoldUntilTime": 0,
            "TemporaryHoldUntilTime": 0,
            "IsInVacationHoldMode": false,
            "VacationHoldCancelable": true,
            "SetpointChangeAllowed": true,
            "OutdoorTemperature": 128,
            "OutdoorHumidity": 128,
            "OutdoorHumidityAvailable": false,
            "OutdoorTemperatureAvailable": false,
            "DispTemperatureStatus": 0,
            "IndoorHumidStatus": 0,
            "OutdoorTempStatus": 128,
            "OutdoorHumidStatus": 128,
            "OutdoorTemperatureSensorNotFault": true,
            "OutdoorHumiditySensorNotFault": true,
            "CurrentSetpointStatus": 0,
            "EquipmentOutputStatus": 0
        },
        "fanData": {
            "fanMode": 0,
            "fanModeAutoAllowed": true,
            "fanModeOnAllowed": true,
            "fanModeCirculateAllowed": true,
            "fanModeFollowScheduleAllowed": false,
            "fanIsRunning": false
        },
        "hasFan": true,
        "canControlHumidification": false,
        "drData": {
            "CoolSetpLimit": null,
            "HeatSetpLimit": null,
            "Phase": -1,
            "OptOutable": false,
            "DeltaCoolSP": null,
            "DeltaHeatSP": null,
            "Load": null
        }
    },
    "alerts": "\r\n\r\n"
}

Please share yours

xinde1989 commented 1 week ago

Maybe there is more data included in the "standard" message with the info we need. On the thermostat control page, there are GET messages every 10 seconds. The response has a latestData json structure. The non humidifier version looks like this:

{
  "success": true,
  "deviceLive": true,
  "communicationLost": false,
  "latestData": {
      "uiData": {
          "DispTemperature": 68,
          "HeatSetpoint": 68,
          "CoolSetpoint": 76,
          "DisplayUnits": "F",
          "StatusHeat": 0,
          "StatusCool": 0,
          "HoldUntilCapable": true,
          "ScheduleCapable": true,
          "VacationHold": 0,
          "DualSetpointStatus": false,
          "HeatNextPeriod": 56,
          "CoolNextPeriod": 56,
          "HeatLowerSetptLimit": 40,
          "HeatUpperSetptLimit": 76,
          "CoolLowerSetptLimit": 74,
          "CoolUpperSetptLimit": 99,
          "ScheduleHeatSp": 68,
          "ScheduleCoolSp": 76,
          "SwitchAutoAllowed": false,
          "SwitchCoolAllowed": true,
          "SwitchOffAllowed": true,
          "SwitchHeatAllowed": true,
          "SwitchEmergencyHeatAllowed": false,
          "SystemSwitchPosition": 1,
          "Deadband": 0,
          "IndoorHumidity": 43,
          "DeviceID": 1234567,
          "Commercial": false,
          "DispTemperatureAvailable": true,
          "IndoorHumiditySensorAvailable": true,
          "IndoorHumiditySensorNotFault": true,
          "VacationHoldUntilTime": 0,
          "TemporaryHoldUntilTime": 0,
          "IsInVacationHoldMode": false,
          "VacationHoldCancelable": true,
          "SetpointChangeAllowed": true,
          "OutdoorTemperature": 128,
          "OutdoorHumidity": 128,
          "OutdoorHumidityAvailable": false,
          "OutdoorTemperatureAvailable": false,
          "DispTemperatureStatus": 0,
          "IndoorHumidStatus": 0,
          "OutdoorTempStatus": 128,
          "OutdoorHumidStatus": 128,
          "OutdoorTemperatureSensorNotFault": true,
          "OutdoorHumiditySensorNotFault": true,
          "CurrentSetpointStatus": 0,
          "EquipmentOutputStatus": 0
      },
      "fanData": {
          "fanMode": 0,
          "fanModeAutoAllowed": true,
          "fanModeOnAllowed": true,
          "fanModeCirculateAllowed": true,
          "fanModeFollowScheduleAllowed": false,
          "fanIsRunning": false
      },
      "hasFan": true,
      "canControlHumidification": false,
      "drData": {
          "CoolSetpLimit": null,
          "HeatSetpLimit": null,
          "Phase": -1,
          "OptOutable": false,
          "DeltaCoolSP": null,
          "DeltaHeatSP": null,
          "Load": null
      }
  },
  "alerts": "\r\n\r\n"
}

Please share yours

{ "success": true, "deviceLive": true, "communicationLost": false, "latestData": { "uiData": { "DispTemperature": 70, "HeatSetpoint": 70, "CoolSetpoint": 74, "DisplayUnits": "F", "StatusHeat": 0, "StatusCool": 0, "HoldUntilCapable": true, "ScheduleCapable": true, "VacationHold": 0, "DualSetpointStatus": false, "HeatNextPeriod": 58, "CoolNextPeriod": 58, "HeatLowerSetptLimit": 40, "HeatUpperSetptLimit": 78, "CoolLowerSetptLimit": 65, "CoolUpperSetptLimit": 99, "ScheduleHeatSp": 70, "ScheduleCoolSp": 74, "SwitchAutoAllowed": true, "SwitchCoolAllowed": true, "SwitchOffAllowed": true, "SwitchHeatAllowed": true, "SwitchEmergencyHeatAllowed": true, "SystemSwitchPosition": 0, "Deadband": 3, "IndoorHumidity": 47, "DeviceID": xxxxxx, "Commercial": false, "DispTemperatureAvailable": true, "IndoorHumiditySensorAvailable": true, "IndoorHumiditySensorNotFault": true, "VacationHoldUntilTime": 0, "TemporaryHoldUntilTime": 0, "IsInVacationHoldMode": false, "VacationHoldCancelable": true, "SetpointChangeAllowed": true, "OutdoorTemperature": 42, "OutdoorHumidity": 95, "OutdoorHumidityAvailable": true, "OutdoorTemperatureAvailable": true, "DispTemperatureStatus": 0, "IndoorHumidStatus": 0, "OutdoorTempStatus": 0, "OutdoorHumidStatus": 0, "OutdoorTemperatureSensorNotFault": true, "OutdoorHumiditySensorNotFault": true, "CurrentSetpointStatus": 0, "EquipmentOutputStatus": 0 }, "fanData": { "fanMode": 0, "fanModeAutoAllowed": true, "fanModeOnAllowed": true, "fanModeCirculateAllowed": true, "fanModeFollowScheduleAllowed": false, "fanIsRunning": false }, "hasFan": true, "canControlHumidification": false, "drData": { "CoolSetpLimit": null, "HeatSetpLimit": null, "Phase": -1, "OptOutable": false, "DeltaCoolSP": null, "DeltaHeatSP": null, "Load": null } }, "alerts": "\r\n\r\n" }

mkmer commented 1 week ago

Hmmm... I don't see any new fields in there.
I'm a bit at a loss how the app "knows" to show the humidifier page. It appears some of the fields in the POST message on the humidifier page is receiving the upper/lower and setpoint values, but the other fields are junk.
In order to add the HA humidifier, we will need to detect that it's available, but I'm not seeing a way to determine that.

xinde1989 commented 6 days ago

Hmmm... I don't see any new fields in there. I'm a bit at a loss how the app "knows" to show the humidifier page. It appears some of the fields in the POST message on the humidifier page is receiving the upper/lower and setpoint values, but the other fields are junk. In order to add the HA humidifier, we will need to detect that it's available, but I'm not seeing a way to determine that.

If needed, I can grant you access to my thermostat so you can take a look?

mkmer commented 6 days ago

I may have found it - > when you click on the menu button, the first POST has some data. Mine looks like this:

AlertSettings   Object { DeviceID: 1234569, DisplayUnits: 1, Name: "ASTRO", … }
DisplaySchedule Object { DeviceID: 1234567, IsCommercial: false, HasFan: false, … }
Humidifier  null
Dehumidifier    null
DeviceID    1234567
Name    "ASTRO"
LocationID  0
LocationName    null
ShowScheduleTab false
ShowHumidificationTab   false
ShowDehumidificationTab false
ScheduleCapable false
ReturnTo    "ControlScreen1234567"
Tab 0
IsOwner false
DisplayUnits    1
IsReallyGateway:false

Hoping your's has ShowHumidificationTab, maybe something more...

xinde1989 commented 6 days ago

I may have found it - > when you click on the menu button, the first POST has some data. Mine looks like this:

AlertSettings Object { DeviceID: 4048977, DisplayUnits: 1, Name: "ASTRO", … }
DisplaySchedule   Object { DeviceID: 4048977, IsCommercial: false, HasFan: false, … }
Humidifier    null
Dehumidifier  null
DeviceID  4048977
Name  "ASTRO"
LocationID    0
LocationName  null
ShowScheduleTab   false
ShowHumidificationTab false
ShowDehumidificationTab   false
ScheduleCapable   false
ReturnTo  "ControlScreen4048977"
Tab   0
IsOwner   false
DisplayUnits  1
IsReallyGateway:false

Hoping your's has ShowHumidificationTab, maybe something more...

{ "AlertSettings": { "DeviceID": xxxxx, "DisplayUnits": 1, "Name": "DINING ROOM", "ApplySettingsToAllZones": false, "TempHigherThanActive": true, "TempHigherThan": 78, "TempHigherThanMinutes": 60, "TempLowerThanActive": true, "TempLowerThan": 62, "TempLowerThanMinutes": 60, "HumidityHigherThanActive": true, "HumidityHigherThan": 80, "HumidityHigherThanMinutes": 60, "HumidityLowerThanActive": true, "HumidityLowerThan": 20, "HumidityLowerThanMinutes": 60, "FaultConditionExistsActive": false, "FaultConditionExistsHours": 1, "NormalConditionsActive": false, "ThermostatAlertActive": true, "CommunicationFailureActive": true, "CommunicationFailureMinutes": 15, "CommunicationLostActive": true, "CommunicationLostHours": 1, "DeviceLostActive": true, "DeviceLostHours": 1 }, "DisplaySchedule": { "Schedule": { "DisplayUnits": 1, "SchedulePeriods": [ { "PeriodID": "0_0", "Day": 0, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "0_1", "Day": 0, "PeriodType": 1, "StartTime": { "Hours": 14, "Minutes": 30, "Seconds": 0, "Milliseconds": 0, "Ticks": 522000000000, "Days": 0, "TotalDays": 0.6041666666666666, "TotalHours": 14.5, "TotalMilliseconds": 52200000, "TotalMinutes": 870, "TotalSeconds": 52200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "0_2", "Day": 0, "PeriodType": 2, "StartTime": { "Hours": 17, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 612000000000, "Days": 0, "TotalDays": 0.7083333333333333, "TotalHours": 17, "TotalMilliseconds": 61200000, "TotalMinutes": 1020, "TotalSeconds": 61200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "0_3", "Day": 0, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "1_0", "Day": 1, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "1_1", "Day": 1, "PeriodType": 1, "StartTime": { "Hours": 14, "Minutes": 30, "Seconds": 0, "Milliseconds": 0, "Ticks": 522000000000, "Days": 0, "TotalDays": 0.6041666666666666, "TotalHours": 14.5, "TotalMilliseconds": 52200000, "TotalMinutes": 870, "TotalSeconds": 52200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "1_2", "Day": 1, "PeriodType": 2, "StartTime": { "Hours": 17, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 612000000000, "Days": 0, "TotalDays": 0.7083333333333333, "TotalHours": 17, "TotalMilliseconds": 61200000, "TotalMinutes": 1020, "TotalSeconds": 61200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "1_3", "Day": 1, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "2_0", "Day": 2, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "2_1", "Day": 2, "PeriodType": 1, "StartTime": { "Hours": 14, "Minutes": 30, "Seconds": 0, "Milliseconds": 0, "Ticks": 522000000000, "Days": 0, "TotalDays": 0.6041666666666666, "TotalHours": 14.5, "TotalMilliseconds": 52200000, "TotalMinutes": 870, "TotalSeconds": 52200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "2_2", "Day": 2, "PeriodType": 2, "StartTime": { "Hours": 17, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 612000000000, "Days": 0, "TotalDays": 0.7083333333333333, "TotalHours": 17, "TotalMilliseconds": 61200000, "TotalMinutes": 1020, "TotalSeconds": 61200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "2_3", "Day": 2, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "3_0", "Day": 3, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "3_1", "Day": 3, "PeriodType": 1, "StartTime": { "Hours": 14, "Minutes": 30, "Seconds": 0, "Milliseconds": 0, "Ticks": 522000000000, "Days": 0, "TotalDays": 0.6041666666666666, "TotalHours": 14.5, "TotalMilliseconds": 52200000, "TotalMinutes": 870, "TotalSeconds": 52200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "3_2", "Day": 3, "PeriodType": 2, "StartTime": { "Hours": 17, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 612000000000, "Days": 0, "TotalDays": 0.7083333333333333, "TotalHours": 17, "TotalMilliseconds": 61200000, "TotalMinutes": 1020, "TotalSeconds": 61200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "3_3", "Day": 3, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "4_0", "Day": 4, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "4_1", "Day": 4, "PeriodType": 1, "StartTime": { "Hours": 14, "Minutes": 30, "Seconds": 0, "Milliseconds": 0, "Ticks": 522000000000, "Days": 0, "TotalDays": 0.6041666666666666, "TotalHours": 14.5, "TotalMilliseconds": 52200000, "TotalMinutes": 870, "TotalSeconds": 52200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "4_2", "Day": 4, "PeriodType": 2, "StartTime": { "Hours": 17, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 612000000000, "Days": 0, "TotalDays": 0.7083333333333333, "TotalHours": 17, "TotalMilliseconds": 61200000, "TotalMinutes": 1020, "TotalSeconds": 61200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "4_3", "Day": 4, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "5_0", "Day": 5, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "5_1", "Day": 5, "PeriodType": 1, "StartTime": { "Hours": 12, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 432000000000, "Days": 0, "TotalDays": 0.5, "TotalHours": 12, "TotalMilliseconds": 43200000, "TotalMinutes": 720, "TotalSeconds": 43200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "5_2", "Day": 5, "PeriodType": 2, "StartTime": { "Hours": 16, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 576000000000, "Days": 0, "TotalDays": 0.6666666666666666, "TotalHours": 16, "TotalMilliseconds": 57600000, "TotalMinutes": 960, "TotalSeconds": 57600 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "5_3", "Day": 5, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "6_0", "Day": 6, "PeriodType": 0, "StartTime": { "Hours": 5, "Minutes": 15, "Seconds": 0, "Milliseconds": 0, "Ticks": 189000000000, "Days": 0, "TotalDays": 0.21875, "TotalHours": 5.25, "TotalMilliseconds": 18900000, "TotalMinutes": 315, "TotalSeconds": 18900 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "6_1", "Day": 6, "PeriodType": 1, "StartTime": { "Hours": 12, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 432000000000, "Days": 0, "TotalDays": 0.5, "TotalHours": 12, "TotalMilliseconds": 43200000, "TotalMinutes": 720, "TotalSeconds": 43200 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "6_2", "Day": 6, "PeriodType": 2, "StartTime": { "Hours": 16, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 576000000000, "Days": 0, "TotalDays": 0.6666666666666666, "TotalHours": 16, "TotalMilliseconds": 57600000, "TotalMinutes": 960, "TotalSeconds": 57600 }, "IsCancelled": false, "HeatSetpoint": 70, "CoolSetpoint": 74, "FanMode": 0 }, { "PeriodID": "6_3", "Day": 6, "PeriodType": 3, "StartTime": { "Hours": 20, "Minutes": 0, "Seconds": 0, "Milliseconds": 0, "Ticks": 720000000000, "Days": 0, "TotalDays": 0.8333333333333333, "TotalHours": 20, "TotalMilliseconds": 72000000, "TotalMinutes": 1200, "TotalSeconds": 72000 }, "IsCancelled": false, "HeatSetpoint": 68, "CoolSetpoint": 74, "FanMode": 0 } ], "MaxNumberOfPeriodsInDay": 4, "ModifiedDays": [] }, "DeviceID": xxxx, "IsCommercial": false, "HasFan": false, "DisplayUnits": 1, "PeriodHeaders": [ { "Label": "Wake", "ImageName": "schedule_icon_1_wake.png", "CssClass": "wake", "Period": 0 }, { "Label": "Leave", "ImageName": "schedule_icon_2_leave.png", "CssClass": "leave", "Period": 1 }, { "Label": "Return", "ImageName": "schedule_icon_3_return.png", "CssClass": "return", "Period": 2 }, { "Label": "Sleep", "ImageName": "schedule_icon_4_sleep.png", "CssClass": "sleep", "Period": 3 } ] }, "Humidifier": { "DeviceId": xxxx, "UpperLimit": 60, "LowerLimit": 10, "Deadband": null, "Mode": 1, "Setpoint": 45, "IndoorHumidityAvailable": true, "IndoorHumidity": 47 }, "Dehumidifier": { "DeviceId": xxxx, "UpperLimit": 80, "LowerLimit": 40, "Deadband": null, "Mode": 1, "Setpoint": 55, "IndoorHumidityAvailable": true, "IndoorHumidity": 47 }, "DeviceID": xxxx, "Name": "DINING ROOM", "LocationID": 0, "LocationName": null, "ShowScheduleTab": false, "ShowHumidificationTab": false, "ShowDehumidificationTab": false, "ScheduleCapable": false, "ReturnTo": "ControlScreenxxxxxxxx", "Tab": 0, "IsOwner": false, "DisplayUnits": 1, "IsReallyGateway": false }

mkmer commented 6 days ago

There it is! Dehumidifier and Humidifier. Does your system do both? Automatically? How does it know when to switch over? Is it simply cooling mode enabled = dehumidify and heating mode = humidify?

xinde1989 commented 6 days ago

I have an EIM so I can hook up both humidifier and dehumidifier to the system. In the Menu, I have a tab for humidifier and another tab for dehumidifier. I set the system to run humidifier on heat only so it's not gonna run in cooling mode. These options are only available on the thermostat itself. You can't change these settings online. The only thing you can set online is turning it off/auto, and change the humidity setting.

Bunky101 commented 6 days ago

Not sure exactly what you are looking for but there is a function called ReloadedHumData(force), see below. It appears to be loading the page values when it loads the tab.

// updating tabs on change of active tab var UpdateTabs = function () { if (tabHeaders == null) { tabHeaders = $("ul.ui-tabs-nav li.ui-corner-top"); }

var tabHeadersLength = $(tabHeaders).length;

$(tabHeaders).each(function (index) {
    if ($(this).hasClass("ui-tabs-active")) {
        if (index > 0) {
            $(this).prev().removeClass("leftSelected").addClass("rightSelected");
        }

        if (index < tabHeadersLength - 1) {
            $(this).next().removeClass("rightSelected").addClass("leftSelected");
        } else {
            $(this).next().addClass("lastSelected");
        }
    } else {
        var nextMargin = $(this).next().removeClass("leftSelected rightSelected lastSelected");
        if (index == tabHeadersLength - 1) {
            $(nextMargin).addClass("last");
        }
    }
});

};

// refreshing functions var RefreshAlerts = function() { $.ajax({ url: alertUrl, cache: false, dataType: "html", success: function (data) { var response = null; try { response = $.parseJSON(data); if (response != null && typeof response == 'object' && response.hasOwnProperty('Redirect')) { window.location.replace(response.Redirect); } } catch (e) { } $("#AlertsPlaceHolder").html(data); }, complete: function() { setTimeout(function() {RefreshAlerts();}, 10000); } }); };

var RegisterModalDialogs = function () { var closingElementIds = new Array(3); closingElementIds[1] = "submitBtn"; closingElementIds[2] = "cancelBtn";

for (var i = 0; i < settings.PeriodHeaders().Days().length; i++) {
    var day = settings.PeriodHeaders().Days()[i].Day;
    var name = settings.PeriodHeaders().Days()[i].Name;
    for (var j = 0; j < settings.PeriodHeaders().Headers().length; j++) {
        var period = settings.PeriodHeaders().Headers()[j].Period();
        var label = settings.PeriodHeaders().Headers()[j].Label();
        var imageName = settings.PeriodHeaders().Headers()[j].ImageName();

        ModalAjaxContentDialog({
            openingElementId: day + '_' + period,
            closingElementIds: closingElementIds,
            url: editSchedulePeriodUrl + '?period=' + day + '_' + period,
            loadingText: loading,
            headerHtml: '<img src="' + imageName.replace('.png', '_lg.png') + '" alt="' + label + '" title="' + label + '"/>' +
                name + ' - ' + label,
            dialogCssClass: "editScheduledPeriod",
            position: "center top",
            onAjaxSubmitSuccess: function () {
                ReloadScheduleData();
            },
            onClose: function () {
                ReloadScheduleData();
            }
        });
    }
}

};

var ReloadScheduleData = function() { $.ajax({ url: scheduleUrl, type: 'POST', cache: false, dataType: "json", success: function (data) { if (data.Schedule == undefined || data.Schedule.SchedulePeriods == undefined || data.Schedule.SchedulePeriods.length == 0) { settings.PeriodHeaders(new PeriodHeadersModel(data.PeriodHeaders)); settings.Schedule(new ScheduleModel(data.Schedule)); } else { settings.Schedule(new ScheduleModel(data.Schedule)); settings.PeriodHeaders(new PeriodHeadersModel(data.PeriodHeaders)); } RegisterModalDialogs(); }, error: function(jqXHR, textStatus, errorThrown) { if (jqXHR.status == 500) { //if scheduling function has been disabled on thermostat, hide schedule tab if (jqXHR.responseText.indexOf("Schedule has been disabled on device.") > -1) { $('#tabs').tabs({ active: 0, });

                if (tabHeaders == null) {
                    tabHeaders = $("ul.ui-tabs-nav li.ui-corner-top");
                }

                var tabHeadersLength = $(tabHeaders).length;

                $(tabHeaders).each(function(index) {
                    if ($(this).is("#scheduleTab")) {
                        if (tabHeadersLength == 2) {
                            $(this).prev().hide();
                            $(this).hide();
                        } else {
                            $(this).next().hide();
                            $(this).hide();
                        }
                    }
                });

                UpdateTabs();

                window.clearTimeout(reloadScheduleTimeout);
            }
        }
    },
    complete: function() {
        window.clearTimeout(reloadScheduleTimeout);
        reloadScheduleTimeout = window.setTimeout("ReloadScheduleData();", 10000);
    }
});

};

var ReloadHumData = function (force) { if (force || !settings.HumChanged()) { $.ajax({ url: humUrl, type: 'POST', cache: false, dataType: "json", success: function(data) { //save data about humidity (saves us calling device with thermostat data) var indoorHumidity = settings.Hum().IndoorHumidity(); var indoorHumidityAvailable = settings.Hum().IndoorHumidityAvailable();

            settings.Hum(new HumModel(data));
            settings.HumChanged(false);

            $("#HumSlider").slider("value", settings.Hum().Setpoint());

            settings.Hum().IndoorHumidity(indoorHumidity);
            settings.Hum().IndoorHumidityAvailable(indoorHumidityAvailable);
        },
    });
}
if (!force) {
    window.clearTimeout(reloadHumTimeout);
    reloadHumTimeout = window.setTimeout("ReloadHumData();", 10000);
}

};

var ReloadDehumData = function (force) { if (force || !settings.DehumChanged()) { $.ajax({ url: dehumUrl, type: 'POST', cache: false, dataType: "json", success: function(data) { var indoorHumidity = settings.Dehum().IndoorHumidity(); var indoorHumidityAvailable = settings.Dehum().IndoorHumidityAvailable();

            settings.Dehum(new DehumModel(data));
            settings.DehumChanged(false);

            $("#DehumSlider").slider("value", settings.Dehum().Setpoint());

            settings.Dehum().IndoorHumidity(indoorHumidity);
            settings.Dehum().IndoorHumidityAvailable(indoorHumidityAvailable);
        },
    });
}
if (!force) {
    window.clearTimeout(reloadDehumTimeout);
    reloadDehumTimeout = window.setTimeout("ReloadDehumData();", 10000);
}

};

var ReloadAlertSettingsData = function() { $.ajax({ url: alertSettingsUrl, type: 'POST', cache: false, dataType: "json", success: function (data) { var units = settings.AlertSettings().DisplayUnits();

        settings.AlertSettings(new AlertSettingsModel(data));
        settings.AlertSettingsChanged(false);

        settings.AlertSettings().DisplayUnits(units);
    }
});

};

//submitting functions var SubmitSchedule = function (){ if (!settings.ScheduleChanged()) { return; }

$.ajax({
    url: submitScheduleUrl,
    type: 'POST',
    cache: false,
    dataType: "json",
    complete: function () {
        settings.Schedule().ModifiedDays.removeAll();
    }
});

};

var CancelSchedule = function () { if (!settings.ScheduleChanged()) { return; }

$.ajax({
    url: cancelScheduleUrl,
    type: 'POST',
    cache: false,
    dataType: "json",
    complete: function() {
        ReloadScheduleData();
    }
});

};

var SubmitHumDehum = function (){ if (settings.HumChanged()) { var humData = ko.toJSON(settings.Hum()); $.ajax({ url: submitHumUrl, type: 'POST', cache: false, dataType: "json", contentType: 'application/json; charset=utf-8', data: humData, complete: function () { settings.HumChanged(false); } }); }

if (settings.DehumChanged()) {
    var dehumData = ko.toJSON(settings.Dehum());
    $.ajax({
        url: submitDehumUrl,
        type: 'POST',
        cache: false,
        dataType: "json",
        contentType: 'application/json; charset=utf-8',
        data: dehumData,
        complete: function (data) {
            settings.DehumChanged(false);
        }
    });
}

};

var SubmitAlertSettings = function (){ if (!settings.AlertSettingsChanged()) { return; }

if (!$('#Device_UserDefinedDeviceName').valid()) {
    return;
}

var alertSettingsData = ko.toJSON(settings.AlertSettings());
$.ajax({
    url: submitAlertSettingsUrl,
    type: 'POST',
    cache: false,
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: alertSettingsData,
    complete: function () {
        settings.AlertSettingsChanged(false);
        if (settings.OldName != settings.AlertSettings().Name()) {
            location.reload();
        }
    }
});

};

mkmer commented 6 days ago

@Bunky101 Thanks for digging into this.
I was looking for the JSON keys utilized to "figure out" when the tabs are shown. I think we have those with the humidifier and dehumidifier keys - if the keys exist, enable the platform. I will need to poll this when the HA integration starts to decide on enabling the humidifier platform and populate the values (upper/lower limits, setpoint, etc). Once I have it enabled in HA, we can use the POST commands to set the values and use the response to update internal values. I don't think we want to poll this data (as it rarely changes), so I'm struggling a bit with how to update it in HA - we don't really have a "I've just tried to access the platform, lets update" like the page has on load. If the values change on the T-stat, and we don't poll it, HA will show the wrong set point.

Here is what I think needs to happen (at this moment in time):

},
"Humidifier": {
"DeviceId": xxxx,
"UpperLimit": 60,
"LowerLimit": 10,
"Deadband": null,
"Mode": 1,
"Setpoint": 45,
"IndoorHumidityAvailable": true,
"IndoorHumidity": 47
},

Humidifier key exists (aka not NULL), enable platform. Upper/lower limit = upper/lower limits as set in t-stat Mode = 0/1 (1 is auto, 0 is off) Setpoint = current value, change it in the post JSON to change it on the t-stat. IndoorHumidity = should be the same as the T-stat key

I may need 2 platforms - one for humidifier and one for dehumidifier? Need to research a bit more.

Bunky101 commented 5 days ago

Thanks for looking into this as I think it will be of use to the community.

It has been years since I programmed anything, the last time was in Java and C, so I’m not up on the latest trends. As I am not familiar JSON nor the Honeywell API I cannot say if the get for all the data (indoor, outdoor, temps, humidity, etc.) can be done with one get or not. I see there is an API on Honeywell’s site, I had to google for it, and I haven’t tried it out but I had assumed you built the integration using it but it probably will answer most or all of these questions. Here is the URL if you are interested in it, https://devportal.prod.honeywell.com/. I’d be happy to help but I’m afraid I’d probably waste your time with too many questions to be of much use, LOL, but feel free to ask.

My planned use case right now is to have an automation that checks my outside temperature to determine what the inside humidity settings should be and then update if there is a difference. I really like the ability to change these settings via the thermostat as well. My thought is that the polling should be the same as the rest of the thermostat integration as a setting that is not current will lead to issues when comparing the values, i.e. my wife changes the setting on the thermostat like she does for temperature.

As I said it is great you are able and willing to work on these integrations so thanks again on behalf of everyone who uses it.

Dave

.

From: mkmer @.*** Sent: November 28, 2024 5:21 AM To: mkmer/AIOSomecomfort Cc: Bunky101; Mention Subject: Re: [mkmer/AIOSomecomfort] Honeywell Humidity Control (Issue #8)

@Bunky101 https://github.com/Bunky101 Thanks for digging into this. I was looking for the JSON keys utilized to "figure out" when the tabs are shown. I think we have those with the humidifier and dehumidifier keys - if the keys exist, enable the platform. I will need to poll this when the HA integration starts to decide on enabling the humidifier platform and populate the values (upper/lower limits, setpoint, etc). Once I have it enabled in HA, we can use the POST commands to set the values and use the response to update internal values. I don't think we want to poll this data (as it rarely changes), so I'm struggling a bit with how to update it in HA - we don't really have a "I've just tried to access the platform, lets update" like the page has on load. If the values change on the T-stat, and we don't poll it, HA will show the wrong set point.

Here is what I think needs to happen (at this moment in time):

}, "Humidifier": { "DeviceId": xxxx, "UpperLimit": 60, "LowerLimit": 10, "Deadband": null, "Mode": 1, "Setpoint": 45, "IndoorHumidityAvailable": true, "IndoorHumidity": 47 },

Humidifier key exists (aka not NULL), enable platform. Upper/lower limit = upper/lower limits as set in t-stat Mode = 0/1 (1 is auto, 0 is off) Setpoint = current value, change it in the post JSON to change it on the t-stat. IndoorHumidity = should be the same as the T-stat key

I may need 2 platforms - one for humidifier and one for dehumidifier? Need to research a bit more.

— Reply to this email directly, view it on GitHub https://github.com/mkmer/AIOSomecomfort/issues/8#issuecomment-2505990932 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ASNCN3VRQD6KCKFQHJ2ZJXD2C4DBBAVCNFSM6AAAAABSTGXRSOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMBVHE4TAOJTGI . You are receiving this because you were mentioned. https://github.com/notifications/beacon/ASNCN3UUSVHTLBOLRXDWEC32C4DBBA5CNFSM6AAAAABSTGXRSOWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTUVLZRRI.gif Message ID: @.***>

Bunky101 commented 5 days ago

Sorry the URL should have been https://developer.honeywellhome.com/.

Dave

From: David R. Miller @.*** Sent: November 28, 2024 2:33 PM To: 'mkmer/AIOSomecomfort'; 'mkmer/AIOSomecomfort' Subject: RE: [mkmer/AIOSomecomfort] Honeywell Humidity Control (Issue #8)

Thanks for looking into this as I think it will be of use to the community.

It has been years since I programmed anything, the last time was in Java and C, so I’m not up on the latest trends. As I am not familiar JSON nor the Honeywell API I cannot say if the get for all the data (indoor, outdoor, temps, humidity, etc.) can be done with one get or not. I see there is an API on Honeywell’s site, I had to google for it, and I haven’t tried it out but I had assumed you built the integration using it but it probably will answer most or all of these questions. Here is the URL if you are interested in it, https://devportal.prod.honeywell.com/. I’d be happy to help but I’m afraid I’d probably waste your time with too many questions to be of much use, LOL, but feel free to ask.

My planned use case right now is to have an automation that checks my outside temperature to determine what the inside humidity settings should be and then update if there is a difference. I really like the ability to change these settings via the thermostat as well. My thought is that the polling should be the same as the rest of the thermostat integration as a setting that is not current will lead to issues when comparing the values, i.e. my wife changes the setting on the thermostat like she does for temperature.

As I said it is great you are able and willing to work on these integrations so thanks again on behalf of everyone who uses it.

Dave

.

From: mkmer @.*** Sent: November 28, 2024 5:21 AM To: mkmer/AIOSomecomfort Cc: Bunky101; Mention Subject: Re: [mkmer/AIOSomecomfort] Honeywell Humidity Control (Issue #8)

@Bunky101 https://github.com/Bunky101 Thanks for digging into this. I was looking for the JSON keys utilized to "figure out" when the tabs are shown. I think we have those with the humidifier and dehumidifier keys - if the keys exist, enable the platform. I will need to poll this when the HA integration starts to decide on enabling the humidifier platform and populate the values (upper/lower limits, setpoint, etc). Once I have it enabled in HA, we can use the POST commands to set the values and use the response to update internal values. I don't think we want to poll this data (as it rarely changes), so I'm struggling a bit with how to update it in HA - we don't really have a "I've just tried to access the platform, lets update" like the page has on load. If the values change on the T-stat, and we don't poll it, HA will show the wrong set point.

Here is what I think needs to happen (at this moment in time):

}, "Humidifier": { "DeviceId": xxxx, "UpperLimit": 60, "LowerLimit": 10, "Deadband": null, "Mode": 1, "Setpoint": 45, "IndoorHumidityAvailable": true, "IndoorHumidity": 47 },

Humidifier key exists (aka not NULL), enable platform. Upper/lower limit = upper/lower limits as set in t-stat Mode = 0/1 (1 is auto, 0 is off) Setpoint = current value, change it in the post JSON to change it on the t-stat. IndoorHumidity = should be the same as the T-stat key

I may need 2 platforms - one for humidifier and one for dehumidifier? Need to research a bit more.

— Reply to this email directly, view it on GitHub https://github.com/mkmer/AIOSomecomfort/issues/8#issuecomment-2505990932 , or unsubscribe https://github.com/notifications/unsubscribe-auth/ASNCN3VRQD6KCKFQHJ2ZJXD2C4DBBAVCNFSM6AAAAABSTGXRSOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDKMBVHE4TAOJTGI . You are receiving this because you were mentioned. https://github.com/notifications/beacon/ASNCN3UUSVHTLBOLRXDWEC32C4DBBA5CNFSM6AAAAABSTGXRSOWGG33NNVSW45C7OR4XAZNMJFZXG5LFINXW23LFNZ2KUY3PNVWWK3TUL5UWJTUVLZRRI.gif Message ID: @.***>

mkmer commented 5 days ago

@Bunky101 Unfortunate, the API is for the Lyric thermostats... I wish we could use it. @xinde1989 If you are willing to allow me , m_kasper@sbcglobal.net. I may change your humidity up and down 1 click for some testing. There are just too many questions popping up as I start to code :(

xinde1989 commented 5 days ago

@Bunky101 Unfortunate, the API is for the Lyric thermostats... I wish we could use it. @xinde1989 If you are willing to allow me , m_kasper@sbcglobal.net. I may change your humidity up and down 1 click for some testing. There are just too many questions popping up as I start to code :(

Done. You should have access to my thermostat. Please take your time.

Bunky101 commented 5 days ago

I obviously didn't remove a key I guess, sure but please don't mess with the temp as it is cold here in Canada and I'd hate to have the furnace accidentally get shut off, lol.On Nov. 29, 2024 7:32 a.m., mkmer @.> wrote: @Bunky101 Unfortunate, the API is for the Lyric thermostats... I wish we could use it. @xinde1989 If you are willing to allow me , @. I may change your humidity up and down 1 click for some testing. There are just too many questions popping up as I start to code :(

—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you were mentioned.Message ID: @.***>