📄 dtrboilerdriver.java
字号:
package net.sf.dz.device.actuator.impl.serial;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 org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.service.PassiveService;import net.sf.dz.device.actuator.ACDriver;/** * Boiler driver using DTR line of a serial port to control the boiler. * * <p> * * In a current implementation, will work only on Unices. Replacing a system * call with direct serial port access will allow it to work on any * platform. * * @author <a href="mailto:tim at buttersideup dot company">Tim Small</a> * @version $Id: DTRBoilerDriver.java,v 1.2 2004/07/21 07:38:29 vtt Exp $ */public class DTRBoilerDriver extends PassiveService implements ACDriver { public static final LogChannel CH_DTR = new LogChannel("AC/DTRBoiler"); /** * The serial port to talk to. */ protected String port; private Integer mode = null; private Integer stage = null; private Double speed = null; protected void configure() throws Throwable { Configuration conf = getConfiguration(); String cfroot = getConfigurationRoot(); // TS: 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_DTR, "Configuration root: " + cfroot); port = conf.getString(cfroot + ".port"); } protected void startup() throws Throwable { // TS: I suppose we should check that the serial port is openable // here, but as soon as I have the boiler under 1wire control, this // class will be redundant.. } private synchronized void connect() throws IOException { // Restore the hardware state if it is available if ( mode != null ) { complain(LOG_NOTICE, CH_DTR, "Restoring mode: " + mode); setMode(mode.intValue()); } if ( speed != null ) { complain(LOG_NOTICE, CH_DTR, "Restoring fan speed: " + speed); setFanSpeed(speed.doubleValue()); } if ( stage != null ) { complain(LOG_NOTICE, CH_DTR, "Restoring stage: " + stage); setStage(stage.intValue()); } notifyAll(); } protected synchronized void shutdown(Throwable cause) throws Throwable { complain(LOG_INFO, CH_DTR, "Shutting down the Boiler...", new Exception("Call stack trace")); // Shut down the Boiler setStage(0); complain(LOG_INFO, CH_DTR, "Boiler turned off"); } /** * Set the unit mode. * * @param mode Operating mode. -1 is cooling, 0 is off, 1 is heating. * Actually, the switch is only between cooling and heating, but * different units may have different rules (the contact is energized * only for cooling, or only for heating). * * @exception IOException if there was a problem talking to the hardware. * * @exception IllegalArgumentException if the stage is neither -1, 0 nor * 1. */ public void setMode(int mode) throws IOException { // This is required for translation complain(LOG_INFO, CH_DTR, "setMode, called, mode " + mode); int value = 0; switch ( mode ) { case -1: case 0: // We only have two modes - heating, and off value = 0; break; case 1: // Need to energize for heating value = 1; break; default: throw new IllegalArgumentException("Invalid mode: " + mode); } this.mode = new Integer(mode); checkStateChange(); } /** * Set the unit stage. * * This method will work with single stage unit only. * * <p> * * @param stage A/C stage. For single stage units, 0 is off, 1 is on. * For multistage units, it is 0, 1, 2 and so on. * * @exception IOException if there was a problem talking to the hardware. * * @exception IllegalArgumentException if the stage is neither 0 nor 1. */ public void setStage(int stage) throws IOException { switch ( stage ) { case 0: case 1: break; default: throw new IllegalArgumentException("Invalid stage: " + stage); } this.stage = new Integer(stage); complain(LOG_INFO, CH_DTR, "State change request - new stage: " + stage); checkStateChange(); } private void checkStateChange() throws IOException { // TS: Water central heating boilers don't have a circulation fan - // they all have a pump, which achieves a similar effect, but the // pump on this boiler is not controllable separately. If the // boiler is on, then the pump is on. if ((this.speed == null) || this.stage == null || this.mode == null) { complain(LOG_INFO, CH_DTR, "either speed, or stage, or mode is null, not thinking about whether to turn on, or off. Speed = " + this.speed + " stage = " + this.stage + " mode = " + this.mode); } else if ( (this.speed.floatValue() > 0.0) && (this.stage.intValue() >0) && (this.mode.intValue() > 0)) { boilerOn(); } else { complain(LOG_INFO, CH_DTR, "Call to pump, but disregarding - speed = " + this.speed + " stage = " + this.stage + " mode = " + this.mode); boilerOff(); } } public void setFanSpeed(double speed) throws IOException { if ( speed != 0 && speed != 1 ) { throw new IllegalArgumentException("Unsupported speed: " + speed + " (only 0 and 1 are valid)"); } this.speed = new Double(speed); checkStateChange(); } private void boilerOff() throws IOException { complain(LOG_INFO, CH_DTR, "Turning *OFF* the boiler"); String cmd = "/bin/stty hupcl <" + port; docmd(cmd); } private void boilerOn() throws IOException { complain(LOG_INFO, CH_DTR, "Turning *ON* the boiler"); String cmd = "/bin/stty -hupcl <" + port; docmd(cmd); } private void docmd(String args) throws IOException { String[] allargs = {"/bin/sh", "-c", args}; Process p = Runtime.getRuntime().exec(allargs); try { p.waitFor(); } catch( InterruptedException ie ) { complain(LOG_WARNING, CH_DTR, "Failed to complete system call:", ie); } BufferedReader in = new BufferedReader( new InputStreamReader(p.getInputStream())); String line=null; while((line=in.readLine() )!=null) { complain(LOG_NOTICE, CH_DTR, "Process output: " + line); } if (p.exitValue() != 0) { complain(LOG_WARNING, CH_DTR, "Non-zero exit status : " + p.exitValue() + " from command '" + allargs + "'"); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -