[shelly] 1PM/1L/2.5: New device#supplyVoltage; Motion: Missing channel for vibration; UNI: Unit for ADC voltage; PF for EM; Bulb: fix range for color temp (#10815)

* fixes #10738, #10799

Signed-off-by: Markus Michels <markus7017@gmail.com>

* - Feature #10090 New device#supplyVoltage channel for Shelly 2.5, 1PM
and 1L
- Change  #10039 Info on "not reachable / timeout" should be warning,
not info
- Fix     #10799 Missing Channel Definition for Vibration Events
- Fix     #10738 Shelly UNI - ADC Voltage units of measure missing
- Fix     #10111 Creating Equipment from Shelly Bulb Duo causes wrong
min/max
- README updated

Signed-off-by: Markus Michels <markus7017@gmail.com>

* #10737 Shelly EM - add powerFactor channel support

Signed-off-by: Markus Michels <markus7017@gmail.com>

* README updated

Signed-off-by: Markus Michels <markus7017@gmail.com>

* channel powerFactor (EM+EM3) is now of type Number:Dimensionless

Signed-off-by: Markus Michels <markus7017@gmail.com>

* Fix for #10864: Do not trigger same alarm within 5 minutes

Signed-off-by: Markus Michels <markus7017@gmail.com>

* better logic for alarm filter

Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
Markus Michels 2021-06-16 00:00:56 +02:00 committed by GitHub
parent c9933454db
commit d0f4b84841
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 72 additions and 28 deletions

View File

@ -207,6 +207,7 @@ Every device has a channel group `device` with the following channels:
| |internalTemp |Number |yes |Internal device temperature (when provided by the device) |
| |selfTest |String |yes |Result from device self-test (pending/not_completed/running/completed/unknown) |
| |alarm |Trigger |yes |Self-Test result not_completed/completed/running/pending |
| |supplyVoltage |Number |yes |Shelly 1PM, 1L, 2.5: Supply voltage (fixed or measured depending on device) |
| |accumulatedWatts |Number |yes |Accumulated power in W of the device (including all meters) |
| |accumulatedTotal |Number |yes |Accumulated total power in kwh of the device (including all meters) |
| |accumulatedReturned|Number |yes |Accumulated returned power in kwh of the device (including all meters) |
@ -401,12 +402,14 @@ In this case the is no real measurement based on power consumption, but the Shel
| |returnedKWH |Number |yes |Total returned energy, kwh |
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
| |voltage |Number |yes |RMS voltage, Volts |
| |powerFactor |Number |yes |Power Factor in percent |
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|meter2 |currentWatts |Number |yes |Current power consumption in Watts |
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
| |returnedKWH |Number |yes |Total returned energy, kwh |
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
| |voltage |Number |yes |RMS voltage, Volts |
| |powerFactor |Number |yes |Power Factor in percent |
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
### Shelly 3EM (thing-type: shellyem3)
@ -431,7 +434,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
| |voltage |Number |yes |RMS voltage, Volts |
| |current |Number |yes |Current in A |
| |powerFactor |Number |yes |Power Factor |
| |powerFactor |Number |yes |Power Factor in percent |
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|meter2 |currentWatts |Number |yes |Current power consumption in Watts |
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
@ -439,7 +442,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
| |voltage |Number |yes |RMS voltage, Volts |
| |current |Number |yes |Current in A |
| |powerFactor |Number |yes |Power Factor |
| |powerFactor |Number |yes |Power Factor in percent |
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |
|meter3 |currentWatts |Number |yes |Current power consumption in Watts |
| |totalKWH |Number |yes |Total energy consumption in Watts since the device powered up (resets on restart)|
@ -447,7 +450,7 @@ The Thing id is derived from the service name, so that's the reason why the Thin
| |reactiveWatts|Number |yes |Instantaneous reactive power, Watts |
| |voltage |Number |yes |RMS voltage, Volts |
| |current |Number |yes |Current in A |
| |powerFactor |Number |yes |Power Factor |
| |powerFactor |Number |yes |Power Factor in percent |
| |lastUpdate |DateTime |yes |Timestamp of the last measurement |

View File

