| |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) |
| |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)
| |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)|
| |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)|
| |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 |
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";
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;
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;
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
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
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) {
private void fillDeviceStatus(ShellySettingsStatus status, boolean updated) {
String alarm = "";
- boolean force = false;
// Update uptime and WiFi, internal temp
ShellyComponents.updateDeviceStatus(this, status);
stats.coiotErrors = coap.getErrorCount();
if (!alarm.isEmpty()) {
- postEvent(alarm, force);
+ postEvent(alarm, false);
}
}
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 {
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;
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
*
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);
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) {
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 {
.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))
.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))
.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))
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;
}
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;
}
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
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
<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>
<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>
<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">
<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">