Skip to content

Commit

Permalink
[daikin] Add demand control support for ac_unit Thing.
Browse files Browse the repository at this point in the history
Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng committed Jul 25, 2024
1 parent 49a43a4 commit 6d8013b
Show file tree
Hide file tree
Showing 11 changed files with 938 additions and 16 deletions.
137 changes: 134 additions & 3 deletions bundles/org.openhab.binding.daikin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ For the BRP072A42 and BRP072C42:
| energycoolingcurrentyear-10 | The energy consumption when cooling for current year October |
| energycoolingcurrentyear-11 | The energy consumption when cooling for current year November |
| energycoolingcurrentyear-12 | The energy consumption when cooling for current year December |
| demandcontrolmode | The demand control mode (OFF, AUTO, MANUAL, SCHEDULED) |
| demandcontrolmaxpower | The maximum power when in MANUAL mode. Values between 40 and 100 are accepted in an increment of 5. |
| demandcontrolschedule | A JSON string that contains the scheduled demand control settings. See below. |

For the BRP15B61:

Expand All @@ -110,6 +113,133 @@ For the BRP15B61:
| zone7 | Turns zone 7 on/off for the air conditioning unit. |
| zone8 | Turns zone 8 on/off for the air conditioning unit. |

## Demand Control

Some units have a _demand control_ feature to limit the maximum power usage to a certain percentage.
This is set through the `demandcontrolmode` channel which accepts `OFF`, `MANUAL`, `SCHEDULED`, or `AUTO`.

When changing the mode from `MANUAL` to another mode, the maximum power setting will be saved in the Binding's memory and restored when switching the mode back to `MANUAL`.
Equally, when changing the mode from `SCHEDULED` to another mode, the current schedule will be saved in the Binding's memory and restored when switching the mode back to `SCHEDULED`.

### Manual Demand Control

Manual demand control requires setting the `demandcontrolmaxpower` channel to the desired limit.
The unit accepts values between 40% and 100% in increments of 5.

Sending a command to the `demandcontrolmaxpower` channel will automatically switch the demand control mode to `MANUAL`.

### Scheduled Demand Control

It is possible to set the demand control power limit based on day of the week and time of day schedules.
When the unit is in scheduled demand control mode, the binding provides the current schedule through the `demandcontrolschedule` channel.
Furthermore, the `demandcontrolmaxpower` channel will provide the _current_ maximum power in effect, as defined within the schedule.
It is important to ensure that openHAB's local time must be in sync with the unit's date/time.
Beware that sending a command to the `demandcontrolmaxpower` will switch the demand control mode to `MANUAL`.

The schedule can be changed by sending a command to the channel `demandcontrolschedule`.
When doing so, the demand control mode will automatically change to `SCHEDULED`, if it wasn't already in that mode.

The schedule is specified in a JSON string in the following format:

```json
{
"monday": [
{
"enabled": true,
"time": <minutes from midnight>,
"power": <power in percent>
}
],
"tuesday": [
// Schedule entries for Tuesday
],
"wednesday": [

],
// more days up to Sunday
"sunday": [

]
}
```

Concrete example:

The JSON format doesn't actually support comments. They are provided for clarity.

```json
{
"monday": [
{
"enabled": true,
"time": 480, // 8 am
"power": 80
},
{
"enabled": true,
"time": 600, // 10 am
"power": 100
},
{
"enabled": true,
"time": 960, // 4pm
"power": 50
}
],
"tuesday": [
{
"enabled": true,
"time": 480, // 8 am
"power": 80
},
{
"enabled": true,
"time": 600, // 10 am
"power": 100
},
{
"enabled": true,
"time": 960, // 4pm
"power": 50
}
],
"wednesday": [
{
"enabled": true,
"time": 480, // 8 am
"power": 80
},
{
"enabled": true,
"time": 600, // 10 am
"power": 100
},
{
"enabled": true,
"time": 960, // 4pm
"power": 50
}
],
"thursday": [
{
"enabled": true,
"time": 480, // 8 am
"power": 100
}
]
// omitted days mean that they contain no schedules
}
```

Note:

- Each day can have up to 4 schedule entries
- `enabled` means whether this schedule element is enabled.
- `time` is the start time of the schedule, expressed in number of minutes from midnight.
- `power` a value of zero means demand power is disabled at the time defined by the `time` element.
- When there are no schedules defined for the current day/time, it is believed that the settings from the previous schedule will apply, bearing in mind that it is a weekly recurring schedule.
This is ultimately determined by the logic in the unit itself, and not controlled by the Binding.

## Full Example

daikin.things:
Expand All @@ -135,7 +265,10 @@ String DaikinACUnit_Fan { channel="daikin:ac_unit:living_room_ac:fanspeed" }
String DaikinACUnit_Fan_Movement { channel="daikin:ac_unit:living_room_ac:fandir" }
Number:Temperature DaikinACUnit_IndoorTemperature { channel="daikin:ac_unit:living_room_ac:indoortemp" }
Number:Temperature DaikinACUnit_OutdoorTemperature { channel="daikin:ac_unit:living_room_ac:outdoortemp" }

