This library is SEMI-SECS-communicate implementation on Java8.
- SECS-I (SEMI-E4)
- SECS-II (SEMI-E5)
- GEM (SEMI-E30, partially)
- HSMS(SEMI-E37), HSMS-SS(SEMI-E37.1), HSMS-GS(SEMI-E37.2)
- SML (PEER Group)
- For use HSMS-SS-Passive example
/* HSMS-SS-Passive open example */
HsmsSsCommunicatorConfig config = new HsmsSsCommunicatorConfig();
config.connectionMode(HsmsConnectionMode.PASSIVE);
config.socketAddress(new InetSocketAddress("127.0.0.1", 5000));
config.sessionId(10);
config.isEquip(true);
config.timeout().t3(45.0F);
config.timeout().t6( 5.0F);
config.timeout().t7(10.0F);
config.timeout().t8( 5.0F);
config.gem().mdln("MDLN-A");
config.gem().softrev("000001");
config.gem().clockType(ClockType.A16);
SecsCommunicator passive = HsmsSsCommunicator.newInstance(config);
passive.open();
- For use HSMS-SS-Active example
/* HSMS-SS-Active open example */
HsmsSsCommunicatorConfig config = new HsmsSsCommunicatorConfig();
config.connectionMode(HsmsConnectionMode.ACTIVE);
config.socketAddress(new InetSocketAddress("127.0.0.1", 5000));
config.sessionId(10);
config.isEquip(false);
config.timeout().t3(45.0F);
config.timeout().t5(10.0F);
config.timeout().t6( 5.0F);
config.timeout().t8( 5.0F);
config.linktest(120.0F);
config.gem().clockType(ClockType.A16);
SecsCommunicator active = HsmsSsCommunicator.newInstance(config);
active.open();
-
For Use HSMS-GS
-
For use SECS-I (onTcpIp) example
/*
SECS-I (onTcpIp) open example.
This is connect/client type connection.
This and 'Secs1OnTcpIpReceiverCommunicator' are a pair.
*/
Secs1OnTcpIpCommunicatorConfig config = new Secs1OnTcpIpCommunicatorConfig();
config.socketAddress(new InetSocketAddress("127.0.0.1", 10000));
config.deviceId(10);
config.isMaster(true);
config.isEquip(true);
config.timeout().t1( 1.0F);
config.timeout().t2(15.0F);
config.timeout().t3(45.0F);
config.timeout().t4(45.0F);
config.retry(3);
config.gem().clockType(ClockType.A16);
SecsCommunicator secs1 = Secs1OnTcpIpCommunicator.newInstance(config);
secs1.open();
- For use SECS-I (onTcpIp) Receiver example
/*
SECS-I (onTcpIp) Receiver open example.
This is bind/server type connection.
This and 'Secs1OnTcpIpCommunicator' are a pair.
*/
Secs1OnTcpIpReceiverCommunicatorConfig config = new Secs1OnTcpIpReceiverCommunicatorConfig();
config.socketAddress(new InetSocketAddress("127.0.0.1", 10000));
config.deviceId(10);
config.isMaster(false);
config.isEquip(false);
config.timeout().t1( 1.0F);
config.timeout().t2(15.0F);
config.timeout().t3(45.0F);
config.timeout().t4(45.0F);
config.retry(3);
config.gem().clockType(ClockType.A16);
SecsCommunicator secs1r = Secs1OnTcpIpReceiverCommunicator.newInstance(config);
secs1r.open();
How to convert TCP/IP <-> RS232C
- Create SECS-II
/* example */
Secs2 secs2 = Secs2.list( /* <L */
Secs2.binary((byte)0x81), /* <B 0x81> */
Secs2.uint2(1001), /* <U2 1001> */
Secs2.ascii("ON FIRE") /* <A "ON FIRE"> */
); /* >. */
See also "/src/examples/example3/ExampleBuildSecs2.java"
- Send Primary-Message
/* Send S5F1 W. example */
Optional<SecsMessage> reply = passive.send(
5, /* Stream-Number */
1, /* Function-Number */
true, /* W-Bit */
secs2 /* SECS-II */
);
-
Receive Reply-Message
SecsCommunicator#send is blocking-method.
Blocking until reply-message received.
Optional has value if W-Bit is true.
Optional is empty if W-Bit is false.
If T3-Timeout, throw SecsWaitReplyMessageException.
- Add Listener
/* Add-Listener example */
active.addSecsMessageReceiveListener((SecsMessage msg) -> {
int strm = msg.getStream(); /* Stream-Number */
int func = msg.getFunction(); /* Function-Number */
boolean wbit = msg.wbit(); /* W-Bit */
Secs2 secs2 = msg.secs2(); /* SECS-II */
});
- Parse SECS-II
/* example Receive Message */
S5F1 W
<L [3]
<B [1] 0x81> /* ALCD (0, 0) */
<U2 [1] 1001> /* ALID (1, 0) */
<A "ON FIRE"> /* ALTX (2) */
>.
byte alcd = msg.secs2().getByte(0, 0);
int alid = msg.secs2().getInt(1, 0);
String altx = msg.secs2().getAscii(2);
✓ is available.
(blank) throw Secs2Exception.
method | B | BOOLEAN | A | I1 | I2 | I4 | I8 | F4 | F8 | U1 | U2 | U4 | U8 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
getByte | ✓ | ||||||||||||
getBytes | ✓ | ||||||||||||
getBoolean | ✓ | ||||||||||||
getAscii | ✓ | ||||||||||||
getInt | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
getLong | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
getBigInteger | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
getFloat | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
getDouble | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
getNumber | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
✓ is that Optional is present.
(blank) is that Optional is empty.
method | B | BOOLEAN | A | I1 | I2 | I4 | I8 | F4 | F8 | U1 | U2 | U4 | U8 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
optionalByte | ✓ | ||||||||||||
optionalBytes | ✓ | ||||||||||||
optionalBoolean | ✓ | ||||||||||||
optionalAscii | ✓ | ||||||||||||
optionalInt | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
optionalLong | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
optionalBigInteger | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | |||||
optionalDouble | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ||
optionalNumber | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
See also "/src/examples/example4/ExampleGetSecs2Value.java"
- Send Reply-Message
Secs2 reply = Secs2.binary((byte)0x0); /* <B 0x0> */
active.send(
primaryMsg, /* Primary-Message */
5, /* Stream-Number */
2, /* Function-Number */
false, /* W-Bit */
reply /* Reply-SECS-II */
);
- Add Listener
/* Add-Listener example */
active.addSecsCommunicatableStateChangeListener((boolean communicatable) -> {
if ( communicatable ) {
System.out.println("communicatable");
} else {
System.out.println("not communicatable");
}
});
Notice: This listener is blocking-method. pass through quickly.
- Waiting until communicate-state-changed
active.waitUntilCommunicatable();
active.waitUntilNotCommunicatable();
/* Open communicator and waiting until communicatable */
active.openAndWaitUntilCommunicatable();
Notice: This method is blocking-method.
- Send Primary-Message case
/* Send S1F1 W. example */
SmlMessage primarySml = SmlMessage.of(
"S1F1 W."
);
active.send(primarySml);
- Send Reply-Message case
/* Send S1F2. example */
SmlMessage replySml = SmlMessage.of(
"S1F2 " +
"<L " +
" <A \"MDLN-A\">" +
" <A \"000001\">" +
">. "
);
passive.send(primaryMsg, replySml);
Notes: SmlMessage can get also SmlMessage#of(java.io.Reader reader)
, SmlMessage#of(java.nio.file.Path path)
, SmlMessageParser.getInstance().parse(CharSequence cs)
, ...
Access from SecsCommunicator#gem
- Create Configuration instance
DynamicEventReportConfig evRptConf = active.gem().newDynamicEventReportConfig();
- Add Configs
-
Add Define Reports
Can be aliased.
RPTID is auto number.
/* no ALias */
DynamicReport rptSimple = evRptConf.addDefineReport(
Arrays.asList(
Long.valueOf(1001L), /* VID-1 */
...
)
);
/* set Alias */
DynamicReport rptAlias = evRptConf.addDefineReport(
"report-alias", /* Report-ALias */
Arrays.asList(
Long.valueOf(2001L), /* VID-1 */
...
)
);
-
Add Enable Collection Events
Can be aliased.
/* no Alias */
DynamicCollectionEvent evSimple = evRptConf.addEnableCollectionEvent(
101L /* CEID */
);
/* set Alias */
DynamicCollectionEvent evAlias = evRptConf.addEnableCollectionEvent(
"event-alias", /* Event-Alias */
201L /* CEID */
);
- Add Links
/* by DynamicReport */
evRptConf.addLinkByReport(
evAlias, /* DynamicCollectionEvent */
Arrays.asList(
rptAlias, /* DynamicReport-1 */
...
)
);
/* by Report-ID */
evRptConf.addLinkById(
evAlias, /* DynamicCollectionEvent */
Arrays.asList(
Long.valueOf(1L), /* RPTID-1 */
...
)
);
- Execute Scenario
ERACK erack = evRptConf.s2f37DisableAll();
DRACK drack = evRptConf.s2f33DeleteAll();
DRACK drack = evRptConf.s2f33Define();
LRACK lrack = evRptConf.s2f35();
ERACK erack = evRptConf.s2f37Enable();
DATAID is auto number.
If has Report-Alias, S6F19 and S6F21 called by Alias.
Optional<SecsMessage> s6f20 = evRptConf.s6f19("report-alias");
Optional<SecsMessage> s6f22 = evRptConf.s6f21("report-alias");
If has Event-Alias, S6F15 and S6F17 called by Alias.
Optional<SecsMessage> s6f16 = evRptConf.s6f15("event-alias");
Optional<SecsMessage> s6f18 = evRptConf.s6f17("event-alias");
From CEID in received S6F11 or S6F13, Get Event-Alias if aliased.
Secs2 ceid = recvS6F11Msg.secs2().get(1); /* Get CEID SECS-II */
Optional<DynamicCollectionEvent> op = evRptConf.getCollectionEvent(ceid);
Optional<String> alias = op.flatMap(ev -> ev.alias()); /* Get Event-ALias */
From RPTID in received S6F11 or S6F13, Get Report-Alias if aliased.
Secs2 rptid = recvS6F11Msg.secs2().get(2, ...); /* Get RPTID SECS-II */
Optional<DynamicReport> op = evRptConf.getReport(rptid);
Optional<String> alias = op.flatMap(rpt -> rpt.alias()); /* Get Report-Alias */
- Send S2F17 and receive reply, parse to LocalDateTime
Clock clock = passive.gem().s2f17();
LocalDateTime ldt = clock.toLocalDateTime();
- Reply S2F18 Now examples
active.gem().s2f18(primaryMsg, Clock.from(LocalDateTime.now()));
active.gem().s2f18(primaryMsg, Clock.now());
active.gem().s2f18Now(primaryMsg);
- Send S2F31 Now examples
TIACK tiack = active.gem().s2f31(Clock.from(LocalDateTime.now()));
TIACK tiack = active.gem().s2f31(Clock.now());
TIACK tiack = active.gem().s2f31Now();
- Receive S2F31, parse to LocalDateTime
Clock clock = Clock.from(recvS2F31Msg.secs2());
LocalDateTime ldt = clock.toLocalDateTime();
TimeFormat (A[12] or A[16]) can be set from AbstractSecsCommunicatorConfig#gem#clockType
.
/* examples */
COMMACK commack = active.gem().s1f13();
OFLACK oflack = active.gem().s1f15();
ONLACK onlack = acitve.gem().s1f17();
passive.gem().s1f14(primaryMsg, COMMACK.OK);
passive.gem().s1f16(primaryMsg);
passive.gem().s1f18(primaryMsg, ONLACK.OK);
active.gem().s5f2(primaryMsg, ACKC5.OK);
active.gem().s6f12(primaryMsg, ACKC6.OK);
passive.gem().s9f1(referenceMsg);
passive.gem().s9f3(referenceMsg);
passive.gem().s9f5(referenceMsg);
passive.gem().s9f7(referenceMsg);
passive.gem().s9f9(referenceMsg);
passive.gem().s9f11(referenceMsg);
Secs2 dataId = passive.gem().autoDataId();