[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 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.
@ -120,7 +122,7 @@ The binding provides the same feature set across all devices as good as possible
| ----------------- | ------------------------------------------------------ | --------- |
| shellyblubutton | Shelly BLU Button 1 | SBBT |
| shellybludw | Shelly BLU Door/Windows | SBDW |
| shellyblumotion | Shelly BLU Motion | SBMO |
## Binding Configuration
@ -1465,6 +1467,17 @@ See notes on discovery of Shelly BLU devices above.
| | 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 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
| Group | Channel | Type | read-only | Description |

View File

@ -103,6 +103,7 @@ public class ShellyBindingConstants {
// Shelly BLU
THING_TYPE_SHELLYBLUBUTTON, //
THING_TYPE_SHELLYBLUDW, //
THING_TYPE_SHELLYBLUMOTION, //
THING_TYPE_SHELLYPROTECTED, //
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);
isDW = thingType.equals(THING_TYPE_SHELLYDOORWIN_STR) || thingType.equals(THING_TYPE_SHELLYDOORWIN2_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);
isIX = thingType.equals(THING_TYPE_SHELLYIX3_STR) || thingType.equals(THING_TYPE_SHELLYPLUSI4_STR)
|| thingType.equals(THING_TYPE_SHELLYPLUSI4DC_STR);
@ -401,7 +402,8 @@ public class ShellyDeviceProfile {
}
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) {

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

View File

@ -1085,6 +1085,10 @@ public class Shelly2ApiJsonDTO {
public Integer windowState;
@SerializedName("Rotation")
public Double rotation;
@SerializedName("Motion")
public Integer motionState;
@SerializedName("Temperature")
public Double temperature;
public Integer rssi;
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.api1.Shelly1ApiJsonDTO.ShellyInputState;
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.ShellySettingsInput;
import org.openhab.binding.shelly.internal.api1.Shelly1ApiJsonDTO.ShellySettingsStatus;
@ -271,12 +272,22 @@ public class ShellyBluApi extends Shelly2ApiRpc {
sensorData.lux.isValid = true;
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 (sensorData.accel == null) {
sensorData.accel = new ShellySensorAccel();
}
sensorData.accel.tilt = e.data.rotation.intValue();
}
if (e.data.motionState != null) {
sensorData.motion = e.data.motionState == 1;
}
if (e.data.buttonEvent != null) {
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();
case SHELLYDT_BLUDW:
return (THING_TYPE_SHELLYBLUDW_STR + "-" + mac).toLowerCase();
case SHELLYDT_BLUMOTION:
return (THING_TYPE_SHELLYBLUMOTION_STR + "-" + mac).toLowerCase();
default:
throw new IllegalArgumentException("Unsupported BLU device model " + model);
}

View File

@ -113,6 +113,7 @@ public class ShellyThingCreator {
// Shelly BLU Series
public static final String SHELLYDT_BLUBUTTON = "SBBT";
public static final String SHELLYDT_BLUDW = "SBDW";
public static final String SHELLYDT_BLUMOTION = "SBMO";
// Thing names
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_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_SHELLYBLUMOTION_STR = THING_TYPE_SHELLYBLU_PREFIX + "motion";
// Password protected or unknown device
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,
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_SHELLYBLUMOTION = new ThingTypeUID(BINDING_ID,
THING_TYPE_SHELLYBLUMOTION_STR);
private static final Map<String, String> THING_TYPE_MAPPING = new LinkedHashMap<>();
static {
@ -383,6 +387,7 @@ public class ShellyThingCreator {
// BLU Series
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_BLUMOTION, THING_TYPE_SHELLYBLUMOTION_STR);
// Wall displays
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;
logger.debug("{}: Using default password from bindingConfig (userId={})", thingName, config.userId);
}
if (config.updateInterval == 0) {
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;
tuid = THING_TYPE_SHELLYBLUDW;
break;
case SHELLYDT_BLUMOTION:
ttype = THING_TYPE_SHELLYBLUMOTION_STR;
tuid = THING_TYPE_SHELLYBLUMOTION;
break;
default:
logger.debug("{}: Unsupported BLU device model {}, MAC={}", gateway, model, mac);
return;

View File

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

View File

@ -12,6 +12,8 @@
*/
package org.openhab.binding.shelly.internal.manager;
import static org.openhab.binding.shelly.internal.ShellyBindingConstants.CONFIG_DEVICEIP;
import java.nio.charset.StandardCharsets;
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_TOTAL_DEV = "totalDevices";
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_DEV_STATUS = "deviceStatus";
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_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);
}
} catch (ShellyApiException e) {
@ -193,10 +198,13 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage {
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
+ "&connection=custom\">Custom URL</option>\n";
html += "\t\t\t\t</select>\n\t\t\t";
html += "\t\t\t\t\t<option class=\"select-hr\" value=\"" + SHELLY_MGR_FWUPDATE_URI + "?uid=" + uid;
if (!profile.isBlu) {
html += "&connection=custom\">Custom URL";
} else {
html += "\">Check Device App";
}
html += "</option>\n\t\t\t\t</select>\n\t\t\t";
return html;
}

View File

@ -538,7 +538,7 @@ public class ShellyManagerPage {
}
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) {

View File

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

View File

@ -42,7 +42,7 @@ message.event.triggered = Event triggered: {0}
message.event.filtered = Event filtered: {0}
message.coap.init.failed = Unable to start CoIoT: {0}
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.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
@ -122,6 +122,7 @@ thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch wit
# BLU devices
thing-type.shelly.shellyblubutton.description = Shelly BLU Button
thing-type.shelly.shellybludw.description = Shelly BLU Door/Window Sensor
thing-type.shelly.shellyblumotion.description = Shelly BLU Motion Sensor
# Wall Displays
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"/>
</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>

View File

@ -4,7 +4,7 @@
* 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 BTHOME_SVC_ID_STR = "fcd2";
@ -25,9 +25,11 @@ let int24 = 5;
let BTH = [];
BTH[0x00] = { n: "pid", t: uint8 };
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[0x1a] = { n: "Door", t: uint8 };
BTH[0x20] = { n: "Moisture", t: uint8 };
BTH[0x21] = { n: "Motion", t: uint8 };
BTH[0x2d] = { n: "Window", t: uint8 };
BTH[0x3a] = { n: "Button", t: uint8 };
BTH[0x3f] = { n: "Rotation", t: int16, f: 0.1 };