Skip to content
This repository has been archived by the owner on May 7, 2020. It is now read-only.

TransformationProfile and SystemOffsetProfile #5679

Merged
merged 20 commits into from
Jun 27, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
7a0a253
WIP: TransformationProfile and SystemOffsetProfile
triller-telekom May 22, 2018
dd0f4eb
Incorporate review changes
triller-telekom Jun 5, 2018
5f214e0
Fix failing test after changes
triller-telekom Jun 6, 2018
d0ee464
Allow BigDecimal as offset parameter and improve warning message
triller-telekom Jun 6, 2018
9f3246c
Allow decimal offsets on quantity states, but with warning
triller-telekom Jun 7, 2018
246e265
ConfigDescription for OffsetProfile
triller-telekom Jun 15, 2018
aff83fb
Split function and format into 2 parameters. ConfigDescriptions for p…
triller-telekom Jun 15, 2018
e7b193b
Turn state formatter into an advanced parameter
triller-telekom Jun 18, 2018
4ed2b9c
Advanced parameters should not be required
triller-telekom Jun 19, 2018
42d147e
Special handling of temperatures in offsetprofile
triller-telekom Jun 19, 2018
782a368
Do the math for temperature offsets in kelvin
triller-telekom Jun 20, 2018
d8f40ad
Extract variables into constants to speed up calculations
triller-telekom Jun 20, 2018
9088d69
Create one profile and factory per transformation service bundle
triller-telekom Jun 21, 2018
eaaa8e8
Documented profile usage in transformation services
triller-telekom Jun 21, 2018
cf186f5
USE DS-annotations for transformation services
triller-telekom Jun 21, 2018
f838438
Fix parameter name and DS service of map transformation
triller-telekom Jun 21, 2018
3135ad7
Fix Javadoc
triller-telekom Jun 22, 2018
27f2411
Supported Items for OffsetProfile are only NumberItems
triller-telekom Jun 22, 2018
660f10d
Address review comments (except javadoc format)
triller-telekom Jun 27, 2018
4bd7ff0
Fix formatting errors
triller-telekom Jun 27, 2018
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
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ Import-Package:
org.hamcrest;core=split,
org.hamcrest.collection,
org.hamcrest.core,
org.hamcrest.number,
org.junit;version="4.0.0",
org.junit.rules,
org.mockito,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/**
* Copyright (c) 2014,2018 Contributors to the Eclipse Foundation
*
* See the NOTICE file(s) distributed with this work for additional
* information regarding copyright ownership.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.eclipse.smarthome.core.thing.internal.profiles;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.number.IsCloseTo.closeTo;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

import javax.measure.Unit;
import javax.measure.quantity.Temperature;

import org.eclipse.smarthome.config.core.Configuration;
import org.eclipse.smarthome.core.library.types.DecimalType;
import org.eclipse.smarthome.core.library.types.QuantityType;
import org.eclipse.smarthome.core.library.unit.ImperialUnits;
import org.eclipse.smarthome.core.library.unit.SIUnits;
import org.eclipse.smarthome.core.thing.profiles.ProfileCallback;
import org.eclipse.smarthome.core.thing.profiles.ProfileContext;
import org.eclipse.smarthome.core.types.Command;
import org.eclipse.smarthome.core.types.State;
import org.junit.Before;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

/**
* Tests for the system:offset profile
*
* @author Stefan Triller - initial contribution
*
*/
public class SystemOffsetProfileTest {

@Before
public void setup() {
// initialize parser with ImperialUnits, otherwise units like °F are unknown
@SuppressWarnings("unused")
Unit<Temperature> fahrenheit = ImperialUnits.FAHRENHEIT;
}

@Test
public void testDecimalTypeOnCommandFromItem() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3");

Command cmd = new DecimalType(23);
offsetProfile.onCommandFromItem(cmd);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).handleCommand(capture.capture());

Command result = capture.getValue();
DecimalType decResult = (DecimalType) result;
assertEquals(20, decResult.intValue());
}

@Test
public void testDecimalTypeOnStateUpdateFromItem() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3");

State state = new DecimalType(23);
offsetProfile.onStateUpdateFromItem(state);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).handleCommand(capture.capture());

Command result = capture.getValue();
DecimalType decResult = (DecimalType) result;
assertEquals(20, decResult.intValue());
}

@Test
public void testQuantityTypeOnCommandFromItem() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3°C");

Command cmd = new QuantityType<Temperature>("23°C");
offsetProfile.onCommandFromItem(cmd);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).handleCommand(capture.capture());

