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

[shelly] Vibration event for DW2 #10618

Merged
merged 5 commits into from
May 9, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 6 additions & 3 deletions bundles/org.openhab.binding.shelly/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ The binding gets in sync with the next status refresh.
Refer to [Advanced Users](doc/AdvancedUsers.md) for more information on openHAB Shelly integration, e.g. firmware update, network communication or log filtering.

Also check out the [Shelly Manager](doc/ShellyManager.md), which

- provides detailed information on your Shellys
- helps to diagnose WiFi issues or device instabilities
- includes some common actions and
Expand Down Expand Up @@ -276,6 +277,7 @@ Check the channel definitions for the various devices to see if the device suppo
You could use the Shelly App to set the timing for those events.

If you want to use those events triggering a rule:

- If a physical switch is connected to the Shelly use the input channel(`input` or `input1`/`input2`) to trigger a rule
- For a momentary button use the `button` trigger channel as trigger, channels `lastEvent` and `eventCount` will provide details on the event

Expand Down Expand Up @@ -309,7 +311,7 @@ A new alarm will be triggered on a new condition or every 5 minutes if the condi
|BATTERY |Device reported an update to the battery status. |
|TEMP_UNDER |Below "temperature under" threshold |
|TEMP_OVER |Above "temperature over" threshold |

|VIBRATION |A vibration/tamper was detected (DW2 only) |

