fix relay id for devices with more than 1 power meter, fix (#15247)

initialization if device doesn't support scripts (Pro4); fix resetMeter
for EM50 (has 2 power meters); removed channel sensors#open; removed
device#voltage updates for Plus/Pro, needs to be verified

Signed-off-by: Markus Michels <markus7017@gmail.com>
This commit is contained in:
Markus Michels 2023-07-16 14:38:40 +02:00 committed by GitHub
parent 4c3b398398
commit 00da6457f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 142 additions and 146 deletions

View File

@ -173,6 +173,7 @@ public class ShellyBindingConstants {
public static final String CHANNEL_EMETER_VOLTAGE = "voltage"; public static final String CHANNEL_EMETER_VOLTAGE = "voltage";
public static final String CHANNEL_EMETER_CURRENT = "current"; public static final String CHANNEL_EMETER_CURRENT = "current";
public static final String CHANNEL_EMETER_PFACTOR = "powerFactor"; public static final String CHANNEL_EMETER_PFACTOR = "powerFactor";
public static final String CHANNEL_EMETER_RESETTOTAL = "resetTotals";
public static final String CHANNEL_GROUP_SENSOR = "sensors"; public static final String CHANNEL_GROUP_SENSOR = "sensors";
public static final String CHANNEL_SENSOR_TEMP = "temperature"; public static final String CHANNEL_SENSOR_TEMP = "temperature";
@ -187,7 +188,6 @@ public class ShellyBindingConstants {
public static final String CHANNEL_SENSOR_SMOKE = "smoke"; public static final String CHANNEL_SENSOR_SMOKE = "smoke";
public static final String CHANNEL_SENSOR_MUTE = "mute"; public static final String CHANNEL_SENSOR_MUTE = "mute";
public static final String CHANNEL_SENSOR_STATE = "state"; public static final String CHANNEL_SENSOR_STATE = "state";
public static final String CHANNEL_SENSOR_OPEN = "open";
public static final String CHANNEL_SENSOR_VALVE = "valve"; public static final String CHANNEL_SENSOR_VALVE = "valve";
public static final String CHANNEL_SENSOR_SSTATE = "status"; // Shelly Gas public static final String CHANNEL_SENSOR_SSTATE = "status"; // Shelly Gas
public static final String CHANNEL_SENSOR_MOTION_ACT = "motionActive"; public static final String CHANNEL_SENSOR_MOTION_ACT = "motionActive";
@ -260,7 +260,8 @@ public class ShellyBindingConstants {
public static final String CHANNEL_DEVST_ACCUWATTS = "accumulatedWatts"; public static final String CHANNEL_DEVST_ACCUWATTS = "accumulatedWatts";
public static final String CHANNEL_DEVST_ACCUTOTAL = "accumulatedWTotal"; public static final String CHANNEL_DEVST_ACCUTOTAL = "accumulatedWTotal";
public static final String CHANNEL_DEVST_ACCURETURNED = "accumulatedReturned"; public static final String CHANNEL_DEVST_ACCURETURNED = "accumulatedReturned";
public static final String CHANNEL_DEVST_RESETTOTAL = "resetTotals"; public static final String CHANNEL_DEVST_RESETTOTAL = CHANNEL_EMETER_RESETTOTAL;
public static final String CHANNEL_DEVST_CHARGER = "charger"; public static final String CHANNEL_DEVST_CHARGER = "charger";
public static final String CHANNEL_DEVST_UPDATE = "updateAvailable"; public static final String CHANNEL_DEVST_UPDATE = "updateAvailable";
public static final String CHANNEL_DEVST_SELFTTEST = "selfTest"; public static final String CHANNEL_DEVST_SELFTTEST = "selfTest";

View File

@ -264,11 +264,6 @@ public class Shelly2ApiClient extends ShellyHttpClient {
} }
} }
if (rs.voltage != null) {
if (status.voltage == null || rs.voltage > status.voltage) {
status.voltage = rs.voltage;
}
}
if (rs.errors != null) { if (rs.errors != null) {
for (String error : rs.errors) { for (String error : rs.errors) {
sr.overpower = rstatus.overpower = SHELLY2_ERROR_OVERPOWER.equals(error); sr.overpower = rstatus.overpower = SHELLY2_ERROR_OVERPOWER.equals(error);
@ -318,9 +313,9 @@ public class Shelly2ApiClient extends ShellyHttpClient {
if (relay.isValid && relay.id != null && relay.id.intValue() == id.intValue()) { if (relay.isValid && relay.id != null && relay.id.intValue() == id.intValue()) {
return idx; return idx;
} }
}
idx++; idx++;
} }
}
return -1; return -1;
} }
@ -330,7 +325,8 @@ public class Shelly2ApiClient extends ShellyHttpClient {
return; return;
} }
sm.isValid = sm.power != null || sm.total != null; sm.isValid = sm.power != null || sm.total != null;
emeter.isValid = emeter.current != null || emeter.voltage != null || emeter.power != null; emeter.isValid = emeter.current != null || emeter.voltage != null || emeter.power != null
|| emeter.total != null;
status.meters.set(id, sm); status.meters.set(id, sm);
status.emeters.set(id, emeter); status.emeters.set(id, emeter);
relayStatus.meters.set(id, sm); relayStatus.meters.set(id, sm);
@ -548,9 +544,6 @@ public class Shelly2ApiClient extends ShellyHttpClient {
} }
} }
if (cs.voltage != null) { if (cs.voltage != null) {
if (status.voltage == null || cs.voltage > status.voltage) {
status.voltage = cs.voltage;
}
emeter.voltage = cs.voltage; emeter.voltage = cs.voltage;
} }
if (cs.current != null) { if (cs.current != null) {

View File

@ -365,6 +365,7 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
} }
protected void installScript(String script, boolean install) throws ShellyApiException { protected void installScript(String script, boolean install) throws ShellyApiException {
try {
ShellyScriptListResponse scriptList = apiRequest( ShellyScriptListResponse scriptList = apiRequest(
new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_LIST), ShellyScriptListResponse.class); new Shelly2RpcRequest().withMethod(SHELLYRPC_METHOD_SCRIPT_LIST), ShellyScriptListResponse.class);
Integer ourId = -1; Integer ourId = -1;
@ -425,8 +426,8 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
restart = true; restart = true;
} }
} catch (ShellyApiException e) { } catch (ShellyApiException e) {
logger.debug("{}: Unable to read current script code -> force update (deviced returned: {})", thingName, logger.debug("{}: Unable to read current script code -> force update (deviced returned: {})",
e.getMessage()); thingName, e.getMessage());
upload = true; upload = true;
} }
} }
@ -472,16 +473,26 @@ public class Shelly2ApiRpc extends Shelly2ApiClient implements ShellyApiInterfac
} while (processed < length); } while (processed < length);
running = false; running = false;
} }
if (enableScript(script, true)) { if (enableScript(script, true) && upload) {
logger.info("{}: Script {} was {} installed successful", thingName, thingName, script); logger.info("{}: Script {} was {} installed successful", thingName, thingName, script);
} }
if (!running) { if (!running) {
running = startScript(ourId, true); running = startScript(ourId, true);
} }
if (!discovery) {
logger.info("{}: Script {} {}", thingName, script, logger.info("{}: Script {} {}", thingName, script,
running ? "was successfully (re)started" : "failed to start"); running ? "was successfully (re)started" : "failed to start");
} }
} catch (ShellyApiException e) {
ShellyApiResult res = e.getApiResult();
if (res.httpCode == HttpStatus.NOT_FOUND_404) { // Shely 4Pro
logger.debug("{}: Script {} was not installed, device doesn't support scripts", thingName, script);
} else {
logger.debug("{}: Unable to install script {}: {}", thingName, script, res.toString());
}
}
}
private boolean startScript(int ourId, boolean start) { private boolean startScript(int ourId, boolean start) {
if (ourId != -1) { if (ourId != -1) {

View File

@ -429,8 +429,6 @@ public class ShellyComponents {
toQuantityType((double) bminutes, DIGITS_NONE, Units.MINUTE)); toQuantityType((double) bminutes, DIGITS_NONE, Units.MINUTE));
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE, getStringType( updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_MODE, getStringType(
getBool(t.targetTemp.enabled) ? SHELLY_TRV_MODE_AUTO : SHELLY_TRV_MODE_MANUAL)); getBool(t.targetTemp.enabled) ? SHELLY_TRV_MODE_AUTO : SHELLY_TRV_MODE_MANUAL));
updated |= thingHandler.updateChannel(CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_OPEN,
getOpenClosed(t.windowOpen));
int pid = getBool(t.schedule) ? getInteger(t.profile) : 0; int pid = getBool(t.schedule) ? getInteger(t.profile) : 0;
updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE, updated |= thingHandler.updateChannel(CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE,

View File

@ -133,10 +133,12 @@ public class ShellyRelayHandler extends ShellyBaseHandler {
logger.debug("{}: Set Auto-OFF timer to {}", thingName, command); logger.debug("{}: Set Auto-OFF timer to {}", thingName, command);
api.setAutoTimer(rIndex, SHELLY_TIMER_AUTOOFF, getNumber(command).doubleValue()); api.setAutoTimer(rIndex, SHELLY_TIMER_AUTOOFF, getNumber(command).doubleValue());
break; break;
case CHANNEL_DEVST_RESETTOTAL: case CHANNEL_EMETER_RESETTOTAL:
logger.debug("{}: Reset Meter Totals", thingName); String id = substringAfter(groupName, CHANNEL_GROUP_METER);
api.resetMeterTotal(0); // currently there is only 1 emdata component int mIdx = id.isEmpty() ? 0 : Integer.parseInt(id) - 1;
updateChannel(groupName, CHANNEL_DEVST_RESETTOTAL, OnOffType.OFF); logger.debug("{}: Reset Meter Totals for meter {}", thingName, mIdx + 1);
api.resetMeterTotal(mIdx); // currently there is only 1 emdata component
updateChannel(groupName, CHANNEL_EMETER_RESETTOTAL, OnOffType.OFF);
break; break;
} }
return true; return true;

View File

@ -201,6 +201,7 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_VOLTAGE, "meterVoltage", ITEMT_VOLT)) .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_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_NUMBER))
.add(new ShellyChannel(m, CHGR_METER, CHANNEL_EMETER_RESETTOTAL, "meterResetTotals", ITEMT_SWITCH))
// Sensors // Sensors
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TEMP, "sensorTemp", ITEMT_TEMP))
@ -209,7 +210,6 @@ public class ShellyChannelDefinitions {
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_ILLUM, "sensorIllumination", ITEMT_STRING)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_ILLUM, "sensorIllumination", ITEMT_STRING))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VOLTAGE, "sensorADC", ITEMT_VOLT)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_VOLTAGE, "sensorADC", ITEMT_VOLT))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_STATE, "sensorContact", ITEMT_CONTACT)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_STATE, "sensorContact", ITEMT_CONTACT))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_OPEN, "sensorOpen", ITEMT_CONTACT))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_SSTATE, "sensorState", ITEMT_STRING)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_SSTATE, "sensorState", ITEMT_STRING))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TILT, "sensorTilt", ITEMT_ANGLE)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_TILT, "sensorTilt", ITEMT_ANGLE))
.add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION, "sensorMotion", ITEMT_SWITCH)) .add(new ShellyChannel(m, CHGR_SENSOR, CHANNEL_SENSOR_MOTION, "sensorMotion", ITEMT_SWITCH))
@ -304,9 +304,13 @@ public class ShellyChannelDefinitions {
&& ((status.temperature != null && getDouble(status.temperature) != SHELLY_API_INVTEMP) && ((status.temperature != null && getDouble(status.temperature) != SHELLY_API_INVTEMP)
|| (status.tmp != null && getDouble(status.tmp.tC) != SHELLY_API_INVTEMP))) { || (status.tmp != null && getDouble(status.tmp.tC) != SHELLY_API_INVTEMP))) {
// Only some devices report the internal device temp // Only some devices report the internal device temp
addChannel(thing, add, boolean hasTemp = !profile.isLight
!profile.isLight && (status.temperature != null || (status.tmp != null && !profile.isSensor)), && (status.temperature != null || (status.tmp != null && !profile.isSensor));
CHGR_DEVST, CHANNEL_DEVST_ITEMP); if (hasTemp && profile.isGen2 && (profile.numMeters > 0 && !profile.hasRelays)) // Shely Plus PM Mini
{
hasTemp = false;
}
addChannel(thing, add, hasTemp, CHGR_DEVST, CHANNEL_DEVST_ITEMP);
} }
addChannel(thing, add, profile.settings.sleepTime != null, CHGR_SENSOR, CHANNEL_SENSOR_SLEEPTIME); addChannel(thing, add, profile.settings.sleepTime != null, CHGR_SENSOR, CHANNEL_SENSOR_SLEEPTIME);
@ -315,7 +319,7 @@ public class ShellyChannelDefinitions {
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS); addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUWATTS);
addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL); addChannel(thing, add, accuChannel, CHGR_DEVST, CHANNEL_DEVST_ACCUTOTAL);
addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED); addChannel(thing, add, accuChannel && (status.emeters != null), CHGR_DEVST, CHANNEL_DEVST_ACCURETURNED);
addChannel(thing, add, profile.is3EM || profile.isEM50, CHGR_DEVST, CHANNEL_DEVST_RESETTOTAL); // 3EM addChannel(thing, add, profile.is3EM, CHGR_DEVST, CHANNEL_DEVST_RESETTOTAL); // 3EM
addChannel(thing, add, status.voltage != null || profile.settings.supplyVoltage != null, CHGR_DEVST, addChannel(thing, add, status.voltage != null || profile.settings.supplyVoltage != null, CHGR_DEVST,
CHANNEL_DEVST_VOLTAGE); CHANNEL_DEVST_VOLTAGE);
addChannel(thing, add, addChannel(thing, add,
@ -480,6 +484,10 @@ public class ShellyChannelDefinitions {
addChannel(thing, newChannels, emeter.current != null, group, CHANNEL_EMETER_CURRENT); addChannel(thing, newChannels, emeter.current != null, group, CHANNEL_EMETER_CURRENT);
addChannel(thing, newChannels, emeter.pf != null, group, CHANNEL_EMETER_PFACTOR); // EM has no PF. but power addChannel(thing, newChannels, emeter.pf != null, group, CHANNEL_EMETER_PFACTOR); // EM has no PF. but power
addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE); addChannel(thing, newChannels, true, group, CHANNEL_LAST_UPDATE);
ShellyThingInterface handler = (ShellyThingInterface) thing.getHandler();
if (handler != null) {
addChannel(thing, newChannels, handler.getProfile().isEM50, group, CHANNEL_DEVST_RESETTOTAL); // 3EM
}
return newChannels; return newChannels;
} }
@ -543,7 +551,6 @@ public class ShellyChannelDefinitions {
addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_PROFILE);
addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE); addChannel(thing, newChannels, true, CHANNEL_GROUP_CONTROL, CHANNEL_CONTROL_SCHEDULE);
addChannel(thing, newChannels, true, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_STATE); addChannel(thing, newChannels, true, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_STATE);
addChannel(thing, newChannels, true, CHANNEL_GROUP_SENSOR, CHANNEL_SENSOR_OPEN);
} }
// Battery // Battery

