📄 onewireacdriver.java
字号:
package net.sf.dz.device.actuator.impl.onewire;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import java.net.Socket;import java.net.SocketException;import java.util.Iterator;import java.util.NoSuchElementException;import java.util.Set;import java.util.StringTokenizer;import java.util.TreeSet;import javax.net.ssl.SSLException;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.service.ActiveService;import net.sf.dz.device.actuator.ACDriver;import net.sf.dz.util.SSLContextFactory;/** * TCP HVAC driver. * * <p> * * Actually, the class name is a misnomer, I guess, for historical reasons - * before the DZ code was GPL'd, it was monolithic, and it was indeed a * 1-Wire driver. * * <p> * * This class is about to be deprecated and replaced by {@link * net.sf.dz.device.actuator.impl.tcp.PnpACDriver PnpHvacDriver}. * * @author Copyright © <a href="mailto:vt@freehold.crocodile.org"> Vadim Tkachenko</a> 2004 * @version $Id: OneWireACDriver.java,v 1.9 2004/06/28 20:35:48 vtt Exp $ */public class OneWireACDriver extends ActiveService implements ACDriver { public static final LogChannel CH_OWAC = new LogChannel("AC/1-Wire"); public static final long INITIAL_RETRY_TIMEOUT = 1000; public static final long MAX_RETRY_TIMEOUT = INITIAL_RETRY_TIMEOUT * 64; /** * The host to talk to. */ private String remoteHost; /** * The port to talk to. */ private int remotePort; /** * Is connection requested to be secure. */ private boolean secure; /** * Password for the key store. * * VT: Don't tell me it's insecure, just fix the implementation to be * more secure, all right? */ private String password; /** * This switch controls the cool/heat. */ protected String modeSwitchAddress; /** * This switch controls the fan on/off. */ protected String fanSwitchAddress; /** * This switch controls the compressor. */ protected String stageSwitchAddress; /** * Initial retry timeout. * * Configurable, defaults to {@link #INITIAL_RETRY_TIMEOUT INITIAL_RETRY_TIMEOUT}. */ protected long initialRetryTimeout = INITIAL_RETRY_TIMEOUT; /** * Maximum retry timeout. * * Configurable, defaults to {@link #MAX_RETRY_TIMEOUT MAX_RETRY_TIMEOUT}. */ protected long maxRetryTimeout = MAX_RETRY_TIMEOUT; /** * Communication channel. */ private Socket socket; /** * Socket reader. */ private BufferedReader in; /** * Socket writer. */ private PrintWriter out; private Integer mode = null; private Integer stage = null; private Double speed = null; protected void configure() throws Throwable { Configuration conf = getConfiguration(); String cfroot = getConfigurationRoot(); // Let's make it clear where we configure from so it will be easier // to change the configuration to non-default complain(LOG_INFO, CH_OWAC, "Configuration root: " + cfroot); modeSwitchAddress = conf.getString(cfroot + ".switch.mode.address"); fanSwitchAddress = conf.getString(cfroot + ".switch.fan.address"); stageSwitchAddress = conf.getString(cfroot + ".switch.stage.address"); remoteHost = conf.getString(cfroot + ".tcp.host", "localhost"); remotePort = conf.getInteger(cfroot + ".tcp.port", 5002); secure = conf.getBoolean(cfroot + ".tcp.secure"); if ( secure ) { password = conf.getString(cfroot + ".tcp.password"); } initialRetryTimeout = conf.getInteger(cfroot + ".retry.timeout.initial", 1000); maxRetryTimeout = conf.getInteger(cfroot + ".retry.timeout.max", 1000*64); } protected void startup() throws Throwable { connect(); } private synchronized void connect() throws Throwable { try { complain(LOG_INFO, CH_OWAC, "Connecting to " + remoteHost + ":" + remotePort); // For the sake of proper initialization sequence and // eliminating the trouble of watching the logs, we'll have to // establish the socket connection now. if ( secure ) { complain(LOG_NOTICE, CH_OWAC, "Secure connection requested"); try { socket = SSLContextFactory.createContext(password).getSocketFactory().createSocket(remoteHost, remotePort); } catch ( SSLException sslex ) { complain(LOG_WARNING, CH_OWAC, "Can't establish a secure connection to " + remoteHost + ":" + remotePort, sslex); complain(LOG_WARNING, CH_OWAC, "Reverting to insecure connection"); } } if ( socket == null ) { socket = new Socket(remoteHost, remotePort); } in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out = new PrintWriter(socket.getOutputStream(), true); if ( !secure ) { // In case we're talking to a secure socket implementation, // we'll get stuck reading the input stream - they won't // tell us anything, nor would they break away (well, maybe // after a really long timeout). Therefore, we'll have to // give them a kick so they kick us out and we'll get a // visible indication of a failure. out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.flush(); // If they're secure, and we're not, we'll get kicked out // right here... } // Also, we have to make sure that all the addresses configured // are present at the remote end String header = null; try { header = in.readLine(); } catch ( SSLException sslex ) { // Oops... The only cause I know of at this time is that we // were able to connect "as secure", but the other end is // not secure. if ( sslex.getMessage() != null ) { if ( sslex.getMessage().equals("Unrecognized SSL message, plaintext connection?") ) { // Let's retry as insecure complain(LOG_WARNING, CH_OWAC, "Can't establish secure connection to " + remoteHost + ":" + remotePort + ", other end seems to be plaintext"); complain(LOG_WARNING, CH_OWAC, "Reverting to insecure connection"); socket = null; in = null; out = null; secure = false; connect(); return; } } else { // I don't know what it is throw sslex; } } complain(LOG_WARNING, CH_OWAC, "Header: " + header); // The format is: // // N: A B ... Z // // Where N is the number of chips detected, and A, B, ... Z are // the chip addresses. Set switchSet = new TreeSet(); Set addressSet = new TreeSet(); // btw, let's check the config as well switchSet.add(modeSwitchAddress); switchSet.add(stageSwitchAddress); switchSet.add(fanSwitchAddress); for ( Iterator i = switchSet.iterator(); i.hasNext(); ) { StringTokenizer st = new StringTokenizer(i.next().toString(), ":"); addressSet.add(st.nextToken()); } try { StringTokenizer stn = new StringTokenizer(header, ":"); // Read the number and ignore it stn.nextToken(); String list = stn.nextToken(); for ( StringTokenizer stl = new StringTokenizer(list, " "); stl.hasMoreTokens(); ) { addressSet.remove(stl.nextToken()); } // Check if the required devices are present if ( !addressSet.isEmpty() ) { list = ""; for ( Iterator i = addressSet.iterator(); i.hasNext(); ) { list += " " + i.next(); } // VT: NOTE: Sometimes it is too harsh to deny the // startup, in particular, when the system is not // complete and/or being debugged. Let's relax the // requirement to have the devices available at the // startup. We'll be having warnings or errors every // time there's an access attempt, so it will be obvious // anyway.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -