Skip to content

Commit

Permalink
Added Sematics actions for Rules (openhab#2088)
Browse files Browse the repository at this point in the history
Signed-off-by: Christoph Weitkamp <[email protected]>
GitOrigin-RevId: 191a629
  • Loading branch information
cweitkamp authored and splatch committed Jul 11, 2023
1 parent 1ed83c2 commit e8afeae
Show file tree
Hide file tree
Showing 7 changed files with 574 additions and 10 deletions.
5 changes: 5 additions & 0 deletions bundles/org.opensmarthouse.core.model.script/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<artifactId>org.openhab.core.transform</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.semantics</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.openhab.core.bundles</groupId>
<artifactId>org.openhab.core.voice</artifactId>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* 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.openhab.core.model.script.actions;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.Mockito.when;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.junit.jupiter.MockitoSettings;
import org.mockito.quality.Strictness;
import org.openhab.core.items.GenericItem;
import org.openhab.core.items.GroupItem;
import org.openhab.core.items.ItemNotFoundException;
import org.openhab.core.items.ItemRegistry;
import org.openhab.core.library.CoreItemFactory;
import org.openhab.core.model.script.internal.engine.action.SemanticsActionService;
import org.openhab.core.semantics.model.equipment.CleaningRobot;
import org.openhab.core.semantics.model.location.Bathroom;
import org.openhab.core.semantics.model.location.Indoor;

/**
* This are tests for {@link Semantics} actions.
*
* @author Christoph Weitkamp - Initial contribution
*/
@ExtendWith(MockitoExtension.class)
@MockitoSettings(strictness = Strictness.WARN)
public class SemanticsTest {

private @Mock ItemRegistry mockedItemRegistry;

private GroupItem indoorLocationItem;
private GroupItem bathroomLocationItem;
private GroupItem equipmentItem;
private GenericItem temperaturePointItem;
private GenericItem humidityPointItem;

@BeforeEach
public void setup() throws ItemNotFoundException {
CoreItemFactory itemFactory = new CoreItemFactory();

indoorLocationItem = new GroupItem("TestHouse");
indoorLocationItem.addTag("Indoor");

bathroomLocationItem = new GroupItem("TestBathRoom");
bathroomLocationItem.addTag("Bathroom");

// Bathroom is placed in Indoor
indoorLocationItem.addMember(bathroomLocationItem);
bathroomLocationItem.addGroupName(indoorLocationItem.getName());

equipmentItem = new GroupItem("Test08");
equipmentItem.addTag("CleaningRobot");

// Equipment (Cleaning Robot) is placed in Bathroom
bathroomLocationItem.addMember(equipmentItem);
equipmentItem.addGroupName(bathroomLocationItem.getName());

temperaturePointItem = itemFactory.createItem(CoreItemFactory.NUMBER, "TestTemperature");
temperaturePointItem.addTag("Measurement");
temperaturePointItem.addTag("Temperature");

// Temperature Point is Property of Equipment (Cleaning Robot)
equipmentItem.addMember(temperaturePointItem);
temperaturePointItem.addGroupName(equipmentItem.getName());

humidityPointItem = itemFactory.createItem(CoreItemFactory.NUMBER, "TestHumidity");
humidityPointItem.addTag("Measurement");
humidityPointItem.addTag("Humidity");

when(mockedItemRegistry.getItem("TestHouse")).thenReturn(indoorLocationItem);
when(mockedItemRegistry.getItem("TestBathRoom")).thenReturn(bathroomLocationItem);
when(mockedItemRegistry.getItem("Test08")).thenReturn(equipmentItem);
when(mockedItemRegistry.getItem("TestTemperature")).thenReturn(temperaturePointItem);
when(mockedItemRegistry.getItem("TestHumidity")).thenReturn(humidityPointItem);

new SemanticsActionService(mockedItemRegistry);
}

@Test
public void testGetLocation() {
assertThat(Semantics.getLocation(indoorLocationItem), is(indoorLocationItem));
assertThat(Semantics.getLocation(bathroomLocationItem), is(bathroomLocationItem));

assertThat(Semantics.getLocation(equipmentItem), is(bathroomLocationItem));

assertThat(Semantics.getLocation(temperaturePointItem), is(bathroomLocationItem));

assertNull(Semantics.getLocation(humidityPointItem));
}

@Test
public void testGetLocationType() {
assertThat(Semantics.getLocationType(indoorLocationItem), is(Indoor.class));
assertThat(Semantics.getLocationType(bathroomLocationItem), is(Bathroom.class));

assertNull(Semantics.getLocationType(humidityPointItem));
}

@Test
public void testGetEquipment() {
assertThat(Semantics.getEquipment(equipmentItem), is(equipmentItem));

assertThat(Semantics.getEquipment(temperaturePointItem), is(equipmentItem));

assertNull(Semantics.getEquipment(humidityPointItem));
}

@Test
public void testGetEquipmentType() {
assertThat(Semantics.getEquipmentType(equipmentItem), is(CleaningRobot.class));

assertThat(Semantics.getEquipmentType(temperaturePointItem), is(CleaningRobot.class));

assertNull(Semantics.getEquipmentType(humidityPointItem));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
/**
* Copyright (c) 2010-2021 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* 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.openhab.core.model.script.actions;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.core.items.Item;
import org.openhab.core.model.script.engine.action.ActionDoc;
import org.openhab.core.model.script.internal.engine.action.SemanticsActionService;
import org.openhab.core.semantics.SemanticTags;
import org.openhab.core.semantics.model.Equipment;
import org.openhab.core.semantics.model.Location;
import org.openhab.core.semantics.model.Point;
import org.openhab.core.semantics.model.Property;
import org.openhab.core.semantics.model.Tag;

/**
* The static methods of this class are made available as functions in the scripts. This allows a script to use
* Semantics features.
*
* @author Christoph Weitkamp - Initial contribution
*/
@NonNullByDefault
public class Semantics {

/**
* Checks if the given {@link Item} is a {@link Location}.
*
* @param item the Item to check
* @return return true, if the given Item is a Location, false otherwise
*/
@ActionDoc(text = "checks if the given Item is is a Location")
public static boolean isLocation(Item item) {
return SemanticsActionService.isLocation(item);
}

/**
* Checks if the given {@link Item} is a {@link Equipment}.
*
* @param item the Item to check
* @return return true, if the given Item is an Equipment, false otherwise
*/
@ActionDoc(text = "checks if the given Item is is an Equipment")
public static boolean isEquipment(Item item) {
return SemanticsActionService.isEquipment(item);
}

/**
* Checks if the given {@link Item} is a {@link Point}.
*
* @param item the Item to check
* @return return true, if the given Item is a Point, false otherwise
*/
@ActionDoc(text = "checks if the given Item is is a Point")
public static boolean isPoint(Item item) {
return SemanticsActionService.isPoint(item);
}

/**
* Gets the related {@link Location} Item of an {@link Item}.
*
* @param item the Item to determine the Location for
* @return the related Location Item of the Item or null
*/
@ActionDoc(text = "gets the Location Item of the Item")
public static @Nullable Item getLocation(Item item) {
if (isLocation(item)) {
// if item is a location, return itself
return item;
} else {
// if item is not a location, iterate its groups and try to determine a location from them
return SemanticsActionService.getLocationItemFromGroupNames(item.getGroupNames());
}
}

/**
* Gets the related {@link Location} type of an {@link Item}.
*
* @param item the Item to determine the Location for
* @return the related Location type of the Item or null
*/
@ActionDoc(text = "gets the Location type of the Item")
public static @Nullable Class<? extends Location> getLocationType(Item item) {
Item locationItem = getLocation(item);
return locationItem != null ? SemanticTags.getLocation(locationItem) : null;
}

/**
* Gets the related {@link Equipment} Item an {@link Item} belongs to.
*
* @param item the Item to retrieve the Equipment Item for
* @return the related Equipment Item the Item belongs to or null
*/
@ActionDoc(text = "gets the Equipment Item an Item belongs to")
public static @Nullable Item getEquipment(Item item) {
if (isEquipment(item)) {
// if item is an equipment return its semantics equipment class
return item;
} else {
// if item is not an equipment, iterate its groups and try to determine a equipment there
return SemanticsActionService.getEquipmentItemFromGroupNames(item.getGroupNames());
}
}

/**
* Gets the {@link Equipment} type an {@link Item} relates to.
*
* @param item the Item to retrieve the Equipment for
* @return the Equipment the Item relates to or null
*/
@ActionDoc(text = "gets the Equipment type an Item belongs to")
public static @Nullable Class<? extends Equipment> getEquipmentType(Item item) {
Item equipmentItem = getEquipment(item);
return equipmentItem != null ? SemanticTags.getEquipment(equipmentItem) : null;

}

/**
* Gets the {@link Point} type an {@link Item}.
*
* @param item the Item to determine the Point for
* @return the Point type of the Item or null
*/
@ActionDoc(text = "gets the Point type of an Item")
public static @Nullable Class<? extends Point> getPointType(Item item) {
return isPoint(item) ? SemanticTags.getPoint(item) : null;
}

/**
* Gets the {@link Property} type an {@link Item} relates to.
*
* @param item the Item to retrieve the Property for
* @return the Property type the Item relates to or null
*/
@ActionDoc(text = "gets the Property type an Item relates to")
public static @Nullable Class<? extends Property> getPropertyType(Item item) {
return isPoint(item) ? SemanticTags.getProperty(item) : null;
}

/**
* Determines the semantic type of an {@link Item} (i.e. a sub-type of {@link Location}, {@link Equipment} or
* {@link Point}).
*
* @param item the Item to get the semantic type for
* @return a sub-type of Location, Equipment or Point
*/
@ActionDoc(text = "gets the semantic type of an Item")
public static @Nullable Class<? extends Tag> getSemanticType(Item item) {
return SemanticTags.getSemanticType(item);
}
}
Loading

0 comments on commit e8afeae

Please sign in to comment.