Command result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertEquals(20, decResult.intValue());
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

@Test
public void testQuantityTypeOnStateUpdateFromItem() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3°C");

State state = new QuantityType<Temperature>("23°C");
offsetProfile.onStateUpdateFromItem(state);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).handleCommand(capture.capture());

Command result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertEquals(20, decResult.intValue());
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

@Test
public void testDecimalTypeOnCommandFromHandler() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3");

Command cmd = new DecimalType(23);
offsetProfile.onCommandFromHandler(cmd);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).sendCommand(capture.capture());

Command result = capture.getValue();
DecimalType decResult = (DecimalType) result;
assertEquals(26, decResult.intValue());
}

@Test
public void testDecimalTypeOnStateUpdateFromHandler() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3");

State state = new DecimalType(23);
offsetProfile.onStateUpdateFromHandler(state);

ArgumentCaptor<State> capture = ArgumentCaptor.forClass(State.class);
verify(callback, times(1)).sendUpdate(capture.capture());

State result = capture.getValue();
DecimalType decResult = (DecimalType) result;
assertEquals(26, decResult.intValue());
}

@Test
public void testQuantityTypeOnCommandFromHandler() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3°C");

Command cmd = new QuantityType<Temperature>("23°C");
offsetProfile.onCommandFromHandler(cmd);

ArgumentCaptor<Command> capture = ArgumentCaptor.forClass(Command.class);
verify(callback, times(1)).sendCommand(capture.capture());

Command result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertEquals(26, decResult.intValue());
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

@Test
public void testQuantityTypeOnStateUpdateFromHandler() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3°C");

State state = new QuantityType<Temperature>("23°C");
offsetProfile.onStateUpdateFromHandler(state);

ArgumentCaptor<State> capture = ArgumentCaptor.forClass(State.class);
verify(callback, times(1)).sendUpdate(capture.capture());

State result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertEquals(26, decResult.intValue());
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

@Test
public void testQuantityTypeOnStateUpdateFromHandlerFahrenheitOffset() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3 °F");

State state = new QuantityType<Temperature>("23 °C");
offsetProfile.onStateUpdateFromHandler(state);

ArgumentCaptor<State> capture = ArgumentCaptor.forClass(State.class);
verify(callback, times(1)).sendUpdate(capture.capture());

State result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertThat(decResult.doubleValue(), is(closeTo(24.6666666666666666666666666666667d, 0.0000000000000001d)));
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

@Test
public void testQuantityTypeOnStateUpdateFromHandlerDecimalOffset() {
ProfileCallback callback = mock(ProfileCallback.class);
SystemOffsetProfile offsetProfile = createProfile(callback, "3");

State state = new QuantityType<Temperature>("23 °C");
offsetProfile.onStateUpdateFromHandler(state);

ArgumentCaptor<State> capture = ArgumentCaptor.forClass(State.class);
verify(callback, times(1)).sendUpdate(capture.capture());

State result = capture.getValue();
@SuppressWarnings("unchecked")
QuantityType<Temperature> decResult = (QuantityType<Temperature>) result;
assertEquals(26, decResult.intValue());
assertEquals(SIUnits.CELSIUS, decResult.getUnit());
}

private SystemOffsetProfile createProfile(ProfileCallback callback, String offset) {
ProfileContext context = mock(ProfileContext.class);
Configuration config = new Configuration();
config.put("offset", offset);
when(context.getConfiguration()).thenReturn(config);

return new SystemOffsetProfile(callback, context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<config-description:config-descriptions
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:config-description="http://eclipse.org/smarthome/schemas/config-description/v1.0.0"
xsi:schemaLocation="http://eclipse.org/smarthome/schemas/config-description/v1.0.0
http://eclipse.org/smarthome/schemas/config-description-1.0.0.xsd">

<config-description uri="profile:system:offset">
<parameter name="offset" type="text" required="true">
<label>Offset</label>
<description>Offset (plain number or number with unit) to be applied on the state towards the item. The negative offset will be applied in the reverse direction.</description>
</parameter>
</config-description>
</config-description:config-descriptions>
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Import-Package:
org.eclipse.smarthome.core.library,
org.eclipse.smarthome.core.library.items,
org.eclipse.smarthome.core.library.types,
org.eclipse.smarthome.core.library.unit,
org.eclipse.smarthome.core.service,
org.eclipse.smarthome.core.storage,
org.eclipse.smarthome.core.thing,
Expand Down
Loading