Skip to content

Commit

Permalink
[insteon] Rewrite insteon binding
Browse files Browse the repository at this point in the history
* introduced device configuration automated determination
* converted mode-based number items to string type with descriptive states
* added number items uom support
* added scenes and x10 device things
* added distinct bridge things for supported hub/plm devices
* added button event trigger channels
* added device products configuration layer
* added device link database support
* added device cache storage
* added device operating flags controls
* added modem configuration flags controls
* added related devices synchronization feature
* added heartbeat timeout monitor
* added ability to link/unlink a device to the modem
* added ability to add missing default links
* added link database & scene management support
* added scene state support
* added new i3 devices basic support
* added ezrain sprinkler device support
* revamped console commands with auto-completion support
* improved discovery service
* improved thing status

Signed-off-by: jsetton <jeremy.setton@gmail.com>
  • Loading branch information
jsetton committed Jul 26, 2024
1 parent 6a58133 commit 41db1f9
Show file tree
Hide file tree
Showing 144 changed files with 31,512 additions and 3,193 deletions.
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
/bundles/org.openhab.binding.icalendar/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.icloud/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.ihc/ @paulianttila
/bundles/org.openhab.binding.insteon/ @openhab/add-ons-maintainers
/bundles/org.openhab.binding.insteon/ @jsetton
/bundles/org.openhab.binding.intesis/ @hmerk
/bundles/org.openhab.binding.iotawatt/ @PRosenb
/bundles/org.openhab.binding.ipcamera/ @Skinah
Expand Down
1,732 changes: 1,163 additions & 569 deletions bundles/org.openhab.binding.insteon/README.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/**
* Copyright (c) 2010-2024 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 java.io.File;
import java.util.Map;
import java.util.Set;

import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.binding.insteon.internal.device.feature.FeatureEnums.VenstarSystemMode;
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 - Rewrite 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 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 ThingTypeUID THING_TYPE_LEGACY_DEVICE = new ThingTypeUID(BINDING_ID, "legacy-device");
public static final ThingTypeUID THING_TYPE_LEGACY_NETWORK = new ThingTypeUID(BINDING_ID, "network");

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

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, THING_TYPE_LEGACY_DEVICE,
THING_TYPE_LEGACY_NETWORK);

// 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 feature names
public static final String FEATURE_DATABASE_DELTA = "databaseDelta";
public static final String FEATURE_HEARTBEAT = "heartbeat";
public static final String FEATURE_HEARTBEAT_INTERVAL = "heartbeatInterval";
public static final String FEATURE_HEARTBEAT_ON_OFF = "heartbeatOnOff";
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_LINK_FF_GROUP = "linkFFGroup";
public static final String FEATURE_LOW_BATTERY_THRESHOLD = "lowBatteryThreshold";
public static final String FEATURE_ON_LEVEL = "onLevel";
public static final String FEATURE_PING = "ping";
public static final String FEATURE_RAMP_RATE = "rampRate";
public static final String FEATURE_SCENE_ON_OFF = "sceneOnOff";
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_TWO_GROUPS = "2Groups";

// List of specific device feature types
public static final String FEATURE_TYPE_FANLINC_FAN = "FanLincFan";
public static final String FEATURE_TYPE_GENERIC_DIMMER = "GenericDimmer";
public static final String FEATURE_TYPE_GENERIC_SWITCH = "GenericSwitch";
public static final String FEATURE_TYPE_KEYPAD_BUTTON = "KeypadButton";
public static final String FEATURE_TYPE_KEYPAD_BUTTON_OFF_MASK = "KeypadButtonOffMask";
public static final String FEATURE_TYPE_KEYPAD_BUTTON_ON_MASK = "KeypadButtonOnMask";
public static final String FEATURE_TYPE_KEYPAD_BUTTON_TOGGLE_MODE = "KeypadButtonToggleMode";
public static final String FEATURE_TYPE_OUTLET_SWITCH = "OutletSwitch";
public static final String FEATURE_TYPE_THERMOSTAT_FAN_MODE = "ThermostatFanMode";
public static final String FEATURE_TYPE_THERMOSTAT_SYSTEM_MODE = "ThermostatSystemMode";
public static final String FEATURE_TYPE_THERMOSTAT_COOL_SETPOINT = "ThermostatCoolSetPoint";
public static final String FEATURE_TYPE_THERMOSTAT_HEAT_SETPOINT = "ThermostatHeatSetPoint";
public static final String FEATURE_TYPE_VENSTAR_FAN_MODE = "VenstarFanMode";
public static final String FEATURE_TYPE_VENSTAR_SYSTEM_MODE = "VenstarSystemMode";
public static final String FEATURE_TYPE_VENSTAR_COOL_SETPOINT = "VenstarCoolSetPoint";
public static final String FEATURE_TYPE_VENSTAR_HEAT_SETPOINT = "VenstarHeatSetPoint";

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

// Map of custom state description options
public static final Map<String, String[]> CUSTOM_STATE_DESCRIPTION_OPTIONS = Map.ofEntries(
// Venstar Thermostat System Mode
Map.entry(DEVICE_TYPE_CLIMATE_CONTROL_VENSTAR_THERMOSTAT + ":" + FEATURE_SYSTEM_MODE,
VenstarSystemMode.names().toArray(String[]::new)));
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,36 @@
*/
package org.openhab.binding.insteon.internal;

