[shelly] BLU Motion, optimize ShellyManager for BLU devices (#15401)

Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
Markus Michels 2023-11-18 21:50:10 +01:00 committed by GitHub
parent 27924d677f
commit a535caa13c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 129 additions and 66 deletions

View File

@ -29,6 +29,8 @@ The binding supports both hardware generations
- Generation 1: The original Shelly devices like the Shelly 1, Shelly 2.5, Shelly Flood etc. - Generation 1: The original Shelly devices like the Shelly 1, Shelly 2.5, Shelly Flood etc.
- Generation 2: The new Plus / Pro series of devices - Generation 2: The new Plus / Pro series of devices
- Shelly Plus Mini: Shelly Plus devices in compact format
- Shelly BLU: Bluetooth based series of devices
The binding provides the same feature set across all devices as good as possible and depending on device specific features. The binding provides the same feature set across all devices as good as possible and depending on device specific features.
@ -120,7 +122,7 @@ The binding provides the same feature set across all devices as good as possible
| ----------------- | ------------------------------------------------------ | --------- | | ----------------- | ------------------------------------------------------ | --------- |
| shellyblubutton | Shelly BLU Button 1 | SBBT | | shellyblubutton | Shelly BLU Button 1 | SBBT |
| shellybludw | Shelly BLU Door/Windows | SBDW | | shellybludw | Shelly BLU Door/Windows | SBDW |
| shellyblumotion | Shelly BLU Motion | SBMO |
## Binding Configuration ## Binding Configuration
@ -1465,6 +1467,17 @@ See notes on discovery of Shelly BLU devices above.
| | lowBattery | Switch | yes | Low battery alert (< 20%) | | | lowBattery | Switch | yes | Low battery alert (< 20%) |
| device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet | | device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet |
## Shelly BLU Motion Sensor (thing-type: shellyblumotion)
See notes on discovery of Shelly BLU devices above.
| Group | Channel | Type | read-only | Description |
| ------- | ------------- | -------- | --------- | ----------------------------------------------------------------------------------- |
| sensors | motion | Switch | yes | ON: Motion detected |
| battery | batteryLevel | Number | yes | Battery Level in % |
| | lowBattery | Switch | yes | Low battery alert (< 20%) |
| device | gatewayDevice | String | yes | Shelly forwarded last status update (BLU gateway), could vary from packet to packet |
## Shelly Wall Displays ## Shelly Wall Displays
| Group | Channel | Type | read-only | Description | | Group | Channel | Type | read-only | Description |

View File

@ -103,6 +103,7 @@ public class ShellyBindingConstants {
// Shelly BLU // Shelly BLU
THING_TYPE_SHELLYBLUBUTTON, // THING_TYPE_SHELLYBLUBUTTON, //
THING_TYPE_SHELLYBLUDW, // THING_TYPE_SHELLYBLUDW, //
THING_TYPE_SHELLYBLUMOTION, //
THING_TYPE_SHELLYPROTECTED, // THING_TYPE_SHELLYPROTECTED, //
THING_TYPE_SHELLYUNKNOWN); THING_TYPE_SHELLYUNKNOWN);

View File

