Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[danfossairunit] Add filter period channel #11371

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 39 additions & 12 deletions bundles/org.openhab.binding.danfossairunit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ These are the available configuration parameters:
| exhaust_temp | recuperator | Number | RO | Temperature of the air when pushed outside |
| battery_life | service | Number | RO | Remaining Air Dial Battery Level (percentage) |
| filter_life | service | Number | RO | Remaining life of filter until exchange is necessary (percentage) |
| filter_period | service | Number | RW | Number of months between filter replacements (between 3 and 12). This value affects calculation of filter_life by the unit, and might get overwritten by Air Dial or Link CC Controller. |


## Full Example
Expand All @@ -63,21 +64,47 @@ updateUnchangedValuesEveryMillis=30000]
### Items

```
Dimmer Lueftung_Drehzahl_Manuell "Drehzahl Lüftung %" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:main#manual_fan_speed"}
Number Lueftung_Drehzahl_Supply "Drehzahl Lüftung Zuluft (rpm)" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:main#supply_fan_speed"}
Number Lueftung_Drehzahl_Extract "Drehzahl Lüftung Abluft (rpm)" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:main#extract_fan_speed"}
String Lueftung_Mode "Betriebsart Lüftung" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:main#mode"}
Switch Lueftung_Boost "Stoßlüftung" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:main#boost"}
Switch Lueftung_Bypass "Lüftung Bypass" (All,Lueftung) {channel = "danfossairunit:airunit:myairunit:recuperator#bypass"}
Dimmer DanfossHRV_ManualFanStep "Manual Fan Step [%s]" {channel = "danfossairunit:airunit:myairunit:main#manual_fan_step"}
Number DanfossHRV_SupplyFanSpeed "Supply Fan Speed" {channel = "danfossairunit:airunit:myairunit:main#supply_fan_speed"}
Number DanfossHRV_ExtractFanSpeed "Extract Fan Speed" {channel = "danfossairunit:airunit:myairunit:main#extract_fan_speed"}
String DanfossHRV_Mode "Operation Mode" {channel = "danfossairunit:airunit:myairunit:main#mode"}
Switch DanfossHRV_Boost "Boost" {channel = "danfossairunit:airunit:myairunit:main#boost"}
Switch DanfossHRV_Bypass "Bypass" {channel = "danfossairunit:airunit:myairunit:recuperator#bypass"}
Number:Dimensionless DanfossHRV_Humidity "Relative humidity" <humidity> { channel = "danfossairunit:airunit:myairunit:humidity#humidity" }
Number:Temperature DanfossHRV_RoomTemperature "Room air temperatuyre" <temperature> { channel = "danfossairunit:airunit:myairunit:temps#room_temp" }
Number:Temperature DanfossHRV_OutdoorTemperature "Outdoor air temperature" <temperature> { channel = "danfossairunit:airunit:myairunit:temps#outdoor_temp" }
Number:Temperature DanfossHRV_SupplyAirTemperature "Supply air temperature" <temperature> { channel = "danfossairunit:airunit:myairunit:recuperator#supply_temp" }
Number:Temperature DanfossHRV_ExtractAirTemperature "Extract air temperature" <temperature> { channel = "danfossairunit:airunit:myairunit:recuperator#extract_temp" }
Number:Temperature DanfossHRV_ExhaustAirTemperature "Exhaust air temperature" <temperature> { channel = "danfossairunit:airunit:myairunit:recuperator#exhaust_temp" }
Number DanfossHRV_RemainingFilterLife "Remaining filter life" { channel = "danfossairunit:airunit:myairunit:service#filter_life" }
Number DanfossHRV_FilterPeriod "Filter period" { channel = "danfossairunit:airunit:myairunit:service#filter_period" }
```

### Sitemap