import static org.openhab.binding.insteon.internal.InsteonLegacyBindingConstants.*;
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.InsteonDiscoveryService;
import org.openhab.binding.insteon.internal.discovery.InsteonLegacyDiscoveryService;
import org.openhab.binding.insteon.internal.handler.InsteonBridgeHandler;
import org.openhab.binding.insteon.internal.handler.InsteonDeviceHandler;
import org.openhab.binding.insteon.internal.handler.InsteonLegacyDeviceHandler;
import org.openhab.binding.insteon.internal.handler.InsteonLegacyNetworkHandler;
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.ThingManager;
import org.openhab.core.thing.ThingRegistry;
import org.openhab.core.thing.ThingTypeUID;
import org.openhab.core.thing.ThingUID;
import org.openhab.core.thing.binding.BaseThingHandlerFactory;
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 +50,29 @@
* handlers.
*
* @author Rob Nielsen - Initial contribution
* @author Jeremy Setton - Rewrite 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 ThingManager thingManager;
private final ThingRegistry thingRegistry;
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, final @Reference ThingManager thingManager,
final @Reference ThingRegistry thingRegistry) {
this.serialPortManager = serialPortManager;
}

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

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

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

return insteonNetworkHandler;
} else if (DEVICE_THING_TYPE.equals(thingTypeUID)) {
if (THING_TYPE_HUB1.equals(thingTypeUID) || THING_TYPE_HUB2.equals(thingTypeUID)
|| THING_TYPE_PLM.equals(thingTypeUID)) {
InsteonBridgeHandler handler = new InsteonBridgeHandler((Bridge) thing, serialPortManager, storageService,
thingRegistry);
InsteonDiscoveryService service = new InsteonDiscoveryService(handler);
registerDiscoveryService(handler, service);
return handler;
} else if (THING_TYPE_LEGACY_NETWORK.equals(thingTypeUID)) {
InsteonLegacyNetworkHandler handler = new InsteonLegacyNetworkHandler((Bridge) thing, serialPortManager,
thingManager, thingRegistry);
InsteonLegacyDiscoveryService service = new InsteonLegacyDiscoveryService(handler);
registerDiscoveryService(handler, service);
return handler;
} else if (THING_TYPE_DEVICE.equals(thingTypeUID)) {
return new InsteonDeviceHandler(thing, stateDescriptionProvider);
} else if (THING_TYPE_LEGACY_DEVICE.equals(thingTypeUID)) {
return new InsteonLegacyDeviceHandler(thing);
} else if (THING_TYPE_SCENE.equals(thingTypeUID)) {
return new InsteonSceneHandler(thing);
} else if (THING_TYPE_X10.equals(thingTypeUID)) {
return new X10DeviceHandler(thing);
}

return null;
}

@Override
protected synchronized void removeHandler(ThingHandler thingHandler) {
if (thingHandler instanceof InsteonLegacyNetworkHandler) {
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();
}
protected synchronized void removeHandler(ThingHandler handler) {
ServiceRegistration<?> serviceReg = discoveryServiceRegs.remove(handler.getThing().getUID());
if (serviceReg != null) {
serviceReg.unregister();
}
}

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

InsteonLegacyDiscoveryService discoveryService = new InsteonLegacyDiscoveryService(handler);
this.discoveryServiceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), discoveryService, new Hashtable<>()));
private synchronized void registerDiscoveryService(ThingHandler handler, DiscoveryService service) {
discoveryServiceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
}
}
Loading

0 comments on commit 41db1f9

Please sign in to comment.