[openwebnet] Improve shutterRun calibration (#14357)
* [openwebnet] improved shutterRun calibration and README * [openwebnet] added Thing status detail when bridge is offline -------- Signed-off-by: Massimo Valla <mvcode00@gmail.com>
This commit is contained in:
@@ -47,7 +47,8 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link OpenWebNetAutomationHandler} is responsible for handling commands/messages for an Automation OpenWebNet
|
||||
* The {@link OpenWebNetAutomationHandler} is responsible for handling
|
||||
* commands/messages for an Automation OpenWebNet
|
||||
* device. It extends the abstract {@link OpenWebNetThingHandler}.
|
||||
*
|
||||
* @author Massimo Valla - Initial contribution
|
||||
@@ -247,18 +248,21 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
positionRequested = percent;
|
||||
} else if (shutterRun >= 1000 && positionEstimation != POSITION_UNKNOWN) {
|
||||
// these two must be known to calculate moveTime.
|
||||
// Calculate how much time we have to move and set a deadline to stop after that time
|
||||
// Calculate how much time we have to move and set a deadline to stop after that
|
||||
// time
|
||||
int moveTime = Math
|
||||
.round(((float) Math.abs(percent - positionEstimation) / POSITION_MAX_STEPS * shutterRun));
|
||||
logger.debug("# {} # target moveTime={}", deviceWhere, moveTime);
|
||||
if (moveTime > MIN_STEP_TIME_MSEC) {
|
||||
ScheduledFuture<?> mSch = moveSchedule;
|
||||
if (mSch != null && !mSch.isDone()) {
|
||||
// a moveSchedule was already scheduled and is not done... let's cancel the schedule
|
||||
// a moveSchedule was already scheduled and is not done... let's cancel the
|
||||
// schedule
|
||||
mSch.cancel(false);
|
||||
logger.debug("# {} # new XX% requested, old moveSchedule cancelled", deviceWhere);
|
||||
}
|
||||
// send a requestFirmwareVersion message to BUS gateways to wake up the CMD connection before
|
||||
// send a requestFirmwareVersion message to BUS gateways to wake up the CMD
|
||||
// connection before
|
||||
// sending further cmds
|
||||
OpenWebNetBridgeHandler h = bridgeHandler;
|
||||
if (h != null && h.isBusGateway()) {
|
||||
@@ -270,7 +274,8 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
// REMINDER: start the schedule BEFORE sending the command, because the synch command waits for
|
||||
// REMINDER: start the schedule BEFORE sending the command, because the synch
|
||||
// command waits for
|
||||
// ACK and can take some 300ms
|
||||
logger.debug("# {} # Starting schedule...", deviceWhere);
|
||||
moveSchedule = scheduler.schedule(() -> {
|
||||
@@ -294,7 +299,7 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
}
|
||||
} else {
|
||||
logger.info(
|
||||
"Command {} cannot be executed: unknown position or shutterRun configuration params not/wrongly set (thing={})",
|
||||
"Command {} cannot be executed: UNDEF position or shutterRun configuration parameter not/wrongly set (thing={})",
|
||||
command, thing.getUID());
|
||||
}
|
||||
}
|
||||
@@ -312,12 +317,14 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
protected void handleMessage(BaseOpenMessage msg) {
|
||||
logger.debug("handleMessage({}) for thing: {}", msg, thing.getUID());
|
||||
updateAutomationState((Automation) msg);
|
||||
// REMINDER: update automation state, and only after update thing status using the super method, to avoid delays
|
||||
// REMINDER: update automation state, and only after update thing status using
|
||||
// the super method, to avoid delays
|
||||
super.handleMessage(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates automation device state based on the Automation message received from OWN network
|
||||
* Updates automation device state based on the Automation message received from
|
||||
* OWN network
|
||||
*
|
||||
* @param msg the Automation message
|
||||
*/
|
||||
@@ -345,10 +352,12 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
logger.debug("& {} & CALIBRATION - started going ALL DOWN...", deviceWhere);
|
||||
}
|
||||
} else if (msg.isStop()) {
|
||||
long stoppedAt = System.currentTimeMillis();
|
||||
long measuredRuntime = System.currentTimeMillis() - startedMovingAtTS;
|
||||
if (calibrating == CALIBRATION_GOING_DOWN && shutterRun == SHUTTER_RUN_UNDEFINED) {
|
||||
shutterRun = (int) (stoppedAt - startedMovingAtTS);
|
||||
logger.debug("& {} & CALIBRATION - reached DOWN ---> shutterRun={}", deviceWhere, shutterRun);
|
||||
// since there are transmission delays we set shutterRun slightly less (-500ms
|
||||
// and -2%) than measuredRuntime
|
||||
shutterRun = (int) ((measuredRuntime - 500) * 0.98);
|
||||
logger.debug("& {} & CALIBRATION - reached DOWN : measuredRuntime={}", deviceWhere, measuredRuntime);
|
||||
updateMovingState(MOVING_STATE_STOPPED);
|
||||
logger.debug("& {} & CALIBRATION - COMPLETED, now going to {}%", deviceWhere, positionRequested);
|
||||
handleShutterCommand(new PercentType(positionRequested));
|
||||
@@ -416,7 +425,8 @@ public class OpenWebNetAutomationHandler extends OpenWebNetThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates positionEstimation and then channel state based on movedTime and current movingState
|
||||
* Updates positionEstimation and then channel state based on movedTime and
|
||||
* current movingState
|
||||
*/
|
||||
private void updatePosition() {
|
||||
int newPos = POSITION_UNKNOWN;
|
||||
|
||||
@@ -517,7 +517,7 @@ public class OpenWebNetBridgeHandler extends ConfigStatusBridgeHandler implement
|
||||
|| (discoveryByActivation && !scanIsActive))) {
|
||||
discoverByActivation(baseMsg);
|
||||
} else {
|
||||
logger.debug("ownId={} has NO DEVICE associated, ignoring it", ownId);
|
||||
logger.debug("ownId={} has NO DEVICE associated to bridge {}: ignoring it", ownId, thing.getUID());
|
||||
}
|
||||
} else {
|
||||
deviceHandler.handleMessage(baseMsg);
|
||||
|
||||
@@ -46,9 +46,10 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/**
|
||||
* The {@link OpenWebNetThingHandler} is responsible for handling commands for an OpenWebNet device.
|
||||
* It's the abstract class for all OpenWebNet things. It should be extended by each specific OpenWebNet category of
|
||||
* device (WHO).
|
||||
* The {@link OpenWebNetThingHandler} is responsible for handling commands for
|
||||
* an OpenWebNet device.
|
||||
* It's the abstract class for all OpenWebNet things. It should be extended by
|
||||
* each specific OpenWebNet category of device (WHO).
|
||||
*
|
||||
* @author Massimo Valla - Initial contribution
|
||||
*/
|
||||
@@ -118,7 +119,7 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
if (bridgeStatusInfo.getStatus() == ThingStatus.ONLINE) {
|
||||
updateStatus(ThingStatus.UNKNOWN, ThingStatusDetail.NONE, "@text/unknown.waiting-state");
|
||||
} else if (bridgeStatusInfo.getStatus() == ThingStatus.OFFLINE) {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE);
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.BRIDGE_OFFLINE, "@text/offline.bridge-offline");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,8 +158,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
protected abstract void handleChannelCommand(ChannelUID channel, Command command);
|
||||
|
||||
/**
|
||||
* Handle incoming message from OWN network via bridge Thing, directed to this device.
|
||||
* It should be further implemented by each specific device handler.
|
||||
* Handle incoming message from OWN network via bridge Thing, directed to this
|
||||
* device. It should be further implemented by each specific device handler.
|
||||
*
|
||||
* @param msg the message to handle
|
||||
*/
|
||||
@@ -203,8 +204,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Request the state for the specified channel. If no answer is received within THING_STATE_REQ_TIMEOUT_SEC, it is
|
||||
* put OFFLINE.
|
||||
* Request the state for the specified channel. If no answer is received within
|
||||
* THING_STATE_REQ_TIMEOUT_SEC, it is put OFFLINE.
|
||||
* The method must be further implemented by each specific handler.
|
||||
*
|
||||
* @param channel the {@link ChannelUID} to request the state for
|
||||
@@ -217,7 +218,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "@text/offline.conf-error-where");
|
||||
return;
|
||||
}
|
||||
// set a schedule to put device OFFLINE if no answer is received after THING_STATE_REQ_TIMEOUT_SEC
|
||||
// set a schedule to put device OFFLINE if no answer is received after
|
||||
// THING_STATE_REQ_TIMEOUT_SEC
|
||||
requestChannelStateTimeout = scheduler.schedule(() -> {
|
||||
if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
|
||||
logger.debug("requestChannelState() TIMEOUT for thing {}", thing.getUID());
|
||||
@@ -228,21 +230,24 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh a device, possibly using a single OWN command if refreshAll=true and if supported.
|
||||
* The method must be further implemented by each specific handler.
|
||||
* Refresh a device, possibly using a single OWN command if refreshAll=true and
|
||||
* if supported. The method must be further implemented by each specific
|
||||
* handler.
|
||||
*
|
||||
* @param refreshAll true if all devices for this handler must be refreshed with a single OWN command, if supported,
|
||||
* otherwise just refresh the single device.
|
||||
* @param refreshAll true if all devices for this handler must be refreshed with
|
||||
* a single OWN command, if supported, otherwise just refresh
|
||||
* the single device.
|
||||
*/
|
||||
protected abstract void refreshDevice(boolean refreshAll);
|
||||
|
||||
/**
|
||||
* If the subclass supports refreshing all devices with a single OWN command, returns the last TS when a refreshAll
|
||||
* was requested, or 0 if not requested yet. If not supported return -1 (default).
|
||||
* If the subclass supports refreshing all devices with a single OWN command,
|
||||
* returns the last TS when a refreshAll was requested, or 0 if not requested
|
||||
* yet. If not supported return -1 (default).
|
||||
* It must be implemented by each subclass that supports all devices refresh.
|
||||
*
|
||||
* @return timestamp when last refreshAll command was sent, 0 if not requested yet, or -1 if it's not supported by
|
||||
* subclass.
|
||||
* @return timestamp when last refreshAll command was sent, 0 if not requested
|
||||
* yet, or -1 if it's not supported by subclass.
|
||||
*/
|
||||
protected long getRefreshAllLastTS() {
|
||||
return -1;
|
||||
@@ -266,8 +271,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
logger.debug("--- refreshAllDevices() : refresh all devices sent {}msec ago, skipping... ({})",
|
||||
ALL_DEVICES_REFRESH_INTERVAL_MSEC, thing.getUID());
|
||||
}
|
||||
// sometimes GENERAL (e.g. #*1*0##) refresh requests do not return state for all devices, so let's
|
||||
// schedule another single refresh device, just in case
|
||||
// sometimes GENERAL (e.g. #*1*0##) refresh requests do not return state for all
|
||||
// devices, so let's schedule another single refresh device, just in case
|
||||
refreshTimeout = scheduler.schedule(() -> {
|
||||
if (thing.getStatus().equals(ThingStatus.UNKNOWN)) {
|
||||
logger.debug(
|
||||
@@ -286,8 +291,9 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract builder for device Where address, to be implemented by each subclass to choose the right Where subclass
|
||||
* (the method is used only if the Thing is associated to a BUS gateway).
|
||||
* Abstract builder for device Where address, to be implemented by each subclass
|
||||
* to choose the right Where subclass (the method is used only if the Thing is
|
||||
* associated to a BUS gateway).
|
||||
*
|
||||
* @param wStr the WHERE string
|
||||
*/
|
||||
@@ -312,7 +318,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to return a Quantity from a Number value or UnDefType.NULL if value is null
|
||||
* Helper method to return a Quantity from a Number value or UnDefType.NULL if
|
||||
* value is null
|
||||
*
|
||||
* @param value to be used
|
||||
* @param unit to be used
|
||||
@@ -323,7 +330,8 @@ public abstract class OpenWebNetThingHandler extends BaseThingHandler {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a prefix String for ownId specific for each handler. To be implemented by sub-classes.
|
||||
* Returns a prefix String for ownId specific for each handler.
|
||||
* To be implemented by sub-classes.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
|
||||
@@ -290,13 +290,14 @@ channel-type.openwebnet.zoneAlarmTimestamp.description = Current alarm's timesta
|
||||
|
||||
# thing status descriptions
|
||||
|
||||
offline.comm-error-disconnected = Disconnected from gateway.
|
||||
offline.comm-error-timeout = Connection to gateway timed out.
|
||||
offline.comm-error-connection = Could not connect to gateway.
|
||||
offline.comm-error-state = Could not get channel state.
|
||||
offline.conf-error-no-ip-address = Cannot connect to gateway. No host/IP address has been provided in configuration.
|
||||
offline.conf-error-no-serial-port = Cannot connect to gateway. No serial port has been provided in configuration.
|
||||
offline.conf-error-where = OpenWebNet Address (where) parameter in configuration is null or invalid.
|
||||
offline.conf-error-no-bridge = No bridge associated. Assign a bridge in configuration.
|
||||
offline.conf-error-auth = Authentication failed. Check gateway password in configuration.
|
||||
offline.comm-error-disconnected = Disconnected from gateway
|
||||
offline.comm-error-timeout = Connection to gateway timed out
|
||||
offline.comm-error-connection = Could not connect to gateway
|
||||
offline.comm-error-state = Could not get channel state
|
||||
offline.conf-error-no-ip-address = Cannot connect to gateway. No host/IP address has been provided in configuration
|
||||
offline.conf-error-no-serial-port = Cannot connect to gateway. No serial port has been provided in configuration
|
||||
offline.conf-error-where = OpenWebNet Address (where) parameter in configuration is null or invalid
|
||||
offline.conf-error-no-bridge = No bridge associated. Assign a bridge in configuration
|
||||
offline.conf-error-auth = Authentication failed. Check gateway password in configuration
|
||||
offline.bridge-offline = Bridge offline
|
||||
unknown.waiting-state = Waiting state update...
|
||||
|
||||
Reference in New Issue
Block a user