View File

@ -116,7 +116,7 @@ thing-type.shelly.shellypro2pm-relay.description= Shelly Pro 2PM - Dual Relay Sw
thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Control with Power Meter thing-type.shelly.shellypro2pm-roller.description = Shelly Pro 2PM - Roller Control with Power Meter
thing-type.shelly.shellypro3.description = Shelly Pro 3 - 3xRelay Switch thing-type.shelly.shellypro3.description = Shelly Pro 3 - 3xRelay Switch
thing-type.shelly.shellypro3em.description = Shelly Pro 3EM - 3xPower Meter thing-type.shelly.shellypro3em.description = Shelly Pro 3EM - 3xPower Meter
thing-type.shelly.shellyproem50.description = Shelly Pro EM-50 - 3xPower Meter + 1xOutput thing-type.shelly.shellyproem50.description = Shelly Pro EM-50 - 2xPower Meter + 1xOutput
thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter thing-type.shelly.shellypro4pm.description = Shelly Pro 4PM - 4xRelay Switch with Power Meter
# BLU devices # BLU devices
@ -299,7 +299,7 @@ channel-type.shelly.lastPower1.label = Last Power
channel-type.shelly.lastPower1.description = Last power consumption #1 - one rounded minute channel-type.shelly.lastPower1.description = Last power consumption #1 - one rounded minute
channel-type.shelly.meterTotal.label = Total Energy Consumption channel-type.shelly.meterTotal.label = Total Energy Consumption
channel-type.shelly.meterTotal.description = Total energy consumption in kW/h since the device powered up (resets on restart) channel-type.shelly.meterTotal.description = Total energy consumption in kW/h since the device powered up (resets on restart)
channel-type.shelly.meterResetTotals.label = Reset Totals channel-type.shelly.meterResetTotals.label = Reset Energy Measurements
channel-type.shelly.meterResetTotals.description = Resets totals measurement data channel-type.shelly.meterResetTotals.description = Resets totals measurement data
channel-type.shelly.meterReturned.label = Total Returned Energy channel-type.shelly.meterReturned.label = Total Returned Energy
channel-type.shelly.meterReturned.description = Total returned energy in kW/h channel-type.shelly.meterReturned.description = Total returned energy in kW/h
@ -411,10 +411,6 @@ channel-type.shelly.sensorContact.label = State
channel-type.shelly.sensorContact.description = State of the contact (open/closed) channel-type.shelly.sensorContact.description = State of the contact (open/closed)
channel-type.shelly.sensorContact.state.option.OPEN = Open channel-type.shelly.sensorContact.state.option.OPEN = Open
channel-type.shelly.sensorContact.state.option.CLOSED = Closed channel-type.shelly.sensorContact.state.option.CLOSED = Closed
channel-type.shelly.sensorOpen.label = Open
channel-type.shelly.sensorOpen.description = OPEN or CLOSED
channel-type.shelly.sensorOpen.state.option.OPEN = Open
channel-type.shelly.sensorOpen.state.option.CLOSED = Closed
channel-type.shelly.sensorState.label = Sensor State channel-type.shelly.sensorState.label = Sensor State
channel-type.shelly.sensorState.description = Sensor State (Warm-Up/Normal/Fault/Unknown) channel-type.shelly.sensorState.description = Sensor State (Warm-Up/Normal/Fault/Unknown)
channel-type.shelly.sensorState.state.option.warmup = Warm-Up channel-type.shelly.sensorState.state.option.warmup = Warm-Up

View File

@ -243,18 +243,6 @@
</state> </state>
</channel-type> </channel-type>
<channel-type id="sensorOpen">
<item-type>Contact</item-type>
<label>@text/channel-type.shelly.sensorOpen.label</label>
<description>@text/channel-type.shelly.sensorOpen.description</description>
<state pattern="%s" readOnly="true">
<options>
<option value="OPEN">@text/channel-type.shelly.sensorOpen.state.option.OPEN</option>
<option value="CLOSED">@text/channel-type.shelly.sensorOpen.state.option.CLOSED</option>
</options>
</state>
</channel-type>
<channel-type id="sensorState"> <channel-type id="sensorState">
<item-type>String</item-type> <item-type>String</item-type>
<label>@text/channel-type.shelly.sensorState.label</label> <label>@text/channel-type.shelly.sensorState.label</label>