From c1cb2eea721191e173c100065c5bc54b94b7d510 Mon Sep 17 00:00:00 2001 From: gurglespuge Date: Sun, 15 Jul 2018 16:15:23 -0700 Subject: [PATCH 1/4] Update GreeDevice.java Fixed bugs in first commit, when you requested an out of limit temp, it defaulted to the wrong limit and setter was ignoring validation screen --- .../internal/discovery/GreeDevice.java | 136 +++++++++++++++++- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java b/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java index c5c7de7..1951b77 100644 --- a/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java +++ b/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java @@ -49,6 +49,8 @@ public class GreeDevice { private final static Charset UTF8_CHARSET = Charset.forName("UTF-8"); + private final static HashMap> tempRanges = createTempRangeMap(); + private final static String [] tempScaleLUT = {"C","F"}; //used to convert TempUn integer to "C" to "F" string for hashmap private Boolean mIsBound = false; private InetAddress mAddress; private int mPort = 0; @@ -269,16 +271,108 @@ public Integer GetDeviceLight() { return GetIntStatusVal("Lig"); } + private static HashMap> createTempRangeMap() + { //Create Hash Look Up for C and F Temperature Ranges for gree A/C units + //f_range = {86,61}, c_range= {16,30} + HashMap> tempRanges = new HashMap<>(); + HashMap hmf = new HashMap<>(); + HashMap hmc= new HashMap<>(); + + hmf.put("min",new Integer(61)); // F + hmf.put("max",new Integer(86)); + tempRanges.put("F",hmf); + + hmc.put("min",new Integer(16)); //C + hmc.put("max",new Integer(30)); + tempRanges.put("C",hmc); + + return tempRanges; + } + + private Integer[] ValidateTemperatureRangeForTempSet(Integer newVal,Integer CorF) { + // Checks input ranges for validity and TempUn for validity + // Uses newVal as priority and tries to validate and determine intent + // For example if value is 75 and TempUn says Celsius, change TempUn to Fahrenheit + // + final String[] minMaxLUT = {"max","min"}; // looks up 0 = C = max, 1 = F = min + HashMap nullCorFLUT = new HashMap<>(); // simple look up table for logic + nullCorFLUT.put("C",new Integer(0)); + nullCorFLUT.put("F",new Integer(1)); + nullCorFLUT.put("INVALID",new Integer(0)); + + String validRangeCorF; // stores if the input range is a valid C or F temperature + + newVal = Math.max(newVal,Math.min(tempRanges.get("C").get("min"),tempRanges.get("F").get("min"))); // force to global min + newVal = Math.min(newVal,Math.max(tempRanges.get("C").get("max"),tempRanges.get("F").get("max"))); // force to global max + + if ((newVal >= tempRanges.get("C").get("min") ) && ( newVal <= tempRanges.get("C").get("max")) ) { + validRangeCorF = "C"; + } else if ((newVal >= tempRanges.get("F").get("min") ) && ( newVal <= tempRanges.get("F").get("max"))) { + validRangeCorF = "F"; + }else{ + logger.warn("Input Temp request {} is invalid",newVal); + validRangeCorF = "INVALID"; + } + + if (CorF == null){ + // if CorF wasnt initialized or is null set it from lookup + CorF = nullCorFLUT.get(validRangeCorF); + } + + if ((CorF == 1) && (validRangeCorF == "C")){ + CorF = 0; // input temp takes priority + } + else if ((CorF == 0) && (validRangeCorF == "F")){ + CorF = 1; // input temp takes priority + } + else if (validRangeCorF == "INVALID"){ + // force min or max temp based on CorF scale to be used + newVal = tempRanges.get(tempScaleLUT[CorF]).get(minMaxLUT[CorF]); + } + + return new Integer[]{newVal,CorF}; + } public void SetDeviceTempSet(DatagramSocket clientSocket, Integer value) throws Exception { + // **value** : set temperature in degrees celsius or Fahrenheit // Only allow this to happen if this device has been bound if (getIsBound() != Boolean.TRUE) { return; } + Integer [] retList; + Integer newVal = new Integer(value); + Integer outVal = new Integer(value); + // Get Celsius or Fahrenheit from status message + Integer CorF = GetIntStatusVal("TemUn"); + // TODO put a param in openhab to allow setting this from the config + + //If commanding Fahrenheit set halfStep to 1 or 0 to tell the A/C which F integer + // temperature to use as celsius alone is ambigious + Integer halfStep = new Integer(0); //default to C + + retList = ValidateTemperatureRangeForTempSet(newVal,CorF); + newVal = retList[0]; + CorF = retList[1]; + + if (CorF == 1){ //If Fahrenheit, + //value argument is degrees F, convert Fahrenheit to Celsius, + //SetTem input to A/C always in Celsius despite passing in 1 to TemUn + outVal = new Integer((int) Math.round((newVal-32.)*5.0/9.0)); //Integer Truncated + //******************TempRec TemSet Mapping for setting Fahrenheit**************************** + //Fahren = [68. , 69. , 70. , 71. , 72. , 73. , 74. , 75. , 76. , 77. , 78. , 79. , 80. , 81. , 82. , 83. , 84. , 85. , 86. ] + //Celsiu = [20.0, 20.5, 21.1, 21.6, 22.2, 22.7, 23.3, 23.8, 24.4, 25.0, 25.5, 26.1, 26.6, 27.2, 27.7, 28.3, 28.8, 29.4, 30.0] + //TemSet = [20, 21, 21, 22, 22, 23, 23, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30] + //TemRec = [ 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0] + //******************TempRec TemSet Mapping for setting Fahrenheit**************************** + // subtract the float verison - the int version to get the fractional difference + // if the difference is positive set halfStep to 1, negative to 0 + halfStep = ((((newVal-32.)*5.0/9.0) - outVal) > 0) ? 1 : 0; + } // Set the values in the HashMap HashMap parameters = new HashMap<>(); - parameters.put("TemUn", new Integer(0)); - parameters.put("SetTem", value); + parameters.put("TemUn", CorF); + parameters.put("SetTem",outVal); + parameters.put("TemRec",halfStep); ExecuteCommand(clientSocket, parameters); } @@ -380,7 +474,7 @@ public Integer GetIntStatusVal(String valueName) { * "StHt": 0, * "TemUn": Temperature unit, 0 for Celsius, 1 for Fahrenheit * "HeatCoolType" - * "TemRec": + * "TemRec": (0 or 1), Send with SetTem, when TemUn==1, distinguishes between upper and lower integer Fahrenheit temp * "SvSt": Power Saving */ // Find the valueName in the Returned Status object @@ -559,6 +653,42 @@ public void getDeviceStatus(DatagramSocket clientSocket) throws Exception { stringReader = new StringReader(statusResponseGson.decryptedPack); statusResponseGson.packJson = gson.fromJson(new JsonReader(stringReader), GreeStatusResponsePack4Gson.class); + UpdateTempFtoC(); } + private void UpdateTempFtoC(){ + // Status message back from A/C always reports degrees C + // If using Fahrenheit, us SetTem, TemUn and TemRec to + // reconstruct the Fahrenheit temperature + // Get Celsius or Fahrenheit from status message + Integer CorF = GetIntStatusVal("TemUn"); + Integer newVal = GetIntStatusVal("SetTem"); + Integer halfStep = GetIntStatusVal("TemRec"); + + if (CorF == null || newVal == null || halfStep == null){ + logger.warn("SetTem,TemUn or TemRec is invalid, not performing conversion"); + } + else if (CorF == 1){ //convert SetTem to Fahrenheit + // Find the valueName in the Returned Status object + String columns[] = statusResponseGson.packJson.cols; + Integer values[] = statusResponseGson.packJson.dat; + List colList = new ArrayList<>(Arrays.asList(columns)); + int valueArrayposition = colList.indexOf("SetTem"); + if (valueArrayposition != -1) { + //convert Celsius to Fahrenheit, + //SetTem status returns degrees C regardless of TempUn setting + + // Perform the float Celsius to Fahrenheit conversion + // add or subtract 0.5 based on the value of TemRec + // (0 = -0.5, 1 = +0.5) + // Pass into a rounding function, this yeild the correct Fahrenheit + // Temperature to match A/C display + newVal = new Integer((int) Math.round(((newVal*9.0/5.0)+32.0)+ halfStep-0.5)); + + //Update the status array with F temp , + // assume this is updating the array in situ + values[valueArrayposition] = newVal; + } + } + } } From 1ff819fa4f1b1e4ee3c95143102d72f91fccc5c6 Mon Sep 17 00:00:00 2001 From: gurglespuge Date: Mon, 16 Jul 2018 19:49:48 -0700 Subject: [PATCH 2/4] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ad123e5..646a573 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ This binding allows you too add Gree Air Conditioners as things. Once added as a thing, the user can control the Air Conditioner, similarly to how the Air Conditioner is controlled using the remote control or smartphone app. -Note: The Gree Air Conditioner must already be setup on the wifi network and must have a fixed IP Address. +Note : The Gree Air Conditioner must already be setup on the wifi network and must have a fixed IP Address. +Note : UPDATE : Added Fahrenheit Support ## Supported Things From 59b83e7895e75f826109c9d54b7552433ed3c736 Mon Sep 17 00:00:00 2001 From: gurglespuge Date: Mon, 16 Jul 2018 19:50:17 -0700 Subject: [PATCH 3/4] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 646a573..d16302e 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,8 @@ This binding allows you too add Gree Air Conditioners as things. Once added as a thing, the user can control the Air Conditioner, similarly to how the Air Conditioner is controlled using the remote control or smartphone app. Note : The Gree Air Conditioner must already be setup on the wifi network and must have a fixed IP Address. -Note : UPDATE : Added Fahrenheit Support + +UPDATE : Added Fahrenheit Support ## Supported Things From 07649800337a2187c8096a9532d43c0705d47d94 Mon Sep 17 00:00:00 2001 From: John Keeler Date: Fri, 20 Jul 2018 07:05:04 -0700 Subject: [PATCH 4/4] moved lookup variable from class to local function becuase no other function use it --- .../openhab/binding/greeair/internal/discovery/GreeDevice.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java b/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java index 1951b77..0708a4f 100644 --- a/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java +++ b/org.openhab.binding.greeair/src/main/java/org/openhab/binding/greeair/internal/discovery/GreeDevice.java @@ -50,7 +50,6 @@ public class GreeDevice { private final static Charset UTF8_CHARSET = Charset.forName("UTF-8"); private final static HashMap> tempRanges = createTempRangeMap(); - private final static String [] tempScaleLUT = {"C","F"}; //used to convert TempUn integer to "C" to "F" string for hashmap private Boolean mIsBound = false; private InetAddress mAddress; private int mPort = 0; @@ -295,6 +294,7 @@ private Integer[] ValidateTemperatureRangeForTempSet(Integer newVal,Integer CorF // For example if value is 75 and TempUn says Celsius, change TempUn to Fahrenheit // final String[] minMaxLUT = {"max","min"}; // looks up 0 = C = max, 1 = F = min + final String [] tempScaleLUT = {"C","F"}; //Look Up Table used to convert TempUn integer 0,1 to "C" to "F" string for hashmap HashMap nullCorFLUT = new HashMap<>(); // simple look up table for logic nullCorFLUT.put("C",new Integer(0)); nullCorFLUT.put("F",new Integer(1));