PatchworkBoy / homebridge-edomoticz

Domoticz Homebridge-Plugin
Other
118 stars 43 forks source link

C vs F For Temperature #106

Closed GreenTentacle closed 6 years ago

GreenTentacle commented 7 years ago

If I have Domoticz' Setup>Settings>Meters/Counters>Temperature Display set to Celsius, then HomeKit translates correctly to Fahrenheit for me, and shows it in the home app correctly.

However, if I set the setting in Domoticz to Fahrenheit, HomeKit shows the value as if it was translated from Celsius.

Is there a way to have eDomoticz accept F or C as the incoming unit type from Domoticz, and then convert to C when it sends it to homekit/homebridge (because it seems to expect C) ?

Ideally, I'd like to be able to view F temperatures in Domoticz' web interface, but have it send C temperatures in MQTT, JSON, etc. But I haven't found a way to do that.

Thanks !

GreenTentacle commented 7 years ago

So it looks like when the display units are set to Celsius in Domoticz settings, the JSON from /json.htm?type=devices&rid=<IDX of my temp sensor> comes through as Celsius, and similarly comes through as Fahrenheit if the display units are set to Fahrenheit. Maybe domoticz should do that better, perhaps a TempUnits element in the JSON or something, but....

There's the "Result/Data" element in the JSON which could probably tell us if the data we're getting is F or C. "Data" : "72.1 F, 91 %", is an example I just got. I think the regex [0-9]+.[0-9]+\s\b([FC])\b,\s[0-9]+.[0-9]?+\s\% would isolate the C or F.

I'm a bit scared to try to work this into the code and do a PR, but I figured it might be easier for someone more handy ? The regex only works for something returning both temp and humidity, so I guess it'd have to be more generalized for other types of temperature-reading devices.

I know, us in the states need to get with the rest of the world and switch to Celsius :(

GreenTentacle commented 7 years ago

So the answer from gizmocuz is to query /json.htm?type=command&param=getconfig for TempSign. I still think it would be useful for domoticz to send the unit with the actual reading JSON, but I don't think that's going to be changed. I don't think I'm competent enough as a developer to add this check and global var to edomoticz, but I'll take a look through the code later.

GreenTentacle commented 7 years ago

Here's my latest idea. There's an element in the settings json domoticz sends called tempunit, which is 0 for C and 1 F (I've found experimentally)

I think eDomoticz's domoticz.js grabs an object called settings with these values.

So if I'm thinking right, a way to do it would be in the getTemperature and getTemperatureAlternative functions in domoticz_accessory.js.

Something like (pseudocode) if domoticz.settings.tempunit=1 (value=helper.convertFtoC(value))

Assuming I added a quick function to helper.js called convertFtoC... something like

function convertFtoC(fahrenheit) 
{
  var fTemp = fahrenheit;
  var fToCel = (fTemp - 32) * 5 / 9;
  return fToCel
} 

Solid reasoning ?

PatchworkBoy commented 6 years ago

Sorry - just read over your code... yes, that should work.

Your pseudocode is correct. Shorthand if ... else is in the format (condition) ? true-outcome : false-outcome; in the below, with nesting (to assist you with understanding what I’ve done).

Shorthand check for a variable being true is just the variable itself... so:

(this.platform.config.farenheight === true) becomes (this.platform.config.farenheight)

And in JS, 1 === true === !0 === !false

With all that in mind, add:

"farenheight":1

...to your config.json, then change line 449 of edomoticz_accessory.js to:

value = ((heat) || (therm)) ? Helper.oneDP(Helper.cleanFloat(s.SetPoint)) : ((this.platform.config.farenheight) ? Helper.oneDP(Helper.cleanFloat(Helper.convertFtoC(s.Temp))) : Helper.oneDP(Helper.cleanFloat(s.Temp)));

and line 462 to:

value = this.platform.config.farenheight ? Helper.oneDP(Helper.cleanFloat(Helper.convertFtoC(s.Temp))) : Helper.oneDP(Helper.cleanFloat(s.Temp));

The above are both single lines of code for reference (they may copy and paste with linebreaks).

And in helper.js...

function convertFtoC(fahrenheit) 
{
  return ((fahrenheit - 32) * 5 / 9);
} 

(I just refactored your code down a bit)

The knock on effects of this on items such as Thermostat SetPoint devices however is unknown... ie: what unit will those commands be sent in, and what would domoticz be expecting... (and in my case a further translation for the scripts that drive my physical thermostat currently attached to Domoticz). There may be further places that would need translations, but the above should get you started.

Without investigating in much greater depth questions such as the above I can’t add it into the main repo yet.