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] Rewrite with backward compatibility #17146

Merged
merged 26 commits into from
Oct 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a2ef429
[insteon] Restructure legacy code for rewrite
jsetton Jul 25, 2024
229c1ac
[insteon] Rewrite insteon binding
jsetton Jul 25, 2024
2f25a14
[insteon] Code review changes
jsetton Sep 14, 2024
5b7059f
[insteon] Rename channels and resource files per naming convention
jsetton Sep 16, 2024
9bf75c8
[insteon] Remove unnecessary logging enabled check
jsetton Sep 17, 2024
d0f4d9b
[insteon] Fix link db read write mode for i2 devices
jsetton Sep 17, 2024
beabb83
[insteon] Shorten bridge discovery enabled parameter labels
jsetton Sep 18, 2024
3c1c83e
[insteon] Rename fanlinc fan feature cmd handler and enum
jsetton Sep 18, 2024
8860ed0
[insteon] Fix message factory remaining buffer logging
jsetton Sep 18, 2024
39434b1
[insteon] Use engine for console extended message ckecksum
jsetton Sep 18, 2024
d399c64
[insteon] Revert light level channel name change
jsetton Sep 18, 2024
befbfad
[insteon] Update channel labels and descriptions
jsetton Sep 20, 2024
ed1f160
[insteon] Add migration guide and debug console commands
jsetton Sep 20, 2024
c1835e6
[insteon] Fix sat report logger static field
jsetton Sep 20, 2024
a416cf1
[Insteon] Fix some channel descriptions
jsetton Sep 20, 2024
d44af3a
[insteon] Extend legacy loader classes from resource loader
jsetton Sep 21, 2024
fe78048
[insteon] Rename base feature handler class
jsetton Sep 21, 2024
b1fbc58
[insteon] Reduce debug logging
jsetton Sep 21, 2024
df47a05
[insteon] Update migration guide
jsetton Sep 21, 2024
dc5e52a
[insteon] Update discovery parameter labels and descriptions
jsetton Sep 21, 2024
881e2f2
[insteon] Update thing status details per documentation
jsetton Oct 1, 2024
4096e4e
[insteon] Fix modem db reader restart on disconnect
jsetton Oct 4, 2024
e8a252f
[insteon] Add scene interface
jsetton Oct 4, 2024
b68b10a
[insteon] Code review additional changes
jsetton Oct 6, 2024
e69cbf9
[insteon] Fix markdown warnings
jsetton Oct 6, 2024
f11860d
[insteon] Update legacy classes meaningful names
jsetton Oct 7, 2024
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
2 changes: 1 addition & 1 deletion CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,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,851 changes: 1,283 additions & 568 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
Expand Up @@ -12,101 +12,99 @@
*/
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_SCALE = "temperatureScale";
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 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");
// List of specific device types
public static final String DEVICE_TYPE_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.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 @@ -14,29 +14,34 @@

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.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.InsteonNetworkHandler;
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,40 +84,42 @@ 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)
|| 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 InsteonNetworkHandler) {
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(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<>()));
private synchronized void registerDiscoveryService(ThingHandler handler, DiscoveryService service) {
discoveryServiceRegs.put(handler.getThing().getUID(),
bundleContext.registerService(DiscoveryService.class.getName(), service, new Hashtable<>()));
}
}
Loading