├── .gitignore
├── .project
├── .settings
├── org.eclipse.jdt.core.prefs
└── org.eclipse.m2e.core.prefs
├── LICENCE
├── README.md
├── pom.xml
└── src
├── assembly
├── jar.xml
├── pack.xml
└── runtime.xml
└── main
├── java
└── de
│ └── myandres
│ └── optolink
│ ├── BroadcastListner.java
│ ├── Channel.java
│ ├── Config.java
│ ├── Main.java
│ ├── OptolinkInterface.java
│ ├── SocketHandler.java
│ ├── Telegram.java
│ ├── Thing.java
│ ├── Viessmann300.java
│ ├── ViessmannHandler.java
│ ├── ViessmannKW.java
│ └── ViessmannProtocol.java
└── resources
├── INSTALL_AUTOSTART.txt
├── logback.xml
├── logback_debug.xml
├── logback_trace.xml
├── optolink-ob.xml
├── optolink.init.d
├── optolink.xml
├── start.sh
├── start_debug.sh
├── start_trace.sh
└── stop.sh
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | /.classpath
3 | conf/
4 | logs/
5 | .settings/
6 | optolink.xml
7 | start.bat
8 | start.sh
9 | start_debug.sh
10 | things-types vs optolink - comparison.xlsx
11 | .gitignore
12 |
--------------------------------------------------------------------------------
/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | optolink
4 |
5 |
6 |
7 |
8 |
9 | org.eclipse.jdt.core.javabuilder
10 |
11 |
12 |
13 |
14 | org.eclipse.m2e.core.maven2Builder
15 |
16 |
17 |
18 |
19 |
20 | org.eclipse.jdt.core.javanature
21 | org.eclipse.m2e.core.maven2Nature
22 |
23 |
24 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.jdt.core.prefs:
--------------------------------------------------------------------------------
1 | eclipse.preferences.version=1
2 | org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
3 | org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
4 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
5 | org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
6 | org.eclipse.jdt.core.compiler.compliance=1.8
7 | org.eclipse.jdt.core.compiler.debug.lineNumber=generate
8 | org.eclipse.jdt.core.compiler.debug.localVariable=generate
9 | org.eclipse.jdt.core.compiler.debug.sourceFile=generate
10 | org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
11 | org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
12 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
13 | org.eclipse.jdt.core.compiler.source=1.8
14 |
--------------------------------------------------------------------------------
/.settings/org.eclipse.m2e.core.prefs:
--------------------------------------------------------------------------------
1 | activeProfiles=
2 | eclipse.preferences.version=1
3 | resolveWorkspaceProjects=true
4 | version=1
5 |
--------------------------------------------------------------------------------
/LICENCE:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # optolink
2 |
3 | Viessmann heating systems with vitotronic has a optolink Interface for maintenance.
4 | This interface can use for get/set data in the heating system.
5 | For more information about this interface see: http://openv.wikispaces.com/
6 |
7 | The java-application is a slim adapter to this interface.
8 | On southbound it use the serial interface for connect the optolink interface (special hardware requert).
9 | On northbound it provides a TCP/IP raw Port for communication and a UDP/IP Port as broadcast interface
10 | to search the adapter in the local network.
11 |
12 | Primary is is develop for a adaption from [openhab2](https://github.com/openhab/openhab2/).
13 | It supports on the northbound the concept of openhab2 things.
14 |
15 | ##Build
16 | The application is develop in Eclipse (Luna) with maven support.
17 | Requierd Lib's: rxtx, slf4j, logback (see pom.xml file)
18 | You can build runtime by Run->Run As->Maven install.
19 | Files for runtime are found in ./traget
20 | Or download the install package from Github.
21 |
22 | ##Install & running
23 | All test was running on a Raspberry PI B with Raspbian "wheezy".
24 | Installing:
25 |
26 | 1. Install the rxtx (apt)
27 | 2. Config /dev/ttyAMA0 (see: https://cae2100.wordpress.com/2012/12/23/raspberry-pi-and-the-serial-port/)
28 | 3. Install your optolink hardware
29 | 4. copy: optolink-runtime.zip from the target folder to Rasberry and extract it.
30 | 5. Edit conf/optolink.xml for your heading system.
31 | 6. start it: ```./start_debug.sh ```
32 |
33 |
34 | ##Test it
35 | Run a terminal programm (like putty), connect to you raspberry by using port 31113 and raw protocol.
36 | Suported command:
37 |
38 | * list -> list all (thing) definition (in xml-File)
39 | * get Thing.Id [channel.Id,channel.Id,..] -> get Data for thing from heating system.
40 | * set Thing-Id:Channel.Id value (The syntax of Value is not checked)
41 |
42 | ##Further doing (my ToDo List)
43 | 1. bug-fixing (if bugs found ;-)
44 | 2. Build a stable version (together with openhab2).
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 | de.myandres.optolink
5 | optolink
6 | jar
7 | optolink
8 |
9 | 1.8
10 | 1.8
11 |
12 |
13 |
14 |
15 | maven-assembly-plugin
16 | 2.5.3
17 |
18 |
19 | jar-with-dependencies
20 |
21 |
22 |
23 | de.myandres.optolink.Main
24 |
25 |
26 |
27 | src/assembly/jar.xml
28 | src/assembly/pack.xml
29 |
30 | optolink
31 |
32 |
33 |
34 | make-assembly
35 | package
36 |
37 | single
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | org.slf4j
47 | slf4j-api
48 | 1.7.10
49 |
50 |
51 |
52 | ch.qos.logback
53 | logback-classic
54 | 1.1.2
55 | runtime
56 |
57 |
58 | org.rxtx
59 | rxtx
60 | 2.1.7
61 |
62 |
63 |
64 | 1.0.0-RC1
65 |
--------------------------------------------------------------------------------
/src/assembly/jar.xml:
--------------------------------------------------------------------------------
1 |
4 | final
5 |
6 | jar
7 |
8 | false
9 |
10 |
11 | true
12 | runtime
13 | false
14 |
15 |
16 |
17 |
18 | ${project.build.outputDirectory}
19 | /
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/assembly/pack.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | bin
7 |
8 | tar.gz
9 | tar.bz2
10 | zip
11 |
12 |
13 |
14 | target
15 | lib
16 |
17 | *jar-with-dependencies.jar
18 |
19 |
20 |
21 |
22 | README*
23 | LICENCE
24 |
25 | unix
26 |
27 |
28 |
29 | src/main/resources
30 | conf
31 |
32 | *.xml
33 |
34 | unix
35 |
36 |
37 | src/main/resources
38 |
39 |
40 | *.sh
41 | *.txt
42 |
43 | unix
44 | 0755
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/assembly/runtime.xml:
--------------------------------------------------------------------------------
1 |
4 | runtime
5 |
6 | tar.gz
7 | tar.bz2
8 | zip
9 |
10 |
11 |
12 | target
13 | lib
14 |
15 | *jar-with-dependencies.jar
16 |
17 |
18 |
19 |
20 | README*
21 | LICENCE
22 |
23 | unix
24 |
25 |
26 |
27 | src/main/resources
28 | conf
29 |
30 | *.xml
31 |
32 | unix
33 |
34 |
35 | src/main/resources
36 |
37 |
38 | *.sh
39 | *.txt
40 |
41 | unix
42 | 0755
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/BroadcastListner.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import java.net.DatagramPacket;
17 | import java.net.DatagramSocket;
18 | import java.net.InetAddress;
19 | import org.slf4j.Logger;
20 | import org.slf4j.LoggerFactory;
21 |
22 | public class BroadcastListner implements Runnable {
23 |
24 | static Logger log = LoggerFactory.getLogger(BroadcastListner.class);
25 |
26 | static final String BROADCAST_MESSAGE = "@@@@VITOTRONIC@@@@/";
27 | int port;
28 | String connectedIP;
29 | String adapterID;
30 |
31 |
32 |
33 | BroadcastListner(int port, String adapterID) {
34 | log.debug("Init Broadcast Listener on Port", port);
35 | this.port = port;
36 | connectedIP = "";
37 | this.adapterID =adapterID;
38 | }
39 |
40 |
41 | @Override
42 | public void run() {
43 | // Runs Listner
44 | log.debug("Listening for Broadcast....");
45 | DatagramSocket datagramSocket = null;
46 | InetAddress remoteIPAddress;
47 | int remotePort;
48 | byte[] byteArray = new byte[1024];
49 |
50 | try {
51 | datagramSocket = new DatagramSocket(port, InetAddress.getByName("0.0.0.0"));
52 | datagramSocket.setBroadcast(true);
53 |
54 |
55 | String str;
56 |
57 | while (true) {
58 | try {
59 | DatagramPacket resivedPacket = new DatagramPacket(byteArray , byteArray.length);
60 | datagramSocket.receive(resivedPacket);
61 | str = new String(resivedPacket.getData()).trim();
62 | log.debug("Resived Broadcast Message: {}", str);
63 | remotePort = resivedPacket.getPort();
64 | log.debug("From Port: {}", remotePort);
65 | remoteIPAddress = resivedPacket.getAddress();
66 | log.debug("From Host: {}",remoteIPAddress.toString());
67 |
68 | if (str.startsWith(BROADCAST_MESSAGE+adapterID) ||
69 | str.startsWith(BROADCAST_MESSAGE+"*")) {
70 | // Someone calls me
71 | str = BROADCAST_MESSAGE + adapterID;
72 | byteArray = str.getBytes();
73 | DatagramPacket sendPacket = new DatagramPacket(byteArray,
74 | byteArray.length, remoteIPAddress, remotePort);
75 | log.debug("Send: '{}' to {}:{}", str, remoteIPAddress.getHostAddress(), remotePort );
76 | datagramSocket.send(sendPacket);
77 |
78 |
79 | } else {
80 | log.debug("Host: {}:{} calls with wrong message: {}",
81 | remoteIPAddress.getHostAddress(),
82 | remotePort,
83 | str);
84 | log.debug("Message will be ignor!");
85 | }
86 |
87 | } catch (Exception e) {
88 | log.error("Something is wrong in broadcast listner thread!!! Diagnostic {}", e);
89 | log.error("Broadcast Listner die ");
90 |
91 | } }
92 |
93 | } catch (Exception e) {
94 | // TODO Auto-generated catch block
95 | log.error("Something is wrong in broadcast listner thread!!! Diagnostic {}", e);
96 | log.error("Broadcast Listner die");
97 |
98 | } finally {
99 | try {
100 | if (datagramSocket != null)
101 | datagramSocket.close();
102 | } catch (Exception e) {
103 | // Ignore
104 | }
105 | }
106 | }
107 |
108 | }
109 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Channel.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class Channel {
20 |
21 | static Logger logger = LoggerFactory.getLogger(Channel.class);
22 |
23 |
24 | private String id;
25 | private String description;
26 | private Telegram telegram;
27 |
28 | Channel (Channel channel) {
29 | logger.trace("Init id: '{}'", channel.getId() );
30 | this.id = channel.getId();
31 | this.description = channel.getDescription();
32 | this.telegram = channel.getTelegram();
33 | }
34 |
35 | Channel (String id ) {
36 | logger.trace("Init id: '{}'", id );
37 | this.id = id;
38 | this.description = null;
39 | this.telegram = null;
40 | }
41 |
42 |
43 | public Telegram getTelegram() {
44 | return telegram;
45 | }
46 |
47 | public void setTelegram(Telegram telegram) {
48 | this.telegram = telegram;
49 | }
50 |
51 | public String getId() {
52 | return id;
53 | }
54 | public void setId(String id) {
55 | this.id = id;
56 | }
57 |
58 | public String getDescription() {
59 | return description;
60 | }
61 |
62 | public void setDescription(String description) {
63 | this.description = description;
64 | }
65 |
66 | }
67 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Config.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import java.io.FileReader;
17 | import java.util.ArrayList;
18 | import java.util.List;
19 |
20 | import org.xml.sax.Attributes;
21 | import org.xml.sax.ContentHandler;
22 | import org.xml.sax.InputSource;
23 | import org.xml.sax.Locator;
24 | import org.xml.sax.SAXException;
25 | import org.xml.sax.XMLReader;
26 | import org.xml.sax.helpers.XMLReaderFactory;
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | /*
31 | * Contains Data from xml-File
32 | * This Data will be static only - dynamic data are stored in DataStore
33 | */
34 |
35 |
36 | public class Config {
37 |
38 | static Logger log = LoggerFactory.getLogger(Config.class);
39 |
40 | private String adapterID="TEST";
41 | private String tty;
42 | private String ttyIP;
43 | private Integer ttyPort;
44 | private String ttyType;
45 | private int ttyTimeOut = 2000; //default
46 | private int port = 31113; // default: unassigned Port. See: http://www.iana.org
47 | private String deviceType;
48 | private String protocol;
49 | private List thingList;
50 |
51 |
52 |
53 | Config(String fileName) throws Exception {
54 | thingList = new ArrayList();
55 | // create XMLReader
56 | XMLReader xmlReader = XMLReaderFactory.createXMLReader();
57 |
58 | log.debug("Try to open File {}", fileName);
59 | // Pfad tho XML Datei
60 | FileReader reader = new FileReader(fileName);
61 | InputSource inputSource = new InputSource(reader);
62 |
63 | log.info("File {} open for parsing", fileName);
64 |
65 |
66 | // set ContentHandler
67 | xmlReader.setContentHandler(new xHandler());
68 |
69 | // start parser
70 | log.debug("Start parsing");
71 | xmlReader.parse(inputSource);
72 | log.info("{} Things are parsed", thingList.size());
73 | }
74 |
75 |
76 | public List getThingList() {
77 | return thingList;
78 | }
79 |
80 | private void addThing(Thing thing) {
81 | log.trace("Add thing id: {}", thing.getId());
82 | thingList.add(new Thing(thing));
83 | }
84 |
85 | public Thing getThing(String id) {
86 | log.trace("get thing id: {}", id);
87 | for (int i = 0; i < thingList.size(); i++) {
88 | if (thingList.get(i).getId().equals(id)) return thingList.get(i);
89 | }
90 | log.error("Add thing id: {} not found", id);
91 | return null;
92 | }
93 |
94 |
95 | private void setAdapterID(String s) {
96 | adapterID = s;
97 | log.info("Set adapterID: {}", adapterID);
98 | }
99 |
100 | public String getAdapterID() {
101 | return adapterID;
102 | }
103 |
104 | private void setTTY(String s) {
105 | tty = s;
106 | log.info("Set tty: {}", tty);
107 | }
108 |
109 | public String getTTY() {
110 | return tty;
111 | }
112 |
113 | private void setTTYType(String s) {
114 | ttyType = s;
115 | log.info("Set ttyType: {}", ttyType);
116 | }
117 |
118 | public String getTTYType() {
119 | return ttyType;
120 | }
121 |
122 | private void setTTYIP (String s) {
123 | ttyIP = s;
124 | log.info("Set ttyIP: {}", ttyIP);
125 | }
126 |
127 | public String getTTYIP() {
128 | return ttyIP;
129 | }
130 |
131 | private void setTTYPort(String s) {
132 | try {
133 | ttyPort = Integer.parseInt(s);
134 | } catch (NumberFormatException e) {
135 | log.error("Wrong Format for Port: {}", s);
136 | }
137 | log.info("Set TTY Port: {}", ttyPort);
138 | }
139 |
140 | public int getTTYPort() {
141 | return ttyPort;
142 | }
143 |
144 | private void setPort(String s) {
145 | try {
146 | port = Integer.parseInt(s);
147 | } catch (NumberFormatException e) {
148 | log.error("Wrong Format for Port: {}", s);
149 | }
150 | log.info("Set Socket Port: {}", port);
151 | }
152 |
153 | public int getPort() {
154 | return port;
155 | }
156 |
157 |
158 | private void setTtyTimeOut(String s) {
159 | try {
160 | ttyTimeOut = Integer.parseInt(s);
161 | } catch (NumberFormatException e) {
162 | log.error("Wrong Format for TTY Timeout: {}", s);
163 | }
164 | log.info("Set TTY Timeout: {} Milliseconds", ttyTimeOut);
165 | }
166 |
167 | public int getTtyTimeOut() {
168 | return ttyTimeOut;
169 | }
170 |
171 |
172 | public String getDeviceType() {
173 | return deviceType;
174 | }
175 |
176 | public String getProtocol() {
177 | return protocol;
178 | }
179 |
180 |
181 | // Handler for reading xml-Tags
182 | public class xHandler implements ContentHandler {
183 |
184 | private Thing thing = null;
185 | private Channel channel = null;
186 | private String path;
187 | private String[] urlPort;
188 | final String IPADDRESS_PATTERN =
189 | "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
190 | "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
191 | "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." +
192 | "([01]?\\d\\d?|2[0-4]\\d|25[0-5]):([0-9]{1,5})$";
193 |
194 | @Override
195 | public void characters(char[] ch, int start, int length)
196 | throws SAXException {
197 | String s = new String(ch, start, length);
198 | switch (path) {
199 | case "root.optolink.tty":
200 | if (s.matches(IPADDRESS_PATTERN)) { // device is at an URL
201 | setTTYType ("URL");
202 | setTTY(s);
203 | urlPort = s.split(":");
204 | setTTYIP (urlPort[0]);
205 | setTTYPort (urlPort[1]);
206 | } else { // device is local
207 | setTTYType ("GPIO");
208 | setTTY(s);
209 | }
210 | break;
211 | case "root.optolink.ttytimeout":
212 | setTtyTimeOut(s);
213 | break;
214 | case "root.optolink.port":
215 | setPort(s);
216 | break;
217 | case "root.optolink.adapterID":
218 | setAdapterID(s);
219 | break;
220 | case "root.optolink.thing.description":
221 | thing.setDescription(s);
222 | break;
223 | case "root.optolink.thing.channel.description":
224 | channel.setDescription(s);
225 | break;
226 | }
227 |
228 | }
229 |
230 | @Override
231 | public void endDocument() throws SAXException {
232 | // TODO Auto-generated method stub
233 |
234 | }
235 |
236 | @Override
237 | public void endElement(String uri, String localName, String pName)
238 | throws SAXException {
239 |
240 | if (localName.equals("thing")) {
241 | addThing(thing);
242 | }
243 | if (localName.equals("channel")) {
244 | thing.addChannel(channel);;
245 | }
246 | path = path.substring(0, path.lastIndexOf('.'));
247 | }
248 |
249 | @Override
250 | public void startDocument() throws SAXException {
251 | path = "root";
252 |
253 | }
254 |
255 | @Override
256 | public void startElement(String uri, String localName, String pName,
257 | Attributes attr) throws SAXException {
258 | path = path + "." + localName;
259 | switch (path) {
260 | case "root.optolink":
261 | deviceType = attr.getValue("device");
262 | protocol = attr.getValue("protocol");
263 | break;
264 | case "root.optolink.thing":
265 | thing = new Thing(attr.getValue("id"), attr.getValue("type"));
266 | break;
267 | case "root.optolink.thing.channel":
268 | channel = new Channel (attr.getValue("id"));
269 | break;
270 | case "root.optolink.thing.channel.telegram":
271 | channel.setTelegram(new Telegram(attr.getValue("address"),
272 | attr.getValue("type"),
273 | attr.getValue("divider")));
274 | break;
275 |
276 | }
277 |
278 | }
279 |
280 | @Override
281 | public void endPrefixMapping(String prefix) throws SAXException {
282 | // Not use Auto-generated method stub
283 |
284 | }
285 |
286 | @Override
287 | public void ignorableWhitespace(char[] ch, int start, int length)
288 | throws SAXException {
289 | // Not use Auto-generated method stub
290 |
291 | }
292 |
293 | @Override
294 | public void processingInstruction(String target, String data)
295 | throws SAXException {
296 | // Not use Auto-generated method stub
297 |
298 | }
299 |
300 | @Override
301 | public void setDocumentLocator(Locator locator) {
302 | // Not use Auto-generated method stub
303 |
304 | }
305 |
306 | @Override
307 | public void skippedEntity(String name) throws SAXException {
308 | // Not use Auto-generated method stub
309 |
310 | }
311 |
312 | @Override
313 | public void startPrefixMapping(String prefix, String uri)
314 | throws SAXException {
315 | // Not use Auto-generated method stub
316 |
317 | }
318 |
319 | } // Handler
320 |
321 | }
322 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Main.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class Main {
20 |
21 | static Logger log = LoggerFactory.getLogger(Main.class);
22 |
23 | // Central Classes, singular only!!
24 | static Config config;
25 | static ViessmannHandler viessmannHandler;
26 | static OptolinkInterface optolinkInterface;
27 |
28 | public static void main(String[] args) {
29 | // TODO Auto-generated method stub
30 |
31 | log.info("Programm gestartet");
32 |
33 | try {
34 |
35 | // config = new Config("src/main/resources/optolink.xml");
36 | config = new Config("conf/optolink.xml");
37 |
38 | // Init TTY Handling for Optolink
39 | optolinkInterface = new OptolinkInterface(config);
40 |
41 | // Init ViessmannHandler
42 | viessmannHandler = new ViessmannHandler(config, optolinkInterface);
43 |
44 | } catch (Exception e) {
45 | log.error("Something is wrong not init", e);
46 | viessmannHandler.close();
47 | optolinkInterface.close();
48 | System.exit(1);
49 | }
50 |
51 | // Install catcher for Kill Signal
52 | Runtime.getRuntime().addShutdownHook(new Thread() {
53 | @Override
54 | public void run() {
55 | viessmannHandler.close();
56 | optolinkInterface.close();
57 | log.info("Programm normal terminated by Signal (Kill)");
58 | }
59 | });
60 |
61 | try {
62 |
63 | // Start SocketHandler
64 | SocketHandler socketHandler = new SocketHandler(config, viessmannHandler);
65 | socketHandler.start();
66 |
67 | } catch (Exception e) {
68 | log.error("Programm abnormal terminated.", e);
69 | }
70 |
71 | }
72 |
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/OptolinkInterface.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import gnu.io.CommPort;
17 | import gnu.io.CommPortIdentifier;
18 | import gnu.io.SerialPort;
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.OutputStream;
22 | import java.net.Socket;
23 | import java.net.SocketTimeoutException;
24 |
25 | import org.slf4j.Logger;
26 | import org.slf4j.LoggerFactory;
27 |
28 | public class OptolinkInterface {
29 |
30 | static Logger log = LoggerFactory.getLogger(OptolinkInterface.class);
31 |
32 | private OutputStream output;
33 | private InputStream input;
34 | private Config config;
35 | private CommPortIdentifier portIdentifier;
36 | private CommPort commPort;
37 | private Socket socket = null;
38 |
39 |
40 | //TODO implement as runnable for URL-based optolinks
41 |
42 | OptolinkInterface(Config config) throws Exception {
43 |
44 | // constructor with implicit open
45 | this.config = config;
46 | if (this.config.getTTYType().matches("URL")) { // device is at an URL
47 | open();
48 | close();
49 | log.debug("TTY type URL is present");
50 | } else { // device is local
51 | log.debug("Open TTY {} ...", this.config.getTTY());
52 | portIdentifier = CommPortIdentifier.getPortIdentifier(this.config.getTTY());
53 |
54 | if (portIdentifier.isCurrentlyOwned()) {
55 | log.error("TTY {} in use.", this.config.getTTY());
56 | throw new IOException();
57 | }
58 | commPort = portIdentifier.open(this.getClass().getName(), this.config.getTtyTimeOut());
59 | if (commPort instanceof SerialPort) {
60 | SerialPort serialPort = (SerialPort) commPort;
61 | serialPort.setSerialPortParams(4800, SerialPort.DATABITS_8,
62 | SerialPort.STOPBITS_2, SerialPort.PARITY_EVEN);
63 |
64 | input = serialPort.getInputStream();
65 | output = serialPort.getOutputStream();
66 | commPort.enableReceiveTimeout(this.config.getTtyTimeOut()); // Reading Time-Out
67 | }
68 | log.debug("TTY {} opened", this.config.getTTY());
69 | }
70 | }
71 |
72 | public synchronized void close() {
73 | if (this.config.getTTYType().matches("URL")) {
74 | log.debug("Close TTY type URL {} ....", this.config.getTTY());
75 | if (socket != null) {
76 | try {
77 | socket.close();
78 | log.debug("TTY type URL {} closed", this.config.getTTY());
79 | } catch (IOException e) {
80 | log.debug("TTY type URL {} can't be closed", this.config.getTTY());
81 | }
82 | }
83 | } else {
84 | log.debug("Close TTY {} ....", this.config.getTTY());
85 | commPort.close();
86 | log.debug("TTY {} closed", this.config.getTTY());
87 | }
88 | }
89 |
90 | public synchronized void open() throws Exception {
91 | if (this.config.getTTYType().matches("URL")) {
92 | log.debug("Open TTY type URL {}", this.config.getTTY());
93 | socket = new Socket (this.config.getTTYIP(), this.config.getTTYPort());
94 | socket.setSoTimeout (this.config.getTtyTimeOut());
95 | input = socket.getInputStream();
96 | output = socket.getOutputStream();
97 | log.debug("TTY type URL is open");
98 | }
99 | }
100 |
101 | public synchronized void flush() {
102 | // Flush input Buffer
103 | if (this.config.getTTYType().matches("URL")) {
104 | // We have to wait a certain time. It seems that input.available always has the count 0
105 | // right after connecting
106 | try {
107 | Thread.sleep(30); // 10 ms is too low. 30 ms chosen for a certain fail safe distance
108 | } catch (InterruptedException e) {
109 | log.debug("Error while sleeping to wait for buffer flush");
110 | }
111 | }
112 | try {
113 | input.skip(input.available());
114 | log.debug("Input Buffer flushed");
115 | } catch (IOException e) {
116 | log.error("Can't flush TTY: {}", this.config.getTTY(), e);
117 | }
118 | }
119 |
120 | public synchronized void write(int data) {
121 | log.trace("TxD: {}", String.format("%02X", (byte) data));
122 | try {
123 | output.write((byte) data);
124 | } catch (IOException e) {
125 | log.error("Can't write Data to TTY {}", this.config.getTTY(), e);
126 | }
127 | }
128 |
129 | public synchronized int read() {
130 | int data = -1;
131 | try {
132 | data = input.read();
133 | log.trace("RxD: {}", String.format("%02X", data));
134 | if (data == -1) log.trace("Timeout from TTY {}", this.config.getTTY());
135 | return data;
136 | } catch (SocketTimeoutException e) {
137 | log.trace("Timeout from TTY {}", this.config.getTTY());
138 | return data;
139 | } catch (Exception e) {
140 | log.error("Can't read Data from TTY {}", this.config.getTTY(), e);
141 | }
142 | return -1; // Ups
143 |
144 | }
145 |
146 | public String getDeviceName() {
147 | return this.config.getDeviceType();
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/SocketHandler.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | /*
17 | * Install a Socked Handler for ip communication
18 | *
19 | * Server can found via Broadcast
20 | * Server API Client can connect via TCP
21 | *
22 | */
23 |
24 | import java.io.BufferedReader;
25 | import java.io.InputStreamReader;
26 | import java.io.PrintStream;
27 | import java.net.ServerSocket;
28 | import java.net.Socket;
29 |
30 | import org.slf4j.Logger;
31 | import org.slf4j.LoggerFactory;
32 |
33 | public class SocketHandler {
34 |
35 | static Logger log = LoggerFactory.getLogger(SocketHandler.class);
36 |
37 | private Config config;
38 | private ServerSocket server;
39 | private ViessmannHandler viessmannHandler;
40 | private PrintStream out;
41 |
42 | SocketHandler(Config config, ViessmannHandler viessmannHandler) throws Exception {
43 |
44 | this.config = config;
45 | this.viessmannHandler = viessmannHandler;
46 |
47 | server = new ServerSocket(config.getPort());
48 | }
49 |
50 | public void start() {
51 |
52 | BroadcastListner broadcastListner = new BroadcastListner(config.getPort(), config.getAdapterID());
53 |
54 | // Put broadcast listner in background
55 |
56 | Thread broadcastListnerThread = new Thread(broadcastListner);
57 | broadcastListnerThread.setName("BcListner");
58 | broadcastListnerThread.start();
59 |
60 | // Wait connection
61 |
62 | while (true) {
63 | try {
64 | log.info("Listen on port {} for connection", config.getPort());
65 | Socket socket = server.accept();
66 | log.info("Connection on port {} accept. Remote host {}", config.getPort(),
67 | socket.getRemoteSocketAddress());
68 | open(socket);
69 | }
70 |
71 | catch (Exception e) {
72 | log.info("Connection on Socket {} rejected or closed by client", config.getPort());
73 | }
74 | }
75 | }
76 |
77 | private void open(Socket socket) throws Exception {
78 |
79 | BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
80 | out = new PrintStream(socket.getOutputStream());
81 |
82 | out.println("");
83 | out.println("");
84 |
85 | String inStr;
86 |
87 | while (true) {
88 | inStr = in.readLine();
89 | if (inStr.toLowerCase().startsWith("exit")) {
90 | break;
91 | }
92 | if (!inStr.equals(null)) {
93 | new Thread(new CommandExec(inStr)).start();
94 | }
95 | }
96 |
97 | out.println("");
98 |
99 | }
100 |
101 | // Start a thread for each call command: No blocking of caller
102 |
103 | public class CommandExec implements Runnable {
104 |
105 | String param;
106 |
107 | CommandExec(String param) {
108 | this.param = param;
109 | }
110 |
111 | @Override
112 | public void run() {
113 | String command;
114 | String param1;
115 | String param2;
116 |
117 | log.debug("Execute Thread for: '{}'", param);
118 | String[] inStr = param.trim().split(" +");
119 | command = inStr[0];
120 | if (inStr.length > 1) {
121 | param1 = inStr[1];
122 | } else {
123 | param1 = "";
124 | }
125 | if (inStr.length > 2) {
126 | param2 = inStr[2];
127 | } else {
128 | param2 = "";
129 | }
130 | exec(command, param1, param2);
131 | log.debug("Thread for: '{}' done", param);
132 | }
133 |
134 | }
135 |
136 | private synchronized void exec(String command, String param1, String param2) {
137 |
138 | if (log.isTraceEnabled()) {
139 | log.trace("Queue Command: |{}|", command);
140 | log.trace(" param1 : |{}|", param1);
141 | log.trace(" param2 : |{}|", param2);
142 | }
143 |
144 | switch (command.toLowerCase()) {
145 |
146 | case "list":
147 | list();
148 | break;
149 | case "get":
150 | if (param2.equals("")) {
151 | getThing(param1);
152 | } else {
153 | getThing(param1, param2);
154 | }
155 | break;
156 | case "set":
157 | set(param1, param2);
158 | break;
159 | default:
160 | log.error("Unknown Client Command:", command);
161 |
162 | log.trace("Queue Command: |{}| done", command);
163 |
164 | }
165 |
166 | }
167 |
168 | private void set(String id, String value) {
169 | // Format id = :
170 |
171 | String[] ids = id.trim().split(":");
172 |
173 | if (ids.length != 2) {
174 | log.error("Wrong format '{}' of id", id);
175 | return;
176 | }
177 | Telegram telegram = config.getThing(ids[0]).getChannel(ids[1]).getTelegram();
178 | if (telegram != null) {
179 | out.println("");
180 | out.println(" ");
181 |
182 | out.println(" ");
184 | out.println(" ");
185 | out.println("");
186 | }
187 |
188 | }
189 |
190 | private void getThing(String id) {
191 | log.debug("Try to get Thing for ID: {}", id);
192 | Thing thing = config.getThing(id);
193 | if (thing != null) {
194 | out.println("");
195 | out.println(" ");
196 | for (Channel channel : thing.getChannelMap()) {
197 | if (!channel.getId().startsWith("*")) {
198 | out.println(" ");
200 | }
201 | }
202 | out.println(" ");
203 | out.println("");
204 | }
205 | }
206 |
207 | private void getThing(String id, String channels) {
208 | Channel channel;
209 | log.debug("Try to get Thing for ID: {} channels: {}", id, channels);
210 | String[] channelList = channels.split(",");
211 | Thing thing = config.getThing(id);
212 | if (thing != null) {
213 | out.println("");
214 | out.println(" ");
215 | for (int i = 0; i < channelList.length; i++) {
216 | channel = thing.getChannel(channelList[i]);
217 | if (channel != null) {
218 | out.println(" ");
220 | } else {
221 | log.error("Channel : {}.{} not define! ", id, channelList[i]);
222 | }
223 | }
224 | out.println(" ");
225 | out.println("");
226 | }
227 | }
228 |
229 | private void list() {
230 | log.debug("List Things for ID");
231 | out.println("");
232 | for (Thing thing : config.getThingList()) {
233 |
234 | if ((thing != null) && !thing.getId().startsWith("*")) {
235 |
236 | out.println(" ");
237 | // out.println(" ");
238 | for (Channel channel : thing.getChannelMap()) {
239 | if (!channel.getId().startsWith("*")) {
240 | out.println(" ");
241 | // out.println(" " + channel.getDescription() + "");
242 | // out.println(" ");
243 | }
244 | }
245 | out.println(" ");
246 |
247 | }
248 | }
249 | out.println("");
250 |
251 | }
252 |
253 | }
254 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Telegram.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class Telegram {
20 |
21 | static Logger log = LoggerFactory.getLogger(Telegram.class);
22 |
23 | // Types of Viessmann
24 | public final static byte BOOLEAN = 1; // 1 Byte -> boolean
25 | public final static byte BYTE = 2; // 1 Byte -> short
26 | public final static byte UBYTE = 3; // 1 Byte -> short
27 | public final static byte SHORT = 4; // 2 Byte -> int
28 | public final static byte USHORT = 5; // 2 Byte -> int
29 | public final static byte INT = 6; // 4 byte -> long
30 | public final static byte UINT = 7; // 4 Byte -> long
31 | public final static byte DATE = 8; // 8 Byte -> date
32 | public final static byte TIMER = 9; // 8 Byte -> timer
33 | public final static byte DUMP = 99; // Dump for unknown Telegram-Type
34 |
35 |
36 | private int address;
37 | private byte type;
38 | private short length;
39 | private short divider;
40 |
41 |
42 | Telegram() {
43 | address = 0;
44 | type = Telegram.DUMP;
45 | length = 0;
46 | divider = 1;
47 | }
48 |
49 | Telegram(String address, String type, String divider) {
50 |
51 | setAddress(address);
52 | setType(type);
53 | setDivider(divider);
54 | }
55 |
56 | Telegram(Telegram telegram) {
57 |
58 | this.address = telegram.address;
59 | this.length = telegram.length;
60 | this.type = telegram.type;
61 | this.divider = telegram.divider;
62 |
63 | }
64 |
65 |
66 | public void setAddress(String address) {
67 | log.trace("----------------------------------------");
68 |
69 | if (address==null) {
70 | log.error("Telegram Address not set") ;
71 | this.address=0;
72 | } else {
73 | try {
74 | this.address = Integer.parseInt(address,16);
75 | } catch (NumberFormatException e) {
76 | log.error("Invalid Address format: {}", address);
77 | this.address=0;
78 | }
79 | }
80 | log.trace("Set Adress to {}({})", address, this.address);
81 | }
82 |
83 |
84 |
85 | public void setType(String type) {
86 | if (type == null)
87 | log.error("Telegram Type not set");
88 | else {
89 | switch (type.toLowerCase()) {
90 | case "boolean":
91 | this.type = Telegram.BOOLEAN;
92 | length=1;
93 | break;
94 | case "byte":
95 | this.type = Telegram.BYTE;
96 | length=1;
97 | break;
98 | case "ubyte":
99 | this.type = Telegram.UBYTE;
100 | length=1;
101 | break;
102 | case "short":
103 | this.type = Telegram.SHORT;
104 | length=2;
105 | break;
106 | case "ushort":
107 | this.type = Telegram.USHORT;
108 | length=2;
109 | break;
110 | case "int":
111 | this.type = Telegram.INT;
112 | length=4;
113 | break;
114 | case "uint":
115 | this.type = Telegram.UINT;
116 | length=4;
117 | break;
118 | case "date":
119 | this.type = Telegram.DATE;
120 | length=8;
121 | break;
122 | case "timer":
123 | this.type = Telegram.TIMER;
124 | length=8;
125 | break;
126 | default: {
127 | log.error("Unknown Type: {}", type);
128 | this.type = Telegram.DUMP;
129 | length=0;
130 |
131 | }
132 | }
133 | }
134 | log.trace("Set Type to {}({}) length={}", type, this.type, length);
135 | }
136 |
137 | public void setDivider(String divider) {
138 | if (divider==null) {
139 | log.debug("divider not set - set to default: 1");
140 | this.divider=1;
141 | } else {
142 | try {
143 | this.divider=Short.parseShort(divider);
144 | }
145 | catch (NumberFormatException e) {
146 | log.error("Invalid divider format: {} - set to default: 1", divider);
147 | this.divider=1;
148 | }
149 | }
150 | log.trace("Set dividerider to {}", this.divider);
151 | }
152 |
153 |
154 | public int getAddress() {
155 | return address;
156 | }
157 |
158 | public String getAddressAsString() {
159 | return String.format("%04X", address);
160 | }
161 |
162 |
163 | public int getLength() {
164 | return length;
165 | }
166 |
167 |
168 | public short getDivider() {
169 | return divider;
170 | }
171 |
172 | public byte getType() {
173 | return type;
174 | }
175 |
176 | }
177 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Thing.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import java.util.List;
17 | import java.util.ArrayList;
18 | import java.util.HashMap;
19 | import java.util.Map;
20 |
21 | import org.slf4j.Logger;
22 | import org.slf4j.LoggerFactory;
23 |
24 | public class Thing {
25 |
26 | static Logger logger = LoggerFactory.getLogger(Thing.class);
27 |
28 | private String type;
29 | private String id;
30 | private String description;
31 | private Map channelMap = new HashMap();
32 |
33 | public List getChannelMap() {
34 | return new ArrayList(channelMap.values());
35 | }
36 |
37 | Thing(String id, String type) {
38 | logger.trace("Init type: '{}' id: '{}'", type, id );
39 | channelMap.clear();
40 | this.type = type;
41 | this.id = id;
42 | this.description = null;;
43 | }
44 |
45 | Thing(Thing thing) {
46 | logger.trace("Init type: '{}' id: '{}'", thing.type, thing.id );
47 | channelMap.clear();
48 | this.channelMap = thing.channelMap;
49 | this.type = thing.type;
50 | this.id = thing.id;
51 | this.description = thing.description;
52 |
53 | }
54 |
55 | public String getType() {
56 | return type;
57 | }
58 |
59 | public void setType(String type) {
60 | this.type = type;
61 | }
62 |
63 | public String getId() {
64 | return id;
65 | }
66 |
67 | public void setId(String id) {
68 | this.id = id;
69 | }
70 |
71 | public String getDescription() {
72 | return description;
73 | }
74 |
75 | public void setDescription(String description) {
76 | this.description = description;
77 | }
78 |
79 | public void addChannel(Channel channel) {
80 | channelMap.put(channel.getId(), new Channel(channel));
81 | }
82 |
83 | public Channel getChannel(String id) {
84 | return channelMap.get(id);
85 | }
86 |
87 |
88 | }
89 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/Viessmann300.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class Viessmann300 implements ViessmannProtocol {
20 |
21 | static Logger log = LoggerFactory.getLogger(Viessmann300.class);
22 |
23 | private OptolinkInterface optolinkInterface;
24 |
25 |
26 | Viessmann300(OptolinkInterface optolinkInterface) {
27 | log.trace("Start Session for Protokoll '300' ....");
28 | this.optolinkInterface = optolinkInterface;
29 | startSession();
30 | log.trace("Start Session for Protokoll '300' started");
31 | }
32 |
33 |
34 | @Override
35 | public synchronized int getData (byte[] buffer, int address, int length) {
36 |
37 | byte[] localBuffer = new byte[16];
38 | int returNumberOfBytes;
39 |
40 | for (int i=0; i<3; i++) {
41 |
42 | log.debug(String.format("Get Data for address %04X .... ", address));
43 |
44 | // construct TxD
45 |
46 | localBuffer[0] = 0x00; // Request
47 | localBuffer[1] = 0x01; // reading Data
48 | localBuffer[2] = (byte)(address >> 8); // upper Byte of address
49 | localBuffer[3] = (byte)(address & 0xff); // lower Byte of address
50 | localBuffer[4] = (byte)length; // number of expected bytes
51 |
52 |
53 | if ( transmit(localBuffer,5)) {; // send Buffer
54 |
55 | // RxD
56 | returNumberOfBytes = receive(localBuffer); // read answer
57 |
58 | if (returNumberOfBytes > 0) {
59 |
60 | // check RxD
61 | int returnAddress;
62 | if (localBuffer[0] == 0x03) log.error("Answer Byte is 0x03: Return Error(Wrong Adress,maybe)");
63 | if (localBuffer[0] != 0x01) log.error("Answer Byte (0x01) expect, but: 0x{} received", String.format("%02X", localBuffer[0]));
64 | if (localBuffer[1] != 0x01) log.error("DataRead Byte (0x01) expect, but: 0x{} received", String.format("%02X",buffer[1]));
65 | returnAddress = ((localBuffer[2] & 0xFF) << 8) + ((int)localBuffer[3] & 0xFF); // Address
66 | if (returnAddress != address) log.error(String.format("Adress (%04X) expect, but: %04X received", address, returnAddress));
67 | for (int j=0;j> 8); // upper Byte of address
95 | localBuffer[3] = (byte)(address & 0xff); // lower Byte of address
96 | localBuffer[4] = (byte)length; // number bytes
97 | switch (length) {
98 | case 1: localBuffer[5] = (byte)(value & 0xff);
99 | break;
100 | case 2: localBuffer[5] = (byte)(value >> 8);
101 | localBuffer[6] = (byte)(value & 0xff);
102 | break;
103 | case 4: localBuffer[5] = (byte)(value >> 24);
104 | localBuffer[6] = (byte)(value >> 16);
105 | localBuffer[7] = (byte)(value >> 8);
106 | localBuffer[8] = (byte)(value & 0xff);
107 | break;
108 | }
109 |
110 | if ( transmit(localBuffer,5+length)) {; // send Buffer
111 |
112 | // RxD
113 | returNumberOfBytes = receive(localBuffer); // read answer
114 |
115 | if (returNumberOfBytes > 0) {
116 |
117 | // check RxD
118 | int returnAddress;
119 | if (localBuffer[0] == 0x03)
120 | log.error("Answer Byte is 0x03: Return Error(Wrong Adress,maybe)");
121 | if (localBuffer[0] != 0x01)
122 | log.error("Answer Byte (0x01) expect, but: 0x{} received",
123 | String.format("%02X", localBuffer[0]));
124 | if (localBuffer[1] != 0x02)
125 | log.error("Data Write Byte (0x02) expect, but: 0x{} received",
126 | String.format("%02X",buffer[1]));
127 | returnAddress = ((localBuffer[2] & 0xFF) << 8) + ((int)localBuffer[3] & 0xFF); // Address
128 | if (returnAddress != address)
129 | log.error(String.format("Adress (%04X) expect, but: %04X received", address, returnAddress));
130 | for (int j=0;j 23 | hr < 0 | min > 59 | min < 0) {
88 | log.error("Invalid time. Hour %d has to between 0 and 23 and Minute %d between 0 and 59", hr,min);
89 | return null;
90 | }
91 | hr = hr << 3;
92 | min = (int) min/10;
93 | buffer[i] = (byte) (hr | min);
94 | }
95 | for (int i = switchTimesLength; i < 8; i++) {
96 | buffer[i] = (byte) 0xff;
97 | }
98 | for (int i = 0; i < 8; i+=2) {
99 | if ((buffer[i] & 0xff) > (buffer[i+1] & 0xff)) {
100 | log.error("Invalid time pair. On time %02x if bigger than Off time %02x", buffer[i],buffer[i+1]);
101 | return null;
102 | }
103 | }
104 | } else {
105 | log.error("Error! SwitchTime has to be in on/off pairs");
106 | return null;
107 | }
108 | locValue = 9;
109 | break;
110 | default : float fl = (new Float(value)) * telegram.getDivider(); // all other writable channels are byte or ubyte
111 | buffer[0] = (byte) fl;
112 | break;
113 | }
114 | if (this.config.getTTYType().matches("URL")) {
115 | try {
116 | optolinkInterface.open();
117 | } catch (Exception e) {
118 | log.error("Opening TTY type URL failed");
119 | optolinkInterface.close();
120 | return null;
121 | }
122 | }
123 | int resultLength = viessmannProtocol.setData(buffer, telegram.getAddress() , telegram.getLength(), locValue);
124 | if (this.config.getTTYType().matches("URL")) {
125 | optolinkInterface.close();
126 | }
127 |
128 | if (resultLength == 0) return null;
129 | else return formatValue(buffer, telegram.getType(), telegram.getDivider());
130 |
131 | }
132 |
133 |
134 |
135 | public synchronized String getValue(Telegram telegram) {
136 | byte [] buffer = new byte[16];
137 |
138 | if (this.config.getTTYType().matches("URL")) {
139 | try {
140 | optolinkInterface.open();
141 | } catch (Exception e) {
142 | log.error("Opening TTY type URL failed");
143 | optolinkInterface.close();
144 | return null;
145 | }
146 | }
147 | int resultLength=viessmannProtocol.getData(buffer,telegram.getAddress(), telegram.getLength());
148 | if (log.isTraceEnabled()) {
149 | log.trace("Number of Bytes: {}", resultLength);
150 | for (int i=0; i>3,(buffer[i] & 7)*10, (buffer[i+1] & 0xF8)>>3,(buffer[i+1] & 7)*10);
175 | }
176 | }
177 | return timer;
178 | case Telegram.DATE:
179 | return String.format("%02x%02x-%02x-%02xT%02x:%02x:%02x",
180 | buffer[0],buffer[1],buffer[2],buffer[3],buffer[5],buffer[6],buffer[7]) ;
181 | case Telegram.BYTE:
182 | result = buffer[0];
183 | break;
184 | case Telegram.UBYTE:
185 | result = 0xFF & buffer[0];
186 | break;
187 | case Telegram.SHORT:
188 | result = ((long)(buffer[1]))*0x100 + (long)(0xFF & buffer[0]);
189 | break;
190 | case Telegram.USHORT:
191 | result = ((long)(0xFF & buffer[1]))*0x100 + (long)(0xFF & buffer[0]);
192 | break;
193 | case Telegram.INT:
194 | result = ((long)(buffer[3]))*0x1000000 + ((long)(0xFF & buffer[2]))*0x10000 + ((long)(0xFF & buffer[1]))*0x100 + (long)(0xFF & buffer[0]);
195 | break;
196 | case Telegram.UINT:
197 | result = ((long)(0xFF & buffer[3]))*0x1000000 + ((long)(0xFF & buffer[2]))*0x10000 + ((long)(0xFF & buffer[1]))*0x100 + (long)(0xFF & buffer[0]);
198 | break;
199 | }
200 | if (divider !=1 )
201 | return String.format(Locale.US,"%.2f", (float)result / divider);
202 | else return String.format("%d", result);
203 |
204 |
205 | }
206 |
207 |
208 | }
209 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/ViessmannKW.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | public class ViessmannKW implements ViessmannProtocol {
20 |
21 |
22 | static Logger log = LoggerFactory.getLogger(ViessmannKW.class);
23 |
24 | private OptolinkInterface optolinkInterface;
25 |
26 |
27 | ViessmannKW(OptolinkInterface optolinkInterface) {
28 | log.trace("Start Session for Protokoll 'KW' ....");
29 | this.optolinkInterface = optolinkInterface;
30 | log.trace("Start Session for Protokoll 'KW' started");
31 | }
32 |
33 |
34 | @Override
35 | public int getData(byte[] buffer, int address, int length) {
36 |
37 | int j=0;
38 | optolinkInterface.flush();
39 | while (optolinkInterface.read() != 0x05 ) { // Wait for 0x05
40 | if (j++ > 10) {
41 | log.error("Can't send Data to OptolinkInterface, missing 0x05");
42 | log.error("!!!!!!!!!!!!!!!! Trouble with communication to OptolinkInterface !!!!!!!!" );
43 | log.error("!!!!!!!!!!!!!!!! Pleace check hardware !!!!!!!!" );
44 | return -1;
45 | }
46 |
47 | }
48 | optolinkInterface.write(0x01); // Answer to 0x05
49 | optolinkInterface.write(0xF7); // Read Data
50 | optolinkInterface.write((byte)(address >> 8)); // upper Byte of address
51 | optolinkInterface.write((byte)(address & 0xff)); // lower Byte of address
52 | optolinkInterface.write((byte)length); // number of expected bytes
53 |
54 | for (int i=0; i 10) {
76 | log.error("Can't send Data to OptolinkInterface, missing 0x05");
77 | log.error("!!!!!!!!!!!!!!!! Trouble with communication to OptolinkInterface !!!!!!!!" );
78 | log.error("!!!!!!!!!!!!!!!! Pleace check hardware !!!!!!!!" );
79 | return -1;
80 | }
81 |
82 | }
83 | optolinkInterface.write(0x01); // Answer to 0x05
84 | optolinkInterface.write(0xF4); // write Data
85 | optolinkInterface.write((byte)(address >> 8)); // upper Byte of address
86 | optolinkInterface.write((byte)(address & 0xff)); // lower Byte of address
87 | optolinkInterface.write((byte)length); // number of expected bytes
88 | switch (length) {
89 | case 1: optolinkInterface.write(buffer[0]); // write lower byte
90 | break;
91 | case 8: optolinkInterface.write(buffer[0]); // Timer data has length 8
92 | optolinkInterface.write(buffer[1]);
93 | optolinkInterface.write(buffer[2]);
94 | optolinkInterface.write(buffer[3]);
95 | optolinkInterface.write(buffer[4]);
96 | optolinkInterface.write(buffer[5]);
97 | optolinkInterface.write(buffer[6]);
98 | optolinkInterface.write(buffer[7]);
99 | break;
100 | }
101 | return length;
102 | }
103 |
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/de/myandres/optolink/ViessmannProtocol.java:
--------------------------------------------------------------------------------
1 | /*******************************************************************************
2 | * Copyright (c) 2015, Stefan Andres. All rights reserved.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the GNU Lesser General Public License
6 | * (LGPL) version 3.0 which accompanies this distribution, and is available at
7 | * http://www.gnu.org/licenses/lgpl-3.0.html
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *******************************************************************************/
14 | package de.myandres.optolink;
15 |
16 | public interface ViessmannProtocol {
17 |
18 | public int getData(byte[] buffer, int address, int length);
19 | void close();
20 | int setData(byte[] buffer, int address, int length, int value);
21 |
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/resources/INSTALL_AUTOSTART.txt:
--------------------------------------------------------------------------------
1 | To start the program at boottime:
2 |
3 | 1.) edit optolink.init.d (USER & HOME)
4 |
5 | 2.) sudo cp optolink.init.d /etc/init.d/optolink
6 |
7 | 3.) sudo 755 /etc/init.d/optolink
8 |
9 | 4.) sudo update-rc-d optolink defaults
10 |
11 |
12 | now optolink adapter going to start at boottime.
13 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | logs/optolink.log
7 |
8 |
9 | logs/optolink-%d{yyyy-ww}.log.zip
10 |
11 | 12
12 |
13 |
14 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M - %msg%n
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/resources/logback_debug.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | logs/optolink_debug.log
7 |
8 |
9 | logs/optolink-%d{yyyy-ww}.log.zip
10 |
11 | 12
12 |
13 |
14 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M - %msg%n
15 |
16 |
17 |
18 |
19 |
20 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/resources/logback_trace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | logs/optolink_trace.log
7 |
8 |
9 | logs/optolink-%d{yyyy-ww}.log.zip
10 |
11 | 12
12 |
13 |
14 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M - %msg%n
15 |
16 |
17 |
18 |
19 |
20 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} %M - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/main/resources/optolink-ob.xml:
--------------------------------------------------------------------------------
1 |
2 |
23 |
24 |
25 |
26 |
27 |
28 | VScotH01
29 | 192.168.178.25:10001
30 | 2000
31 | 31113
32 |
33 |
34 |
35 |
36 | Viessmann Vitodens 300-W
37 |
38 | System ID
39 |
40 |
41 |
42 | System Date and Time
43 |
44 |
45 |
46 | Outside Temperature
47 |
48 |
49 |
50 | General malfunction heating
51 |
52 |
53 |
54 |
55 |
56 | Hot Water Storage Tank an Buffer
57 |
58 | Hot water temperature.
59 |
60 |
61 |
62 | Hot water temperatur target temperature.
63 |
64 |
65 |
66 | Cirulation Pump for Hot Water TODO which pump?
67 |
68 |
69 |
70 |
71 |
72 |
73 | Burner
74 |
75 | The furnace Power in %
76 |
77 |
78 |
79 | Exhaust temperature
80 |
81 |
82 |
83 | Boiler temperature
84 |
85 |
86 |
87 |
88 | State of Burner
89 |
90 |
91 |
92 |
93 |
94 |
95 | Heading Circuit of the first Floor.
96 |
97 | Flow temperature
98 |
99 |
100 |
101 | pump
102 |
103 |
104 |
105 | Operation mode (0,1,2,3,4).
106 |
107 |
108 |
109 | Inside Temperature
110 |
111 |
112 |
113 | Room Set temperature.
114 |
115 |
116 |
117 | Timer Monday
118 |
119 |
120 |
121 | Timer Tuesday
122 |
123 |
124 |
125 | Timer Wednesday
126 |
127 |
128 |
129 | Timer Thursday
130 |
131 |
132 |
133 | Timer Friday
134 |
135 |
136 |
137 | Timer Saturday
138 |
139 |
140 |
141 | Timer Sunday
142 |
143 |
144 |
145 | Timer Monday
146 |
147 |
148 |
149 | Timer Tuesday
150 |
151 |
152 |
153 | Timer Wednesday
154 |
155 |
156 |
157 | Timer Thursday
158 |
159 |
160 |
161 | Timer Friday
162 |
163 |
164 |
165 | Timer Saturday
166 |
167 |
168 |
169 | Timer Sunday
170 |
171 |
172 |
173 |
--------------------------------------------------------------------------------
/src/main/resources/optolink.init.d:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Start/stop the optolink
3 | #
4 | ### BEGIN INIT INFO
5 | # Provides: optolink
6 | # Default-Start: 2 3 4 5
7 | # Default-Stop:
8 | # Short-Description: Regular background program processing Viessmann optolink adapter
9 | ### END INIT INFO
10 |
11 | HOME=/home/pi/optolink
12 | USER=pi
13 |
14 | PATH=/bin:/usr/bin:/sbin:/usr/sbin
15 |
16 | test -f $HOME/start.sh || exit 0
17 |
18 |
19 |
20 | case "$1" in
21 | start) cd $HOME
22 | sudo -u $USER ./start.sh &
23 | ;;
24 | stop) cd $HOME
25 | ./stop.sh
26 | ;;
27 | restart) log_daemon_msg "Restarting periodic command scheduler" "cron"
28 | $0 stop
29 | $0 start
30 | ;;
31 | status)
32 | exit 0
33 | ;;
34 | *) log_action_msg "Usage: /etc/init.d/cron {start|stop|status|restart}"
35 | exit 2
36 | ;;
37 | esac
38 | exit 0
39 |
--------------------------------------------------------------------------------
/src/main/resources/optolink.xml:
--------------------------------------------------------------------------------
1 |
2 |
22 |
23 |
24 |
25 |
26 |
27 | VITOLIGNO
28 | /dev/ttyAMA0
29 | 2000
30 | 31113
31 |
32 |
33 |
34 |
35 | Viessmann Vitoligno 300P
36 |
37 | System ID
38 |
39 |
40 |
41 | System Date and Time
42 |
43 |
44 |
45 | Outsite Temperature
46 |
47 |
48 |
49 | The furnace temperature of the burner boiler
50 |
51 |
52 |
53 |
54 |
55 | Hot Water Storage Tank an Buffer
56 |
57 | Hot water temperatur on top of the buffer.
58 |
59 |
60 |
61 | Temperature in the middle of the buffer
62 |
63 |
64 |
65 | Temperature on the bottom of the buffer
66 |
67 |
68 |
69 | Cirulation Pump for Hot Water
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | Burner/Fireplace
78 |
79 | The furnace Power in %
80 |
81 |
82 |
83 | O2 in %
84 |
85 |
86 |
87 | Primary air shutter %
88 |
89 |
90 |
91 | Secondary air shutter %
92 |
93 |
94 |
95 | actual Fanspeed
96 |
97 |
98 |
99 | target Fanspeed
100 |
101 |
102 |
103 |
104 | The furnace Power in %
105 |
106 |
107 |
108 |
109 | State of Burner
110 |
111 |
112 |
113 | Counts the number of starts sience first start of heating.
114 |
115 |
116 |
117 | On time of the burner sience first start of heating.
118 |
119 |
120 |
121 | Consumed Pellets since start of heating in t.
122 |
123 |
124 |
125 | return flow uprating
126 |
127 |
128 |
129 |
130 |
131 | Heading Circuit of the first Floor.
132 |
133 | Flow temperature
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 | Party temperature.
142 |
143 |
144 |
145 | The savemode.
146 |
147 |
148 |
149 | Partymode.
150 |
151 |
152 |
153 | Party temperature.
154 |
155 |
156 |
157 | Party temperature.
158 |
159 |
160 |
161 | Save temperature.
162 |
163 |
164 |
165 | The gradient relativ to outsite temperature.
166 |
167 |
168 |
169 | The niveau relativ to outsite temperature.
170 |
171 |
172 |
173 |
174 |
175 |
176 | Heading Circuit of the first Floor.
177 |
178 | Flow temperature
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 | Operation mode (0,1,2,3,4).
187 |
188 |
189 |
190 | The savemode.
191 |
192 |
193 |
194 | Partymode.
195 |
196 |
197 |
198 | Party temperature.
199 |
200 |
201 |
202 | Room temperature.
203 |
204 |
205 |
206 | Save temperature.
207 |
208 |
209 |
210 | The gradient relativ to outsite temperature.
211 |
212 |
213 |
214 | The niveau relativ to outsite temperature.
215 |
216 |
217 |
218 |
219 |
220 |
221 | Thermo Solar System.
222 |
223 | Collector temperature.
224 |
225 |
226 |
227 | Temperatur of storage tank (same storage tank bottom)
228 |
229 |
230 |
231 | Pump to load the storage tank from the solar panel.
232 |
233 |
234 |
235 |
236 | Load suppression
237 |
238 |
239 |
240 | On time of the solar pump in hours.
241 |
242 |
243 |
244 | Consumed power from the sun in KW.
245 |
246 |
247 |
248 |
--------------------------------------------------------------------------------
/src/main/resources/start.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PID=./optolink.pid
4 |
5 |
6 | prog_arg="-Dlogback.configurationFile=lib/logback.xml"
7 | prog_arg="${prog_arg} -Djava.library.path=/usr/lib/jni"
8 | prog_arg="${prog_arg} -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0"
9 |
10 |
11 | java $prog_arg -jar lib/optolink-jar-with-dependencies.jar >/dev/null 2>&1 &
12 | echo $! >$PID
13 |
14 | echo "Optolink adapter started"
--------------------------------------------------------------------------------
/src/main/resources/start_debug.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | prog_arg="-Dlogback.configurationFile=conf/logback_debug.xml"
5 | prog_arg="${prog_arg} -Djava.library.path=/usr/lib/jni"
6 | prog_arg="${prog_arg} -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0"
7 |
8 |
9 | java $prog_arg -jar lib/optolink-jar-with-dependencies.jar
--------------------------------------------------------------------------------
/src/main/resources/start_trace.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 |
4 | prog_arg="-Dlogback.configurationFile=conf/logback_trace.xml"
5 | prog_arg="${prog_arg} -Djava.library.path=/usr/lib/jni"
6 | prog_arg="${prog_arg} -Dgnu.io.rxtx.SerialPorts=/dev/ttyAMA0"
7 |
8 |
9 | java $prog_arg -jar lib/optolink-jar-with-dependencies.jar
--------------------------------------------------------------------------------
/src/main/resources/stop.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | PID=./optolink.pid
4 |
5 |
6 | if [ -f $PID ]; then
7 | ps `cat $PID`
8 | if [ $? == 0 ]; then
9 | kill `cat $PID`
10 | echo "Optolink adapter killed"
11 | rm $PID
12 | else
13 | echo "Prozess not found"
14 | exit 1
15 | fi
16 | else
17 | echo "File ${PID} found"
18 | exit 1
19 | fi
20 |
--------------------------------------------------------------------------------