@ -301,6 +301,7 @@ public class ShellyBindingConstants {
public static final String CHANNEL_DEVST_CHARGER = "charger";
public static final String CHANNEL_DEVST_UPDATE = "updateAvailable";
public static final String CHANNEL_DEVST_SELFTTEST = "selfTest";
public static final String CHANNEL_DEVST_VOLTAGE = "supplyVoltage";
public static final String CHANNEL_LED_STATUS_DISABLE = "statusLed";
public static final String CHANNEL_LED_POWER_DISABLE = "powerLed";

View File

@ -576,6 +576,9 @@ public class ShellyApiJsonDTO {
public Double maxPower;
public ArrayList<ShellySettingsRelay> relays;
public Double voltage; // AC voltage for Shelly 2.5
@SerializedName("supply_voltage")
public Long supplyVoltage; // Shelly 1PM/1L: 0=110V, 1=220V
public ArrayList<ShellySettingsDimmer> dimmers;
public ArrayList<ShellySettingsRgbwLight> lights;
public ArrayList<ShellySettingsEMeter> emeters;
@ -677,6 +680,8 @@ public class ShellyApiJsonDTO {
public ShellyActionsStats astats;
public ArrayList<ShellySettingsRelay> relays;
public Double voltage; // Shelly 2.5
public ArrayList<ShellySettingsRoller> rollers;
public Integer input; // RGBW2 has no JSON array
public ArrayList<ShellyInputState> inputs;

View File

@ -152,7 +152,8 @@ public class ShellyCoIoTVersion1 extends ShellyCoIoTProtocol implements ShellyCo
toQuantityType(getDouble(s.value), DIGITS_VOLT, Units.AMPERE));
break;
case "pf":
updateChannel(updates, rGroup, CHANNEL_EMETER_PFACTOR, getDecimal(s.value));
updateChannel(updates, rGroup, CHANNEL_EMETER_PFACTOR,
toQuantityType(getDecimal(s.value), Units.PERCENT));
break;
case "position":
// work around: Roller reports 101% instead max 100

View File

@ -193,7 +193,7 @@ public class ShellyCoIoTVersion2 extends ShellyCoIoTProtocol implements ShellyCo
break;
case "3118":
updateChannel(updates, mGroup, CHANNEL_SENSOR_VOLTAGE,
toQuantityType(getDouble(s.value), DIGITS_VOLT, Units.VOLT));
toQuantityType(getDouble(s.value), 2, Units.VOLT));
break;
case "4101": // relay_0/light_0: P, power, W

View File

@ -367,7 +367,7 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL
if (res.isNotCalibrtated()) {
logger.warn("{}: {}", thingName, messages.get("roller.calibrating"));
} else {
logger.info("{}: {} - {}", thingName, messages.get("command.failed", command, channelUID),
logger.warn("{}: {} - {}", thingName, messages.get("command.failed", command, channelUID),
e.toString());
}
} catch (IllegalArgumentException e) {
@ -528,7 +528,6 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL
private void fillDeviceStatus(ShellySettingsStatus status, boolean updated) {
String alarm = "";
boolean force = false;
// Update uptime and WiFi, internal temp
ShellyComponents.updateDeviceStatus(this, status);
@ -567,7 +566,7 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL
stats.coiotErrors = coap.getErrorCount();
if (!alarm.isEmpty()) {
postEvent(alarm, force);
postEvent(alarm, false);
}
}
@ -597,7 +596,8 @@ public class ShellyBaseHandler extends BaseThingHandler implements ShellyDeviceL
State value = cache.getValue(channelId);
String lastAlarm = value != UnDefType.NULL ? value.toString() : "";
if (force || !lastAlarm.equals(alarm) || (now() > (stats.lastAlarmTs + HEALTH_CHECK_INTERVAL_SEC))) {
if (force || !lastAlarm.equals(alarm)
|| (lastAlarm.equals(alarm) && now() > stats.lastAlarmTs + HEALTH_CHECK_INTERVAL_SEC)) {
if (alarm.isEmpty() || alarm.equals(ALARM_TYPE_NONE)) {
cache.updateChannel(channelId, getStringType(alarm));
} else {

View File

@ -160,14 +160,10 @@ public class ShellyComponents {
toQuantityType(getDouble(emeter.reactive), DIGITS_WATT, Units.WATT));
updated |= thingHandler.updateChannel(groupName, CHANNEL_EMETER_VOLTAGE,
toQuantityType(getDouble(emeter.voltage), DIGITS_VOLT, Units.VOLT));
if (emeter.current != null) {
// Shelly
updated |= thingHandler.updateChannel(groupName, CHANNEL_EMETER_CURRENT,
toQuantityType(getDouble(emeter.current), DIGITS_VOLT, Units.AMPERE));
updated |= thingHandler.updateChannel(groupName, CHANNEL_EMETER_PFACTOR,
getDecimal(emeter.pf));
}
updated |= thingHandler.updateChannel(groupName, CHANNEL_EMETER_CURRENT,
toQuantityType(getDouble(emeter.current), DIGITS_VOLT, Units.AMPERE));
updated |= thingHandler.updateChannel(groupName, CHANNEL_EMETER_PFACTOR,
toQuantityType(computePF(emeter), Units.PERCENT));
accumulatedWatts += getDouble(emeter.power);
accumulatedTotal += getDouble(emeter.total) / 1000;
@ -234,6 +230,19 @@ public class ShellyComponents {
return updated;
}
private static Double computePF(ShellySettingsEMeter emeter) {
if (emeter.pf != null) { // EM3
return emeter.pf; // take device value
}
// EM: compute from provided values
if (Math.abs(emeter.power) + Math.abs(emeter.reactive) > 1.5) {
double pf = emeter.power / Math.sqrt(emeter.power * emeter.power + emeter.reactive * emeter.reactive);
return pf;
}
return 0.0;
}
/**
* Update Sensor channel
*
@ -324,7 +333,7 @@ public class ShellyComponents {
if ((sdata.adcs != null) && (sdata.adcs.size() > 0)) {
ShellyADC adc = sdata.adcs.get(0);
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_VOLTAGE,
getDecimal(adc.voltage));
toQuantityType(getDouble(adc.voltage), 2, Units.VOLT));
}
boolean charger = (getInteger(profile.settings.externalPower) == 1) || getBool(sdata.charger);

View File

@ -336,8 +336,20 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
boolean updated = false;
// Check for Relay in Standard Mode
if (profile.hasRelays && !profile.isRoller && !profile.isDimmer) {
logger.trace("{}: Updating {} relay(s)", thingName, profile.numRelays);
double voltage = -1;
if (status.voltage == null && profile.settings.supplyVoltage != null) {
// Shelly 1PM/1L (fix)
voltage = profile.settings.supplyVoltage == 0 ? 110.0 : 220.0;
} else {
// Shelly 2.5 (measured)
voltage = getDouble(status.voltage);
}
if (voltage > 0) {
updated |= updateChannel(CHANNEL_GROUP_DEV_STATUS, CHANNEL_DEVST_VOLTAGE,
toQuantityType(voltage, DIGITS_VOLT, Units.VOLT));
}
logger.trace("{}: Updating {} relay(s)", thingName, profile.numRelays);
int i = 0;
ShellyStatusRelay rstatus = api.getRelayStatus(i);
for (ShellyShortStatusRelay relay : rstatus.relays) {

View File

@ -110,7 +110,7 @@ public class ShellyManagerOverviewPage extends ShellyManagerPage {
if (!warnings.isEmpty() && (status != ThingStatus.UNKNOWN)) {
properties.put(ATTRIBUTE_STATUS_ICON, ICON_ATTENTION);
}
if (!deviceType.equalsIgnoreCase("unknown") && (status == ThingStatus.ONLINE)) {
if (!"unknown".equalsIgnoreCase(deviceType) && (status == ThingStatus.ONLINE)) {
properties.put(ATTRIBUTE_FIRMWARE_SEL, fillFirmwareHtml(uid, deviceType, profile.mode));
properties.put(ATTRIBUTE_ACTION_LIST, fillActionHtml(th, uid));
} else {

View File

@ -109,6 +109,7 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS, "meterAccuWatts", ITEMT_POWER))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL, "meterAccuTotal", ITEMT_POWER))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED, "meterAccuReturned", ITEMT_POWER))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_VOLTAGE, "supplyVoltage", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_DEVST_CHARGER, "charger", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_LED_STATUS_DISABLE, "ledStatusDisable", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_DEVST, CHANNEL_LED_POWER_DISABLE, "ledPowerDisable", ITEMT_SWITCH))
@ -165,7 +166,7 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_REACTWATTS, "meterReactive", ITEMT_POWER))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_VOLTAGE, "meterVoltage", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_CURRENT, "meterCurrent", ITEMT_AMP))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_PFACTOR, "meterPowerFactor", ITEMT_NUMBER))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_PFACTOR, "meterPowerFactor", ITEMT_PERCENT))
// Sensors
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP))
@ -179,6 +180,7 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION, "sensorMotion", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION_TS, "motionTimestamp", ITEMT_DATETIME))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION_ACT, "motionActive", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VIBRATION, "vibration", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_FLOOD, "sensorFlood", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_SMOKE, "sensorSmoke", ITEMT_SWITCH))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_PPM, "sensorPPM", ITEMT_NUMBER))
@ -258,12 +260,14 @@ public class ShellyChannelDefinitions {
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS);
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL);
addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED);
addChannel(thing, add, status.voltage != null || profile.settings.supplyVoltage != null, CHGR_DEVST,
CHANNEL_DEVST_VOLTAGE);
addChannel(thing, add, true, CHGR_DEVST, CHANNEL_DEVST_UPDATE);
addChannel(thing, add, true, CHGR_DEVST, CHANNEL_DEVST_UPTIME);
addChannel(thing, add, true, CHGR_DEVST, CHANNEL_DEVST_HEARTBEAT);
addChannel(thing, add, profile.settings.ledPowerDisable != null, CHGR_DEVST, CHANNEL_LED_POWER_DISABLE);
addChannel(thing, add, profile.settings.ledPowerDisable != null, CHGR_DEVST, CHANNEL_LED_STATUS_DISABLE); // WiFi
//
return add;
}
@ -391,7 +395,8 @@ public class ShellyChannelDefinitions {
addChannel(thing, newChannels, emeter.reactive != null, group, CHANNEL_EMETER_REACTWATTS);
addChannel(thing, newChannels, emeter.voltage != null, group, CHANNEL_EMETER_VOLTAGE);
addChannel(thing, newChannels, emeter.current != null, group, CHANNEL_EMETER_CURRENT);
addChannel(thing, newChannels, emeter.pf != null, group, CHANNEL_EMETER_PFACTOR);
addChannel(thing, newChannels, emeter.power != null, group, CHANNEL_EMETER_PFACTOR); // EM has no PF. but power
addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE);
return newChannels;
}

View File

@ -501,6 +501,8 @@ channel-type.shelly.inputState2.label = Eingang 2
channel-type.shelly.inputState2.description = Status des Relais-Eingangs 2
channel-type.shelly.inputState3.label = Eingang 3
channel-type.shelly.inputState3.description = Status des Relais-Eingangs 3
channel-type.shelly.supplyVoltage.label = Spannung
channel-type.shelly.supplyVoltage.description = Eingangsspannung (Wechselstrom)
channel-type.shelly.dimmerBrightness.label = Helligkeit
channel-type.shelly.dimmerBrightness.description = Helligkeit (0-100%, 0=aus)
channel-type.shelly.whiteBrightness.label = Helligkeit
@ -648,7 +650,7 @@ channel-type.shelly.uptime.description = Anzahl Sekunden seit dem das Ger
channel-type.shelly.heartBeat.label = Letzte Aktivität
channel-type.shelly.heartBeat.description = Zeitpunkt der letzten Aktivität. Hierbei kann es sich um einen erfolgreichen API-Aufruf, oder Sensor-Aktualisierung handeln. Dies schließt eine erfolgreiche Netzwerk-Kommunikation ein (WiFi + IP).
channel-type.shelly.updateAvailable.label = Firmwareaktualisierung vorhanden
channel-type.shelly.updateAvailable.description = ON: Es ist eine neuere Firmwareversion verfügbar (kann mit der Shelly App durchgef¸hrt werden)
channel-type.shelly.updateAvailable.description = ON: Es ist eine neuere Firmwareversion verfügbar (kann mit der Shelly App durchgeführt werden)
channel-type.shelly.deviceTemp.label = Gerätetemperatur
channel-type.shelly.deviceTemp.description = Temperatur im Gerät. Hohe Temperaturen deuten ggf. auch ein Hitzestau/Installationsproblem hin.
channel-type.shelly.lastUpdate.label = Letzte Aktualisierung

View File

@ -235,8 +235,7 @@
<channel-type id="whiteTemp">
<item-type>Dimmer</item-type>
<label>Light Temperature</label>
<description>Light Temperature 3000..6500K</description>
<state min="3000" max="6500" step="10" readOnly="false"></state>
<description>Light Temperature 2700/3000..6500K (0-100%)</description>
</channel-type>
<channel-type id="whiteBrightness">
<item-type>Dimmer</item-type>

View File

@ -456,6 +456,13 @@
<state readOnly="true" pattern="%.2f %unit%">
</state>
</channel-type>
<channel-type id="supplyVoltage" advanced="true">
<item-type>Number:ElectricPotential</item-type>
<label>Supply Voltage</label>
<description>Supply voltage of the device in Volt</description>
<state readOnly="true" pattern="%.2f %unit%">
</state>
</channel-type>
<channel-type id="meterAccuWatts" advanced="true">
<item-type>Number:Power</item-type>
<label>Accumulated Watt</label>
@ -523,7 +530,7 @@
<item-type>Number</item-type>
<label>Power Factor</label>
<description></description>
<state readOnly="true" pattern="%.3f %unit%">
<state readOnly="true" pattern="%.2f %unit%">
</state>
</channel-type>
<channel-type id="timestamp">

View File

@ -332,7 +332,7 @@
<item-type>Number:ElectricPotential</item-type>
<label>Voltage (ADC)</label>
<description>ADC voltage in V</description>
<state readOnly="true" pattern="%.0f %unit%">
<state readOnly="true" pattern="%.2f %unit%">
</state>
</channel-type>
<channel-type id="sensorValve">