forked from openhab/openhab-addons
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract dynamic channel creation to separate classes.
Signed-off-by: Jacob Laursen <[email protected]>
- Loading branch information
Showing
4 changed files
with
488 additions
and
156 deletions.
There are no files selected for viewing
245 changes: 245 additions & 0 deletions
245
...main/java/org/openhab/binding/hdpowerview/internal/builders/AutomationChannelBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,245 @@ | ||
/** | ||
* 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.binding.hdpowerview.internal.builders; | ||
|
||
import java.time.DayOfWeek; | ||
import java.time.LocalTime; | ||
import java.time.format.TextStyle; | ||
import java.util.ArrayList; | ||
import java.util.EnumSet; | ||
import java.util.List; | ||
import java.util.StringJoiner; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; | ||
import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; | ||
import org.openhab.binding.hdpowerview.internal.api.responses.SceneCollections.SceneCollection; | ||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; | ||
import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents; | ||
import org.openhab.binding.hdpowerview.internal.api.responses.ScheduledEvents.ScheduledEvent; | ||
import org.openhab.core.library.CoreItemFactory; | ||
import org.openhab.core.thing.Channel; | ||
import org.openhab.core.thing.ChannelGroupUID; | ||
import org.openhab.core.thing.ChannelUID; | ||
import org.openhab.core.thing.binding.builder.ChannelBuilder; | ||
import org.openhab.core.thing.type.ChannelTypeUID; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* The {@link AutomationChannelBuilder} class creates automation channels | ||
* from structured scheduled event data. | ||
* | ||
* @author Jacob Laursen - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class AutomationChannelBuilder { | ||
|
||
private final Logger logger = LoggerFactory.getLogger(AutomationChannelBuilder.class); | ||
private final HDPowerViewTranslationProvider translationProvider; | ||
private final ChannelGroupUID channelGroupUid; | ||
private final ChannelTypeUID channelTypeUid = new ChannelTypeUID(HDPowerViewBindingConstants.BINDING_ID, | ||
HDPowerViewBindingConstants.CHANNELTYPE_AUTOMATION_ENABLED); | ||
|
||
private List<Channel> channels; | ||
private List<Scene> scenes; | ||
private List<SceneCollection> sceneCollections; | ||
private List<ScheduledEvent> scheduledEvents; | ||
|
||
public AutomationChannelBuilder(HDPowerViewTranslationProvider translationProvider, | ||
ChannelGroupUID channelGroupUid) { | ||
this.translationProvider = translationProvider; | ||
this.channelGroupUid = channelGroupUid; | ||
this.channels = new ArrayList<>(0); | ||
this.scheduledEvents = new ArrayList<>(0); | ||
this.scenes = new ArrayList<>(0); | ||
this.sceneCollections = new ArrayList<>(0); | ||
} | ||
|
||
/** | ||
* Creates an {@link AutomationChannelBuilder} for the given {@link HDPowerViewTranslationProvider} and | ||
* {@link ChannelGroupUID}. | ||
* | ||
* @param translationProvider the {@link HDPowerViewTranslationProvider} | ||
* @param channelGroupUid parent {@link ChannelGroupUID} for created channels | ||
* @return channel builder | ||
*/ | ||
public static AutomationChannelBuilder create(HDPowerViewTranslationProvider translationProvider, | ||
ChannelGroupUID channelGroupUid) { | ||
return new AutomationChannelBuilder(translationProvider, channelGroupUid); | ||
} | ||
|
||
/** | ||
* Adds created channels to existing list. | ||
* | ||
* @param channels list that channels will be added to | ||
* @return channel builder | ||
*/ | ||
public AutomationChannelBuilder withChannels(List<Channel> channels) { | ||
this.channels = channels; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the scenes. | ||
* | ||
* @param scenes the scenes | ||
* @return channel builder | ||
*/ | ||
public AutomationChannelBuilder withScenes(List<Scene> scenes) { | ||
this.scenes = scenes; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the scene collections. | ||
* | ||
* @param sceneCollections the scene collections | ||
* @return channel builder | ||
*/ | ||
public AutomationChannelBuilder withSceneCollections(List<SceneCollection> sceneCollections) { | ||
this.sceneCollections = sceneCollections; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the scheduled events. | ||
* | ||
* @param scheduledEvents the sceduled events | ||
* @return channel builder | ||
*/ | ||
public AutomationChannelBuilder withScheduledEvents(List<ScheduledEvent> scheduledEvents) { | ||
this.scheduledEvents = scheduledEvents; | ||
return this; | ||
} | ||
|
||
/** | ||
* Builds and returns the channels. | ||
* | ||
* @return the {@link Channel} list | ||
*/ | ||
public List<Channel> build() { | ||
scheduledEvents.stream().forEach(scheduledEvent -> { | ||
Channel channel = createChannel(scheduledEvent, scenes, sceneCollections); | ||
if (channel != null) { | ||
channels.add(channel); | ||
} | ||
}); | ||
|
||
return channels; | ||
} | ||
|
||
private @Nullable Channel createChannel(ScheduledEvent scheduledEvent, List<Scene> scenes, | ||
List<SceneCollection> sceneCollections) { | ||
String referencedName = getReferencedSceneOrSceneCollectionName(scheduledEvent, scenes, sceneCollections); | ||
if (referencedName == null) { | ||
return null; | ||
} | ||
ChannelUID channelUid = new ChannelUID(channelGroupUid, Integer.toString(scheduledEvent.id)); | ||
String label = getScheduledEventName(referencedName, scheduledEvent); | ||
String description = translationProvider.getText("dynamic-channel.automation-enabled.description", | ||
referencedName); | ||
Channel channel = ChannelBuilder.create(channelUid, CoreItemFactory.SWITCH).withType(channelTypeUid) | ||
.withLabel(label).withDescription(description).build(); | ||
|
||
return channel; | ||
} | ||
|
||
private @Nullable String getReferencedSceneOrSceneCollectionName(ScheduledEvent scheduledEvent, List<Scene> scenes, | ||
List<SceneCollection> sceneCollections) { | ||
if (scheduledEvent.sceneId > 0) { | ||
for (Scene scene : scenes) { | ||
if (scene.id == scheduledEvent.sceneId) { | ||
return scene.getName(); | ||
} | ||
} | ||
logger.error("Scene '{}' was not found for scheduled event '{}'", scheduledEvent.sceneId, | ||
scheduledEvent.id); | ||
return null; | ||
} else if (scheduledEvent.sceneCollectionId > 0) { | ||
for (SceneCollection sceneCollection : sceneCollections) { | ||
if (sceneCollection.id == scheduledEvent.sceneCollectionId) { | ||
return sceneCollection.getName(); | ||
} | ||
} | ||
logger.error("Scene collection '{}' was not found for scheduled event '{}'", | ||
scheduledEvent.sceneCollectionId, scheduledEvent.id); | ||
return null; | ||
} else { | ||
logger.error("Scheduled event '{}'' not related to any scene or scene collection", scheduledEvent.id); | ||
return null; | ||
} | ||
} | ||
|
||
private String getScheduledEventName(String sceneName, ScheduledEvent scheduledEvent) { | ||
String timeString, daysString; | ||
|
||
switch (scheduledEvent.eventType) { | ||
case ScheduledEvents.SCHEDULED_EVENT_TYPE_TIME: | ||
timeString = LocalTime.of(scheduledEvent.hour, scheduledEvent.minute).toString(); | ||
break; | ||
case ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNRISE: | ||
if (scheduledEvent.minute == 0) { | ||
timeString = translationProvider.getText("dynamic-channel.automation.at_sunrise"); | ||
} else if (scheduledEvent.minute < 0) { | ||
timeString = translationProvider.getText("dynamic-channel.automation.before_sunrise", | ||
getFormattedTimeOffset(-scheduledEvent.minute)); | ||
} else { | ||
timeString = translationProvider.getText("dynamic-channel.automation.after_sunrise", | ||
getFormattedTimeOffset(scheduledEvent.minute)); | ||
} | ||
break; | ||
case ScheduledEvents.SCHEDULED_EVENT_TYPE_SUNSET: | ||
if (scheduledEvent.minute == 0) { | ||
timeString = translationProvider.getText("dynamic-channel.automation.at_sunset"); | ||
} else if (scheduledEvent.minute < 0) { | ||
timeString = translationProvider.getText("dynamic-channel.automation.before_sunset", | ||
getFormattedTimeOffset(-scheduledEvent.minute)); | ||
} else { | ||
timeString = translationProvider.getText("dynamic-channel.automation.after_sunset", | ||
getFormattedTimeOffset(scheduledEvent.minute)); | ||
} | ||
break; | ||
default: | ||
return sceneName; | ||
} | ||
|
||
EnumSet<DayOfWeek> days = scheduledEvent.getDays(); | ||
if (EnumSet.allOf(DayOfWeek.class).equals(days)) { | ||
daysString = translationProvider.getText("dynamic-channel.automation.all-days"); | ||
} else if (ScheduledEvents.WEEKDAYS.equals(days)) { | ||
daysString = translationProvider.getText("dynamic-channel.automation.weekdays"); | ||
} else if (ScheduledEvents.WEEKENDS.equals(days)) { | ||
daysString = translationProvider.getText("dynamic-channel.automation.weekends"); | ||
} else { | ||
StringJoiner joiner = new StringJoiner(", "); | ||
days.forEach(day -> joiner.add(day.getDisplayName(TextStyle.SHORT, translationProvider.getLocale()))); | ||
daysString = joiner.toString(); | ||
} | ||
|
||
return translationProvider.getText("dynamic-channel.automation-enabled.label", sceneName, timeString, | ||
daysString); | ||
} | ||
|
||
private String getFormattedTimeOffset(int minutes) { | ||
if (minutes >= 60) { | ||
int remainder = minutes % 60; | ||
if (remainder == 0) { | ||
return translationProvider.getText("dynamic-channel.automation.hour", minutes / 60); | ||
} | ||
return translationProvider.getText("dynamic-channel.automation.hour-minute", minutes / 60, remainder); | ||
} | ||
return translationProvider.getText("dynamic-channel.automation.minute", minutes); | ||
} | ||
} |
104 changes: 104 additions & 0 deletions
104
.../src/main/java/org/openhab/binding/hdpowerview/internal/builders/SceneChannelBuilder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
/** | ||
* 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.binding.hdpowerview.internal.builders; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import org.eclipse.jdt.annotation.NonNullByDefault; | ||
import org.openhab.binding.hdpowerview.internal.HDPowerViewBindingConstants; | ||
import org.openhab.binding.hdpowerview.internal.HDPowerViewTranslationProvider; | ||
import org.openhab.binding.hdpowerview.internal.api.responses.Scenes.Scene; | ||
import org.openhab.core.library.CoreItemFactory; | ||
import org.openhab.core.thing.Channel; | ||
import org.openhab.core.thing.ChannelGroupUID; | ||
import org.openhab.core.thing.ChannelUID; | ||
import org.openhab.core.thing.binding.builder.ChannelBuilder; | ||
import org.openhab.core.thing.type.ChannelTypeUID; | ||
|
||
/** | ||
* The {@link SceneChannelBuilder} class creates scene channels | ||
* from structured scene data. | ||
* | ||
* @author Jacob Laursen - Initial contribution | ||
*/ | ||
@NonNullByDefault | ||
public class SceneChannelBuilder { | ||
|
||
private final HDPowerViewTranslationProvider translationProvider; | ||
private final ChannelGroupUID channelGroupUid; | ||
private final ChannelTypeUID channelTypeUid = new ChannelTypeUID(HDPowerViewBindingConstants.BINDING_ID, | ||
HDPowerViewBindingConstants.CHANNELTYPE_SCENE_ACTIVATE); | ||
|
||
private List<Channel> channels; | ||
private List<Scene> scenes; | ||
|
||
public SceneChannelBuilder(HDPowerViewTranslationProvider translationProvider, ChannelGroupUID channelGroupUid) { | ||
this.translationProvider = translationProvider; | ||
this.channelGroupUid = channelGroupUid; | ||
this.channels = new ArrayList<>(0); | ||
this.scenes = new ArrayList<>(0); | ||
} | ||
|
||
/** | ||
* Creates an {@link SceneChannelBuilder} for the given {@link HDPowerViewTranslationProvider} and | ||
* {@link ChannelGroupUID}. | ||
* | ||
* @param translationProvider the {@link HDPowerViewTranslationProvider} | ||
* @param channelGroupUid parent {@link ChannelGroupUID} for created channels | ||
* @return channel builder | ||
*/ | ||
public static SceneChannelBuilder create(HDPowerViewTranslationProvider translationProvider, | ||
ChannelGroupUID channelGroupUid) { | ||
return new SceneChannelBuilder(translationProvider, channelGroupUid); | ||
} | ||
|
||
/** | ||
* Adds created channels to existing list. | ||
* | ||
* @param channels list that channels will be added to | ||
* @return channel builder | ||
*/ | ||
public SceneChannelBuilder withChannels(List<Channel> channels) { | ||
this.channels = channels; | ||
return this; | ||
} | ||
|
||
/** | ||
* Sets the scenes. | ||
* | ||
* @param scenes the scenes | ||
* @return channel builder | ||
*/ | ||
public SceneChannelBuilder withScenes(List<Scene> scenes) { | ||
this.scenes = scenes; | ||
return this; | ||
} | ||
|
||
/** | ||
* Builds and returns the channels. | ||
* | ||
* @return the {@link Channel} list | ||
*/ | ||
public List<Channel> build() { | ||
scenes.stream().sorted().forEach(scene -> channels.add(createChannel(scene))); | ||
return channels; | ||
} | ||
|
||
private Channel createChannel(Scene scene) { | ||
ChannelUID channelUid = new ChannelUID(channelGroupUid, Integer.toString(scene.id)); | ||
String description = translationProvider.getText("dynamic-channel.scene-activate.description", scene.getName()); | ||
return ChannelBuilder.create(channelUid, CoreItemFactory.SWITCH).withType(channelTypeUid) | ||
.withLabel(scene.getName()).withDescription(description).build(); | ||
} | ||
} |
Oops, something went wrong.