[New] Added virtual string and boolean connectors

This commit is contained in:
Robert von Burg 2020-01-28 14:35:21 +01:00
parent 96eef75f8c
commit a1429b8d7b
6 changed files with 63 additions and 44 deletions

View File

@ -76,6 +76,10 @@ public abstract class PlcService implements PlcListener {
this.plcHandler.send(resource, action, value);
}
protected void notify(String resource, String action, Object value) {
this.plcHandler.notify(resource, action, value);
}
protected StrolchTransaction openTx(PrivilegeContext ctx, boolean readOnly) {
return this.plcHandler.openTx(ctx.getCertificate(), readOnly);
}

View File

@ -2,9 +2,9 @@ package li.strolch.plc.core.hw.connections;
import li.strolch.plc.core.hw.Plc;
public class InMemoryBooleanConnection extends SimplePlcConnection {
public class VirtualBooleanValueConnection extends SimplePlcConnection {
public InMemoryBooleanConnection(Plc plc, String id) {
public VirtualBooleanValueConnection(Plc plc, String id) {
super(plc, id);
}

View File

@ -0,0 +1,17 @@
package li.strolch.plc.core.hw.connections;
import li.strolch.plc.core.hw.Plc;
public class VirtualStringValueConnection extends SimplePlcConnection {
public VirtualStringValueConnection(Plc plc, String id) {
super(plc, id);
}
@Override
public void send(String address, Object value) {
String string = (String) value;
logger.info("Setting address " + this.id + " to " + string);
this.plc.notify(this.id, string);
}
}

View File

@ -9,7 +9,6 @@ public class StartupPlcService extends PlcService {
public static final String PLC = "PLC";
public static final String STARTED = "Started";
public static final String STOPPED = "Stopped";
public StartupPlcService(ComponentContainer container, PlcHandler plcHandler) {
super(container, plcHandler);
@ -17,13 +16,13 @@ public class StartupPlcService extends PlcService {
@Override
public void start(StrolchTransaction tx) {
send(PLC, STARTED);
notify(PLC, STARTED, true);
super.start(tx);
}
@Override
public void stop() {
send(PLC, STOPPED);
notify(PLC, STARTED, false);
super.stop();
}
}

View File

@ -17,9 +17,17 @@
<!--
Simple Boolean connection
-->
<Resource Id="booleanConnection" Name="Single Boolean PLC Connection" Type="PlcConnection">
<Resource Id="virtualString" Name="Virtual String PLC Connection" Type="PlcConnection">
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="className" Name="Connection Class" Type="String" Value="li.strolch.plc.core.hw.connections.InMemoryBooleanConnection"/>
<Parameter Id="className" Name="Connection Class" Type="String" Value="li.strolch.plc.core.hw.connections.VirtualStringValueConnection"/>
<Parameter Id="state" Name="Connection State" Type="String" Interpretation="Enumeration" Uom="ConnectionState" Value="Disconnected"/>
<Parameter Id="stateMsg" Name="Connection State Msg" Type="String" Interpretation="Enumeration" Uom="ConnectionState"
Value=""/>
</ParameterBag>
</Resource>
<Resource Id="virtualBoolean" Name="Virtual Boolean PLC Connection" Type="PlcConnection">
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="className" Name="Connection Class" Type="String" Value="li.strolch.plc.core.hw.connections.VirtualBooleanValueConnection"/>
<Parameter Id="state" Name="Connection State" Type="String" Interpretation="Enumeration" Uom="ConnectionState" Value="Disconnected"/>
<Parameter Id="stateMsg" Name="Connection State Msg" Type="String" Interpretation="Enumeration" Uom="ConnectionState"
Value=""/>
@ -95,12 +103,12 @@
<Parameter Id="addresses" Name="Addresses" Type="StringList" Interpretation="Resource-Ref" Uom="PlcAddress"
Value="addrPlcStarted"/>
<Parameter Id="telegrams" Name="Telegrams" Type="StringList" Interpretation="Resource-Ref" Uom="PlcTelegram"
Value="telPlcStarted, telPlcStopped"/>
Value=""/>
</ParameterBag>
</Resource>
<Resource Id="addrPlcStarted" Name="PLC - Started" Type="PlcAddress">
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="address" Name="HW Address" Type="String" Interpretation="PlcConnection" Value="booleanConnection"/>
<Parameter Id="address" Name="HW Address" Type="String" Interpretation="PlcConnection" Value="virtualBoolean"/>
<Parameter Id="resource" Name="Resource ID for PlcAddress" Type="String" Value="PLC"/>
<Parameter Id="action" Name="Action ID for PlcAddress" Type="String" Value="Started"/>
<Parameter Id="valueType" Name="Value Type" Type="String" Interpretation="Interpretation" Uom="PlcValueType" Value="Boolean"/>
@ -108,26 +116,6 @@
<Parameter Id="index" Name="Index" Type="Integer" Value="10"/>
</ParameterBag>
</Resource>
<Resource Id="telPlcStarted" Name="PLC - Started" Type="PlcTelegram">
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="address" Name="HW Address" Type="String" Interpretation="PlcConnection" Value="booleanConnection"/>
<Parameter Id="resource" Name="Resource ID for PlcAddress" Type="String" Value="PLC"/>
<Parameter Id="action" Name="Action ID for PlcAddress" Type="String" Value="Started"/>
<Parameter Id="valueType" Name="Value Type" Type="String" Interpretation="Interpretation" Uom="PlcValueType" Value="Boolean"/>
<Parameter Id="value" Name="Value" Type="Boolean" Value="true"/>
<Parameter Id="index" Name="Index" Type="Integer" Value="10"/>
</ParameterBag>
</Resource>
<Resource Id="telPlcStopped" Name="PLC - Stopped" Type="PlcTelegram">
<ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
<Parameter Id="address" Name="HW Address" Type="String" Interpretation="PlcConnection" Value="booleanConnection"/>
<Parameter Id="resource" Name="Resource ID for PlcAddress" Type="String" Value="PLC"/>
<Parameter Id="action" Name="Action ID for PlcAddress" Type="String" Value="Stopped"/>
<Parameter Id="valueType" Name="Value Type" Type="String" Interpretation="Interpretation" Uom="PlcValueType" Value="Boolean"/>
<Parameter Id="value" Name="Value" Type="Boolean" Value="false"/>
<Parameter Id="index" Name="Index" Type="Integer" Value="20"/>
</ParameterBag>
</Resource>
<!--
BarcodeReader

View File

@ -27,6 +27,7 @@ import li.strolch.agent.api.*;
import li.strolch.model.Resource;
import li.strolch.model.parameter.StringParameter;
import li.strolch.persistence.api.StrolchTransaction;
import li.strolch.plc.core.PlcHandler;
import li.strolch.plc.model.ConnectionState;
import li.strolch.privilege.model.PrivilegeContext;
import li.strolch.runtime.configuration.ComponentConfiguration;
@ -71,13 +72,24 @@ public class PlcGwHandler extends StrolchComponent {
@Override
public void start() throws Exception {
notifyPlcConnectionState(ConnectionState.Disconnected);
delayConnect(INITIAL_DELAY, TimeUnit.SECONDS);
super.start();
}
private void notifyPlcConnectionState(ConnectionState disconnected) {
try {
getComponent(PlcHandler.class).notify("PLC", "ServerConnected", disconnected.name());
} catch (Exception e) {
logger.error("Failed to notify PLC of connection state", e);
}
}
@Override
public void stop() throws Exception {
notifyPlcConnectionState(ConnectionState.Disconnected);
if (this.gwSession != null) {
try {
this.gwSession.close(new CloseReason(CloseCodes.GOING_AWAY, "Shutting down"));
@ -120,7 +132,7 @@ public class PlcGwHandler extends StrolchComponent {
logger.error("Failed to connect to server! Will try to connect again in " + RETRY_DELAY + "s", e);
}
closeGwSessionUpdateState("Failed to connect to server", ConnectionState.Failed,
closeBrokenGwSessionUpdateState("Failed to connect to server",
"Connection refused to connect to server. Will try to connect again in " + RETRY_DELAY + "s: "
+ getExceptionMessageWithCauses(e));
delayConnect(RETRY_DELAY, TimeUnit.SECONDS);
@ -131,7 +143,7 @@ public class PlcGwHandler extends StrolchComponent {
this.lastSystemStateNotification = System.currentTimeMillis();
if (tryPingServer()) {
logger.error("Failed to ping server. Will try to connect again in " + RETRY_DELAY + "s");
closeGwSessionUpdateState("Ping failed", ConnectionState.Failed,
closeBrokenGwSessionUpdateState("Ping failed",
"Failed to ping server. Will try to connect again in " + RETRY_DELAY + "s");
delayConnect(RETRY_DELAY, TimeUnit.SECONDS);
return;
@ -151,7 +163,7 @@ public class PlcGwHandler extends StrolchComponent {
} catch (IOException e) {
String msg = "Failed to send Auth to server";
logger.error(msg, e);
closeGwSessionUpdateState(msg, ConnectionState.Failed, msg);
closeBrokenGwSessionUpdateState(msg, msg);
delayConnect(RETRY_DELAY, TimeUnit.SECONDS);
return;
}
@ -165,20 +177,18 @@ public class PlcGwHandler extends StrolchComponent {
.scheduleWithFixedDelay(this::pingServer, 1, RETRY_DELAY, TimeUnit.SECONDS);
}
private void closeGwSessionUpdateState(String closeReason, ConnectionState connectionState,
String connectionStateMsg) {
private void closeBrokenGwSessionUpdateState(String closeReason, String connectionStateMsg) {
try {
runAsAgent(ctx -> {
closeGwSessionUpdateState(ctx, closeReason, connectionState, connectionStateMsg);
});
runAsAgent(ctx -> closeBrokenGwSessionUpdateState(ctx, closeReason, connectionStateMsg));
} catch (Exception e) {
logger.error("Failed to close GW Session!", e);
}
notifyPlcConnectionState(ConnectionState.Failed);
}
private void closeGwSessionUpdateState(PrivilegeContext ctx, String closeReason, ConnectionState connectionState,
String connectionStateMsg) {
saveServerConnectionState(ctx, connectionState, connectionStateMsg);
private void closeBrokenGwSessionUpdateState(PrivilegeContext ctx, String closeReason, String connectionStateMsg) {
saveServerConnectionState(ctx, ConnectionState.Failed, connectionStateMsg);
closeGwSession(closeReason);
}
@ -206,7 +216,7 @@ public class PlcGwHandler extends StrolchComponent {
private void pingServer() {
if (tryPingServer()) {
logger.error("Failed to ping server. Reconnecting...");
closeGwSessionUpdateState("Ping failed", ConnectionState.Failed,
closeBrokenGwSessionUpdateState("Ping failed",
"Failed to ping server. Will try to connect again in " + RETRY_DELAY + "s");
delayConnect(RETRY_DELAY, TimeUnit.MILLISECONDS);
}
@ -268,7 +278,7 @@ public class PlcGwHandler extends StrolchComponent {
if (!response.has(PARAM_STATE) || !response.has(PARAM_STATE_MSG) || !response.has(PARAM_AUTH_TOKEN)) {
closeGwSessionUpdateState(ctx, "Auth failed!", ConnectionState.Failed,
closeBrokenGwSessionUpdateState(ctx, "Auth failed!",
"Failed to authenticated with Server: At least one of " + PARAM_STATE + ", " + PARAM_STATE_MSG
+ ", " + PARAM_AUTH_TOKEN + " params is missing on Auth Response");
@ -277,20 +287,21 @@ public class PlcGwHandler extends StrolchComponent {
}
if (!response.get(PARAM_STATE).getAsBoolean()) {
closeGwSessionUpdateState(ctx, "Failed to authenticated with server!", ConnectionState.Failed,
closeBrokenGwSessionUpdateState(ctx, "Failed to authenticated with server!",
"Failed to authenticated with Server: " + response.get(PARAM_STATE_MSG).getAsString());
throw new IllegalStateException("Auth failed to Server: " + response.get(PARAM_STATE_MSG).getAsString());
}
String serverAuthToken = response.get(PARAM_AUTH_TOKEN).getAsString();
if (isEmpty(serverAuthToken)) {
closeGwSessionUpdateState(ctx, "Missing auth token on AUTH response!", ConnectionState.Failed,
closeBrokenGwSessionUpdateState(ctx, "Missing auth token on AUTH response!",
"Missing auth token on AUTH response!");
throw new IllegalStateException("Missing auth token on AUTH response!");
}
logger.info(this.gwSession.getId() + ": Successfully authenticated with Server!");
saveServerConnectionState(ctx, ConnectionState.Connected, "");
notifyPlcConnectionState(ConnectionState.Connected);
}
public void pong(PongMessage message, Session session) {