```
Slider item=Lueftung_Drehzahl_Manuell
Text item=Lueftung_Drehzahl_Supply
Text item=Lueftung_Drehzahl_Extract
Selection item=Lueftung_Mode mappings=[DEMAND="Bedarfslüftung", OFF="Aus", PROGRAM="Programm", MANUAL="manuell"]
Switch item=Lueftung_Boost
Switch item=Lueftung_Bypass
sitemap danfoss label="Danfoss" {
Frame label="Control" {
Selection item=DanfossHRV_Mode mappings=[DEMAND="Demand", OFF="Off", PROGRAM="Program", MANUAL="Manual"]
Slider item=DanfossHRV_ManualFanStep step=10 visibility=[DanfossHRV_Mode=="MANUAL"]
Switch item=DanfossHRV_Bypass
Switch item=DanfossHRV_Boost
}
Frame label="Measurements" {
Text item=DanfossHRV_Humidity
Text item=DanfossHRV_RoomTemperature
Text item=DanfossHRV_OutdoorTemperature
Text item=DanfossHRV_SupplyAirTemperature
Text item=DanfossHRV_ExtractAirTemperature
Text item=DanfossHRV_ExhaustAirTemperature
}
Frame label="Fan" {
Text item=DanfossHRV_SupplyFanSpeed
Text item=DanfossHRV_ExtractFanSpeed
}
Frame label="Filter" {
Text item=DanfossHRV_RemainingFilterLife
Slider item=DanfossHRV_FilterPeriod minValue=3 maxValue=12
}
}
```
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,9 @@ public enum Channel {

// service channels
CHANNEL_BATTERY_LIFE("battery_life", ChannelGroup.SERVICE, DanfossAirUnit::getBatteryLife),
CHANNEL_FILTER_LIFE("filter_life", ChannelGroup.SERVICE, DanfossAirUnit::getFilterLife);
CHANNEL_FILTER_LIFE("filter_life", ChannelGroup.SERVICE, DanfossAirUnit::getFilterLife),
CHANNEL_FILTER_PERIOD("filter_period", ChannelGroup.SERVICE, DanfossAirUnit::getFilterPeriod,
DanfossAirUnit::setFilterPeriod);

private final String channelName;
private final ChannelGroup group;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public class Commands {
public static byte[] EXHAUST_TEMPERATURE = { 0x14, 0x75 };
public static byte[] BATTERY_LIFE = { 0x03, 0x0f };
public static byte[] FILTER_LIFE = { 0x14, 0x6a };
public static byte[] FILTER_PERIOD = { 0x14, 0x69 };
public static byte[] CURRENT_TIME = { 0x15, (byte) 0xe0 };
public static byte[] AWAY_TO = { 0x15, 0x20 };
public static byte[] AWAY_FROM = { 0x15, 0x21 };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
/**
* This interface defines a communication controller that can be used to send requests to the Danfoss Air Unit.
*
* @author Jacob Laursen - Refactoring, bugfixes and enhancements
* @author Jacob Laursen - Initial contribution
*/
@NonNullByDefault
public interface CommunicationController {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,16 @@ public DecimalType getBatteryLife() throws IOException {
}

public DecimalType getFilterLife() throws IOException {
return new DecimalType(BigDecimal.valueOf(asPercentByte(getByte(REGISTER_1_READ, FILTER_LIFE))));
BigDecimal value = BigDecimal.valueOf(asPercentByte(getByte(REGISTER_1_READ, FILTER_LIFE)));
return new DecimalType(value.setScale(1, RoundingMode.HALF_UP));
}

public DecimalType getFilterPeriod() throws IOException {
return new DecimalType(BigDecimal.valueOf(getByte(REGISTER_1_READ, FILTER_PERIOD)));
}

public DecimalType setFilterPeriod(Command cmd) throws IOException {
return setNumberTypeRegister(cmd, FILTER_PERIOD);
}

public DateTimeType getCurrentTime() throws IOException, UnexpectedResponseValueException {
Expand All @@ -225,6 +234,14 @@ public PercentType setManualFanStep(Command cmd) throws IOException {
return setPercentTypeRegister(cmd, MANUAL_FAN_SPEED_STEP);
}

private DecimalType setNumberTypeRegister(Command cmd, byte[] register) throws IOException {
if (cmd instanceof DecimalType) {
byte value = (byte) ((DecimalType) cmd).intValue();
set(REGISTER_1_WRITE, register, value);
}
return new DecimalType(BigDecimal.valueOf(getByte(REGISTER_1_READ, register)));
}

private PercentType setPercentTypeRegister(Command cmd, byte[] register) throws IOException {
if (cmd instanceof PercentType) {
byte value = (byte) ((((PercentType) cmd).intValue() + 5) / 10);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ private synchronized void discover() {
logger.debug("Try to discover all Danfoss Air CCM devices");

try (DatagramSocket socket = new DatagramSocket()) {

Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface networkInterface = interfaces.nextElement();
Expand All @@ -96,7 +95,6 @@ private synchronized void discover() {
sendBroadcastToDiscoverThing(socket, interfaceAddress.getBroadcast());
}
}

} catch (IOException e) {
logger.debug("No Danfoss Air CCM device found. Diagnostic: {}", e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@
<label>Remaining Filter Life</label>
<description>Remaining life of filter until exchange is necessary</description>
</channel>
<channel id="filter_period" typeId="filterPeriod"/>
</channels>
</channel-group-type>

Expand Down Expand Up @@ -190,6 +191,12 @@
<category>Fan</category>
<state step="10" min="0" max="100" readOnly="true"/>
</channel-type>
<channel-type id="filterPeriod" advanced="true">
<item-type>Number</item-type>
<label>Filter Period</label>
<description>Number of months between filter replacements</description>
<state pattern="%d" min="3" max="12"/>
</channel-type>
<channel-type id="percentage">
<item-type>Number</item-type>
<label>Percentage</label>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openhab.core.library.types.DateTimeType;
import org.openhab.core.library.types.DecimalType;
import org.openhab.core.library.types.OnOffType;
import org.openhab.core.library.types.PercentType;
import org.openhab.core.library.types.QuantityType;
Expand All @@ -31,7 +32,7 @@
/**
* This class provides test cases for {@link DanfossAirUnit}
*
* @author Jacob Laursen - Refactoring, bugfixes and enhancements
* @author Jacob Laursen - Initial contribution
*/
public class DanfossAirUnitTest extends JavaTest {

Expand Down Expand Up @@ -153,4 +154,12 @@ public void getManualFanStepWhenOutOfRangeThrows() throws IOException {
var airUnit = new DanfossAirUnit(communicationController);
assertThrows(UnexpectedResponseValueException.class, () -> airUnit.getManualFanStep());
}

@Test
public void getFilterLifeWhenNearestNeighborIsBelowRoundsDown() throws IOException {
byte[] response = new byte[] { (byte) 0xf0 };
when(this.communicationController.sendRobustRequest(REGISTER_1_READ, FILTER_LIFE)).thenReturn(response);
var airUnit = new DanfossAirUnit(communicationController);
assertEquals(new DecimalType("94.1"), airUnit.getFilterLife());
}
}