diff --git a/.github/openHAB40.svg b/.github/openHAB40.svg new file mode 100644 index 0000000..fe683c1 --- /dev/null +++ b/.github/openHAB40.svg @@ -0,0 +1 @@ +openHAB: 4.0openHAB4.0 \ No newline at end of file diff --git a/README.md b/README.md index cc4b777..d456de3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This binding for openHAB has ability to connect Simatic PLC over Ethernet with isoTCP. So it should be possible to connect to the Simatic PLC S7-300, S7-400, S7-1200 and S7-1500 series. -[![openHAB](/.github/openHAB30.svg)](https://github.com/openhab) +[![openHAB](/.github/openHAB40.svg)](https://github.com/openhab) [![Version](https://img.shields.io/github/v/release/docbender/openHAB-Simatic?include_prereleases)](https://github.com/docbender/openHAB-Simatic/releases) [![Download](https://img.shields.io/github/downloads/docbender/openHAB-Simatic/total.svg)](https://github.com/docbender/openHAB-Simatic/releases) [![Issues](https://img.shields.io/github/issues/docbender/openHAB-Simatic)](https://github.com/docbender/openHAB-Simatic/issues) diff --git a/org.openhab.binding.simatic/.classpath b/org.openhab.binding.simatic/.classpath deleted file mode 100644 index 76cca7a..0000000 --- a/org.openhab.binding.simatic/.classpath +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.openhab.binding.simatic/.factorypath b/org.openhab.binding.simatic/.factorypath deleted file mode 100644 index 964633a..0000000 --- a/org.openhab.binding.simatic/.factorypath +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/org.openhab.binding.simatic/.project b/org.openhab.binding.simatic/.project deleted file mode 100644 index e1cd64f..0000000 --- a/org.openhab.binding.simatic/.project +++ /dev/null @@ -1,34 +0,0 @@ - - - org.openhab.binding.simatic - - - - - - org.eclipse.jdt.core.javabuilder - - - - - org.eclipse.m2e.core.maven2Builder - - - - - - org.eclipse.jdt.core.javanature - org.eclipse.m2e.core.maven2Nature - - - - 1599460331536 - - 30 - - org.eclipse.core.resources.regexFilterMatcher - node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__ - - - - diff --git a/org.openhab.binding.simatic/.settings/org.eclipse.core.resources.prefs b/org.openhab.binding.simatic/.settings/org.eclipse.core.resources.prefs deleted file mode 100644 index abdea9a..0000000 --- a/org.openhab.binding.simatic/.settings/org.eclipse.core.resources.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -encoding//src/main/java=UTF-8 -encoding//src/main/resources=UTF-8 -encoding/=UTF-8 diff --git a/org.openhab.binding.simatic/.settings/org.eclipse.jdt.apt.core.prefs b/org.openhab.binding.simatic/.settings/org.eclipse.jdt.apt.core.prefs deleted file mode 100644 index 687ad91..0000000 --- a/org.openhab.binding.simatic/.settings/org.eclipse.jdt.apt.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.apt.aptEnabled=true -org.eclipse.jdt.apt.genSrcDir=target\\generated-sources\\annotations -org.eclipse.jdt.apt.genTestSrcDir=target\\generated-test-sources\\test-annotations diff --git a/org.openhab.binding.simatic/.settings/org.eclipse.jdt.core.prefs b/org.openhab.binding.simatic/.settings/org.eclipse.jdt.core.prefs deleted file mode 100644 index 2985089..0000000 --- a/org.openhab.binding.simatic/.settings/org.eclipse.jdt.core.prefs +++ /dev/null @@ -1,9 +0,0 @@ -eclipse.preferences.version=1 -org.eclipse.jdt.core.compiler.codegen.targetPlatform=11 -org.eclipse.jdt.core.compiler.compliance=11 -org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled -org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning -org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore -org.eclipse.jdt.core.compiler.processAnnotations=enabled -org.eclipse.jdt.core.compiler.release=disabled -org.eclipse.jdt.core.compiler.source=11 diff --git a/org.openhab.binding.simatic/.settings/org.eclipse.m2e.core.prefs b/org.openhab.binding.simatic/.settings/org.eclipse.m2e.core.prefs deleted file mode 100644 index f897a7f..0000000 --- a/org.openhab.binding.simatic/.settings/org.eclipse.m2e.core.prefs +++ /dev/null @@ -1,4 +0,0 @@ -activeProfiles= -eclipse.preferences.version=1 -resolveWorkspaceProjects=true -version=1 diff --git a/org.openhab.binding.simatic/pom.xml b/org.openhab.binding.simatic/pom.xml index 82b6807..f6ed073 100644 --- a/org.openhab.binding.simatic/pom.xml +++ b/org.openhab.binding.simatic/pom.xml @@ -1,17 +1,17 @@ - - - - 4.0.0 - - - org.openhab.addons.bundles - org.openhab.addons.reactor.bundles - 3.3.0 - - - org.openhab.binding.simatic - - openHAB Add-ons :: Bundles :: Simatic Binding - - + + + + 4.0.0 + + + org.openhab.addons.bundles + org.openhab.addons.reactor.bundles + 4.0.1 + + + org.openhab.binding.simatic + + openHAB Add-ons :: Bundles :: Simatic Binding + + diff --git a/org.openhab.binding.simatic/src/main/history/dependencies.xml b/org.openhab.binding.simatic/src/main/history/dependencies.xml index 17988c6..4367216 100644 --- a/org.openhab.binding.simatic/src/main/history/dependencies.xml +++ b/org.openhab.binding.simatic/src/main/history/dependencies.xml @@ -1,9 +1,9 @@ - + openhab-runtime-base wrap - mvn:org.openhab.addons.bundles/org.openhab.binding.simatic/3.3.0 + mvn:org.openhab.addons.bundles/org.openhab.binding.simatic/4.0.1 wrap:mvn:org.lastnpe.eea/eea-all/2.2.1 diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/handler/simaticBridgeHandler.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/handler/simaticBridgeHandler.java index 38234e2..adaebb7 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/handler/simaticBridgeHandler.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/handler/simaticBridgeHandler.java @@ -16,7 +16,6 @@ import java.util.ArrayList; import java.util.concurrent.TimeUnit; -import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.openhab.binding.simatic.internal.SimaticBindingConstants; @@ -27,9 +26,6 @@ import org.openhab.binding.simatic.internal.simatic.SimaticTCP200; import org.openhab.binding.simatic.internal.simatic.SimaticUpdateMode; import org.openhab.core.library.types.DecimalType; -import org.openhab.core.library.types.QuantityType; -import org.openhab.core.library.types.StringType; -import org.openhab.core.library.unit.Units; import org.openhab.core.thing.Bridge; import org.openhab.core.thing.ChannelUID; import org.openhab.core.thing.Thing; @@ -57,7 +53,7 @@ public class SimaticBridgeHandler extends BaseBridgeHandler { public @Nullable SimaticGenericDevice connection = null; // bridge channels - private @Nullable ChannelUID chVersion, chPduSize, chAreasCount, chAreas, chTagCount, chRequests, chBytes; + private @Nullable ChannelUID chTagCount, chRequests, chBytes; private int channelCount = 0; /** Initial scheduler delay */ @@ -74,15 +70,7 @@ public SimaticBridgeHandler(Bridge bridge) { // retrieve bridge channels getThing().getChannels().forEach((channel) -> { - if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_VERSION)) { - chVersion = channel.getUID(); - } else if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_PDU_SIZE)) { - chPduSize = channel.getUID(); - } else if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_AREAS_COUNT)) { - chAreasCount = channel.getUID(); - } else if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_AREAS)) { - chAreas = channel.getUID(); - } else if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_TAG_COUNT)) { + if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_TAG_COUNT)) { chTagCount = channel.getUID(); } else if (channel.getChannelTypeUID().equals(SimaticBindingConstants.CHANNEL_TYPE_REQUESTS)) { chRequests = channel.getUID(); @@ -95,7 +83,7 @@ public SimaticBridgeHandler(Bridge bridge) { @SuppressWarnings("null") @Override public void initialize() { - updateState(chVersion, new StringType(SimaticBindingConstants.VERSION)); + updateProperty(SimaticBindingConstants.PROPERTY_BINDING_VERSION, SimaticBindingConstants.VERSION); config = getConfigAs(SimaticBridgeConfiguration.class); @@ -174,10 +162,39 @@ public void initialize() { // react on connection changes connection.onConnectionChanged((connected) -> { if (connected) { - updateState(chPduSize, new DecimalType((Number) connection.getPduSize())); - updateState(chAreasCount, new DecimalType((Number) connection.getReadAreas().size())); - updateState(chAreas, new StringType( - (connection.getReadAreas().size() == 0) ? "none" : connection.getReadAreas().toString())); + updateProperty(SimaticBindingConstants.PROPERTY_PDU, String.valueOf(connection.getPduSize())); + updateProperty(SimaticBindingConstants.PROPERTY_AREAS_COUNT, + String.valueOf(connection.getReadAreas().size())); + updateProperty(SimaticBindingConstants.PROPERTY_AREAS, + (connection.getReadAreas().size() == 0) ? "none" : connection.getReadAreas().toString()); + if (connection.info.getPlcName() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_PLC_NAME, connection.info.getPlcName()); + } + if (connection.info.getModuleName() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_MODULE_NAME, connection.info.getModuleName()); + } + if (connection.info.getModuleTypeName() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_MODULE_NAME_TYPE, + connection.info.getModuleTypeName()); + } + if (connection.info.getCopyright() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_COPYRIGHT, connection.info.getCopyright()); + } + if (connection.info.getSerialNumber() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_SERIAL, connection.info.getSerialNumber()); + } + if (connection.info.getOrderNr() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_ORDER_NUMBER, connection.info.getOrderNr()); + } + if (connection.info.getHwVersion() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_HW_VERSION, connection.info.getHwVersion()); + } + if (connection.info.getFwVersion() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_FW_VERSION, connection.info.getFwVersion()); + } + if (connection.info.getMemorySize() != null) { + updateProperty(SimaticBindingConstants.PROPERTY_MEMORY_SIZE, connection.info.getMemorySize()); + } updateStatus(ThingStatus.ONLINE); } else { @@ -186,8 +203,8 @@ public void initialize() { }); connection.onMetricsUpdated((requests, bytes) -> { - updateState(chRequests, new DecimalType((Number) requests)); - updateState(chBytes, new DecimalType((Number) bytes)); + updateState(chRequests, new DecimalType(requests)); + updateState(chBytes, new DecimalType(bytes)); }); // temporarily status @@ -221,30 +238,14 @@ public void dispose() { logger.debug("{} - bridge has been stopped", getThing().getLabel()); } - @SuppressWarnings("null") @Override public void handleCommand(ChannelUID channelUID, Command command) { logger.debug("{} - Command {} for channel {}", thing.getLabel(), command, channelUID); // get cached values if (command instanceof RefreshType) { - if (channelUID.equals(chVersion)) { - updateState(channelUID, new StringType(SimaticBindingConstants.VERSION)); - } else if (channelUID.equals(chPduSize)) { - if (connection != null && connection.isConnected()) { - updateState(chPduSize, new QuantityType<>(connection.getPduSize(), Units.BYTE)); - } - } else if (channelUID.equals(chAreas)) { - if (connection != null && connection.isConnected()) { - updateState(chAreas, new StringType( - (connection.getReadAreas().size() == 0) ? "none" : connection.getReadAreas().toString())); - } - } else if (channelUID.equals(chAreasCount)) { - if (connection != null && connection.isConnected()) { - updateState(chAreasCount, new DecimalType((Number) connection.getReadAreas().size())); - } - } else if (channelUID.equals(chTagCount)) { - updateState(channelUID, new DecimalType((Number) channelCount)); + if (channelUID.equals(chTagCount)) { + updateState(channelUID, new DecimalType(channelCount)); } } } @@ -274,7 +275,7 @@ public void updateConfig() { } } - var stateItems = new ArrayList<@NonNull SimaticChannel>(stateChannelCount); + var stateItems = new ArrayList(stateChannelCount); for (Thing th : getThing().getThings()) { var h = ((SimaticGenericHandler) th.getHandler()); @@ -291,15 +292,9 @@ public void updateConfig() { if (connection != null) { var c = connection; c.setDataAreas(stateItems); - - if (c.isConnected()) { - updateState(chAreasCount, new DecimalType((Number) c.getReadAreas().size())); - updateState(chAreas, - new StringType((c.getReadAreas().size() == 0) ? "none" : c.getReadAreas().toString())); - } } - updateState(chTagCount, new DecimalType((Number) channelCount)); + updateState(chTagCount, new DecimalType(channelCount)); logger.debug("{} - updating {} channels({} read)", getThing().getLabel(), channelCount, stateChannelCount); } diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/S7Connection.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/S7Connection.java index ea647ff..f2f1348 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/S7Connection.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/S7Connection.java @@ -512,4 +512,257 @@ public void finalize() throws Throwable { disconnectPLC(); iface.finalize(); } + + public class S7SZL { + public int LENTHDR; + public int N_DR; + public byte[] Data; + public int Size; + + public S7SZL(int size) { + Data = new byte[size]; + Size = size; + } + } + + public class S7CpuInfo { + public String ModuleTypeName; + public String SerialNumber; + public String PlcName; + public String Copyright; + public String ModuleName; + } + + public class S7ModuleInfo { + public String OrderNr; + public String HwOrderNr; + public String HwVersion; + public String FwVersion; + } + + public class S7MemoryInfo { + public long Size; + } + + /** + * Read SSL from Simatic + * + * @param ID + * @param Index + * @param SZL + * @return + * @throws IOException + */ + private int ReadSZL(int ID, int Index, S7SZL SZL) throws IOException { + int DataSZL; + int Offset = 0; + boolean Done = false; + boolean First = true; + byte Seq_in = 0; + byte Seq_out = 0; + int dataSize = 0; + SZL.LENTHDR = 0; + int res; + + do { + PDU p = new PDU(msgOut, PDUstartOut); + p.initHeader(7); + + if (First) { + byte parameters[] = { 0x00, 0x01, 0x12, 0x04, 0x11, 0x44, 0x01, 0x00 }; + byte data[] = { (byte) 0xff, 0x09, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00 }; + Nodave.setUSByte(parameters, 7, Seq_out); + Nodave.setUSBEWord(data, 4, ID); + Nodave.setUSBEWord(data, 6, Index); + p.addParam(parameters); + p.addData(data); + } else { + byte parameters[] = { 0x00, 0x01, 0x12, 0x08, 0x12, 0x44, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00 }; + byte data[] = { 0x0a, 0x00, 0x00, 0x00 }; + Nodave.setUSByte(parameters, 7, ++Seq_out); + p.addParam(parameters); + p.addData(data); + } + + res = exchange(p); + if (res != 0) { + return res;// Nodave.RESULT_UNKNOWN_ERROR; + } + + PDU p2 = new PDU(msgIn, PDUstartIn); + res = p2.setupReceivedPDU(); + if (res != 0) { + return res; + } + + // sequence number + Seq_in = msgIn[24]; + // last data unit = 0x0 + Done = msgIn[26] == 0; + + var errorCode = Nodave.USBEWord(msgIn, p2.param + 10); + byte returnCode = msgIn[p2.data]; + + // no success + if (errorCode == 0 && returnCode != (byte) 0xFF) { + return Nodave.RESULT_UNKNOWN_ERROR; + // SZL not supported + } else if (errorCode == 0xd401) { + return Nodave.RESULT_ITEM_NOT_AVAILABLE; + } else if (errorCode != 0) { + return errorCode; + } + + if (First) { + SZL.LENTHDR = Nodave.USBEWord(msgIn, p2.data + 8); + SZL.N_DR = Nodave.USBEWord(msgIn, p2.data + 10); + // data length + DataSZL = Nodave.USBEWord(msgIn, p2.data + 2) - (12 - 2 - 2); + // copy data + System.arraycopy(msgIn, p2.data + 12, SZL.Data, Offset, DataSZL); + } else { + // data length + DataSZL = Nodave.USBEWord(msgIn, p2.data + 2); + // copy data + System.arraycopy(msgIn, p2.data + 8, SZL.Data, Offset, DataSZL); + } + + Offset += DataSZL; + dataSize += DataSZL; + First = false; + } while (!Done); + + return 0; + } + + /** + * Retrieve CPU info + * + * @param Info + * @return + * @throws IOException + */ + public int GetCpuInfo(S7CpuInfo Info) throws IOException { + S7SZL SZL = new S7SZL(1024); + int _LastError = ReadSZL(0x001C, 0x000, SZL); + if (_LastError != 0) { + return _LastError; + } + + for (int i = 0; i < SZL.N_DR; i++) { + int id = Nodave.USBEWord(SZL.Data, i * SZL.LENTHDR); + var text = new String(SZL.Data, i * SZL.LENTHDR + 2, SZL.LENTHDR - 2).trim(); + + if (id == 1) { + Info.PlcName = text; + } else if (id == 2) { + Info.ModuleName = text; + } else if (id == 4) { + Info.Copyright = text; + } else if (id == 5) { + Info.SerialNumber = text; + } else if (id == 7) { + Info.ModuleTypeName = text; + } + } + return 0; + } + + /** + * Retrieve device module info + * + * @param Info + * @return + * @throws IOException + */ + public int GetModuleInfo(S7ModuleInfo Info) throws IOException { + S7SZL SZL = new S7SZL(1024); + int _LastError = ReadSZL(0x0011, 0x000, SZL); + if (_LastError != 0) { + return _LastError; + } + + for (int i = 0; i < SZL.N_DR; i++) { + int id = Nodave.USBEWord(SZL.Data, i * SZL.LENTHDR); + var orderNr = new String(SZL.Data, i * SZL.LENTHDR + 2, 20).trim(); + var v1 = Nodave.USByte(SZL.Data, i * SZL.LENTHDR + 2 + 23); + var v2 = Nodave.USByte(SZL.Data, i * SZL.LENTHDR + 2 + 24); + var v3 = Nodave.USByte(SZL.Data, i * SZL.LENTHDR + 2 + 25); + + String version = String.valueOf(v1); + if (v2 <= 9) { + version += "." + v2; + } + if (v3 <= 9) { + version += "." + v3; + } + + // module + if (id == 1) { + Info.OrderNr = orderNr; + // HW + } else if (id == 6) { + Info.HwOrderNr = orderNr; + Info.HwVersion = version; + // FW + } else if (id == 7) { + Info.FwVersion = version; + } + } + return 0; + } + + /** + * Retrieve device memory info + * + * @param Info + * @return + * @throws IOException + */ + public int GetMemoryInfo(S7MemoryInfo Info) throws IOException { + S7SZL SZL = new S7SZL(1024); + int _LastError = ReadSZL(0x0113, 0x01, SZL); + if (_LastError != 0) { + return _LastError; + } + + for (int i = 0; i < SZL.N_DR; i++) { + int id = Nodave.USBEWord(SZL.Data, i * SZL.LENTHDR); + var size = Nodave.USBELong(SZL.Data, i * SZL.LENTHDR + 4); + + if (id == 1) { + Info.Size = size; + } + } + return 0; + } + + /** + * Convert data array to string + * + * @param data + * @param length + * @return + */ + private static String arrayToString(byte[] data, int length) { + StringBuilder s = new StringBuilder(); + + for (int i = 0; i < length; i++) { + byte b = data[i]; + if (s.length() == 0) { + s.append("["); + } else { + s.append(" "); + } + + // if(SimpleBinaryBinding.JavaVersion >= 1.8) + // s.append("0x" + Integer.toHexString(Byte.toUnsignedInt(b)).toUpperCase()); + // else + s.append("0x" + Integer.toHexString(b & 0xFF).toUpperCase()); + } + + s.append("]"); + + return s.toString(); + } } diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/TCPConnection.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/TCPConnection.java index 791a032..997bffb 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/TCPConnection.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/libnodave/TCPConnection.java @@ -175,7 +175,6 @@ public int exchange(PDU p1) throws IOException { */ @Override public int connectPLC() throws IOException { - int res; byte[] b4 = { (byte) 0x11, (byte) 0xE0, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0xC1, (byte) 0x02, (byte) 0x01, (byte) 0x00, (byte) 0xC2, (byte) 0x02, (byte) 0x01, (byte) 0x02, (byte) 0xC0, (byte) 0x01, (byte) 0x09 }; @@ -193,13 +192,7 @@ public int connectPLC() throws IOException { if ((Nodave.Debug & Nodave.DEBUG_CONNECT) != 0) { System.out.println("daveConnectPLC() step 1."); } - /* - * PDU p = new PDU(msgOut, 7); - * p.initHeader(1); - * p.addParam(b61); - * exchange(p); - * return (0); - */ + return negPDUlengthRequest(); } } diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticDeviceInfo.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticDeviceInfo.java new file mode 100644 index 0000000..1ee75c8 --- /dev/null +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticDeviceInfo.java @@ -0,0 +1,128 @@ +package org.openhab.binding.simatic.internal.simatic; + +import java.io.IOException; + +import org.openhab.binding.simatic.internal.libnodave.Nodave; +import org.openhab.binding.simatic.internal.libnodave.S7Connection; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Retrieve and hold PLC information + * + * @author VitaTucek + * + */ +public class SimaticDeviceInfo { + private static final Logger logger = LoggerFactory.getLogger(SimaticDeviceInfo.class); + + private String moduleTypeName; + private String serialNumber; + private String plcName; + private String copyright; + private String moduleName; + private String orderNr; + private String hwOrderNr; + private String hwVersion; + private String fwVersion; + private long memorySize; + + /** + * Get readable result + * + * @param source + * @return + */ + private String getString(String source) { + /* + * if (source == null) { + * return "-"; + * } + */ + return source; + } + + public String getModuleTypeName() { + return getString(moduleTypeName); + } + + public String getSerialNumber() { + return getString(serialNumber); + } + + public String getPlcName() { + return getString(plcName); + } + + public String getCopyright() { + return getString(copyright); + } + + public String getModuleName() { + return getString(moduleName); + } + + public String getOrderNr() { + return getString(orderNr); + } + + public String getHwOrderNr() { + return getString(hwOrderNr); + } + + public String getHwVersion() { + return getString(hwVersion); + } + + public String getFwVersion() { + return getString(fwVersion); + } + + public String getMemorySize() { + if (memorySize == -1) { + return null; + } else if (memorySize > 1024 * 1024) { + return String.valueOf(memorySize / (1024 * 1024)) + " MB"; + } else if (memorySize > 1024) { + return String.valueOf(memorySize / 1024) + " kB"; + } else { + return String.valueOf(memorySize) + " B"; + } + } + + /** + * Get connected device information + * + * @param dc + * @throws IOException + */ + public void getInfo(S7Connection dc) throws IOException { + S7Connection.S7CpuInfo cpuinfo = dc.new S7CpuInfo(); + int res; + if ((res = dc.GetCpuInfo(cpuinfo)) == 0) { + moduleName = cpuinfo.ModuleName; + moduleTypeName = cpuinfo.ModuleTypeName; + plcName = cpuinfo.PlcName; + serialNumber = cpuinfo.SerialNumber; + copyright = cpuinfo.Copyright; + } else { + logger.debug("{} - GetCpuInfo error: {}", this.toString(), Nodave.strerror(res)); + } + S7Connection.S7ModuleInfo moduleInfo = dc.new S7ModuleInfo(); + if ((res = dc.GetModuleInfo(moduleInfo)) == 0) { + orderNr = moduleInfo.OrderNr; + hwOrderNr = moduleInfo.HwOrderNr; + hwVersion = moduleInfo.HwVersion; + fwVersion = moduleInfo.FwVersion; + } else { + logger.debug("{} - GetModuleInfo error: {}", this.toString(), Nodave.strerror(res)); + } + S7Connection.S7MemoryInfo memoryInfo = dc.new S7MemoryInfo(); + if ((res = dc.GetMemoryInfo(memoryInfo)) == 0) { + memorySize = memoryInfo.Size; + } else { + memorySize = -1; + logger.debug("{} - GetMemoryInfo error: {}", this.toString(), Nodave.strerror(res)); + } + } +} diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticGenericDevice.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticGenericDevice.java index 3891114..715bdba 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticGenericDevice.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticGenericDevice.java @@ -67,6 +67,7 @@ public class SimaticGenericDevice implements SimaticIDevice { protected final AtomicBoolean tryReconnect = new AtomicBoolean(false); /** PDU size **/ protected int pduSize = 0; + public final SimaticDeviceInfo info = new SimaticDeviceInfo(); protected final Charset charset; protected final SimaticUpdateMode updateMode; diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticTCP.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticTCP.java index cef2dcf..2bba6bb 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticTCP.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simatic/SimaticTCP.java @@ -138,6 +138,8 @@ public Boolean open() { portState.setState(PortStates.LISTENING); // prepare data after PDU is negotiated prepareData(); + // request device info + info.getInfo(dc); setConnected(true); } else { logger.error("{} - cannot connect to PLC", this.toString()); diff --git a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simaticBindingConstants.java b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simaticBindingConstants.java index d1064a1..9e4431a 100644 --- a/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simaticBindingConstants.java +++ b/org.openhab.binding.simatic/src/main/java/org/openhab/binding/simatic/internal/simaticBindingConstants.java @@ -25,7 +25,7 @@ @NonNullByDefault public class SimaticBindingConstants { - public static final String VERSION = "3.3.0"; + public static final String VERSION = "4.0.1"; private static final String BINDING_ID = "simatic"; @@ -34,19 +34,26 @@ public class SimaticBindingConstants { public static final ThingTypeUID THING_TYPE_GENERIC = new ThingTypeUID(BINDING_ID, "generic_device"); // List of all Bridge Channel ids - public static final String CHANNEL_VERSION = "chVersionTypeID"; - public static final String CHANNEL_PDU_SIZE = "chPduTypeID"; - public static final String CHANNEL_AREAS_COUNT = "chAreasCountTypeID"; - public static final String CHANNEL_AREAS = "chAreasTypeID"; public static final String CHANNEL_TAG_COUNT = "chTagCountTypeID"; public static final String CHANNEL_REQUESTS = "chRequestsTypeID"; public static final String CHANNEL_BYTES = "chBytesTypeID"; + // List of all Property IDs + public static final String PROPERTY_BINDING_VERSION = "bindingVersion"; + public static final String PROPERTY_PDU = "pdu"; + public static final String PROPERTY_AREAS_COUNT = "areasCount"; + public static final String PROPERTY_AREAS = "areas"; + public static final String PROPERTY_PLC_NAME = "plcName"; + public static final String PROPERTY_MODULE_NAME = "moduleName"; + public static final String PROPERTY_MODULE_NAME_TYPE = "moduleNameType"; + public static final String PROPERTY_COPYRIGHT = "copyright"; + public static final String PROPERTY_SERIAL = "serialNumber"; + public static final String PROPERTY_ORDER_NUMBER = "orderNumber"; + public static final String PROPERTY_HW_VERSION = "hardwareVersion"; + public static final String PROPERTY_FW_VERSION = "firmwareVersion"; + public static final String PROPERTY_MEMORY_SIZE = "workingMemorySize"; + // List of all Channel Type UIDs - public static final ChannelTypeUID CHANNEL_TYPE_VERSION = new ChannelTypeUID(BINDING_ID, CHANNEL_VERSION); - public static final ChannelTypeUID CHANNEL_TYPE_PDU_SIZE = new ChannelTypeUID(BINDING_ID, CHANNEL_PDU_SIZE); - public static final ChannelTypeUID CHANNEL_TYPE_AREAS_COUNT = new ChannelTypeUID(BINDING_ID, CHANNEL_AREAS_COUNT); - public static final ChannelTypeUID CHANNEL_TYPE_AREAS = new ChannelTypeUID(BINDING_ID, CHANNEL_AREAS); public static final ChannelTypeUID CHANNEL_TYPE_TAG_COUNT = new ChannelTypeUID(BINDING_ID, CHANNEL_TAG_COUNT); public static final ChannelTypeUID CHANNEL_TYPE_REQUESTS = new ChannelTypeUID(BINDING_ID, CHANNEL_REQUESTS); public static final ChannelTypeUID CHANNEL_TYPE_BYTES = new ChannelTypeUID(BINDING_ID, CHANNEL_BYTES); diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/addon/addon.xml b/org.openhab.binding.simatic/src/main/resources/OH-INF/addon/addon.xml new file mode 100644 index 0000000..4330975 --- /dev/null +++ b/org.openhab.binding.simatic/src/main/resources/OH-INF/addon/addon.xml @@ -0,0 +1,10 @@ + + + binding + Simatic Binding + This is the binding for Simatic. + local + diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/binding/binding.xml b/org.openhab.binding.simatic/src/main/resources/OH-INF/binding/binding.xml deleted file mode 100644 index 754a764..0000000 --- a/org.openhab.binding.simatic/src/main/resources/OH-INF/binding/binding.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - Simatic Binding - This is the binding for Simatic. - VitaTucek - diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic.properties b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic.properties new file mode 100644 index 0000000..2ccbb05 --- /dev/null +++ b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic.properties @@ -0,0 +1,91 @@ +# add-on +addon.simatic.name = Simatic Binding +addon.simatic.description = This is the binding for Simatic + +# thing types +thing-type.simatic.bridge.label = Simatic Bridge +thing-type.simatic.bridge.description = Represent single PLC or more exactly its connection, which uses individual things +thing-type.simatic.generic_device.label = Simatic Thing +thing-type.simatic.generic_device.description = Generic thing for Simatic Binding. This thing requires bridge to be defined. + +# thing type config description +thing-type.config.simatic.bridge.address.label = PLC IP/Host address +thing-type.config.simatic.bridge.address.description = Network IP/Host address of PLC. +thing-type.config.simatic.bridge.rack.label = Rack number +thing-type.config.simatic.bridge.rack.description = The rack number in which CPU is presented. +thing-type.config.simatic.bridge.slot.label = Slot number +thing-type.config.simatic.bridge.slot.description = The slot number where CPU is inserted. +thing-type.config.simatic.bridge.pollRate.label = Poll rate [ms] +thing-type.config.simatic.bridge.pollRate.description = Determine period of data read from device. +thing-type.config.simatic.bridge.charset.label = Code page +thing-type.config.simatic.bridge.charset.description = Define code page for communicated strings (e.g. ISO-8859-1, cp1250). If blank or wrong code page is defined, system code page is used. +thing-type.config.simatic.bridge.communicationType.label = Communication type +thing-type.config.simatic.bridge.communicationType.description = Which type of communication should be established. Possibilities are PG, OP, S7 (default). +thing-type.config.simatic.bridge.isS7200.label = PLC is S7-200 series +thing-type.config.simatic.bridge.isS7200.description = Communication partner is CP243 of Simatic S7-200. +thing-type.config.simatic.bridge.updateMode.label = Value update mode +thing-type.config.simatic.bridge.updateMode.description = Update read value can be OnChange or Poll. In OnChange mode only changed values are sent into OH core (default). In Poll mode every value is sent into OH core (more CPU intensive). + +# channel types +channel-type.simatic.chVersionTypeID.label = Version +channel-type.simatic.chVersionTypeID.description = Binding version +channel-type.simatic.chPduTypeID.label = PDU size +channel-type.simatic.chPduTypeID.description = Negotiated PDU size +channel-type.simatic.chAreasCountTypeID.label = Areas count +channel-type.simatic.chAreasCountTypeID.description = Communicated PLC data areas count +channel-type.simatic.chAreasTypeID.label = Areas +channel-type.simatic.chAreasTypeID.description = Communicated PLC data areas +channel-type.simatic.chTagCountTypeID.label = Channels count +channel-type.simatic.chTagCountTypeID.description = Channels count +channel-type.simatic.chRequestsTypeID.label = Request rate +channel-type.simatic.chRequestsTypeID.description = Requests per second to device +channel-type.simatic.chBytesTypeID.label = Data rate +channel-type.simatic.chBytesTypeID.description = Bytes per second grabbed from device +channel-type.simatic.chNumber.label = Number Value +channel-type.simatic.chNumber.description = Supported Simatic data types are Bit, Byte, Word, Dword, Float. +channel-type.simatic.chColor.label = Color Value +channel-type.simatic.chColor.description = In Simatic represented RGB as Dword. Each Byte is single color part. +channel-type.simatic.chString.label = Text Value +channel-type.simatic.chString.description = Represented as array of Bytes. +channel-type.simatic.chContact.label = Open/Close Contact +channel-type.simatic.chContact.description = Simatic data type is Byte or Bit. 0 - Close, 1 - Open. +channel-type.simatic.chSwitch.label = On/Off Switch +channel-type.simatic.chSwitch.description = Simatic data type is Byte or Bit. 0 - Off, 1 - On. +channel-type.simatic.chDimmer.label = Percentage Value +channel-type.simatic.chDimmer.description = Simatic data type is Byte. Range is 0-100. +channel-type.simatic.chRollershutter.label = Rollershutter +channel-type.simatic.chRollershutter.description = Simatic status data type is Byte for position (0-100%). Simatic command data types are Byte or Word. Byte for Stop/Up/Down (2-Stop,4-Up,8-Down). Word first Byte for Move/Stop/Up/Down (1-Move,2-Stop,4-Up,8-Down) and second Byte for target position (0-100%). + +# channel types config +channel-type.config.simatic.chNumber.stateAddress.label = State address +channel-type.config.simatic.chNumber.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chNumber.commandAddress.label = Command address +channel-type.config.simatic.chNumber.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chNumber.unit.label = Unit +channel-type.config.simatic.chNumber.unit.description = Received number unit. If specified, unit is send into openHAB together with new value. No validation against data type is provided. +channel-type.config.simatic.chColor.stateAddress.label = State address +channel-type.config.simatic.chColor.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chColor.commandAddress.label = Command address +channel-type.config.simatic.chColor.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chString.stateAddress.label = State address +channel-type.config.simatic.chString.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chString.commandAddress.label = Command address +channel-type.config.simatic.chString.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chContact.stateAddress.label = State address +channel-type.config.simatic.chContact.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chContact.commandAddress.label = Command address +channel-type.config.simatic.chContact.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chSwitch.stateAddress.label = State address +channel-type.config.simatic.chSwitch.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chSwitch.commandAddress.label = Command address +channel-type.config.simatic.chSwitch.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chDimmer.stateAddress.label = State address +channel-type.config.simatic.chDimmer.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chDimmer.commandAddress.label = Command address +channel-type.config.simatic.chDimmer.commandAddress.description = Simatic address to command item. If empty, no data will be sent. +channel-type.config.simatic.chRollershutter.stateAddress.label = State address +channel-type.config.simatic.chRollershutter.stateAddress.description = Simatic address to get item state. If empty, no data will be received. +channel-type.config.simatic.chRollershutter.commandAddress.label = Command address +channel-type.config.simatic.chRollershutter.commandAddress.description = Simatic address to command item. If empty, no data will be sent. + + diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_cs.properties b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_cs.properties new file mode 100644 index 0000000..2c88cbf --- /dev/null +++ b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_cs.properties @@ -0,0 +1,91 @@ +# add-on +addon.simatic.name = Simatic Binding +addon.simatic.description = Simatic binding + +# thing types +thing-type.simatic.bridge.label = Simatic Bridge +thing-type.simatic.bridge.description = Reprezentuje konkrétní PLC nebo přesněji jeho spojení, které užívají jednotlivé proměnné. +thing-type.simatic.generic_device.label = Simatic Thing +thing-type.simatic.generic_device.description = Zařízení Simaticu. Vyžaduje, aby byl definovaný bridge. + +# thing type config description +thing-type.config.simatic.bridge.address.label = PLC IP/Host adresa +thing-type.config.simatic.bridge.address.description = Síťová IP/Host adresa PLC. +thing-type.config.simatic.bridge.rack.label = Číslo racku +thing-type.config.simatic.bridge.rack.description = Číslo racku, ve které je vloženo PLC. +thing-type.config.simatic.bridge.slot.label = Číslo slotu +thing-type.config.simatic.bridge.slot.description = Číslo slotu, ve které je vloženo PLC. +thing-type.config.simatic.bridge.pollRate.label = Perioda čtení [ms] +thing-type.config.simatic.bridge.pollRate.description = Perioda čtení dat z PLC. +thing-type.config.simatic.bridge.charset.label = Kódová stránka +thing-type.config.simatic.bridge.charset.description = Definuje kódovou stránku pro přenášené stringy (např. ISO-8859-1, cp1250). Pokud není vyplněno nebo je vyplněna chybná kódová stránka, je použita systémová. +thing-type.config.simatic.bridge.communicationType.label = Typ komunikace +thing-type.config.simatic.bridge.communicationType.description = Určuje jaký typ komunikace s PLC bude navázán. Možnosti jsou PG, OP, S7 (výchozí). +thing-type.config.simatic.bridge.isS7200.label = PLC je ze série S7-200 +thing-type.config.simatic.bridge.isS7200.description = Komunikační partner je CP243 ze Simatic S7-200. +thing-type.config.simatic.bridge.updateMode.label = Mód aktualizace +thing-type.config.simatic.bridge.updateMode.description = Čtení hodnot může probíhat v módu OnChange nebo Poll. V módu OnChange jsou do OH posílány pouze změny hodnot (výchozí). V módu Poll je každá změna posílána do OH (více náročné na CPU). + +# channel types +channel-type.simatic.chVersionTypeID.label = Verze +channel-type.simatic.chVersionTypeID.description = Verze modulu +channel-type.simatic.chPduTypeID.label = Velikost PDU +channel-type.simatic.chPduTypeID.description = Dohodnutá velikost PDU mezi modulem a PLC +channel-type.simatic.chAreasCountTypeID.label = Počet datových oblastí komunikovaných s PLC +channel-type.simatic.chAreasCountTypeID.description = Počet komunikovaných datových oblastí s PLC +channel-type.simatic.chAreasTypeID.label = Oblasti +channel-type.simatic.chAreasTypeID.description = Výpis komunikovaných datových oblastí +channel-type.simatic.chTagCountTypeID.label = Počet kanálů +channel-type.simatic.chTagCountTypeID.description = Počet nakonfigurovaných kanálů / tagů +channel-type.simatic.chRequestsTypeID.label = Intenzita požadavků +channel-type.simatic.chRequestsTypeID.description = Požadavků za sekundu zaslaných na PLC +channel-type.simatic.chBytesTypeID.label = Rychlost přenosu dat +channel-type.simatic.chBytesTypeID.description = Bytů přenesených za sekundu +channel-type.simatic.chNumber.label = Číselná hodnota +channel-type.simatic.chNumber.description = Podporované datové typy pro Simatic jsou Bit, Byte, Word, Dword, Float. +channel-type.simatic.chColor.label = Barva +channel-type.simatic.chColor.description = V Simaticu je RGB hodnota reprezentována jako Dword. Každý Byte reprezentuje jednotlivou barevnou složku. +channel-type.simatic.chString.label = Text +channel-type.simatic.chString.description = Text reprezentovaný jako pole Bytů. +channel-type.simatic.chContact.label = Kontakt Otevřeno/Zavřeno +channel-type.simatic.chContact.description = Datový typ v Simaticu je Byte nebo Bit. 0 - Zavřeno, 1 - Otevřeno. +channel-type.simatic.chSwitch.label = Spínač Zapnuto/Vypnuto +channel-type.simatic.chSwitch.description = Datový typ Simaticu je Byte nebo Bit. 0 - Vypnuto, 1 - Zapnuto. +channel-type.simatic.chDimmer.label = Stmívač +channel-type.simatic.chDimmer.description = Datový typ je Byte. Rozsah 0-100%. +channel-type.simatic.chRollershutter.label = Roleta +channel-type.simatic.chRollershutter.description = Datový typ stavu je Byte pro polohu (0-100%). Datový typ povelu je Byte nebo Word. Byte pro Stop/Nahoru/Dolů (2-Stop,4-Nahoru,8-Dolů). U Wordu první Byte je pro Přesun/Stop/Nahoru/Dolů (1-Přesun,2-Stop,4-Nahoru,8-Dolů) a druhý Byte pro cílovou pozici (0-100%). + +# channel types config +channel-type.config.simatic.chNumber.stateAddress.label = Adresa stavu +channel-type.config.simatic.chNumber.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chNumber.commandAddress.label = Adresa povelu +channel-type.config.simatic.chNumber.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chNumber.unit.label = Jednotka +channel-type.config.simatic.chNumber.unit.description = Jednotka nakonfigurované hodnoty. Pokud je jednotka definovaná, je odeslána spolu s přijatou hodnotou do openHABu. Žádné validace datového typu nebudou provedeny. +channel-type.config.simatic.chColor.stateAddress.label = Adresa stavu +channel-type.config.simatic.chColor.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chColor.commandAddress.label = Adresa povelu +channel-type.config.simatic.chColor.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chString.stateAddress.label = Adresa stavu +channel-type.config.simatic.chString.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chString.commandAddress.label = Adresa povelu +channel-type.config.simatic.chString.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chContact.stateAddress.label = Adresa stavu +channel-type.config.simatic.chContact.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chContact.commandAddress.label = Adresa povelu +channel-type.config.simatic.chContact.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chSwitch.stateAddress.label = Adresa stavu +channel-type.config.simatic.chSwitch.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chSwitch.commandAddress.label = Adresa povelu +channel-type.config.simatic.chSwitch.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chDimmer.stateAddress.label = Adresa stavu +channel-type.config.simatic.chDimmer.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chDimmer.commandAddress.label = Adresa povelu +channel-type.config.simatic.chDimmer.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. +channel-type.config.simatic.chRollershutter.stateAddress.label = Adresa stavu +channel-type.config.simatic.chRollershutter.stateAddress.description = Simatic adresa pro získání hodnoty proměnné. Pokud je prázdná, žádná data nebudou načtena. +channel-type.config.simatic.chRollershutter.commandAddress.label = Adresa povelu +channel-type.config.simatic.chRollershutter.commandAddress.description = Simatic adresa povelu. Pokud je prázdná, žádná data nebudou odeslána do PLC. + + diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_de.properties b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_de.properties new file mode 100644 index 0000000..c2aad36 --- /dev/null +++ b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_de.properties @@ -0,0 +1,91 @@ +# add-on +addon.simatic.name = Simatic Binding +addon.simatic.description = Das Simatic binding für den Simatic PLC + +# thing types +thing-type.simatic.bridge.label = Simatic Bridge +thing-type.simatic.bridge.description = Eine einzelne SPS oder genauer gesagt deren Verbindung, die einzelne Gerät verwendet. +thing-type.simatic.generic_device.label = Simatic Thing +thing-type.simatic.generic_device.description = Gerät für Simatic Binding. Für dieses Gerät muss eine Bridge definiert werden. + +# thing type config description +thing-type.config.simatic.bridge.address.label = PLC IP/Host-Adresse +thing-type.config.simatic.bridge.address.description = Netzwerk IP/Host-Adresse der SPS. +thing-type.config.simatic.bridge.rack.label = Racknummer +thing-type.config.simatic.bridge.rack.description = Die Racknummer, in der die CPU präsentiert wird. +thing-type.config.simatic.bridge.slot.label = Slotnummer +thing-type.config.simatic.bridge.slot.description = The Slotnummer, in der die CPU eingesetzt wird. +thing-type.config.simatic.bridge.pollRate.label = Poolrate [ms] +thing-type.config.simatic.bridge.pollRate.description = Zeitraum der vom Gerät gelesenen Daten bestimmen. +thing-type.config.simatic.bridge.charset.label = Code Seite +thing-type.config.simatic.bridge.charset.description = Definition der Codepage für kommunizierte Texte (z. B. ISO-8859-1, cp1250). Wenn eine freie oder falsche Codepage definiert ist, wird die System-Codepage verwendet. +thing-type.config.simatic.bridge.communicationType.label = Kommunikationstyp +thing-type.config.simatic.bridge.communicationType.description = Welche Kommunikationart soll aufgebaut werden. Mögliche Optionen sind PG, OP, S7 (Standard). +thing-type.config.simatic.bridge.isS7200.label = SPS ist die S7-200 Serie +thing-type.config.simatic.bridge.isS7200.description = Kommunikationspartner ist der CP243 der Simatic S7-200. +thing-type.config.simatic.bridge.updateMode.label = Modus der Wertaktualisierung +thing-type.config.simatic.bridge.updateMode.description = Der Wert kann bei OnChange oder Poll aktualisiert werden. Im Modus OnChange werden nur geänderte Werte an den OH-Core gesendet (Standard). Im Poll-Modus wird jeder Wert an den OH-Core gesendet (CPU intensiv). + +# channel types +channel-type.simatic.chVersionTypeID.label = Version +channel-type.simatic.chVersionTypeID.description = Binding version +channel-type.simatic.chPduTypeID.label = PDU-Größe +channel-type.simatic.chPduTypeID.description = Ausgehandelte PDU-Größe +channel-type.simatic.chAreasCountTypeID.label = Datenbereichezahl +channel-type.simatic.chAreasCountTypeID.description = Anzahl der kommunizierten SPS-Datenbereiche +channel-type.simatic.chAreasTypeID.label = Datenbereiche +channel-type.simatic.chAreasTypeID.description = Kommunizierte SPS-Datenbereiche +channel-type.simatic.chTagCountTypeID.label = Anzahl der Kanäle +channel-type.simatic.chTagCountTypeID.description = Anzahl der Kanäle +channel-type.simatic.chRequestsTypeID.label = Anfragerate +channel-type.simatic.chRequestsTypeID.description = Anfragen pro Sekunde an das Gerät +channel-type.simatic.chBytesTypeID.label = Übertragungsrate +channel-type.simatic.chBytesTypeID.description = Vom Gerät abgegriffene Bytes pro Sekunde +channel-type.simatic.chNumber.label = Wert +channel-type.simatic.chNumber.description = Unterstützte Simatic Datentypen sind Bit, Byte, Word, Dword, Float. +channel-type.simatic.chColor.label = Farbe +channel-type.simatic.chColor.description = In Simatic wird RGB als Dword dargestellt. Jedes Byte ist ein einzelner Farbanteil. +channel-type.simatic.chString.label = Text +channel-type.simatic.chString.description = Als Array von Bytes dargestellt. +channel-type.simatic.chContact.label = Öffnen/Schließen Kontakt +channel-type.simatic.chContact.description = Simatic Datentyp ist Byte oder Bit. 0 - Schließen, 1 - Öffnen. +channel-type.simatic.chSwitch.label = Ein/Aus Schalter +channel-type.simatic.chSwitch.description = Simatic Datentyp ist Byte oder Bit. 0 - Aus, 1 - Ein. +channel-type.simatic.chDimmer.label = Dimmer +channel-type.simatic.chDimmer.description = Der Simatic Datentyp ist Byte. Der Bereich ist 0-100. +channel-type.simatic.chRollershutter.label = Rollladen +channel-type.simatic.chRollershutter.description = Der Simatic Statusdatentyp ist Byte für die Position (0-100%). Simatic Befehlsdatentypen sind Byte oder Word. Byte für Stop/Auf/Ab (2-Stop,4-Auf,8-Ab). Word erstes Byte für Bewegung/Stop/Auf/Ab (1-Bewegung,2-Stop,4-Auf,8-Ab) und zweites Byte für die Zielposition (0-100%). + +# channel types config +channel-type.config.simatic.chNumber.stateAddress.label = Statusadresse +channel-type.config.simatic.chNumber.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chNumber.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chNumber.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chNumber.unit.label = Einheit +channel-type.config.simatic.chNumber.unit.description = Empfangene Nummerneinheit. Wenn die Einheit angegeben ist, wird sie zusammen mit dem neuen Wert an openHAB gesendet. Eine Validierung gegen den Datentyp ist nicht vorgesehen. +channel-type.config.simatic.chColor.stateAddress.label = Statusadresse +channel-type.config.simatic.chColor.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chColor.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chColor.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chString.stateAddress.label = Statusadresse +channel-type.config.simatic.chString.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chString.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chString.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chContact.stateAddress.label = Statusadresse +channel-type.config.simatic.chContact.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chContact.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chContact.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chSwitch.stateAddress.label = Statusadresse +channel-type.config.simatic.chSwitch.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chSwitch.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chSwitch.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chDimmer.stateAddress.label = Statusadresse +channel-type.config.simatic.chDimmer.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chDimmer.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chDimmer.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. +channel-type.config.simatic.chRollershutter.stateAddress.label = Statusadresse +channel-type.config.simatic.chRollershutter.stateAddress.description = Simatic Adresse mit Channelstatus. Wenn leer, werden keine Daten empfangen. +channel-type.config.simatic.chRollershutter.commandAddress.label = Sollwertadresse +channel-type.config.simatic.chRollershutter.commandAddress.description = Simatic Adresse für das Channelbefehl. Wenn leer, werden keine Daten gesendet. + + diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_xx_XX.properties b/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_xx_XX.properties deleted file mode 100644 index 93e98ee..0000000 --- a/org.openhab.binding.simatic/src/main/resources/OH-INF/i18n/simatic_xx_XX.properties +++ /dev/null @@ -1,17 +0,0 @@ -# FIXME: please substitute the xx_XX with a proper locale, ie. de_DE -# FIXME: please do not add the file to the repo if you add or change no content -# binding -binding.simatic.name = -binding.simatic.description = - -# thing types -thing-type.simatic.sample.label = -thing-type.simatic.sample.description = - -# thing type config description -thing-type.config.simatic.sample.config1.label = -thing-type.config.simatic.sample.config1.description = - -# channel types -channel-type.simatic.sample-channel.label = -channel-type.simatic.sample-channel.description = diff --git a/org.openhab.binding.simatic/src/main/resources/OH-INF/thing/thing-types.xml b/org.openhab.binding.simatic/src/main/resources/OH-INF/thing/thing-types.xml index 8036b7a..462c87f 100644 --- a/org.openhab.binding.simatic/src/main/resources/OH-INF/thing/thing-types.xml +++ b/org.openhab.binding.simatic/src/main/resources/OH-INF/thing/thing-types.xml @@ -1,247 +1,238 @@ - - - - - - Represent single PLC or more exactly its connection, which uses individual things. - - - - - - - - - - - - - Network IP/Host address of PLC - network-address - - - - The rack number in which CPU is presented - 0 - - - - The slot number where CPU is inserted - 2 - - - - Determine period of data read from device. - 1000 - true - - - - Define code page for communicated strings (e.g. ISO-8859-1, cp1250). If blank or wrong code page is - defined, system code page is used. - - true - - - - Which type of communication should be established. Possibilities are PG, OP, S7 (default). - S7 - - - - - - true - - - - Communication partner is CP243 of Simatic S7-200 - false - true - - - - Update read value can be OnChange or Poll. In OnChange mode only changed values are sent into OH core (default). In Poll mode every value is sent into OH core (more CPU intensive). - - - - - OnChange - true - - - - - - - - - - - Generic thing for Simatic Binding. This thing requires bridge to be defined. - - - - - - String - - Binding version - - - - Number - - Negotiated PDU size - - - - Number - - Communicated PLC data areas count - - - - String - - Communicated PLC data areas - - - - Number - - Channels count - - - - Number - - Requests per second to device - - - - Number - - Bytes per second grabbed from device - - - - - - Number - - Supported Simatic data types are Bit, Byte, Word, Dword, Float - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - Received number unit. If specified, unit is send into openHAB together with new value. No validation against data type is provided. - - - - - Color - - In Simatic represented RGB as Dword. Each Byte is single color part. - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - - String - - Represented as array of Bytes. - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - - Contact - - Simatic data type is Byte or Bit. 0 - Close, 1 - Open - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - - Switch - - Simatic data type is Byte or Bit. 0 - Off, 1 - On - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - - Dimmer - - Simatic data type is Byte. Range is 0-100 - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - - Rollershutter - - - - - - - Simatic address to get item state. If empty, no data will be received. - - - - Simatic address to command item. If empty, no data will be sent. - - - - + + + + + + Represent single PLC or more exactly its connection, which uses individual things. + + + + + + + - + Siemens + - + - + - + + + + + Network IP/Host address of PLC + network-address + + + + The rack number in which CPU is presented + 0 + + + + The slot number where CPU is inserted + 2 + + + + Determine period of data read from device. + 1000 + true + + + + Define code page for communicated strings (e.g. ISO-8859-1, cp1250). If blank or wrong code page is + defined, system code page is used. + + true + + + + Which type of communication should be established. Possibilities are PG, OP, S7 (default). + S7 + + + + + + true + + + + Communication partner is CP243 of Simatic S7-200 + false + true + + + + Update read value can be OnChange or Poll. In OnChange mode only changed values are sent into OH core (default). In Poll mode every value is sent into OH core (more CPU intensive). + + + + + OnChange + true + + + + + + + + + + + Generic thing for Simatic Binding. This thing requires bridge to be defined. + + + + + + Number + + Communicated PLC data areas count + + + + String + + Communicated PLC data areas + + + + Number + + Channels count + + + + Number + + Requests per second to device + + + + Number + + Bytes per second grabbed from device + + + + + + Number + + Supported Simatic data types are Bit, Byte, Word, Dword, Float + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + Received number unit. If specified, unit is send into openHAB together with new value. No validation against data type is provided. + + + + + Color + + In Simatic represented RGB as Dword. Each Byte is single color part. + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + + String + + Represented as array of Bytes. + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + + Contact + + Simatic data type is Byte or Bit. 0 - Close, 1 - Open + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + + Switch + + Simatic data type is Byte or Bit. 0 - Off, 1 - On + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + + Dimmer + + Simatic data type is Byte. Range is 0-100 + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + + + Rollershutter + + + + + + + Simatic address to get item state. If empty, no data will be received. + + + + Simatic address to command item. If empty, no data will be sent. + + + +