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

[insteon] Improvements for OH3 #13310

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1,152 changes: 594 additions & 558 deletions bundles/org.openhab.binding.insteon/README.md

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Expand Up @@ -12,101 +12,73 @@
*/
package org.openhab.binding.insteon.internal;

import java.io.File;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.OpenHAB;
import org.openhab.core.thing.ThingTypeUID;

/**
* The {@link InsteonBindingConstants} class defines common constants, which are
* used across the whole binding.
*
* @author Rob Nielsen - Initial contribution
* @author Jeremy Setton - Improvements for openHAB 3 insteon binding
*/
@NonNullByDefault
public class InsteonBindingConstants {
public static final String BINDING_ID = "insteon";
public static final String BINDING_DATA_DIR = OpenHAB.getUserDataFolder() + File.separator + BINDING_ID;

// List of all Thing Type UIDs
public static final ThingTypeUID DEVICE_THING_TYPE = new ThingTypeUID(BINDING_ID, "device");
public static final ThingTypeUID NETWORK_THING_TYPE = new ThingTypeUID(BINDING_ID, "network");
public static final ThingTypeUID THING_TYPE_DEVICE = new ThingTypeUID(BINDING_ID, "device");
public static final ThingTypeUID THING_TYPE_HUB1 = new ThingTypeUID(BINDING_ID, "hub1");
public static final ThingTypeUID THING_TYPE_HUB2 = new ThingTypeUID(BINDING_ID, "hub2");
public static final ThingTypeUID THING_TYPE_PLM = new ThingTypeUID(BINDING_ID, "plm");
public static final ThingTypeUID THING_TYPE_SCENE = new ThingTypeUID(BINDING_ID, "scene");
public static final ThingTypeUID THING_TYPE_X10 = new ThingTypeUID(BINDING_ID, "x10");

public static final Set<ThingTypeUID> DISCOVERABLE_THING_TYPES_UIDS = Set.of(THING_TYPE_DEVICE, THING_TYPE_SCENE);

public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Set.of(THING_TYPE_DEVICE, THING_TYPE_HUB1,
THING_TYPE_HUB2, THING_TYPE_PLM, THING_TYPE_SCENE, THING_TYPE_X10);

// List of all Thing properties
public static final String PROPERTY_DEVICE_ADDRESS = "address";
public static final String PROPERTY_DEVICE_TYPE = "deviceType";
public static final String PROPERTY_ENGINE_VERSION = "engineVersion";
public static final String PROPERTY_PRODUCT_ID = "productId";
public static final String PROPERTY_SCENE_GROUP = "group";

// List of all channel parameters
public static final String PARAMETER_GROUP = "group";
public static final String PARAMETER_ON_LEVEL = "onLevel";
public static final String PARAMETER_RAMP_RATE = "rampRate";

// List of specific device features
public static final String FEATURE_DATABASE_DELTA = "databaseDelta";
public static final String FEATURE_HEARTBEAT_MONITOR = "heartbeatMonitor";
public static final String FEATURE_INSTEON_ENGINE = "insteonEngine";
public static final String FEATURE_LED_CONTROL = "ledControl";
public static final String FEATURE_LED_ON_OFF = "ledOnOff";
public static final String FEATURE_OFF_MASK = "offMask";
public static final String FEATURE_ON_LEVEL = "onLevel";
public static final String FEATURE_ON_MASK = "onMask";
public static final String FEATURE_PING = "ping";
public static final String FEATURE_RAMP_RATE = "rampRate";
public static final String FEATURE_STAY_AWAKE = "stayAwake";
public static final String FEATURE_SYSTEM_MODE = "systemMode";
public static final String FEATURE_TEMPERATURE_FORMAT = "temperatureFormat";
public static final String FEATURE_TOGGLE_MODE = "toggleMode";

// List of specific device types
public static final String CLIMATE_CONTROL_VENSTAR_THERMOSTAT = "ClimateControl_VenstarThermostat";

// List of all Channel ids
public static final String AC_DELAY = "acDelay";
public static final String BACKLIGHT_DURATION = "backlightDuration";
public static final String BATTERY_LEVEL = "batteryLevel";
public static final String BATTERY_PERCENT = "batteryPercent";
public static final String BATTERY_WATERMARK_LEVEL = "batteryWatermarkLevel";
public static final String BEEP = "beep";
public static final String BOTTOM_OUTLET = "bottomOutlet";
public static final String BUTTON_A = "buttonA";
public static final String BUTTON_B = "buttonB";
public static final String BUTTON_C = "buttonC";
public static final String BUTTON_D = "buttonD";
public static final String BUTTON_E = "buttonE";
public static final String BUTTON_F = "buttonF";
public static final String BUTTON_G = "buttonG";
public static final String BUTTON_H = "buttonH";
public static final String BROADCAST_ON_OFF = "broadcastOnOff";
public static final String CONTACT = "contact";
public static final String COOL_SET_POINT = "coolSetPoint";
public static final String DIMMER = "dimmer";
public static final String FAN = "fan";
public static final String FAN_MODE = "fanMode";
public static final String FAST_ON_OFF = "fastOnOff";
public static final String FAST_ON_OFF_BUTTON_A = "fastOnOffButtonA";
public static final String FAST_ON_OFF_BUTTON_B = "fastOnOffButtonB";
public static final String FAST_ON_OFF_BUTTON_C = "fastOnOffButtonC";
public static final String FAST_ON_OFF_BUTTON_D = "fastOnOffButtonD";
public static final String FAST_ON_OFF_BUTTON_E = "fastOnOffButtonE";
public static final String FAST_ON_OFF_BUTTON_F = "fastOnOffButtonF";
public static final String FAST_ON_OFF_BUTTON_G = "fastOnOffButtonG";
public static final String FAST_ON_OFF_BUTTON_H = "fastOnOffButtonH";
public static final String HEAT_SET_POINT = "heatSetPoint";
public static final String HUMIDITY = "humidity";
public static final String HUMIDITY_HIGH = "humidityHigh";
public static final String HUMIDITY_LOW = "humidityLow";
public static final String IS_COOLING = "isCooling";
public static final String IS_HEATING = "isHeating";
public static final String KEYPAD_BUTTON_A = "keypadButtonA";
public static final String KEYPAD_BUTTON_B = "keypadButtonB";
public static final String KEYPAD_BUTTON_C = "keypadButtonC";
public static final String KEYPAD_BUTTON_D = "keypadButtonD";
public static final String KEYPAD_BUTTON_E = "keypadButtonE";
public static final String KEYPAD_BUTTON_F = "keypadButtonF";
public static final String KEYPAD_BUTTON_G = "keypadButtonG";
public static final String KEYPAD_BUTTON_H = "keypadButtonH";
public static final String KWH = "kWh";
public static final String LAST_HEARD_FROM = "lastHeardFrom";
public static final String LED_BRIGHTNESS = "ledBrightness";
public static final String LED_ONOFF = "ledOnOff";
public static final String LIGHT_DIMMER = "lightDimmer";
public static final String LIGHT_LEVEL = "lightLevel";
public static final String LIGHT_LEVEL_ABOVE_THRESHOLD = "lightLevelAboveThreshold";
public static final String LOAD_DIMMER = "loadDimmer";
public static final String LOAD_SWITCH = "loadSwitch";
public static final String LOAD_SWITCH_FAST_ON_OFF = "loadSwitchFastOnOff";
public static final String LOAD_SWITCH_MANUAL_CHANGE = "loadSwitchManualChange";
public static final String LOWBATTERY = "lowBattery";
public static final String MANUAL_CHANGE = "manualChange";
public static final String MANUAL_CHANGE_BUTTON_A = "manualChangeButtonA";
public static final String MANUAL_CHANGE_BUTTON_B = "manualChangeButtonB";
public static final String MANUAL_CHANGE_BUTTON_C = "manualChangeButtonC";
public static final String MANUAL_CHANGE_BUTTON_D = "manualChangeButtonD";
public static final String MANUAL_CHANGE_BUTTON_E = "manualChangeButtonE";
public static final String MANUAL_CHANGE_BUTTON_F = "manualChangeButtonF";
public static final String MANUAL_CHANGE_BUTTON_G = "manualChangeButtonG";
public static final String MANUAL_CHANGE_BUTTON_H = "manualChangeButtonH";
public static final String NOTIFICATION = "notification";
public static final String ON_LEVEL = "onLevel";
public static final String RAMP_DIMMER = "rampDimmer";
public static final String RAMP_RATE = "rampRate";
public static final String RESET = "reset";
public static final String STAGE1_DURATION = "stage1Duration";
public static final String SWITCH = "switch";
public static final String SYSTEM_MODE = "systemMode";
public static final String TAMPER_SWITCH = "tamperSwitch";
public static final String TEMPERATURE = "temperature";
public static final String TEMPERATURE_LEVEL = "temperatureLevel";
public static final String TOP_OUTLET = "topOutlet";
public static final String UPDATE = "update";
public static final String WATTS = "watts";
// Map of custom state description options
public static final Map<String, String[]> CUSTOM_STATE_DESCRIPTION_OPTIONS = Map.of(
// Venstar Thermostat System Mode
CLIMATE_CONTROL_VENSTAR_THERMOSTAT + ":" + FEATURE_SYSTEM_MODE,
new String[] { "OFF", "HEAT", "COOL", "AUTO", "PROGRAM_HEAT", "PROGRAM_COOL", "PROGRAM_AUTO" });
}
Expand Up @@ -14,21 +14,20 @@

