AC/Heatpump control
-
@ksga Thanks to showing interest with MyController. Can you post your program logic? We can create JavaScript and execute your logic
-
Sure @jkandasa
The LUA script that Toni wrote looks like this:-- These are the configuration variables, set them according to your system modelCmd = '0' -- Panasonic CKP, see https://github.com/mysensors/Arduino/blob/development/libraries/MySensors/examples/HeatpumpIRController/HeatpumpIRController.ino#L68 textDev = 'IR data' -- Name of the 'IR data' MySensors device irSendDev = 'IR send' -- Name of the 'IR send' MySensors device commandArray = {} for key, value in pairs(devicechanged) do if (key == 'Heatpump Mode' or key == 'Heatpump Fan Speed' or key == 'Heatpump Temperature') then mode = otherdevices['Heatpump Mode'] fanSpeed = otherdevices['Heatpump Fan Speed'] temperature = math.floor(otherdevices_svalues['Heatpump Temperature']) if (mode == 'Off') then powerModeCmd = '00' elseif (mode == 'Auto') then powerModeCmd = '11' elseif (mode == 'Heat') then powerModeCmd = '12' elseif (mode == 'Cool') then powerModeCmd = '13' elseif (mode == 'Dry') then powerModeCmd = '14' elseif (mode == 'Fan') then powerModeCmd = '15' elseif (mode == 'Maint') then powerModeCmd = '16' end if (fanSpeed == 'Auto') then fanSpeedCmd = '0' elseif (fanSpeed == 'Fan 1') then fanSpeedCmd = '1' elseif (fanSpeed == 'Fan 2') then fanSpeedCmd = '2' elseif (fanSpeed == 'Fan 3') then fanSpeedCmd = '3' elseif (fanSpeed == 'Fan 4') then fanSpeedCmd = '4' elseif (fanSpeed == 'Fan 5') then fanSpeedCmd = '5' end temperatureCmd = string.format("%02x", temperature) modeCmd = '00' .. modelCmd .. powerModeCmd .. fanSpeedCmd .. temperatureCmd print(string.format('Mode: %s, fan: %s, temp: %s, modeCmd: %s', mode, fanSpeed, temperature, modeCmd)) commandArray['UpdateDevice'] = otherdevices_idx[textDev] .. '|0|' .. modeCmd commandArray['IR send'] = 'On' end end return commandArray
The code will generate an eight digit code looking something like this:
12345678
Position 1+2: Always "00", double zero
Position 3: Model code - in my case "4" - refers to Arduino sketch
Position 4+5: Power mode - for example "11" - Auto mode
Position 6: Fan speed - for example "3" - speed 3
Position 7+8: Temperature in hex - for example "18" - 24 degreesAbove would result in the string: 00411318 - Auto mode, Fan speed 3, 24 degrees
The mode, fanSpeed and temperature variables defined in the first section refers to the dummy devices that were needed on Domoticz
-
Hi @jkandasa
I don't want to put any pressure on you or anything like that - I'm very grateful for all your hard work that has gone into this project - which ROCKS btwBut - was my above info useful, or was it insufficient to explain the issue?
-
@ksga Sorry for the delay response,
JavaScript code for the above LUA script,
//Get sensor values with UID Tags var mode = mcApi.uidTag().getByUid("hp-mode").getResource().getValue(); //Heatpump Mode var fanSpeed = mcApi.uidTag().getByUid("hp-fs").getResource().getValue(); //Heatpump Fan Speed var temperature = parseInt(mcApi.uidTag().getByUid("hp-temperature").getResource().getValue()).toFixed(0); //Heatpump Temperature var modelCmd = '0'; //Default var powerModeCmd = "00"; //Default value var fanSpeedCmd = "0"; //Default value //Update mode if (mode == 'off'){ powerModeCmd = '00'; }else if (mode == 'Auto'){ powerModeCmd = '11'; }else if (mode == 'Heat'){ powerModeCmd = '12'; }else if (mode == 'Cool'){ powerModeCmd = '13'; }else if (mode == 'Dry'){ powerModeCmd = '14'; }else if (mode == 'Fan'){ powerModeCmd = '15'; }else if (mode == 'Maint'){ powerModeCmd = '16'; } //Update Fan speed if (fanSpeed == 'Auto'){ fanSpeedCmd = '0'; }else if (fanSpeed == 'Fan 1'){ fanSpeedCmd = '1'; }else if (fanSpeed == 'Fan 2'){ fanSpeedCmd = '2'; }else if (fanSpeed == 'Fan 3'){ fanSpeedCmd = '3'; }else if (fanSpeed == 'Fan 4'){ fanSpeedCmd = '4'; }else if (fanSpeed == 'Fan 5'){ fanSpeedCmd = '5'; } var temperatureCmd = parseInt(temperature).toString(16).toUpperCase(); if(temperatureCmd.length < 2) { temperatureCmd = '0' + temperatureCmd; } var modeCmd = '00'+modelCmd+powerModeCmd+fanSpeedCmd+temperatureCmd; // send to your IR // Get IR sensor via UID-Tag var irSensor = mcApi.uidTag().getByUid("my-ir-sen").getResource(); // Update value irSensor.value = modeCmd; // Send value to sensor mcApi.sensor().sendPayload(irSensor);
You have to set UID Tag for each sensor and get sensor value with
UID Tag
. There is no event mechanism in MC right now. You have to configure a timer job to run this operation. -
No worries @jkandasa
I'm trying to create the needed sensors. I assume I'll have to create some additional "dummy" sensors on the AC node.
Is it possible to create a custom "Multi selector" sensor?
The existing HVAC ones doesn't quite match the settings on my unit.Regarding the script itself - would it not need some logic to prevent it from sending the value if nothing has changed?
I added the script on the "Utilities > Scripts tab" - created an "Execute Script" operation on the "Resources > Operations" tab, and finally a simple timer, running every 15 seconds, operating the "operation".If the script doesn't check for changes and stop if none has happened, I suspect that I will hear a most annoying beep from the heatpump four times every minute
I won't mind, but I'm sure I will shortly be single again....UPDATE
It works as I feared
Tried just doing "Text" sensors for holding the variables, and the code picks them up (except for fan speed), and sends them to the heatpump faithfully every time the script runs...
Mildly annoyingAlso, I think I should change from "simple" to "cron" for the timer. However it won't accept my cron entry "*/4 * * * * *" trying to make it run every 15 seconds...
-
Is it possible to create a custom "Multi selector" sensor?
Right now it is impossible in MyController.
Regarding the script itself - would it not need some logic to prevent it from sending the value if nothing has changed?
you can check
timestamp
orpreviousValue
of a sensor variable.timestamp
>> would be a great one, you can make a condition with reference timestamp, if any one of sensorVariable timestamp changed, you can trigger further operation.
previousValue
>> comparevalue
withpreviousValue
, may not be a perfect solution! Might be changed multiple times within few seconds with the same value. Which leads false indication.I vote for
timestamp
solution, Here is simple check based ontimestamp
, For this you have to create newvariable
onVariable repository
to take last execution time as a reference time. Create variablehp-lastcheck
onUtilities >> Variables repository
, add0
as Value(default value, to avoid script null failure).//Get last check from variable repository var lastCheckVariable = mcApi.variable().get("hp-lastcheck"); var lastCheck = lastCheckVariable.value; //Get sensor values with UID Tags var modeSensor = mcApi.uidTag().getByUid("hp-mode").getResource(); //Heatpump Mode, sensor var fanSpeedSensor = mcApi.uidTag().getByUid("hp-fs").getResource(); //Heatpump Fan Speed, sensor var temperatureSensor = mcApi.uidTag().getByUid("hp-temperature").getResource(); //Heatpump Temperature, sensor // Take refrance of current time, to update last check var currentTime = Date.now(); if(modeSensor.timestamp >= lastCheck || fanSpeedSensor.timestamp >= lastCheck || temperatureSensor.timestamp >= lastCheck){ // Update values var mode = modeSensor.getValue(); //Heatpump Mode var fanSpeed = fanSpeedSensor.getValue(); //Heatpump Fan Speed var temperature = parseInt(temperatureSensor.getValue()).toFixed(0); //Heatpump Temperature var modelCmd = '0'; //Default var powerModeCmd = "00"; //Default value var fanSpeedCmd = "0"; //Default value //Update mode if (mode == 'off'){ powerModeCmd = '00'; }else if (mode == 'Auto'){ powerModeCmd = '11'; }else if (mode == 'Heat'){ powerModeCmd = '12'; }else if (mode == 'Cool'){ powerModeCmd = '13'; }else if (mode == 'Dry'){ powerModeCmd = '14'; }else if (mode == 'Fan'){ powerModeCmd = '15'; }else if (mode == 'Maint'){ powerModeCmd = '16'; } //Update Fan speed if (fanSpeed == 'Auto'){ fanSpeedCmd = '0'; }else if (fanSpeed == 'Fan 1'){ fanSpeedCmd = '1'; }else if (fanSpeed == 'Fan 2'){ fanSpeedCmd = '2'; }else if (fanSpeed == 'Fan 3'){ fanSpeedCmd = '3'; }else if (fanSpeed == 'Fan 4'){ fanSpeedCmd = '4'; }else if (fanSpeed == 'Fan 5'){ fanSpeedCmd = '5'; } var temperatureCmd = parseInt(temperature).toString(16).toUpperCase(); if(temperatureCmd.length < 2) { temperatureCmd = '0' + temperatureCmd; } var modeCmd = '00'+modelCmd+powerModeCmd+fanSpeedCmd+temperatureCmd; // send to your IR // Get IR sensor via UID-Tag var irSensor = mcApi.uidTag().getByUid("my-ir-sen").getResource(); // Update value irSensor.value = modeCmd; // Send value to sensor mcApi.sensor().sendPayload(irSensor); } //Update lastCheck refrence lastCheckVariable.value = currentTime; mcApi.variable().update(lastCheckVariable);
I think I should change from "simple" to "cron" for the timer. However it won't accept my cron entry "*/4 * * * * *" trying to make it run every 15 seconds...
In MyController cron is based on Quartz Scheduler. You should have at least one
?
in your cron. Kindly refer this tutorial.
For 15 seconds:0/15 * * * * ?
-
@jkandasa
Thanks.. Will give it a go..Is it also correct that the //Update Fan Speed should use
if (fanSpeed == 'Auto')
and not:
if (mode == 'Auto')
and so on...? -
Is it also correct that the
if (fanSpeed == 'Auto')
and not:
if (mode == 'Auto')
and so on...?I am sorry it is a problem of copy/paste I have updated the script.
-
@ksga Does this script works as you expected?
-
Hi @jkandasa
Sorry for not posting the feedback yet...But yes - It works like a charm. And the timestamp solution seems to do what its supposed to