* Added new channel: * secondActionPressed: Indicates if second action of rocker switch is pressed too * Added two new profiles for channel rockerSwitchAction: * rockerswitchaction-toggle-switch * rockerswitchaction-toggle-player * EnOceanSensorHandler can now handle extensible channels too * EEP F6-02 refactoring Also-by: Dietmar Franzen <dfranzen@fb3.fra-uas.de> Signed-off-by: Daniel Weber <uni@fruggy.de>
This commit is contained in:
parent
cc92423d90
commit
4b13a26f15
@ -76,7 +76,7 @@ Hence if your device supports one of the following EEPs the chances are good tha
|
||||
|---------------------------------|-------------|---------------|------------------------------|--------------------------------|-----------|
|
||||
| bridge | - | - | repeaterMode, setBaseId | USB300, EnOceanPi | - |
|
||||
| pushButton | F6-01/D2-03 | 0x01/0x0A | pushButton, doublePress,<br/>longPress, batteryLevel | NodOn soft button | Manually/Discovery |
|
||||
| rockerSwitch | F6-02 | 0x01-02 | rockerswitchA, rockerswitchB | Eltako FT55 | Discovery |
|
||||
| rockerSwitch | F6-02 | 0x01-02 | rockerswitchA, rockerswitchB,<br/>rockerSwitchAction | Eltako FT55 | Discovery |
|
||||
| mechanicalHandle | F6-10 | 0x00-01 | windowHandleState, contact | Hoppe SecuSignal handles, Eltako TF-FGB | Discovery |
|
||||
| contact | D5-00 | 0x01 | contact | Eltako FTK(E) & TF-FKB | Discovery |
|
||||
| temperatureSensor | A5-02 | 0x01-30 | temperature | Thermokon SR65 | Discovery |
|
||||
@ -102,6 +102,9 @@ Hence if your device supports one of the following EEPs the chances are good tha
|
||||
Furthermore following supporting EEP family is available too: A5-11, types 0x03 (rollershutter position status), 0x04 (extended light status) and D0-06 (battery level indication).
|
||||
|
||||
A `rockerSwitch` is used to receive messages from a physical EnOcean Rocker Switch.
|
||||
Channel `rockerswitchA` and `rockerswitchB` just react if corresponding rocker switch channel is pressed as single action.
|
||||
These channels do not emit an event if ChannelA and ChannelB are pressed simultaneously.
|
||||
To handle simultaneously pressed channels you have to use the `rockerSwitchAction` channel.
|
||||
A `classicDevice` is used for older EnOcean devices which react only on rocker switch messages (like Opus GN-A-R12V-SR-4).
|
||||
As these devices do not send their current status, you have to add additional listener channels for each physical Rocker Switch to your thing.
|
||||
In this way you can still sync your item status with the physical status of your device whenever it gets modified by a physical rocker switch.
|
||||
@ -258,6 +261,7 @@ The channels of a thing are determined automatically based on the chosen EEP.
|
||||
| doublePress | Trigger | Channel type system:rawbutton, emits PRESSED |
|
||||
| longPress | Trigger | Channel type system:rawbutton, emits PRESSED and RELEASED events |
|
||||
| rockerswitchA/B | Trigger | Channel type system:rawrocker, emits DIR1_PRESSED, DIR1_RELEASED, DIR2_PRESSED, DIR2_RELEASED events |
|
||||
| rockerSwitchAction | Trigger | Emits combined rocker switch actions for channel A and B and RELEASED events |
|
||||
| windowHandleState | String | Textual representation of handle position (OPEN, CLOSED, TILTED) |
|
||||
| windowSashState | String | Textual representation of sash position (OPEN, CLOSED, TILTED) |
|
||||
| windowCalibrationState | String | Textual representation of the calibration state (OK, ERROR, INVALID) |
|
||||
@ -372,6 +376,14 @@ then
|
||||
end
|
||||
```
|
||||
|
||||
If you also want to react to simultaneously pressed channels you have to use the `rockerSwitchAction` channel.
|
||||
This channel emits events in the following form "DirectionChannelA|DirectionChannelB" (for example "Dir1|Dir2").
|
||||
If a channel is not pressed a "-" is emitted.
|
||||
To bind this channel to an item you have to use the `rockerswitchaction-toggle-switch` or the `rockerswitchaction-toggle-player` profile.
|
||||
To define for which button press combination the linked item should toggle you have to set the configuration parameters `channelAFilter` and `channelBFilter` accordingly.
|
||||
The options for these parameters are "*" (any direction), "Dir1", "Dir2", "-" (corresponding channel not pressed at all).
|
||||
An example can be found below.
|
||||
|
||||
## Example
|
||||
|
||||
```xtend
|
||||
@ -399,6 +411,7 @@ Bridge enocean:bridge:gtwy "EnOcean Gateway" [ path="/dev/ttyAMA0" ] {
|
||||
|
||||
```xtend
|
||||
Player Kitchen_Sonos "Sonos" (Kitchen) {channel="sonos:PLAY1:ID:control", channel="enocean:rockerSwitch:gtwy:rs01:rockerswitchA" [profile="system:rawrocker-to-play-pause"]}
|
||||
Switch Light_Switch { channel="enocean:rockerSwitch:gtwy:rs01:rockerSwitchAction" [profile="enocean:rockerswitchaction-toggle-switch", channelAFilter="DIR1", channelBFilter="DIR1"]}
|
||||
Dimmer Kitchen_Hue "Hue" <light> {channel="enocean:rockerSwitch:gtwy:rs01:rockerswitchB" [profile="system:rawrocker-to-dimmer"], channel="hue:0220:0017884f6626:9:brightness"}
|
||||
Rollershutter Kitchen_Rollershutter "Roller shutter" <blinds> (Kitchen) {channel="enocean:rollershutter:gtwy:r01:rollershutter", autoupdate="false"}
|
||||
Switch Garage_Light "Switch" {
|
||||
|
||||
@ -132,6 +132,9 @@ public class EnOceanBindingConstants {
|
||||
|
||||
public static final String CHANNEL_ROCKERSWITCH_CHANNELA = "rockerswitchA";
|
||||
public static final String CHANNEL_ROCKERSWITCH_CHANNELB = "rockerswitchB";
|
||||
public static final String CHANNEL_ROCKERSWITCH_ACTION = "rockerSwitchAction";
|
||||
public static final ChannelTypeUID CHANNELTYPE_ROCKERSWITCH_ACTION_UID = new ChannelTypeUID(BINDING_ID,
|
||||
CHANNEL_ROCKERSWITCH_ACTION);
|
||||
|
||||
public static final String CHANNEL_VIRTUALSWITCHA = "virtualSwitchA";
|
||||
public static final String CHANNEL_VIRTUALROLLERSHUTTERA = "virtualRollershutterA";
|
||||
@ -357,6 +360,9 @@ public class EnOceanBindingConstants {
|
||||
Map.entry(CHANNEL_ROCKERSWITCH_CHANNELB,
|
||||
new EnOceanChannelDescription(DefaultSystemChannelTypeProvider.SYSTEM_RAWROCKER.getUID(), null,
|
||||
"Rocker Switch - Channel B", false, false)),
|
||||
Map.entry(CHANNEL_ROCKERSWITCH_ACTION,
|
||||
new EnOceanChannelDescription(CHANNELTYPE_ROCKERSWITCH_ACTION_UID, null, "Rocker Switch Action",
|
||||
false, false)),
|
||||
|
||||
Map.entry(CHANNEL_VIRTUALSWITCHA,
|
||||
new EnOceanChannelDescription(new ChannelTypeUID(BINDING_ID, CHANNEL_VIRTUALSWITCHA),
|
||||
|
||||
@ -19,9 +19,11 @@ package org.openhab.binding.enocean.internal.config;
|
||||
public class EnOceanChannelRockerSwitchListenerConfig extends EnOceanChannelRockerSwitchConfigBase {
|
||||
|
||||
public String enoceanId;
|
||||
public boolean handleSecondAction;
|
||||
|
||||
public EnOceanChannelRockerSwitchListenerConfig() {
|
||||
super();
|
||||
enoceanId = null;
|
||||
handleSecondAction = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* 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.enocean.internal.config;
|
||||
|
||||
/**
|
||||
* This {@link EnOceanProfileRockerSwitchActionConfig} config class is used for rockerSwitchAction profiles to define in
|
||||
* which case it should react.
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
public class EnOceanProfileRockerSwitchActionConfig {
|
||||
|
||||
public String channelAFilter;
|
||||
public String channelBFilter;
|
||||
|
||||
public EnOceanProfileRockerSwitchActionConfig() {
|
||||
channelAFilter = "*";
|
||||
channelBFilter = "*";
|
||||
}
|
||||
}
|
||||
@ -179,13 +179,14 @@ public enum EEPType {
|
||||
CHANNEL_DOUBLEPRESS, CHANNEL_LONGPRESS, CHANNEL_BATTERY_LEVEL),
|
||||
|
||||
RockerSwitch2RockerStyle1(RORG.RPS, 0x02, 0x01, false, F6_02_01.class, THING_TYPE_ROCKERSWITCH,
|
||||
CHANNEL_ROCKERSWITCH_CHANNELA, CHANNEL_ROCKERSWITCH_CHANNELB, CHANNEL_VIRTUALSWITCHA,
|
||||
CHANNEL_VIRTUALROLLERSHUTTERA, CHANNEL_VIRTUALROCKERSWITCHB, CHANNEL_ROCKERSWITCHLISTENERSWITCH,
|
||||
CHANNEL_ROCKERSWITCHLISTENERROLLERSHUTTER),
|
||||
CHANNEL_ROCKERSWITCH_CHANNELA, CHANNEL_ROCKERSWITCH_CHANNELB, CHANNEL_ROCKERSWITCH_ACTION,
|
||||
CHANNEL_VIRTUALSWITCHA, CHANNEL_VIRTUALROLLERSHUTTERA, CHANNEL_VIRTUALROCKERSWITCHB,
|
||||
CHANNEL_ROCKERSWITCHLISTENERSWITCH, CHANNEL_ROCKERSWITCHLISTENERROLLERSHUTTER),
|
||||
|
||||
RockerSwitch2RockerStyle2(RORG.RPS, 0x02, 0x02, false, F6_02_02.class, THING_TYPE_ROCKERSWITCH,
|
||||
CHANNEL_ROCKERSWITCH_CHANNELA, CHANNEL_ROCKERSWITCH_CHANNELB, CHANNEL_VIRTUALSWITCHA,
|
||||
CHANNEL_VIRTUALROLLERSHUTTERA, CHANNEL_VIRTUALROCKERSWITCHB, CHANNEL_ROCKERSWITCHLISTENERSWITCH,
|
||||
CHANNEL_ROCKERSWITCHLISTENERROLLERSHUTTER),
|
||||
CHANNEL_ROCKERSWITCH_CHANNELA, CHANNEL_ROCKERSWITCH_CHANNELB, CHANNEL_ROCKERSWITCH_ACTION,
|
||||
CHANNEL_VIRTUALSWITCHA, CHANNEL_VIRTUALROLLERSHUTTERA, CHANNEL_VIRTUALROCKERSWITCHB,
|
||||
CHANNEL_ROCKERSWITCHLISTENERSWITCH, CHANNEL_ROCKERSWITCHLISTENERROLLERSHUTTER),
|
||||
|
||||
MechanicalHandle00(RORG.RPS, 0x10, 0x00, false, F6_10_00.class, THING_TYPE_MECHANICALHANDLE,
|
||||
CHANNEL_WINDOWHANDLESTATE, CHANNEL_CONTACT),
|
||||
|
||||
@ -0,0 +1,178 @@
|
||||
/**
|
||||
* 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.enocean.internal.eep.F6_02;
|
||||
|
||||
import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
|
||||
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchConfigBase.SwitchMode;
|
||||
import org.openhab.binding.enocean.internal.eep.Base._RPSMessage;
|
||||
import org.openhab.binding.enocean.internal.messages.ERP1Message;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.thing.CommonTriggerEvents;
|
||||
import org.openhab.core.types.State;
|
||||
import org.openhab.core.types.UnDefType;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
public abstract class F6_02 extends _RPSMessage {
|
||||
|
||||
final byte AI = 0;
|
||||
final byte A0 = 1;
|
||||
final byte BI = 2;
|
||||
final byte B0 = 3;
|
||||
final byte PRESSED = 16;
|
||||
final byte PRESSED_SEC = 1;
|
||||
|
||||
final String DIR1 = "DIR1";
|
||||
final String DIR2 = "DIR2";
|
||||
final String NODIR = "-";
|
||||
|
||||
int secondByte = -1;
|
||||
int secondStatus = -1;
|
||||
|
||||
public F6_02() {
|
||||
super();
|
||||
}
|
||||
|
||||
public F6_02(ERP1Message packet) {
|
||||
super(packet);
|
||||
}
|
||||
|
||||
private String getChannelADir() {
|
||||
if ((bytes[0] >>> 5) == A0 && (bytes[0] & PRESSED) != 0) {
|
||||
return DIR1;
|
||||
} else if ((bytes[0] >>> 5) == AI && (bytes[0] & PRESSED) != 0) {
|
||||
return DIR2;
|
||||
} else {
|
||||
return NODIR;
|
||||
}
|
||||
}
|
||||
|
||||
private String getChannelBDir() {
|
||||
if ((bytes[0] >>> 5) == B0 && (bytes[0] & PRESSED) != 0) {
|
||||
return DIR1;
|
||||
} else if ((bytes[0] >>> 5) == BI && (bytes[0] & PRESSED) != 0) {
|
||||
return DIR2;
|
||||
} else if (((bytes[0] & 0xf) >>> 1) == B0 && (bytes[0] & PRESSED_SEC) != 0) {
|
||||
return DIR1;
|
||||
} else if (((bytes[0] & 0xf) >>> 1) == BI && (bytes[0] & PRESSED_SEC) != 0) {
|
||||
return DIR2;
|
||||
} else {
|
||||
return NODIR;
|
||||
}
|
||||
}
|
||||
|
||||
protected String getRockerSwitchAction(Configuration config) {
|
||||
String dirA = getChannelADir();
|
||||
String dirB = getChannelBDir();
|
||||
|
||||
return dirA + "|" + dirB;
|
||||
}
|
||||
|
||||
protected String getChannelEvent(byte dir1, byte dir2) {
|
||||
if ((bytes[0] & PRESSED_SEC) != 0) {
|
||||
// Do not emit an event if channelA is pressed together with channelB as it is undetermined which one gets
|
||||
// fired first
|
||||
return null;
|
||||
} else if ((bytes[0] >>> 5) == dir1) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR1_PRESSED : CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR2_PRESSED : CommonTriggerEvents.DIR2_RELEASED;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected State getState(byte dir1, byte dir2, boolean handleSecondAction, SwitchMode switchMode,
|
||||
String channelTypeId, State currentState) {
|
||||
// We are just listening on the pressed event here
|
||||
switch (switchMode) {
|
||||
case RockerSwitch:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON : UpDownType.UP;
|
||||
}
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
|
||||
: UpDownType.DOWN;
|
||||
}
|
||||
} else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir1) {
|
||||
if (((bytes[0] & PRESSED_SEC) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON : UpDownType.UP;
|
||||
}
|
||||
} else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir2) {
|
||||
if (((bytes[0] & PRESSED_SEC) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
|
||||
: UpDownType.DOWN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir1:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
} else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir1) {
|
||||
if (((bytes[0] & PRESSED_SEC) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir2:
|
||||
if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
} else if (handleSecondAction && ((bytes[0] & 0xf) >>> 1) == dir2) {
|
||||
if (((bytes[0] & PRESSED_SEC) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON : inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
protected State inverse(OnOffType currentState) {
|
||||
return currentState == OnOffType.ON ? OnOffType.OFF : OnOffType.ON;
|
||||
}
|
||||
|
||||
protected State inverse(UpDownType currentState) {
|
||||
return currentState == UpDownType.UP ? UpDownType.DOWN : UpDownType.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateData(byte[] bytes) {
|
||||
return super.validateData(bytes) && !getBit(bytes[0], 7);
|
||||
}
|
||||
}
|
||||
@ -17,13 +17,11 @@ import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchConfigBase.Channel;
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelVirtualRockerSwitchConfig;
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchListenerConfig;
|
||||
import org.openhab.binding.enocean.internal.eep.Base._RPSMessage;
|
||||
import org.openhab.binding.enocean.internal.messages.ERP1Message;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.thing.CommonTriggerEvents;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
@ -33,16 +31,7 @@ import org.openhab.core.types.UnDefType;
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
public class F6_02_01 extends _RPSMessage {
|
||||
|
||||
final byte AI = 0;
|
||||
final byte A0 = 1;
|
||||
final byte BI = 2;
|
||||
final byte B0 = 3;
|
||||
final byte PRESSED = 16;
|
||||
|
||||
int secondByte = -1;
|
||||
int secondStatus = -1;
|
||||
public class F6_02_01 extends F6_02 {
|
||||
|
||||
public F6_02_01() {
|
||||
super();
|
||||
@ -57,21 +46,23 @@ public class F6_02_01 extends _RPSMessage {
|
||||
Configuration config) {
|
||||
|
||||
if (t21 && nu) {
|
||||
byte dir1 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? A0 : B0;
|
||||
byte dir2 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? AI : BI;
|
||||
if (CHANNEL_ROCKERSWITCH_ACTION.equals(channelTypeId)) {
|
||||
return getRockerSwitchAction(config);
|
||||
} else {
|
||||
byte dir1 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? A0 : B0;
|
||||
byte dir2 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? AI : BI;
|
||||
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR1_PRESSED
|
||||
: CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR2_PRESSED
|
||||
: CommonTriggerEvents.DIR2_RELEASED;
|
||||
return getChannelEvent(dir1, dir2);
|
||||
}
|
||||
} else if (t21 && !nu) {
|
||||
if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR1_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR2_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR2_RELEASED;
|
||||
if (CHANNEL_ROCKERSWITCH_ACTION.equals(channelTypeId)) {
|
||||
return CommonTriggerEvents.RELEASED;
|
||||
} else {
|
||||
if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR1_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR2_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR2_RELEASED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +73,7 @@ public class F6_02_01 extends _RPSMessage {
|
||||
protected void convertFromCommandImpl(String channelId, String channelTypeId, Command command,
|
||||
Function<String, State> getCurrentStateFunc, Configuration config) {
|
||||
if (command instanceof StringType) {
|
||||
StringType s = (StringType) command;
|
||||
String s = ((StringType) command).toString();
|
||||
|
||||
if (s.equals(CommonTriggerEvents.DIR1_RELEASED) || s.equals(CommonTriggerEvents.DIR2_RELEASED)) {
|
||||
setStatus(_RPSMessage.T21Flag);
|
||||
@ -106,72 +97,20 @@ public class F6_02_01 extends _RPSMessage {
|
||||
@Override
|
||||
protected State convertToStateImpl(String channelId, String channelTypeId,
|
||||
Function<String, State> getCurrentStateFunc, Configuration config) {
|
||||
// this method is used by the classic device listener channels to convert an rocker switch message into an
|
||||
// this method is used by the classic device listener channels to convert a rocker switch message into an
|
||||
// appropriate item update
|
||||
State currentState = getCurrentStateFunc.apply(channelId);
|
||||
if (t21 && nu) {
|
||||
EnOceanChannelVirtualRockerSwitchConfig c = config.as(EnOceanChannelVirtualRockerSwitchConfig.class);
|
||||
EnOceanChannelRockerSwitchListenerConfig c = config.as(EnOceanChannelRockerSwitchListenerConfig.class);
|
||||
byte dir1 = c.getChannel() == Channel.ChannelA ? A0 : B0;
|
||||
byte dir2 = c.getChannel() == Channel.ChannelA ? AI : BI;
|
||||
|
||||
// We are just listening on the pressed event here
|
||||
switch (c.getSwitchMode()) {
|
||||
case RockerSwitch:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON
|
||||
: UpDownType.UP;
|
||||
}
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
|
||||
: UpDownType.DOWN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir1:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON
|
||||
: inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir2:
|
||||
if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON
|
||||
: inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return getState(dir1, dir2, c.handleSecondAction, c.getSwitchMode(), channelTypeId, currentState);
|
||||
}
|
||||
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
private State inverse(OnOffType currentState) {
|
||||
return currentState == OnOffType.ON ? OnOffType.OFF : OnOffType.ON;
|
||||
}
|
||||
|
||||
private State inverse(UpDownType currentState) {
|
||||
return currentState == UpDownType.UP ? UpDownType.DOWN : UpDownType.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean validateData(byte[] bytes) {
|
||||
return super.validateData(bytes) && !getBit(bytes[0], 7);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidForTeachIn() {
|
||||
if (t21) {
|
||||
|
||||
@ -17,13 +17,11 @@ import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchConfigBase.Channel;
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelVirtualRockerSwitchConfig;
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanChannelRockerSwitchListenerConfig;
|
||||
import org.openhab.binding.enocean.internal.eep.Base._RPSMessage;
|
||||
import org.openhab.binding.enocean.internal.messages.ERP1Message;
|
||||
import org.openhab.core.config.core.Configuration;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.library.types.StringType;
|
||||
import org.openhab.core.library.types.UpDownType;
|
||||
import org.openhab.core.thing.CommonTriggerEvents;
|
||||
import org.openhab.core.types.Command;
|
||||
import org.openhab.core.types.State;
|
||||
@ -33,13 +31,7 @@ import org.openhab.core.types.UnDefType;
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
public class F6_02_02 extends _RPSMessage {
|
||||
|
||||
final byte AI = 0;
|
||||
final byte A0 = 1;
|
||||
final byte BI = 2;
|
||||
final byte B0 = 3;
|
||||
final byte PRESSED = 16;
|
||||
public class F6_02_02 extends F6_02 {
|
||||
|
||||
public F6_02_02() {
|
||||
super();
|
||||
@ -54,21 +46,22 @@ public class F6_02_02 extends _RPSMessage {
|
||||
Configuration config) {
|
||||
|
||||
if (t21 && nu) {
|
||||
byte dir1 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? AI : BI;
|
||||
byte dir2 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? A0 : B0;
|
||||
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR1_PRESSED
|
||||
: CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
return ((bytes[0] & PRESSED) != 0) ? CommonTriggerEvents.DIR2_PRESSED
|
||||
: CommonTriggerEvents.DIR2_RELEASED;
|
||||
if (CHANNEL_ROCKERSWITCH_ACTION.equals(channelTypeId)) {
|
||||
return getRockerSwitchAction(config);
|
||||
} else {
|
||||
byte dir1 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? AI : BI;
|
||||
byte dir2 = channelId.equals(CHANNEL_ROCKERSWITCH_CHANNELA) ? A0 : B0;
|
||||
return getChannelEvent(dir1, dir2);
|
||||
}
|
||||
} else if (t21 && !nu) {
|
||||
if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR1_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR2_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR2_RELEASED;
|
||||
if (CHANNEL_ROCKERSWITCH_ACTION.equals(channelTypeId)) {
|
||||
return CommonTriggerEvents.RELEASED;
|
||||
} else {
|
||||
if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR1_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR1_RELEASED;
|
||||
} else if (lastEvent != null && lastEvent.equals(CommonTriggerEvents.DIR2_PRESSED)) {
|
||||
return CommonTriggerEvents.DIR2_RELEASED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +72,7 @@ public class F6_02_02 extends _RPSMessage {
|
||||
protected void convertFromCommandImpl(String channelId, String channelTypeId, Command command,
|
||||
Function<String, State> getCurrentStateFunc, Configuration config) {
|
||||
if (command instanceof StringType) {
|
||||
StringType s = (StringType) command;
|
||||
String s = ((StringType) command).toString();
|
||||
|
||||
if (s.equals(CommonTriggerEvents.DIR1_RELEASED) || s.equals(CommonTriggerEvents.DIR2_RELEASED)) {
|
||||
setStatus(_RPSMessage.T21Flag);
|
||||
@ -103,67 +96,20 @@ public class F6_02_02 extends _RPSMessage {
|
||||
@Override
|
||||
protected State convertToStateImpl(String channelId, String channelTypeId,
|
||||
Function<String, State> getCurrentStateFunc, Configuration config) {
|
||||
// this method is used by the classic device listener channels to convert an rocker switch message into an
|
||||
// this method is used by the classic device listener channels to convert a rocker switch message into an
|
||||
// appropriate item update
|
||||
State currentState = getCurrentStateFunc.apply(channelId);
|
||||
if (t21 && nu) {
|
||||
EnOceanChannelVirtualRockerSwitchConfig c = config.as(EnOceanChannelVirtualRockerSwitchConfig.class);
|
||||
EnOceanChannelRockerSwitchListenerConfig c = config.as(EnOceanChannelRockerSwitchListenerConfig.class);
|
||||
byte dir1 = c.getChannel() == Channel.ChannelA ? AI : BI;
|
||||
byte dir2 = c.getChannel() == Channel.ChannelA ? A0 : B0;
|
||||
|
||||
// We are just listening on the pressed event here
|
||||
switch (c.getSwitchMode()) {
|
||||
case RockerSwitch:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.ON
|
||||
: UpDownType.UP;
|
||||
}
|
||||
} else if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH) ? OnOffType.OFF
|
||||
: UpDownType.DOWN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir1:
|
||||
if ((bytes[0] >>> 5) == dir1) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON
|
||||
: inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ToggleDir2:
|
||||
if ((bytes[0] >>> 5) == dir2) {
|
||||
if (((bytes[0] & PRESSED) != 0)) {
|
||||
return channelTypeId.equals(CHANNEL_ROCKERSWITCHLISTENERSWITCH)
|
||||
? (currentState == UnDefType.UNDEF ? OnOffType.ON
|
||||
: inverse((OnOffType) currentState))
|
||||
: (currentState == UnDefType.UNDEF ? UpDownType.UP
|
||||
: inverse((UpDownType) currentState));
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return getState(dir1, dir2, c.handleSecondAction, c.getSwitchMode(), channelTypeId, currentState);
|
||||
}
|
||||
|
||||
return UnDefType.UNDEF;
|
||||
}
|
||||
|
||||
private State inverse(OnOffType currentState) {
|
||||
return currentState == OnOffType.ON ? OnOffType.OFF : OnOffType.ON;
|
||||
}
|
||||
|
||||
private State inverse(UpDownType currentState) {
|
||||
return currentState == UpDownType.UP ? UpDownType.DOWN : UpDownType.UP;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValidForTeachIn() {
|
||||
return false; // Never treat a message as F6-02-02, let user decide which orientation of rocker switch is used
|
||||
|
||||
@ -129,7 +129,8 @@ public class EnOceanBaseSensorHandler extends EnOceanBaseThingHandler implements
|
||||
|
||||
protected Predicate<Channel> channelFilter(EEPType eepType, byte[] senderId) {
|
||||
return c -> {
|
||||
boolean result = eepType.GetSupportedChannels().containsKey(c.getUID().getId());
|
||||
|
||||
boolean result = eepType.isChannelSupported(c);
|
||||
return (isLinked(c.getUID()) || c.getKind() == ChannelKind.TRIGGER) && result;
|
||||
};
|
||||
}
|
||||
|
||||
@ -0,0 +1,109 @@
|
||||
/**
|
||||
* 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.enocean.internal.profiles;
|
||||
|
||||
import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
|
||||
import static org.openhab.binding.enocean.internal.profiles.EnOceanProfiles.*;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.thing.Channel;
|
||||
import org.openhab.core.thing.profiles.Profile;
|
||||
import org.openhab.core.thing.profiles.ProfileAdvisor;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileFactory;
|
||||
import org.openhab.core.thing.profiles.ProfileType;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeProvider;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.thing.type.ChannelType;
|
||||
import org.openhab.core.thing.type.ChannelTypeRegistry;
|
||||
import org.osgi.service.component.annotations.Activate;
|
||||
import org.osgi.service.component.annotations.Component;
|
||||
import org.osgi.service.component.annotations.Reference;
|
||||
|
||||
/**
|
||||
* The {@link EnOceanProfileFactory} class creates EnOceanProfiles
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
@Component
|
||||
@NonNullByDefault
|
||||
public class EnOceanProfileFactory implements ProfileFactory, ProfileAdvisor, ProfileTypeProvider {
|
||||
|
||||
private static final Set<ProfileType> SUPPORTED_PROFILE_TYPES = Set.of(ROCKERSWITCHACTION_TOGGLE_SWITCH_TYPE,
|
||||
ROCKERSWITCHACTION_TOGGLE_PLAYER_TYPE);
|
||||
|
||||
private static final Set<ProfileTypeUID> SUPPORTED_PROFILE_TYPE_UIDS = Set.of(ROCKERSWITCHACTION_TOGGLE_SWITCH,
|
||||
ROCKERSWITCHACTION_TOGGLE_PLAYER);
|
||||
|
||||
private final ChannelTypeRegistry channelTypeRegistry;
|
||||
|
||||
@Activate
|
||||
public EnOceanProfileFactory(final @Reference ChannelTypeRegistry channelTypeRegistry) {
|
||||
this.channelTypeRegistry = channelTypeRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProfileType> getProfileTypes(@Nullable Locale locale) {
|
||||
return Collections.unmodifiableList(SUPPORTED_PROFILE_TYPES.stream().collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ProfileTypeUID getSuggestedProfileTypeUID(Channel channel, @Nullable String itemType) {
|
||||
ChannelType channelType = channelTypeRegistry.getChannelType(channel.getChannelTypeUID());
|
||||
if (channelType == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getSuggestedProfileTypeUID(channelType, itemType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable ProfileTypeUID getSuggestedProfileTypeUID(ChannelType channelType, @Nullable String itemType) {
|
||||
|
||||
if (CHANNELTYPE_ROCKERSWITCH_ACTION_UID.equals(channelType.getUID())) {
|
||||
if (CoreItemFactory.PLAYER.equalsIgnoreCase(itemType)) {
|
||||
return ROCKERSWITCHACTION_TOGGLE_PLAYER;
|
||||
} else if (CoreItemFactory.SWITCH.equalsIgnoreCase(itemType)) {
|
||||
return ROCKERSWITCHACTION_TOGGLE_SWITCH;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable Profile createProfile(ProfileTypeUID profileTypeUID, ProfileCallback callback,
|
||||
ProfileContext profileContext) {
|
||||
if (ROCKERSWITCHACTION_TOGGLE_PLAYER.equals(profileTypeUID)) {
|
||||
return new RockerSwitchActionTogglePlayerProfile(callback, profileContext);
|
||||
} else if (ROCKERSWITCHACTION_TOGGLE_SWITCH.equals(profileTypeUID)) {
|
||||
return new RockerSwitchActionToggleSwitchProfile(callback, profileContext);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<ProfileTypeUID> getSupportedProfileTypeUIDs() {
|
||||
return Collections.unmodifiableList(SUPPORTED_PROFILE_TYPE_UIDS.stream().collect(Collectors.toList()));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,45 @@
|
||||
/**
|
||||
* 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.enocean.internal.profiles;
|
||||
|
||||
import static org.openhab.binding.enocean.internal.EnOceanBindingConstants.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.CoreItemFactory;
|
||||
import org.openhab.core.thing.profiles.ProfileType;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeBuilder;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
|
||||
/**
|
||||
* The {@link EnOceanProfiles} class defines profile constants
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class EnOceanProfiles {
|
||||
public static final ProfileTypeUID ROCKERSWITCHACTION_TOGGLE_SWITCH = new ProfileTypeUID(BINDING_ID,
|
||||
"rockerswitchaction-toggle-switch");
|
||||
|
||||
public static final ProfileTypeUID ROCKERSWITCHACTION_TOGGLE_PLAYER = new ProfileTypeUID(BINDING_ID,
|
||||
"rockerswitchaction-toggle-player");
|
||||
|
||||
static final ProfileType ROCKERSWITCHACTION_TOGGLE_SWITCH_TYPE = ProfileTypeBuilder
|
||||
.newTrigger(ROCKERSWITCHACTION_TOGGLE_SWITCH, "Rocker Switch Action Toggle Switch")
|
||||
.withSupportedItemTypes(CoreItemFactory.SWITCH)
|
||||
.withSupportedChannelTypeUIDs(CHANNELTYPE_ROCKERSWITCH_ACTION_UID).build();
|
||||
|
||||
static final ProfileType ROCKERSWITCHACTION_TOGGLE_PLAYER_TYPE = ProfileTypeBuilder
|
||||
.newTrigger(ROCKERSWITCHACTION_TOGGLE_PLAYER, "Rocker Switch Action Toggle Player")
|
||||
.withSupportedItemTypes(CoreItemFactory.PLAYER)
|
||||
.withSupportedChannelTypeUIDs(CHANNELTYPE_ROCKERSWITCH_ACTION_UID).build();
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.enocean.internal.profiles;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.eclipse.jdt.annotation.Nullable;
|
||||
import org.openhab.binding.enocean.internal.config.EnOceanProfileRockerSwitchActionConfig;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.TriggerProfile;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public abstract class RockerSwitchActionBaseProfile implements TriggerProfile {
|
||||
|
||||
protected final ProfileCallback callback;
|
||||
protected ProfileContext context;
|
||||
|
||||
protected @Nullable State previousState;
|
||||
|
||||
final String ANYDIR = "*";
|
||||
|
||||
public RockerSwitchActionBaseProfile(ProfileCallback callback, ProfileContext context) {
|
||||
this.callback = callback;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected boolean isEventValid(String event) {
|
||||
String[] directions = event.split("\\|");
|
||||
if (directions.length != 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
EnOceanProfileRockerSwitchActionConfig config = context.getConfiguration()
|
||||
.as(EnOceanProfileRockerSwitchActionConfig.class);
|
||||
if (!(config.channelAFilter.equals(ANYDIR) || config.channelAFilter.equals(directions[0]))) {
|
||||
return false;
|
||||
} else if (!(config.channelBFilter.equals(ANYDIR) || config.channelBFilter.equals(directions[1]))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* 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.enocean.internal.profiles;
|
||||
|
||||
import static org.openhab.binding.enocean.internal.profiles.EnOceanProfiles.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.PlayPauseType;
|
||||
import org.openhab.core.thing.CommonTriggerEvents;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* The {@link RockerSwitchActionTogglePlayerProfile} is used for channel rockerSwitchAction to be able to bind this
|
||||
* trigger channel directly to a player item
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RockerSwitchActionTogglePlayerProfile extends RockerSwitchActionBaseProfile {
|
||||
|
||||
public RockerSwitchActionTogglePlayerProfile(ProfileCallback callback, ProfileContext context) {
|
||||
super(callback, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileTypeUID getProfileTypeUID() {
|
||||
return ROCKERSWITCHACTION_TOGGLE_PLAYER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromItem(State state) {
|
||||
previousState = state.as(PlayPauseType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTriggerFromHandler(String event) {
|
||||
// Ignore released event
|
||||
if (!CommonTriggerEvents.RELEASED.equals(event) && isEventValid(event)) {
|
||||
PlayPauseType newState = PlayPauseType.PLAY.equals(previousState) ? PlayPauseType.PAUSE
|
||||
: PlayPauseType.PLAY;
|
||||
callback.sendCommand(newState);
|
||||
previousState = newState;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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.enocean.internal.profiles;
|
||||
|
||||
import static org.openhab.binding.enocean.internal.profiles.EnOceanProfiles.*;
|
||||
|
||||
import org.eclipse.jdt.annotation.NonNullByDefault;
|
||||
import org.openhab.core.library.types.OnOffType;
|
||||
import org.openhab.core.thing.CommonTriggerEvents;
|
||||
import org.openhab.core.thing.profiles.ProfileCallback;
|
||||
import org.openhab.core.thing.profiles.ProfileContext;
|
||||
import org.openhab.core.thing.profiles.ProfileTypeUID;
|
||||
import org.openhab.core.types.State;
|
||||
|
||||
/**
|
||||
* The {@link RockerSwitchActionToggleSwitchProfile} is used for channel rockerSwitchAction to be able to bind this
|
||||
* trigger channel directly to a switch item
|
||||
*
|
||||
* @author Daniel Weber - Initial contribution
|
||||
*/
|
||||
@NonNullByDefault
|
||||
public class RockerSwitchActionToggleSwitchProfile extends RockerSwitchActionBaseProfile {
|
||||
|
||||
public RockerSwitchActionToggleSwitchProfile(ProfileCallback callback, ProfileContext context) {
|
||||
super(callback, context);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProfileTypeUID getProfileTypeUID() {
|
||||
return ROCKERSWITCHACTION_TOGGLE_SWITCH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateUpdateFromItem(State state) {
|
||||
previousState = state.as(OnOffType.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTriggerFromHandler(String event) {
|
||||
// Ignore released event
|
||||
if (!CommonTriggerEvents.RELEASED.equals(event) && isEventValid(event)) {
|
||||
OnOffType newState = OnOffType.ON.equals(previousState) ? OnOffType.OFF : OnOffType.ON;
|
||||
callback.sendCommand(newState);
|
||||
previousState = newState;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -29,6 +29,11 @@
|
||||
</options>
|
||||
<default>channelA</default>
|
||||
</parameter>
|
||||
<parameter name="handleSecondAction" type="boolean">
|
||||
<label>Handle Second Action</label>
|
||||
<description>React if selected channel is pressed as second action too</description>
|
||||
<default>false</default>
|
||||
</parameter>
|
||||
<parameter name="switchMode" type="text">
|
||||
<label>Switch Mode</label>
|
||||
<options>
|
||||
@ -56,4 +61,27 @@
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
<config-description uri="profile:enocean:rockerswitchaction-toggle-switch">
|
||||
<parameter name="channelAFilter" type="text">
|
||||
<label>Channel A Filter</label>
|
||||
<default>*</default>
|
||||
<options>
|
||||
<option value="*">Any Direction</option>
|
||||
<option value="DIR1">Direction 1</option>
|
||||
<option value="DIR2">Direction 2</option>
|
||||
<option value="-">No Direction</option>
|
||||
</options>
|
||||
</parameter>
|
||||
<parameter name="channelBFilter" type="text">
|
||||
<label>Channel B Filter</label>
|
||||
<default>*</default>
|
||||
<options>
|
||||
<option value="*">Any Direction</option>
|
||||
<option value="DIR1">Direction 1</option>
|
||||
<option value="DIR2">Direction 2</option>
|
||||
<option value="-">No Direction</option>
|
||||
</options>
|
||||
</parameter>
|
||||
</config-description>
|
||||
|
||||
</config-description:config-descriptions>
|
||||
|
||||
@ -20,6 +20,9 @@
|
||||
<channel typeId="system.rawrocker" id="rockerswitchB">
|
||||
<label>Rocker Switch - Channel B</label>
|
||||
</channel>
|
||||
<channel id="rockerSwitchAction" typeId="rockerSwitchAction">
|
||||
<label>Rocker Switch Action</label>
|
||||
</channel>
|
||||
</channels>
|
||||
|
||||
<config-description>
|
||||
|
||||
@ -810,4 +810,23 @@
|
||||
<state min="0" max="100" pattern="%.1f rpm" readOnly="true"/>
|
||||
</channel-type>
|
||||
|
||||
<channel-type id="rockerSwitchAction">
|
||||
<kind>trigger</kind>
|
||||
<label>Rocker Switch Action</label>
|
||||
<description>Is triggered when a certain combination of rockers is pressed or released.</description>
|
||||
<event>
|
||||
<options>
|
||||
<option value="DIR1|-"></option>
|
||||
<option value="DIR2|-"></option>
|
||||
<option value="DIR1|DIR1"></option>
|
||||
<option value="DIR1|DIR2"></option>
|
||||
<option value="DIR2|DIR1"></option>
|
||||
<option value="DIR2|DIR2"></option>
|
||||
<option value="-|DIR1"></option>
|
||||
<option value="-|DIR2"></option>
|
||||
<option value="RELEASED"></option>
|
||||
</options>
|
||||
</event>
|
||||
</channel-type>
|
||||
|
||||
</thing:thing-descriptions>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user