// Demand control, when supported by the unit
String DaikinACUnit_DemandControl_Mode { channel="daikin:ac_unit:living_room_ac:demandcontrolmode" }
Dimmer DaikinACUnit_DemandControl_MaxPower { channel="daikin:ac_unit:living_room_ac:demandcontrolmaxpower" }
String DaikinACUnit_DemandControl_Schedule { channel="daikin:ac_unit:living_room_ac:demandcontrolschedule" }

// for Airbase (BRP15B61)
Switch DaikinACUnit_Power { channel="daikin:airbase_ac_unit:living_room_ac:power" }
Expand All @@ -153,7 +286,6 @@ Switch DaikinACUnit_Zone5 { channel="daikin:airbase_ac_unit:living_room_ac:zone5
Switch DaikinACUnit_Zone6 { channel="daikin:airbase_ac_unit:living_room_ac:zone6" }
Switch DaikinACUnit_Zone7 { channel="daikin:airbase_ac_unit:living_room_ac:zone7" }
Switch DaikinACUnit_Zone8 { channel="daikin:airbase_ac_unit:living_room_ac:zone8" }

```

daikin.sitemap:
Expand Down Expand Up @@ -183,5 +315,4 @@ Switch item=DaikinACUnit_Zone5 visibility=[DaikinACUnit_Power==ON]
Switch item=DaikinACUnit_Zone6 visibility=[DaikinACUnit_Power==ON]
Switch item=DaikinACUnit_Zone7 visibility=[DaikinACUnit_Power==ON]
Switch item=DaikinACUnit_Zone8 visibility=[DaikinACUnit_Power==ON]

```
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public class DaikinBindingConstants {
public static final String CHANNEL_AC_SPECIALMODE = "specialmode";
public static final String CHANNEL_AC_STREAMER = "streamer";

public static final String CHANNEL_AC_DEMAND_MODE = "demandcontrolmode";
public static final String CHANNEL_AC_DEMAND_MAX_POWER = "demandcontrolmaxpower";
public static final String CHANNEL_AC_DEMAND_SCHEDULE = "demandcontrolschedule";

// additional channels for Airbase Controller
public static final String CHANNEL_AIRBASE_AC_FAN_SPEED = "airbasefanspeed";
public static final String CHANNEL_AIRBASE_AC_ZONE = "zone";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import org.eclipse.jetty.http.HttpStatus;
import org.openhab.binding.daikin.internal.api.BasicInfo;
import org.openhab.binding.daikin.internal.api.ControlInfo;
import org.openhab.binding.daikin.internal.api.DemandControl;
import org.openhab.binding.daikin.internal.api.EnergyInfoDayAndWeek;
import org.openhab.binding.daikin.internal.api.EnergyInfoYear;
import org.openhab.binding.daikin.internal.api.Enums.SpecialMode;
Expand Down Expand Up @@ -62,6 +63,8 @@ public class DaikinWebTargets {
private String getEnergyInfoYearUri;
private String getEnergyInfoWeekUri;
private String setSpecialModeUri;
private String setDemandControlUri;
private String getDemandControlUri;

private String setAirbaseControlInfoUri;
private String getAirbaseControlInfoUri;
Expand Down Expand Up @@ -90,6 +93,8 @@ public DaikinWebTargets(@Nullable HttpClient httpClient, @Nullable String host,
getEnergyInfoYearUri = baseUri + "aircon/get_year_power_ex";
getEnergyInfoWeekUri = baseUri + "aircon/get_week_power_ex";
setSpecialModeUri = baseUri + "aircon/set_special_mode";
setDemandControlUri = baseUri + "aircon/set_demand_control";
getDemandControlUri = baseUri + "aircon/get_demand_control";

// Daikin Airbase API
getAirbaseBasicInfoUri = baseUri + "skyfi/common/basic_info";
Expand Down Expand Up @@ -169,6 +174,18 @@ public void setStreamerMode(boolean state) throws DaikinCommunicationException {
}
}

public DemandControl getDemandControl() throws DaikinCommunicationException {
String response = invoke(getDemandControlUri);
return DemandControl.parse(response);
}

public boolean setDemandControl(DemandControl info) throws DaikinCommunicationException {
Map<String, String> queryParams = info.getParamString();
String result = invoke(setDemandControlUri, queryParams);
Map<String, String> responseMap = InfoParser.parse(result);
return Optional.ofNullable(responseMap.get("ret")).orElse("").equals("OK");
}

// Daikin Airbase API
public AirbaseControlInfo getAirbaseControlInfo() throws DaikinCommunicationException {
String response = invoke(getAirbaseControlInfoUri);
Expand Down
Loading

0 comments on commit 6d8013b

Please sign in to comment.