import static org.openhab.binding.insteon.internal.InsteonBindingConstants.*;

import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.insteon.internal.discovery.InsteonDeviceDiscoveryService;
import org.openhab.binding.insteon.internal.discovery.InsteonDiscoveryService;
import org.openhab.binding.insteon.internal.handler.InsteonBridgeHandler;
import org.openhab.binding.insteon.internal.handler.InsteonDeviceHandler;
import org.openhab.binding.insteon.internal.handler.InsteonNetworkHandler;
import org.openhab.binding.insteon.internal.handler.InsteonSceneHandler;
import org.openhab.binding.insteon.internal.handler.X10DeviceHandler;
import org.openhab.core.config.discovery.DiscoveryService;
import org.openhab.core.io.transport.serial.SerialPortManager;
import org.openhab.core.storage.StorageService;
import org.openhab.core.thing.Bridge;
import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
Expand All @@ -37,6 +36,7 @@
import org.openhab.core.thing.binding.ThingHandler;
import org.openhab.core.thing.binding.ThingHandlerFactory;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

Expand All @@ -45,26 +45,24 @@
* handlers.
*
* @author Rob Nielsen - Initial contribution
* @author Jeremy Setton - Improvements for openHAB 3 insteon binding
*/
@NonNullByDefault
@Component(configurationPid = "binding.insteon", service = ThingHandlerFactory.class)
public class InsteonHandlerFactory extends BaseThingHandlerFactory {

private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES_UIDS = Collections
.unmodifiableSet(Stream.of(DEVICE_THING_TYPE, NETWORK_THING_TYPE).collect(Collectors.toSet()));

private final SerialPortManager serialPortManager;
private final InsteonStateDescriptionProvider stateDescriptionProvider;
private final StorageService storageService;
private final Map<ThingUID, ServiceRegistration<?>> discoveryServiceRegs = new HashMap<>();
private final Map<ThingUID, ServiceRegistration<?>> serviceRegs = new HashMap<>();

private @Nullable SerialPortManager serialPortManager;

@Reference
protected void setSerialPortManager(final SerialPortManager serialPortManager) {
@Activate
public InsteonHandlerFactory(final @Reference SerialPortManager serialPortManager,
final @Reference InsteonStateDescriptionProvider stateDescriptionProvider,
final @Reference StorageService storageService) {
this.serialPortManager = serialPortManager;
}

protected void unsetSerialPortManager(final SerialPortManager serialPortManager) {
this.serialPortManager = null;
this.stateDescriptionProvider = stateDescriptionProvider;
this.storageService = storageService;
}

@Override
Expand All @@ -76,40 +74,39 @@ public boolean supportsThingType(ThingTypeUID thingTypeUID) {
protected @Nullable ThingHandler createHandler(Thing thing) {
ThingTypeUID thingTypeUID = thing.getThingTypeUID();

if (NETWORK_THING_TYPE.equals(thingTypeUID)) {
InsteonNetworkHandler insteonNetworkHandler = new InsteonNetworkHandler((Bridge) thing, serialPortManager);
registerServices(insteonNetworkHandler);

return insteonNetworkHandler;
} else if (DEVICE_THING_TYPE.equals(thingTypeUID)) {
return new InsteonDeviceHandler(thing);
if (THING_TYPE_HUB1.equals(thingTypeUID) || THING_TYPE_HUB2.equals(thingTypeUID)) {
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, storageService);
registerDiscoveryService(handler);
return handler;
} else if (THING_TYPE_PLM.equals(thingTypeUID)) {
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, serialPortManager, storageService);
registerDiscoveryService(handler);
return handler;
} else if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
return new InsteonDeviceHandler(thing, stateDescriptionProvider);
} else if (THING_TYPE_SCENE.equals(thingTypeUID)) {
return new InsteonSceneHandler(thing);
} else if (THING_TYPE_X10.equals(thingTypeUID)) {
return new X10DeviceHandler(thing);
}

return null;
}

private synchronized void registerDiscoveryService(InsteonBridgeHandler handler) {
InsteonDiscoveryService discoveryService = new InsteonDiscoveryService(handler);
discoveryServiceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
}

@Override
protected synchronized void removeHandler(ThingHandler thingHandler) {
if (thingHandler instanceof InsteonNetworkHandler) {
if (thingHandler instanceof InsteonBridgeHandler) {
ThingUID uid = thingHandler.getThing().getUID();
ServiceRegistration<?> serviceRegs = this.serviceRegs.remove(uid);
if (serviceRegs != null) {
serviceRegs.unregister();
}

ServiceRegistration<?> discoveryServiceRegs = this.discoveryServiceRegs.remove(uid);
if (discoveryServiceRegs != null) {
discoveryServiceRegs.unregister();
ServiceRegistration<?> discoveryServiceReg = discoveryServiceRegs.remove(uid);
if (discoveryServiceReg != null) {
discoveryServiceReg.unregister();
}
}
}

private synchronized void registerServices(InsteonNetworkHandler handler) {
this.serviceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(InsteonNetworkHandler.class.getName(), handler, new Hashtable<>()));

InsteonDeviceDiscoveryService discoveryService = new InsteonDeviceDiscoveryService(handler);
this.discoveryServiceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
}
}
@@ -0,0 +1,42 @@
/**
* Copyright (c) 2010-2022 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.insteon.internal;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.events.EventPublisher;
import org.openhab.core.thing.binding.BaseDynamicStateDescriptionProvider;
import org.openhab.core.thing.i18n.ChannelTypeI18nLocalizationService;
import org.openhab.core.thing.link.ItemChannelLinkRegistry;
import org.openhab.core.thing.type.DynamicStateDescriptionProvider;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

/**
* Dynamic provider of state options for Insteon
*
* @author Jeremy Setton - Initial contribution
*/
@Component(service = { DynamicStateDescriptionProvider.class, InsteonStateDescriptionProvider.class })
@NonNullByDefault
public class InsteonStateDescriptionProvider extends BaseDynamicStateDescriptionProvider {

@Activate
public InsteonStateDescriptionProvider(final @Reference EventPublisher eventPublisher,
final @Reference ItemChannelLinkRegistry itemChannelLinkRegistry,
final @Reference ChannelTypeI18nLocalizationService channelTypeI18nLocalizationService) {
this.eventPublisher = eventPublisher;
this.itemChannelLinkRegistry = itemChannelLinkRegistry;
this.channelTypeI18nLocalizationService = channelTypeI18nLocalizationService;
}
}