Anyone ever looked into DITRA-HEAT (Floor warming) WiFi Thermostat?

Our contractor is installing one (https://www.schluter.ca/schluter-ca/en_CA/ditra-heat-wifi) as part of our bathroom reno and I was wondering if anyone’s looked at it from a OpenHAB perspective?

A search didn’t bring anything up, and it’s not installed yet, so I’ve no hands-on information to share.

1 Like

Hi I was wondering if this ever gained any traction. I have this installed in my house and would like to be able to control it with openhab. I’d be relying on someone else as I dont have the skills to write the binding.

Thanks
jared

I have this in my house as well, got it up and working a few days ago. Would be nice to be integrate with openhab.

Ping. I’ve got one of these in my new home, and I’m just getting started with OpenHAB. I can’t promise anything since i have about a billion other priorities, but maybe in a few months I’ll try to decipher their API. Their web version is pretty basic, so hopefully it’s not too difficult.

1 Like

I’m in the same boat. No time to look in to this. If you do put something together, I’m happy to help test though.

I’m looking into this a bit. So far, I’ve found out that it’s actually provided by OJ Electronics. They have their own branded thermostat, an OJ Microline UWG4 too. AFAICT, there is no local access - you have to go through their cloud API. For Ditra devices, this is located at https://ditra-heat-e-wifi.schluter.com/. For OJ, it’s at https://mythermostat.info/. Interestingly, both domains are hosted by the same server (point to the same IP address), and the Ditra iOS app also uses https://mythermostat.info/. They do have separate user databases though, and you specify which one when making the authentication call:

POST /api/authenticate/user

Takes a JSON object POST body with fields for Email, Password, and Application. Application is 0 for OJ’s web version, 7 for Ditra’s web version, or 8 for Ditra’s iOS App (my same password works across iOS and web, but not OJ’s web. I didn’t bother installing the OJ app and capturing its traffic. presumably it sends 1. Presumably there are other brands that are the same hardware and cloud service, too).

Response is a JSON object, with fields SessionId, NewAccount, ErrorCode, RoleType, Email, and Language. SessionId is probably all we’re interested in. It’s some sort of session identifier. I’m still trying to determine the longevity of this ID, but it’s definitely not cookie based session. This token is all you need to make further requests.

GET /api/useraccount?sessionid=

Response is a JSON object with fields (strings unless otherwise indicated) City, Country, DistributerId (integer; mine is 0), Email, FirstName, Inactive (boolean), Language, LastName, MondayFirstDayOfWeek (boolean), Password (null, thankfully), RoleType (integer, matches the auth response), SafetyAnswer, SafetyQuestion, StateProvince (empty string for me), StreetName (empty string for me), TempUnitIsCelsius (boolean), Use12Hour (boolean), ZipCode (empty string for me)

GET /api/thermostats?sessionid=

Response is a JSON Object with a single field, Groups. Groups is an array of JSON objects with AwayMode (boolean), GroupId (integer), GroupName, and Thermostats. Thermostats is an array of JSON objects. Each object is the same as an individual thermostat call; see below

GET /api/unassigned_thermostats?sessionid=

Response is a JSON object with a single field, Thermostats, which is an array. Presumably of the same Thermostat object as /thermostats and /thermostat return. Mine is empty.

GET /api/thermostat?sessionid=&serialnumber=<serialnumber; get it from the thermostats call>

Response is a JSON object. I’ll just paste mine in slightly redacted for simplicity.

{
  "SerialNumber": "<redacted>",
  "Room": "master tile",
  "GroupName": "",
  "GroupId": -1,
  "Temperature": 2474, # looks to be Celsius multiplied by 100, even when user account is set to Fahrenheit
  "SetPointTemp": 2444,
  "RegulationMode": 1, # 1 is on schedule, 2 is "for a few hours", 3 is "permanently", 4 is "for a few days"
  "VacationEnabled": false,
  "VacationBeginDay": "31/05/2019 00:00:00",
  "VacationEndDay": "08/06/2019 00:00:00",
  "VacationTemperature": 878,
  "ComfortTemperature": 2388,
  "ComfortEndTime": "08/06/2019 02:15:00 +00:00",
  "ManualTemperature": 2166,
  "LastPrimaryModeIsAuto": true,
  "Online": true,
  "Heating": false,
  "EarlyStartOfHeating": false,
  "MaxTemp": 4000,
  "MinTemp": 500,
  "ErrorCode": 0,
  "Confirmed": true,
  "Email": "<redacted>",
  "TZOffset": "-06:00",
  "Assigned": true,
  "KwhCharge": 0.11,
  "LoadMeasuringActive": true,
  "LoadManuallySetWatt": 100,
  "LoadMeasuredWatt": 892,
  "SWVersion": "1012P108",
  "HasBeenAssigned": true,
  "DistributerId": 10207,
  "Schedules": []
  "Support": "Customer Service\r\nUSA: 1-800-472-4588\r\nCanada: 1-800-667-8746\r\ninfo@schluter.com\r\n"
}

Schedules is an array of 7 JSON objects, with fields WeekDayGrpNo (one based), and Events, another array of 6 JSON objects that look like:

 {
      "ScheduleType": 0,
      "Clock": "07:00:00",
      "TempFloor": 2555,
      "Active": true
  }

GET /api/newthermostat?sessionid=

Presumably a long-poll to get notified if a thermostat is added. The only thing I ever see is:

{
  "SequenceNr": 0,
  "Action": 0,
  "Thermostat": null
}

GET /api/notification?sessionid=&sequencenr=0

A long-poll to get notified of changes from another API user or the thermostat itself. A basic response looks the same as /newthermostat. Other responses return a full thermostat object with an Action of 2, and a SequenceNr that seems to be otherwise discarded.

POST /api/thermostat?sessionid=&serialnumber=

Request body is a JSON thermostat object that contains only the keys you want to change. Response is: { "Success": true }. In particular, “Return to Schedule” button sends RegulationMode: 1, VacationEnabled: false. Manually adjusting “for a few hours” sends ComfortTemperature, ComfortEndTime, RegulationMode: 2, and VacationEnabled: false. Manually adjusting “for a few days” sends RegulationMode: 4, VacationBeginDay: “07/06/2019 00:00:00”, VacationEnabled: true, VacationEndDay: <same above, but a different day>, VacationTemperature. Manually adjusting “permanently” sends ManualTemperature, RegulationMode: 3, and VacationEnabled: false. I haven’t bothered messing with anything else like schedules, but presumably it matches the thermostat response, and you just send what you want to change.

Welp, apparently sessions don’t last too long. An hour, maybe less? I’m now getting a 401.

More endpoints, though:

GET /api/discontinuedthermostats

An object with key Thermostats, and value is an array (empty for me).

GET /api/energyusage?sessionid=&serialnumber=&view=week&date=2019-06-02&history=0&calc=yes&weekstart=sunday

view=day gives 24 entries, view=week gives 7 entries, view=year gives 12 entries. history is always 0. for year, the date is simply the year.

Response:

{
  "MondayIsFirstDay": false,
  "EnergyUsage": [
    {
      "Usage": [
        {
          "Minutes": 0,
          "EnergyKWattHour": 0,
          "ChargeKWattHour": 0
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 5.0152777777777775,
          "ChargeKWattHour": 0.5516805555555555
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 4.276222222222223,
          "ChargeKWattHour": 0.4703844444444445
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 0,
          "ChargeKWattHour": 0
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 0,
          "ChargeKWattHour": 0
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 0,
          "ChargeKWattHour": 0
        },
        {
          "Minutes": 0,
          "EnergyKWattHour": 0,
          "ChargeKWattHour": 0
        }
      ]
    }
  ]
}

Hey @ccutrer,

sorry for warming up such an old thread :slight_smile:

I am currently trying to reach the DITRA API. I have a (orange) DITRA-device, no blue OJ Electronics. However, i only got a username/password after registering my device in the Android app.
On both links https://ditra-heat-e-wifi.schluter.com/ and https://mythermostat.info/ my login-data do not work. On my smartphone they do.

Do you have any idea what could help to get that working?

Kind regards in advance
Matthew

Hi,

The App looks like the OJ Electronics App. I will have a look which API the DITRA App is calling.

By the way: Please do not confuse the app and the website. These are completely different things with different APIs

2 Likes

@Matthew
I own a square Schluter DITRA WIFI thermostat.
This version does have also a username/password combination.

Do you have that one also?

Yes, to be precise: Schlüter®-DITRA-HEAT-E-R-WIFI
Looks like:
image

I got that up and running with adjusted settings for ojelectonics binding and Help of @Christian_Kittel. We want to adjust the binding to better work with DITRA devices out of the box. In the meantime see our GitHub issue for configuration options: [ojelectronics] Provide comfortable choice between various types of Cloud-Version to use · Issue #9547 · openhab/openhab-addons · GitHub

2 Likes

Oh hey, cool, a built in binding! Except where do I find the API key? I can log in just fine with the iOS app or at https://ditra-heat-e-wifi.schluter.com with the same credentials. It seems like it’s been forever since I captured that traffic in 2019. It looks like the website uses OpenID Connect now, but other than that the API looks like it hasn’t changed.