@ -220,7 +220,8 @@ public class ShellyDeviceProfile {
isHT = thingType.equals(THING_TYPE_SHELLYHT_STR) || thingType.equals(THING_TYPE_SHELLYPLUSHT_STR); isHT = thingType.equals(THING_TYPE_SHELLYHT_STR) || thingType.equals(THING_TYPE_SHELLYPLUSHT_STR);
isDW = thingType.equals(THING_TYPE_SHELLYDOORWIN_STR) || thingType.equals(THING_TYPE_SHELLYDOORWIN2_STR) isDW = thingType.equals(THING_TYPE_SHELLYDOORWIN_STR) || thingType.equals(THING_TYPE_SHELLYDOORWIN2_STR)
|| thingType.equals(THING_TYPE_SHELLYBLUDW_STR); || thingType.equals(THING_TYPE_SHELLYBLUDW_STR);
isMotion = thingType.startsWith(THING_TYPE_SHELLYMOTION_STR); isMotion = thingType.startsWith(THING_TYPE_SHELLYMOTION_STR)
|| thingType.equals(THING_TYPE_SHELLYBLUMOTION_STR);
isSense = thingType.equals(THING_TYPE_SHELLYSENSE_STR); isSense = thingType.equals(THING_TYPE_SHELLYSENSE_STR);
isIX = thingType.equals(THING_TYPE_SHELLYIX3_STR) || thingType.equals(THING_TYPE_SHELLYPLUSI4_STR) isIX = thingType.equals(THING_TYPE_SHELLYIX3_STR) || thingType.equals(THING_TYPE_SHELLYPLUSI4_STR)
|| thingType.equals(THING_TYPE_SHELLYPLUSI4DC_STR); || thingType.equals(THING_TYPE_SHELLYPLUSI4DC_STR);
@ -401,7 +402,8 @@ public class ShellyDeviceProfile {
} }
public static boolean isGeneration2(String thingType) { public static boolean isGeneration2(String thingType) {
return thingType.startsWith("shellyplus") || thingType.startsWith("shellypro") || isBluSeries(thingType); return thingType.startsWith("shellyplus") || thingType.startsWith("shellypro")
|| thingType.startsWith("shellymini") || isBluSeries(thingType);
} }
public static boolean isBluSeries(String thingType) { public static boolean isBluSeries(String thingType) {

View File

@ -18,7 +18,6 @@ import static org.openhab.binding.shelly.internal.api2.Shelly2ApiJsonDTO.*;
import static org.openhab.binding.shelly.internal.util.ShellyUtils.*; import static org.openhab.binding.shelly.internal.util.ShellyUtils.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Random; import java.util.Random;
@ -102,57 +101,46 @@ public class Shelly2ApiClient extends ShellyHttpClient {
super(thingName, config, httpClient); super(thingName, config, httpClient);
} }
protected static final Map<String, String> MAP_INMODE_BTNTYPE = new HashMap<>(); protected static final Map<String, String> MAP_INMODE_BTNTYPE = Map.of(//
static { SHELLY2_BTNT_MOMENTARY, SHELLY_BTNT_MOMENTARY, //
MAP_INMODE_BTNTYPE.put(SHELLY2_BTNT_MOMENTARY, SHELLY_BTNT_MOMENTARY); SHELLY2_BTNT_FLIP, SHELLY_BTNT_TOGGLE, //
MAP_INMODE_BTNTYPE.put(SHELLY2_BTNT_FLIP, SHELLY_BTNT_TOGGLE); SHELLY2_BTNT_FOLLOW, SHELLY_BTNT_EDGE, //
MAP_INMODE_BTNTYPE.put(SHELLY2_BTNT_FOLLOW, SHELLY_BTNT_EDGE); SHELLY2_BTNT_DETACHED, SHELLY_BTNT_MOMENTARY);
MAP_INMODE_BTNTYPE.put(SHELLY2_BTNT_DETACHED, SHELLY_BTNT_MOMENTARY);
}
protected static final Map<String, String> MAP_INPUT_EVENT_TYPE = new HashMap<>(); protected static final Map<String, String> MAP_INPUT_EVENT_TYPE = Map.of(//
static { SHELLY2_EVENT_1PUSH, SHELLY_BTNEVENT_1SHORTPUSH, //
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_1PUSH, SHELLY_BTNEVENT_1SHORTPUSH); SHELLY2_EVENT_2PUSH, SHELLY_BTNEVENT_2SHORTPUSH, //
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_2PUSH, SHELLY_BTNEVENT_2SHORTPUSH); SHELLY2_EVENT_3PUSH, SHELLY_BTNEVENT_3SHORTPUSH, //
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_3PUSH, SHELLY_BTNEVENT_3SHORTPUSH); SHELLY2_EVENT_LPUSH, SHELLY_BTNEVENT_LONGPUSH, //
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_LPUSH, SHELLY_BTNEVENT_LONGPUSH); SHELLY2_EVENT_LSPUSH, SHELLY_BTNEVENT_LONGSHORTPUSH, //
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_LSPUSH, SHELLY_BTNEVENT_LONGSHORTPUSH); SHELLY2_EVENT_SLPUSH, SHELLY_BTNEVENT_SHORTLONGPUSH);
MAP_INPUT_EVENT_TYPE.put(SHELLY2_EVENT_SLPUSH, SHELLY_BTNEVENT_SHORTLONGPUSH);
}
protected static final Map<String, String> MAP_INPUT_EVENT_ID = new HashMap<>(); protected static final Map<String, String> MAP_INPUT_EVENT_ID = Map.of(//
static { SHELLY2_EVENT_BTNUP, SHELLY_EVENT_BTN_OFF, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_BTNUP, SHELLY_EVENT_BTN_OFF); SHELLY2_EVENT_BTNDOWN, SHELLY_EVENT_BTN_ON, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_BTNDOWN, SHELLY_EVENT_BTN_ON); SHELLY2_EVENT_1PUSH, SHELLY_EVENT_SHORTPUSH, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_1PUSH, SHELLY_EVENT_SHORTPUSH); SHELLY2_EVENT_2PUSH, SHELLY_EVENT_DOUBLE_SHORTPUSH, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_2PUSH, SHELLY_EVENT_DOUBLE_SHORTPUSH); SHELLY2_EVENT_3PUSH, SHELLY_EVENT_TRIPLE_SHORTPUSH, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_3PUSH, SHELLY_EVENT_TRIPLE_SHORTPUSH); SHELLY2_EVENT_LPUSH, SHELLY_EVENT_LONGPUSH, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_LPUSH, SHELLY_EVENT_LONGPUSH); SHELLY2_EVENT_LSPUSH, SHELLY_EVENT_LONG_SHORTPUSH, //
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_LSPUSH, SHELLY_EVENT_LONG_SHORTPUSH); SHELLY2_EVENT_SLPUSH, SHELLY_EVENT_SHORT_LONGTPUSH);
MAP_INPUT_EVENT_ID.put(SHELLY2_EVENT_SLPUSH, SHELLY_EVENT_SHORT_LONGTPUSH);
}
protected static final Map<String, String> MAP_INPUT_MODE = new HashMap<>(); protected static final Map<String, String> MAP_INPUT_MODE = Map.of(//
static { SHELLY2_RMODE_SINGLE, SHELLY_INP_MODE_ONEBUTTON, //
MAP_INPUT_MODE.put(SHELLY2_RMODE_SINGLE, SHELLY_INP_MODE_ONEBUTTON); SHELLY2_RMODE_DUAL, SHELLY_INP_MODE_OPENCLOSE, //
MAP_INPUT_MODE.put(SHELLY2_RMODE_DUAL, SHELLY_INP_MODE_OPENCLOSE); SHELLY2_RMODE_DETACHED, SHELLY_INP_MODE_ONEBUTTON);
MAP_INPUT_MODE.put(SHELLY2_RMODE_DETACHED, SHELLY_INP_MODE_ONEBUTTON);
}
protected static final Map<String, String> MAP_ROLLER_STATE = new HashMap<>(); protected static final Map<String, String> MAP_ROLLER_STATE = Map.of(//
static { SHELLY2_RSTATE_OPEN, SHELLY_RSTATE_OPEN, //
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_OPEN, SHELLY_RSTATE_OPEN); SHELLY2_RSTATE_CLOSED, SHELLY_RSTATE_CLOSE, //
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_CLOSED, SHELLY_RSTATE_CLOSE); SHELLY2_RSTATE_OPENING, SHELLY2_RSTATE_OPENING, // Gen2-only
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_OPENING, SHELLY2_RSTATE_OPENING); // Gen2-only SHELLY2_RSTATE_CLOSING, SHELLY2_RSTATE_CLOSING, // Gen2-only
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_CLOSING, SHELLY2_RSTATE_CLOSING); // Gen2-only SHELLY2_RSTATE_STOPPED, SHELLY_RSTATE_STOP, //
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_STOPPED, SHELLY_RSTATE_STOP); SHELLY2_RSTATE_CALIB, SHELLY2_RSTATE_CALIB); // Gen2-only
MAP_ROLLER_STATE.put(SHELLY2_RSTATE_CALIB, SHELLY2_RSTATE_CALIB); // Gen2-only
} protected static final Map<String, String> MAP_PROFILE = Map.of(//
protected static final Map<String, String> MAP_PROFILE = new HashMap<>(); SHELLY_CLASS_RELAY, SHELLY2_PROFILE_RELAY, //
static { SHELLY_CLASS_ROLLER, SHELLY2_PROFILE_COVER);
MAP_PROFILE.put(SHELLY_CLASS_RELAY, SHELLY2_PROFILE_RELAY);
MAP_PROFILE.put(SHELLY_CLASS_ROLLER, SHELLY2_PROFILE_COVER);
}
protected @Nullable ArrayList<@Nullable ShellySettingsRelay> fillRelaySettings(ShellyDeviceProfile profile, protected @Nullable ArrayList<@Nullable ShellySettingsRelay> fillRelaySettings(ShellyDeviceProfile profile,
Shelly2GetConfigResult dc) { Shelly2GetConfigResult dc) {

View File

@ -1085,6 +1085,10 @@ public class Shelly2ApiJsonDTO {
public Integer windowState; public Integer windowState;
@SerializedName("Rotation") @SerializedName("Rotation")
public Double rotation; public Double rotation;
@SerializedName("Motion")
public Integer motionState;
@SerializedName("Temperature")
public Double temperature;
public Integer rssi; public Integer rssi;
public Integer tx_power; public Integer tx_power;

View File

@ -27,6 +27,7 @@ import org.openhab.binding.shelly.internal.api.ShellyApiException;
import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile; import org.openhab.binding.shelly.internal.api.ShellyDeviceProfile;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputState; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellyInputState;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySensorSleepMode; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySensorSleepMode;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySensorTmp;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsDevice;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsInput; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsInput;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus; import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
@ -271,12 +272,22 @@ public class ShellyBluApi extends Shelly2ApiRpc {
sensorData.lux.isValid = true; sensorData.lux.isValid = true;
sensorData.lux.value = (double) e.data.illuminance; sensorData.lux.value = (double) e.data.illuminance;
} }
if (e.data.temperature != null) {
if (sensorData.tmp == null) {
sensorData.tmp = new ShellySensorTmp();
}
sensorData.tmp.tC = e.data.temperature;
sensorData.tmp.isValid = true;
}
if (e.data.rotation != null) { if (e.data.rotation != null) {
if (sensorData.accel == null) { if (sensorData.accel == null) {
sensorData.accel = new ShellySensorAccel(); sensorData.accel = new ShellySensorAccel();
} }
sensorData.accel.tilt = e.data.rotation.intValue(); sensorData.accel.tilt = e.data.rotation.intValue();
} }
if (e.data.motionState != null) {
sensorData.motion = e.data.motionState == 1;
}
if (e.data.buttonEvent != null) { if (e.data.buttonEvent != null) {
ShellyInputState input = deviceStatus.inputs != null ? deviceStatus.inputs.get(0) ShellyInputState input = deviceStatus.inputs != null ? deviceStatus.inputs.get(0)
@ -314,6 +325,8 @@ public class ShellyBluApi extends Shelly2ApiRpc {
return (THING_TYPE_SHELLYBLUBUTTON_STR + "-" + mac).toLowerCase(); return (THING_TYPE_SHELLYBLUBUTTON_STR + "-" + mac).toLowerCase();
case SHELLYDT_BLUDW: case SHELLYDT_BLUDW:
return (THING_TYPE_SHELLYBLUDW_STR + "-" + mac).toLowerCase(); return (THING_TYPE_SHELLYBLUDW_STR + "-" + mac).toLowerCase();
case SHELLYDT_BLUMOTION:
return (THING_TYPE_SHELLYBLUMOTION_STR + "-" + mac).toLowerCase();
default: default:
throw new IllegalArgumentException("Unsupported BLU device model " + model); throw new IllegalArgumentException("Unsupported BLU device model " + model);
} }

View File

@ -113,6 +113,7 @@ public class ShellyThingCreator {
// Shelly BLU Series // Shelly BLU Series
public static final String SHELLYDT_BLUBUTTON = "SBBT"; public static final String SHELLYDT_BLUBUTTON = "SBBT";
public static final String SHELLYDT_BLUDW = "SBDW"; public static final String SHELLYDT_BLUDW = "SBDW";
public static final String SHELLYDT_BLUMOTION = "SBMO";
// Thing names // Thing names
public static final String THING_TYPE_SHELLY1_STR = "shelly1"; public static final String THING_TYPE_SHELLY1_STR = "shelly1";
@ -191,6 +192,7 @@ public class ShellyThingCreator {
public static final String THING_TYPE_SHELLYBLU_PREFIX = "shellyblu"; public static final String THING_TYPE_SHELLYBLU_PREFIX = "shellyblu";
public static final String THING_TYPE_SHELLYBLUBUTTON_STR = THING_TYPE_SHELLYBLU_PREFIX + "button"; public static final String THING_TYPE_SHELLYBLUBUTTON_STR = THING_TYPE_SHELLYBLU_PREFIX + "button";
public static final String THING_TYPE_SHELLYBLUDW_STR = THING_TYPE_SHELLYBLU_PREFIX + "dw"; public static final String THING_TYPE_SHELLYBLUDW_STR = THING_TYPE_SHELLYBLU_PREFIX + "dw";
public static final String THING_TYPE_SHELLYBLUMOTION_STR = THING_TYPE_SHELLYBLU_PREFIX + "motion";
// Password protected or unknown device // Password protected or unknown device
public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice"; public static final String THING_TYPE_SHELLYPROTECTED_STR = "shellydevice";
@ -306,6 +308,8 @@ public class ShellyThingCreator {
public static final ThingTypeUID THING_TYPE_SHELLYBLUBUTTON = new ThingTypeUID(BINDING_ID, public static final ThingTypeUID THING_TYPE_SHELLYBLUBUTTON = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBLUBUTTON_STR); THING_TYPE_SHELLYBLUBUTTON_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBLUDW = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBLUDW_STR); public static final ThingTypeUID THING_TYPE_SHELLYBLUDW = new ThingTypeUID(BINDING_ID, THING_TYPE_SHELLYBLUDW_STR);
public static final ThingTypeUID THING_TYPE_SHELLYBLUMOTION = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBLUMOTION_STR);
private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>(); private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>();
static { static {
@ -383,6 +387,7 @@ public class ShellyThingCreator {
// BLU Series // BLU Series
THING_TYPE_MAPPING.put(SHELLYDT_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR); THING_TYPE_MAPPING.put(SHELLYDT_BLUBUTTON, THING_TYPE_SHELLYBLUBUTTON_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR); THING_TYPE_MAPPING.put(SHELLYDT_BLUDW, THING_TYPE_SHELLYBLUDW_STR);
THING_TYPE_MAPPING.put(SHELLYDT_BLUMOTION, THING_TYPE_SHELLYBLUMOTION_STR);
// Wall displays // Wall displays
THING_TYPE_MAPPING.put(SHELLYDT_PLUSWALLDISPLAY, THING_TYPE_SHELLYPLUSWALLDISPLAY_STR); THING_TYPE_MAPPING.put(SHELLYDT_PLUSWALLDISPLAY, THING_TYPE_SHELLYPLUSWALLDISPLAY_STR);

View File

@ -1019,6 +1019,7 @@ public abstract class ShellyBaseHandler extends BaseThingHandler
config.password = bindingConfig.defaultPassword; config.password = bindingConfig.defaultPassword;
logger.debug("{}: Using default password from bindingConfig (userId={})", thingName, config.userId); logger.debug("{}: Using default password from bindingConfig (userId={})", thingName, config.userId);
} }
if (config.updateInterval == 0) { if (config.updateInterval == 0) {
config.updateInterval = UPDATE_STATUS_INTERVAL_SECONDS * UPDATE_SKIP_COUNT; config.updateInterval = UPDATE_STATUS_INTERVAL_SECONDS * UPDATE_SKIP_COUNT;
} }

View File

@ -67,6 +67,10 @@ public class ShellyBluSensorHandler extends ShellyBaseHandler {
ttype = THING_TYPE_SHELLYBLUDW_STR; ttype = THING_TYPE_SHELLYBLUDW_STR;
tuid = THING_TYPE_SHELLYBLUDW; tuid = THING_TYPE_SHELLYBLUDW;
break; break;
case SHELLYDT_BLUMOTION:
ttype = THING_TYPE_SHELLYBLUMOTION_STR;
tuid = THING_TYPE_SHELLYBLUMOTION;
break;
default: default:
logger.debug("{}: Unsupported BLU device model {}, MAC={}", gateway, model, mac); logger.debug("{}: Unsupported BLU device model {}, MAC={}", gateway, model, mac);
return; return;

View File

@ -376,7 +376,9 @@ public class ShellyManagerActionPage extends ShellyManagerPage {
boolean gen2 = profile.isGen2; boolean gen2 = profile.isGen2;
list.put(ACTION_RES_STATS, "Reset Statistics"); list.put(ACTION_RES_STATS, "Reset Statistics");
list.put(ACTION_RESTART, "Reboot Device"); if (!profile.isBlu) {
list.put(ACTION_RESTART, "Reboot Device");
}
if (!gen2 || !profile.isBlu) { if (!gen2 || !profile.isBlu) {
list.put(ACTION_PROTECT, "Protect Device"); list.put(ACTION_PROTECT, "Protect Device");
} }
@ -413,10 +415,13 @@ public class ShellyManagerActionPage extends ShellyManagerPage {
!profile.settings.bluetooth ? "Enable Bluetooth" : "Disable Bluetooth"); !profile.settings.bluetooth ? "Enable Bluetooth" : "Disable Bluetooth");
} }
boolean set = profile.settings.cloud != null && getBool(profile.settings.cloud.enabled); if (!profile.isBlu) {
list.put(set ? ACTION_DISCLOUD : ACTION_ENCLOUD, set ? "Disable Cloud" : "Enable Cloud"); boolean set = profile.settings.cloud != null && getBool(profile.settings.cloud.enabled);
list.put(set ? ACTION_DISCLOUD : ACTION_ENCLOUD, set ? "Disable Cloud" : "Enable Cloud");
list.put(ACTION_RESET, "-Factory Reset");
}
list.put(ACTION_RESET, "-Factory Reset");
if (!gen2 && profile.extFeatures) { if (!gen2 && profile.extFeatures) {
list.put(ACTION_OTACHECK, "Check for Update"); list.put(ACTION_OTACHECK, "Check for Update");
boolean debug_enable = getBool(profile.settings.debugEnable); boolean debug_enable = getBool(profile.settings.debugEnable);

View File

@ -12,6 +12,8 @@
*/ */
package org.openhab.binding.shelly.internal.manager; package org.openhab.binding.shelly.internal.manager;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.CONFIG_DEVICEIP;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
@ -82,6 +84,7 @@ public class ShellyManagerConstants {
public static final String ATTRIBUTE_MESSAGE = "message"; public static final String ATTRIBUTE_MESSAGE = "message";
public static final String ATTRIBUTE_TOTAL_DEV = "totalDevices"; public static final String ATTRIBUTE_TOTAL_DEV = "totalDevices";
public static final String ATTRIBUTE_STATUS_ICON = "iconStatus"; public static final String ATTRIBUTE_STATUS_ICON = "iconStatus";
public static final String ATTRIBUTE_DEVICEIP = CONFIG_DEVICEIP;
public static final String ATTRIBUTE_DISPLAY_NAME = "displayName"; public static final String ATTRIBUTE_DISPLAY_NAME = "displayName";
public static final String ATTRIBUTE_DEV_STATUS = "deviceStatus"; public static final String ATTRIBUTE_DEV_STATUS = "deviceStatus";
public static final String ATTRIBUTE_DEBUG_MODE = "debugMode"; public static final String ATTRIBUTE_DEBUG_MODE = "debugMode";

View File

@ -117,6 +117,11 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage {
properties.put(ATTRIBUTE_FIRMWARE_SEL, ""); properties.put(ATTRIBUTE_FIRMWARE_SEL, "");
properties.put(ATTRIBUTE_ACTION_LIST, ""); properties.put(ATTRIBUTE_ACTION_LIST, "");
} }
if (profile.isBlu) {
properties.put(ATTRIBUTE_DISPLAY_NAME, profile.thingName);
properties.put(ATTRIBUTE_DEVICEIP, "n/a");
properties.put(PROPERTY_WIFI_NETW, "Bluetooth");
}
html += loadHTML(OVERVIEW_DEVICE, properties); html += loadHTML(OVERVIEW_DEVICE, properties);
} }
} catch (ShellyApiException e) { } catch (ShellyApiException e) {
@ -193,10 +198,13 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage {
logger.debug("{}: Unable to retrieve firmware list: {}", LOG_PREFIX, e.toString()); logger.debug("{}: Unable to retrieve firmware list: {}", LOG_PREFIX, e.toString());
} }
html += "\t\t\t\t\t<option class=\"select-hr\" value=\"" + SHELLY_MGR_FWUPDATE_URI + "?uid=" + uid html += "\t\t\t\t\t<option class=\"select-hr\" value=\"" + SHELLY_MGR_FWUPDATE_URI + "?uid=" + uid;
+ "&connection=custom\">Custom URL</option>\n"; if (!profile.isBlu) {
html += "&connection=custom\">Custom URL";
html += "\t\t\t\t</select>\n\t\t\t"; } else {
html += "\">Check Device App";
}
html += "</option>\n\t\t\t\t</select>\n\t\t\t";
return html; return html;
} }

View File

@ -538,7 +538,7 @@ public class ShellyManagerPage {
} }
protected static String getDeviceIp(Map<String, String> properties) { protected static String getDeviceIp(Map<String, String> properties) {
return getString(properties.get("deviceIp")); return getString(properties.get(ATTRIBUTE_DEVICEIP));
} }
protected static String getDeviceName(Map<String, String> properties) { protected static String getDeviceName(Map<String, String> properties) {

View File

@ -657,19 +657,19 @@ public class ShellyChannelDefinitions {
this.typeId = typeId; this.typeId = typeId;
groupLabel = getText(PREFIX_GROUP + group + ".label"); groupLabel = getText(PREFIX_GROUP + group + ".label");
if (groupLabel.contains(PREFIX_GROUP)) { if (groupLabel.startsWith(PREFIX_GROUP)) {
groupLabel = ""; groupLabel = "";
} }
groupDescription = getText(PREFIX_GROUP + group + ".description"); groupDescription = getText(PREFIX_GROUP + group + ".description");
if (groupDescription.contains(PREFIX_GROUP)) { if (groupDescription.startsWith(PREFIX_GROUP)) {
groupDescription = ""; groupDescription = "";
} }
label = getText(PREFIX_CHANNEL + typeId.replace(':', '.') + ".label"); label = getText(PREFIX_CHANNEL + typeId.replace(':', '.') + ".label");
if (label.contains(PREFIX_CHANNEL)) { if (label.startsWith(PREFIX_CHANNEL)) {
label = ""; label = "";
} }
description = getText(PREFIX_CHANNEL + typeId + ".description"); description = getText(PREFIX_CHANNEL + typeId + ".description");
if (description.contains(PREFIX_CHANNEL)) { if (description.startsWith(PREFIX_CHANNEL)) {
description = ""; // no resource found description = ""; // no resource found
} }
} }

View File

@ -42,7 +42,7 @@ message.event.triggered = Event triggered: {0}
message.event.filtered = Event filtered: {0} message.event.filtered = Event filtered: {0}
message.coap.init.failed = Unable to start CoIoT: {0} message.coap.init.failed = Unable to start CoIoT: {0}
message.discovery.disabled = Device is marked as non-discoverable, will be skipped message.discovery.disabled = Device is marked as non-discoverable, will be skipped
message.discovery.protected = Device {0} is protected and reports 'Access denied', check userId/password message.discovery.protected = Device {0} is protected and reports 'Access denied', check userId/password.
message.discovery.failed = Device discovery of device with address {0} failed: {1} message.discovery.failed = Device discovery of device with address {0} failed: {1}
message.roller.calibrating = Device is not calibrated, use Shelly App to perform initial roller calibration. message.roller.calibrating = Device is not calibrated, use Shelly App to perform initial roller calibration.
message.roller.favmissing = Roller position favorites are not supported by installed firmware or not configured in the Shelly App message.roller.favmissing = Roller position favorites are not supported by installed firmware or not configured in the Shelly App
@ -122,6 +122,7 @@ thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch wit
# BLU devices # BLU devices
thing-type.shelly.shellyblubutton.description = Shelly BLU Button thing-type.shelly.shellyblubutton.description = Shelly BLU Button
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
thing-type.shelly.shellyblumotion.description = Shelly BLU Motion Sensor
# Wall Displays # Wall Displays
thing-type.shelly.shellywalldisplay.description = Shelly Wall Display with sensors and input/output thing-type.shelly.shellywalldisplay.description = Shelly Wall Display with sensors and input/output

View File

@ -32,4 +32,17 @@
<config-description-ref uri="thing-type:shelly:blubattery"/> <config-description-ref uri="thing-type:shelly:blubattery"/>
</thing-type> </thing-type>
<thing-type id="shellyblumotion">
<label>Shelly BLU Motion</label>
<description>@text/thing-type.shelly.shellyblumotion.description</description>
<category>Sensor</category>
<channel-groups>
<channel-group id="sensors" typeId="sensorData"/>
<channel-group id="battery" typeId="batteryStatus"/>
<channel-group id="device" typeId="deviceStatus"/>
</channel-groups>
<representation-property>serviceName</representation-property>
<config-description-ref uri="thing-type:shelly:blubattery"/>
</thing-type>
</thing:thing-descriptions> </thing:thing-descriptions>

View File

@ -4,7 +4,7 @@
* Version 0.2 * Version 0.2
*/ */
let ALLTERCO_DEVICE_NAME_PREFIX = ["SBBT", "SBDW"]; let ALLTERCO_DEVICE_NAME_PREFIX = ["SBBT", "SBDW", "SBMO"];
let ALLTERCO_MFD_ID_STR = "0ba9"; let ALLTERCO_MFD_ID_STR = "0ba9";
let BTHOME_SVC_ID_STR = "fcd2"; let BTHOME_SVC_ID_STR = "fcd2";
@ -25,9 +25,11 @@ let int24 = 5;
let BTH = []; let BTH = [];
BTH[0x00] = { n: "pid", t: uint8 }; BTH[0x00] = { n: "pid", t: uint8 };
BTH[0x01] = { n: "Battery", t: uint8, u: "%" }; BTH[0x01] = { n: "Battery", t: uint8, u: "%" };
BTH[0x02] = { n: "Temperature", t: int16, f: 0.01 };
BTH[0x05] = { n: "Illuminance", t: uint24, f: 0.01 }; BTH[0x05] = { n: "Illuminance", t: uint24, f: 0.01 };
BTH[0x1a] = { n: "Door", t: uint8 }; BTH[0x1a] = { n: "Door", t: uint8 };
BTH[0x20] = { n: "Moisture", t: uint8 }; BTH[0x20] = { n: "Moisture", t: uint8 };
BTH[0x21] = { n: "Motion", t: uint8 };
BTH[0x2d] = { n: "Window", t: uint8 }; BTH[0x2d] = { n: "Window", t: uint8 };
BTH[0x3a] = { n: "Button", t: uint8 }; BTH[0x3a] = { n: "Button", t: uint8 };
BTH[0x3f] = { n: "Rotation", t: int16, f: 0.1 }; BTH[0x3f] = { n: "Rotation", t: int16, f: 0.1 };