Refer to section [Full Example:shelly.rules](#shelly-rules) for examples how to catch alarm triggers in openHAB rules

Expand Down Expand Up @@ -803,6 +805,7 @@ You can define 2 items (1 Switch, 1 Number) mapping to the same channel, see exa
| |lastError |String |yes |Last device error. |
|battery |batteryLevel |Number |yes |Battery Level in % |
| |lowBattery |Switch |yes |Low battery alert (< 20%) |
|device |alarm |Trigger |yes |Will receive trigger VIBRATION if DW2 detects vibration |

### Shelly Motion (thing-type: shellymotion)

Expand Down Expand Up @@ -1090,8 +1093,8 @@ when
Channel "shelly:shelly25-roller:XXXXXX:device#alarm" triggered
then
if (receivedEvent !== null) { // A (channel) event triggered the rule
eventSource = receivedEvent.getChannel().asString
eventType = receivedEvent.getEvent()
eventSource = triggeredChannel
eventType = receivedEvent
...
}
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,6 @@ public class ShellyBindingConstants {
public static final String PROPERTY_UPDATE_NEW_VERS = "updateNewVersion";
public static final String PROPERTY_COAP_DESCR = "coapDeviceDescr";
public static final String PROPERTY_COAP_VERSION = "coapVersion";
public static final String PROPERTY_STATS_TIMEOUTS = "statsTimeoutErrors";
public static final String PROPERTY_STATS_TRECOVERED = "statsTimeoutsRecovered";
public static final String PROPERTY_COIOTAUTO = "coiotAutoEnable";

// Relay
Expand Down Expand Up @@ -337,6 +335,7 @@ public class ShellyBindingConstants {
public static final String ALARM_TYPE_LOADERR = "LOAD_ERROR";
public static final String ALARM_TYPE_SENSOR_ERROR = "SENSOR_ERROR";
public static final String ALARM_TYPE_LOW_BATTERY = "LOW_BATTERY";
public static final String EVENT_TYPE_VIBRATION = "VIBRATION";

// Event types
public static final String EVENT_TYPE_RELAY = "relay";
Expand Down Expand Up @@ -364,4 +363,5 @@ public class ShellyBindingConstants {
public static final int UPDATE_MIN_DELAY = 15;// update every x triggers or when a key was pressed
public static final int UPDATE_SETTINGS_INTERVAL_SECONDS = 60; // check for updates every x sec
public static final int HEALTH_CHECK_INTERVAL_SEC = 300; // Health check interval, 5min
public static final int VIBRATION_FILTER_SEC = 5; // Absore duplicate vibration events for xx sec
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class ShellyApiException extends Exception {
private static final long serialVersionUID = -5809459454769761821L;

private ShellyApiResult apiResult = new ShellyApiResult();
private static String NONE = "none";
private static final String NONE = "none";

public ShellyApiException(Exception exception) {
super(exception);
Expand Down Expand Up @@ -117,7 +117,7 @@ public ShellyApiResult getApiResult() {
}

private boolean isEmpty() {
return nonNullString(super.getMessage()).equals(NONE);
return NONE.equals(nonNullString(super.getMessage()));
}

private static String nonNullString(@Nullable String s) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,6 @@ public static class ShellySettingsRelay {
public String pushLongUrl; // to access when roller stopped
@SerializedName("shortpush_url")
public String pushShortUrl; // to access when roller stopped

public Boolean schedule;
// ArrayList<ShellySettingsScheduleRules> schedule_rules;
}

public static class ShellySettingsDimmer {
Expand Down Expand Up @@ -442,8 +439,6 @@ public static class ShellySettingsRoller {
public Boolean isValid;
@SerializedName("safety_switch")
public Boolean safetySwitch;
public Boolean schedule;
// ArrayList<ShellySettingsScheduleRules> schedule_rules; // not used for now
@SerializedName("obstacle_mode")
public String obstaclMode; // SHELLY_OBSTMODE_
@SerializedName("obstacle_action")
Expand All @@ -468,7 +463,8 @@ public static class ShellySettingsRgbwLight {
public Boolean ison; // true: output is ON
public Integer brightness;
public Integer transition;
public String default_state;
@SerializedName("default_state")
public String defaultState;
@SerializedName("auto_on")
public Double autoOn; // Automatic flip back timer, seconds. Will engage after turning Shelly1 OFF.
@SerializedName("auto_off")
Expand Down Expand Up @@ -565,20 +561,14 @@ public static class ShellySettingsGlobal {
public ShellySensorSleepMode sleepMode; // FW 1.6
@SerializedName("external_power")
public Integer externalPower; // H&T FW 1.6, seems to be the same like charger for the Sense
public Boolean debug_enable; // FW 1.10+
@SerializedName("debug_enable") // FW 1.10+
public Boolean debugEnable;

public String timezone;
public Double lat;
public Double lng;
public Boolean tzautodetect;
public String time;
// @SerializedName("tz_utc_offset")
// public Integer tzUTCOoffset; // FW 1.6+
// @SerializedName("tz_dst")
// public Boolean tzDdst; // FW 1.6+
// @SerializedName("tz_dst_auto")
// public Boolean tzDstAuto; // FW 1.6+
// public Long unixtime; // FW 1.6+

public ShellySettingsHwInfo hwinfo;
public String mode;
Expand Down Expand Up @@ -619,15 +609,6 @@ public static class ShellySettingsGlobal {
@SerializedName("vibration_url")
public String vibrationUrl; // URL reports when DW detects vibration FW 1.6.5+

// @SerializedName("tilt_enabled")
// public Boolean tiltEnabled; // Whether tilt monitoring is activated
// @SerializedName("tilt_calibrated")
// public Boolean tiltCalibrated; // Whether calibration data is valid
// @SerializedName("vibration_enabled")
// public Boolean vibrationEnabled; // Whether vibration monitoring is activated
// @SerializedName("reverse_open_close")
// public Boolean reverseOpenClose; // Whether to reverse which position the sensor consideres "open"

// Gas FW 1.7
@SerializedName("set_volume")
public Integer volume; // Speaker volume for alarm
Expand Down Expand Up @@ -700,8 +681,6 @@ public static class ShellySettingsStatus {
public Integer input; // RGBW2 has no JSON array
public ArrayList<ShellyInputState> inputs;
public ArrayList<ShellySettingsLight> lights;
// @SerializedName("night_mode") // FW 1.5.7+
// public ShellySettingsNightMode nightMode;
public ArrayList<ShellyShortLightStatus> dimmers;
public ArrayList<ShellySettingsMeter> meters;
public ArrayList<ShellySettingsEMeter> emeters;
Expand Down Expand Up @@ -735,27 +714,6 @@ public static class ShellySettingsStatus {
public static class ShellySettingsInput {
@SerializedName("btn_type")
public String btnType;

// attributes not yet processed
// public String name;
// @SerializedName("btn_reverse")
// public Integer btnReverse;
// @SerializedName("btn_on_url")
// public String btnOnUrl;
// @SerializedName("btn_off_url")
// public String btnOffUrl;
// @SerializedName("shortpush_url")
// public String shortpushUrl;
// @SerializedName("longpush_url")
// public String longpushUrl;
// @SerializedName("double_shortpush_url")
// public String doubleShortpushUrl;
// @SerializedName("triple_shortpush_url")
// public String tripleShortpushUrl;
// @SerializedName("shortpush_longpush_url")
// public String shortpushLongpushUrl;
// @SerializedName("longpush_shortpush_url")
// public String longpushShortpushUrl;
}

public static class ShellyControlRelay {
Expand Down Expand Up @@ -791,23 +749,14 @@ public static class ShellyShortLightStatus {
public Boolean ison; // Whether output channel is on or off
public String mode; // color or white - valid only for Bulb and RGBW2 even Dimmer returns it also
public Integer brightness; // brightness: 0.100%
// @SerializedName("has_timer")
// public Boolean hasTimer; // Whether a timer is currently armed for this channel
// @SerializedName("timer_remaining")
// public Integer timerRemaining;
// public Integer wgite;
// public Integer temp; // light temp
}

public static class ShellyStatusRelay {
public String name; // FW 1.8: Symbolic channel name is configurable

@SerializedName("wifi_sta")
public ShellySettingsWiFiNetwork wifiSta; // WiFi status
// public ShellyStatusCloud cloud; // Cloud status
// public ShellyStatusMqtt mqtt; // mqtt status
public ShellySettingsCoiot coiot; // Firmware 1.6+
// public String time; // current time
public Integer serial;
public String mac; // MAC
public ArrayList<ShellyShortStatusRelay> relays; // relay status
Expand All @@ -821,30 +770,11 @@ public static class ShellyStatusRelay {

public Double temperature; // device temp acc. on the selected temp unit
public ShellyStatusSensor.ShellySensorTmp tmp;

@SerializedName("has_update")
public Boolean hasUpdate; // If a newer firmware version is available
public ShellySettingsUpdate update; // /status/firmware value

@SerializedName("ram_total")
public Integer ramTotal; // Total and available amount of system memory in bytes
@SerializedName("ram_free")
public Integer ramFree;
@SerializedName("fs_size")
public Integer fsSize;
@SerializedName("fs_free")
public Integer fsFree; // Total and available amount of file system space in bytes
public Integer uptime; // econds elapsed since boot
}

public static class ShellyStatusDimmer {
@SerializedName("wifi_sta")
public ShellySettingsWiFiNetwork wifiSta; // WiFi status
// public ShellyStatusCloud cloud; // Cloud status
// public ShellyStatusMqtt mqtt; // mqtt status
public String time; // current time
public Integer serial;
public String mac; // MAC
public ArrayList<ShellyShortLightStatus> lights; // relay status
public ArrayList<ShellySettingsMeter> meters; // current meter value

Expand All @@ -853,21 +783,6 @@ public static class ShellyStatusDimmer {

public Boolean loaderror;
public Boolean overload;

@SerializedName("has_update")
public Boolean hasUpdate; // If a newer firmware version is available
public ShellySettingsUpdate update; // /status/firmware value

@SerializedName("ram_total")
public Integer ramTotal; // Total and available amount of system memory in
// bytes
@SerializedName("ram_free")
public Integer ramFree;
@SerializedName("fs_size")
public Integer fsSize;
@SerializedName("fs_free")
public Integer fsFree; // Total and available amount of file system space in bytes
public Integer uptime; // seconds elapsed since boot
}

public static class ShellyControlRoller {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
@NonNullByDefault
public class ShellyDeviceProfile {
private final Logger logger = LoggerFactory.getLogger(ShellyDeviceProfile.class);
private final static Pattern VERSION_PATTERN = Pattern.compile("v\\d+\\.\\d+\\.\\d+(-[a-z0-9]*)?");
private static final Pattern VERSION_PATTERN = Pattern.compile("v\\d+\\.\\d+\\.\\d+(-[a-z0-9]*)?");

public boolean initialized = false; // true when initialized

Expand Down Expand Up @@ -131,6 +131,7 @@ public ShellyDeviceProfile initialize(String thingType, String json) throws Shel
extFeatures = version.compare(fwVersion, SHELLY_API_FW_110) >= 0;
discoverable = (settings.discoverable == null) || settings.discoverable;

isRoller = mode.equalsIgnoreCase(SHELLY_MODE_ROLLER);
inColor = isLight && mode.equalsIgnoreCase(SHELLY_MODE_COLOR);

numRelays = !isLight ? getInteger(settings.device.numOutputs) : 0;
Expand Down Expand Up @@ -184,8 +185,6 @@ public void initFromThingType(String name) {
}

isDimmer = deviceType.equalsIgnoreCase(SHELLYDT_DIMMER) || deviceType.equalsIgnoreCase(SHELLYDT_DIMMER2);
isRoller = mode.equalsIgnoreCase(SHELLY_MODE_ROLLER);

isBulb = thingType.equals(THING_TYPE_SHELLYBULB_STR);
isDuo = thingType.equals(THING_TYPE_SHELLYDUO_STR) || thingType.equals(THING_TYPE_SHELLYVINTAGE_STR)
|| thingType.equals(THING_TYPE_SHELLYDUORGBW_STR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,8 +246,8 @@ public ShellySettingsLogin getLoginSettings() throws ShellyApiException {
}

public ShellySettingsLogin setLoginCredentials(String user, String password) throws ShellyApiException {
return callApi(SHELLY_URL_SETTINGS + "/login?enabled=yes&username=" + user + "&password=" + password,
ShellySettingsLogin.class);
return callApi(SHELLY_URL_SETTINGS + "/login?enabled=yes&username=" + urlEncode(user) + "&password="
+ urlEncode(password), ShellySettingsLogin.class);
}

public String getCoIoTDescription() throws ShellyApiException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,6 @@ public ShellyCoIoTProtocol(String thingName, ShellyBaseHandler thingHandler, Map
protected boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescrSen sen, CoIotSensor s,
Map<String, State> updates, ShellyColorUtils col) {
// Process status information and convert into channel updates
// Integer rIndex = Integer.parseInt(sen.links) + 1;
// String rGroup = getProfile().numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL
// : CHANNEL_GROUP_RELAY_CONTROL + rIndex;
int rIndex = getIdFromBlk(sen);
String rGroup = getProfile().numRelays <= 1 ? CHANNEL_GROUP_RELAY_CONTROL
: CHANNEL_GROUP_RELAY_CONTROL + rIndex;
Expand Down Expand Up @@ -130,8 +127,10 @@ protected boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescr
s.value == 1 ? OnOffType.ON : OnOffType.OFF);
break;
case "vibration": // DW with FW1.6.5+
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION,
s.value == 1 ? OnOffType.ON : OnOffType.OFF);
if (s.value == 1) {
thingHandler.triggerChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE,
EVENT_TYPE_VIBRATION);
}
break;
case "luminositylevel": // +
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ILLUM, getStringType(s.valueStr));
Expand Down Expand Up @@ -166,7 +165,7 @@ protected boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescr
updateChannel(updates, CHANNEL_GROUP_COLOR_CONTROL, CHANNEL_COLOR_GAIN,
ShellyColorUtils.toPercent((int) s.value, SHELLY_MIN_GAIN, SHELLY_MAX_GAIN));
break;
case "sensorerror": // +
case "sensorerror":
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ERROR, getStringType(s.valueStr));
break;
default:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,8 +177,15 @@ public boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescrSen
toQuantityType(s.value, DIGITS_NONE, Units.DEGREE_ANGLE));
break;
case "vibration": // DW with FW1.6.5+
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION,
s.value == 1 ? OnOffType.ON : OnOffType.OFF);
if (profile.isMotion) {
// handle as status
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION,
s.value == 1 ? OnOffType.ON : OnOffType.OFF);
} else if (s.value == 1) {
// handle as event
thingHandler.triggerChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE,
EVENT_TYPE_VIBRATION);
}
break;
case "temp": // Shelly Bulb
case "colortemperature": // Shelly Duo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,10 @@ public boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescrSen
// skip, could check against thing mode...
break;

case "1101": // S, output, 0/1
case "1101": // relay_0: output, 0/1
case "1201": // relay_1: output, 0/1
case "1301": // relay_2: output, 0/1
case "1401": // relay_3: output, 0/1
updatePower(profile, updates, rIndex, sen, s, sensorUpdates);
break;
case "1102": // roler_0: S, roller, open/close/stop -> roller state
Expand Down Expand Up @@ -316,8 +319,14 @@ public boolean handleStatusUpdate(List<CoIotSensor> sensorUpdates, CoIotDescrSen
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_ALARM_STATE, getStringType(s.valueStr));
break;
case "6110": // A, vibration, 0/1, -1=unknown
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION,
value == 1 ? OnOffType.ON : OnOffType.OFF);
if (profile.isMotion) {
// handle as status
updateChannel(updates, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VIBRATION,
s.value == 1 ? OnOffType.ON : OnOffType.OFF);
} else if (s.value == 1) {
// handle as event
thingHandler.triggerChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_ALARM, EVENT_TYPE_VIBRATION);
}
break;
case "9102": // EV, wakeupEvent, battery/button/periodic/poweron/sensor/ext_power, "unknown"=unknown
if (s.valueArray.size() > 0) {
Expand Down
Loading