Skip to content

Commit

Permalink
[solax] Implementation of refresh command and improved thread safety (o…
Browse files Browse the repository at this point in the history
…penhab#15958)

* Implementation of refresh command and better multi-thread handling

---------

Signed-off-by: Konstantin Polihronov <[email protected]>
  • Loading branch information
theater authored Nov 27, 2023
1 parent 4d13a6d commit f4aa1c6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
@NonNullByDefault
public class SolaxBindingConstants {

private static final String BINDING_ID = "solax";
protected static final String BINDING_ID = "solax";
private static final String THING_LOCAL_CONNECT_INVERTER_ID = "local-connect-inverter";

// List of all Thing Type UIDs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Set;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

import javax.measure.Quantity;
import javax.measure.Unit;
Expand All @@ -42,6 +43,7 @@
import org.openhab.core.thing.ThingStatusDetail;
import org.openhab.core.thing.binding.BaseThingHandler;
import org.openhab.core.types.Command;
import org.openhab.core.types.RefreshType;
import org.openhab.core.types.UnDefType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -69,6 +71,8 @@ public class SolaxLocalAccessHandler extends BaseThingHandler {

private final Set<String> unsupportedExistingChannels = new HashSet<String>();

private final ReentrantLock retrieveDataCallLock = new ReentrantLock();

public SolaxLocalAccessHandler(Thing thing) {
super(thing);
}
Expand All @@ -88,19 +92,25 @@ public void initialize() {
}

private void retrieveData() {
try {
String rawJsonData = localHttpConnector.retrieveData();
logger.debug("Raw data retrieved = {}", rawJsonData);

if (rawJsonData != null && !rawJsonData.isEmpty()) {
updateFromData(rawJsonData);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
SolaxBindingConstants.I18N_KEY_OFFLINE_COMMUNICATION_ERROR_JSON_CANNOT_BE_RETRIEVED);
if (retrieveDataCallLock.tryLock()) {
try {
String rawJsonData = localHttpConnector.retrieveData();
logger.debug("Raw data retrieved = {}", rawJsonData);

if (rawJsonData != null && !rawJsonData.isEmpty()) {
updateFromData(rawJsonData);
} else {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
SolaxBindingConstants.I18N_KEY_OFFLINE_COMMUNICATION_ERROR_JSON_CANNOT_BE_RETRIEVED);
}
} catch (IOException e) {
logger.debug("Exception received while attempting to retrieve data via HTTP", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
} finally {
retrieveDataCallLock.unlock();
}
} catch (IOException e) {
logger.debug("Exception received while attempting to retrieve data via HTTP", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
} else {
logger.debug("Unable to retrieve data because a request is already in progress.");
}
}

Expand Down Expand Up @@ -283,7 +293,11 @@ private void logRemovedChannels(List<Channel> channelsToRemove) {

@Override
public void handleCommand(ChannelUID channelUID, Command command) {
// Nothing to do here as of now. Maybe implement a REFRESH command in the future.
if (command instanceof RefreshType) {
scheduler.execute(this::retrieveData);
} else {
logger.debug("Binding {} only supports refresh command", SolaxBindingConstants.BINDING_ID);
}
}

@Override
Expand Down

0 comments on commit f4aa1c6

Please sign in to comment.