⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 controller.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
字号:
package net.sf.dz.daemon.tcp;import java.io.BufferedReader;import java.io.PrintWriter;import java.net.Socket;import java.util.Iterator;import java.util.Map;import java.util.Set;import java.util.StringTokenizer;import java.util.TreeMap;import java.util.TreeSet;import net.sf.dz.daemon.onewire.OneWireServer;import net.sf.dz.daemon.onewire.DeviceContainer;import net.sf.dz.daemon.onewire.SwitchContainer;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.sem.RWLock;/** * The TCP controller. * * Accepts the control messages, interprets and tries to execute. * * @author Copyright &copy; <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2002 * @version $Id: Controller.java,v 1.16 2004/06/28 20:35:47 vtt Exp $ */public class Controller extends Connector {    public static final LogChannel CH_CTL = new LogChannel("TCP/Controller");    public static final LogChannel CH_LOCK = new LogChannel(CH_CTL, "lock");        /**     * Set of known switch addresses.     */     private Set deviceSet = new TreeSet();          /**      * Map of known device channel numbers by address.      *      * It is assumed that the device with the same 1-Wire address will      * never change its channel count, therefore, the probe for channel      * count will be attempted only once.      */    private Map channelMap = new TreeMap();    /**     * Device map.     *     * The key is the device address, the value is the device container.     */    private Map switchMap = new TreeMap();        /**     * Server map.     *     * The key is the device address, the value is the server the device is     * controlled by. This is necessary to obtain a write lock from the server.     */    private Map serverMap = new TreeMap();        /**     * Clean flag.     */    private boolean clean = true;        protected LogChannel getLogChannel() {            return CH_CTL;    }    protected String getAnnounce() {            StringBuffer sb = new StringBuffer();                sb.append("DZ DAC Switches").append(super.getAnnounce()).append("/");;                // Need to get the data from the switch map, because otherwise we're        // likely to get devices other than switches                synchronized ( deviceSet ) {                    for ( Iterator i = deviceSet.iterator(); i.hasNext(); ) {                            sb.append(" ").append(getDeviceSignature(i.next().toString()));            }        }            return sb.toString();    }        protected String getDeviceSignature(String address) {            String signature = "";                Integer iCount = (Integer)channelMap.get(address);                if ( iCount == null ) {                    complain(LOG_WARNING, CH_CTL, address + ": how come we don't have a channel map for it? Assuming 2 until able to resolve");            iCount = new Integer(2);        }                int channelCount = iCount.intValue();                for ( int idx = 0; idx < channelCount; idx++ ) {                    signature += address + ":" + idx;                        if ( idx < (channelCount - 1) ) {                                signature += " ";            }        }                return signature;    }    protected int getChannelCount(String address) {            String signature = "";                Integer iCount = (Integer)channelMap.get(address);                if ( iCount == null ) {                    complain(LOG_WARNING, CH_CTL, address + ": how come we don't have a channel map for it? Assuming 2 until able to resolve");            iCount = new Integer(2);        }                return iCount.intValue();    }        protected String getServiceSignature() {            return "DZ DAC Switches";    }    protected int getDefaultListenPort() {            return 5002;    }        protected int getDefaultBroadcastPort() {            return 5003;    }        protected ConnectionHandler createHandler(Socket socket, BufferedReader br, PrintWriter pw) {            clean = false;            return new ControlHandler(socket, br, pw);    }        protected synchronized void cleanup() throws Throwable {            if ( clean || switchMap.isEmpty() ) {                    complain(LOG_DEBUG, CH_CTL, "Already clean");            return;        }                for ( Iterator i = switchMap.values().iterator(); i.hasNext(); ) {                    SwitchContainer sc = (SwitchContainer)i.next();                        complain(LOG_INFO, CH_CTL, "Cleanup: shutting down " + sc);                        sc.reset();        }                complain(LOG_INFO, CH_CTL, "Cleaned up");            clean = true;    }        protected void shutdown2(Throwable cause) throws Throwable {    }    protected boolean isUnique() {            return true;    }        protected synchronized void broadcastArrival(String address, String type) {            for ( Iterator si = serverSet.iterator(); si.hasNext(); ) {                    OneWireServer s = (OneWireServer)si.next();            DeviceContainer dc = s.getDeviceContainer(address);                        // The only containers we care about are DS2406 and DS2408.                        // VT: NOTE: This may change in the future. But at this point            // adding DS2409 to the switch map messes things up because the            // controller will try to shut them off on shutdown - this            // doesn't really make any sense because they're supposed to be            // controlled by lower level logic anyway.                        // VT: NOTE: Actually, now DS2409 is cut off a level above this            // call - in OneWireServer.                        if ( (dc != null) && (dc instanceof SwitchContainer) ) {                            deviceSet.add(address);                switchMap.put(address, dc);                serverMap.put(address, s);                                updateChannelMap(address, (SwitchContainer)dc);                            announce(getAnnounce());                                for ( Iterator i = iterator(); i.hasNext(); ) {                                    ConnectionHandler ch = (ConnectionHandler)i.next();                                        ch.iHave();                    ch.send("+ " + address);                }                                return;            }        }    }        private synchronized void updateChannelMap(String address, SwitchContainer sc) {            if ( channelMap.get(address) != null ) {                    // The number of channels for a given 1-Wire address will never            // change, they're burned into the hardware                        return;        }                channelMap.put(address, new Integer(sc.getChannelCount()));    }        protected synchronized void broadcastDeparture(String address) {            if ( !deviceSet.contains(address) ) {                    // This is not ours            return;        }            deviceSet.remove(address);        switchMap.remove(address);        serverMap.remove(address);                announce(getAnnounce());        for ( Iterator i = iterator(); i.hasNext(); ) {                    ConnectionHandler ch = (ConnectionHandler)i.next();                        ch.iHave();                        for ( StringTokenizer st = new StringTokenizer(getDeviceSignature(address), " ");                  st.hasMoreTokens(); ) {                                  ch.send("- " + st.nextToken());            }        }            }        protected class ControlHandler extends ConnectionHandler {            public ControlHandler(Socket socket, BufferedReader br, PrintWriter pw) {                    super(socket, br, pw);        }                protected void sayHello() {                    // VT: FIXME: Isn't this a duplication of the arrival/departure            // notification handler?                    Set switchSet = new TreeSet();                        for ( Iterator si = serverSet.iterator(); si.hasNext(); ) {                            OneWireServer s = (OneWireServer)si.next();                                for ( Iterator ai = s.iterator(); ai.hasNext(); ) {                                    String address = ai.next().toString();                    DeviceContainer dc = s.getDeviceContainer(address);                                        if ( dc instanceof SwitchContainer ) {                                            switchSet.add(address);                        switchMap.put(address, dc);                        serverMap.put(address, s);                    }                }            }                        iHave();        }                public synchronized void iHave() {                    String message = "";            int deviceCount = 0;                        for ( Iterator i = deviceSet.iterator(); i.hasNext(); ) {                            String address = i.next().toString();                                message += getDeviceSignature(address);                deviceCount += getChannelCount(address);                                if ( i.hasNext() ) {                                    message += " ";                }            }                        send("IHAVE " + deviceCount + ": " + message);        }            protected CommandParser createParser() {                    return new ControlParser();        }                protected class ControlParser extends CommandParser {                    protected void parse2(String command) throws Throwable {                            complain(LOG_INFO, CH_CTL, "Command received: '" + command + "'");                                StringTokenizer st = new StringTokenizer(command, " ");                                // Have a problem here. Old format is:                //                //    <addr> read <channel>                //    <addr> write <channel> value                //                // New format is:                //                //    <addrc> read                //    <addrc> write value                //                // where <addrc> is <addr>:<channel>.                //                // At this point, old style direct TCP connector uses                // old format, PnP aware code uses new format (which is                // better because it treats a channel as an atomic                // entity), so will have to parse both. An indication of                // a new format is a colon in the first word.                String address = st.nextToken();                                if ( address.indexOf(":") != -1 ) {                                    parseNew(address, st);                                } else {                                    parseOld(address, st);                }            }                        private void parseOld(String address, StringTokenizer st) throws Throwable {                            String verb = st.nextToken();                String channel = st.nextToken();                boolean value = false;                                if ( "write".equalsIgnoreCase(verb) ) {                                    String sValue = st.nextToken();                                        if ( "1".equals(sValue) ) {                                            value = true;                    } else if ( "0".equals(sValue) ) {                                            value = false;                    } else {                                            throw new IllegalArgumentException("Illegal value: '" + sValue + "'");                    }                }                                execute(address, Integer.parseInt(channel), verb, value);            }                        private void parseNew(String extendedAddress, StringTokenizer st) throws Throwable {                            int offset = extendedAddress.indexOf(":");                                String address = extendedAddress.substring(0, offset);                String channel = extendedAddress.substring(offset + 1);                String verb = st.nextToken();                boolean value = false;                                complain(LOG_DEBUG, CH_CTL, "Extended: " + extendedAddress);                complain(LOG_DEBUG, CH_CTL, "Address:  " + address);                complain(LOG_DEBUG, CH_CTL, "Channel:  " + channel);                complain(LOG_DEBUG, CH_CTL, "Verb:     " + verb);                                if ( "write".equalsIgnoreCase(verb) ) {                                    String sValue = st.nextToken();                                        if ( "1".equals(sValue) ) {                                            value = true;                    } else if ( "0".equals(sValue) ) {                                            value = false;                    } else {                                            throw new IllegalArgumentException("Illegal value: '" + sValue + "'");                    }                    complain(LOG_DEBUG, CH_CTL, "Value:   " + value);                }                                execute(address, Integer.parseInt(channel), verb, value);            }                        private void execute(String address, int channel, String verb, boolean value) throws Throwable {                            SwitchContainer sc = (SwitchContainer)switchMap.get(address);                                if ( sc == null ) {                                    send("E " + address + ":" + channel + " Device Not Present");                    return;                }                                if ( "read".equalsIgnoreCase(verb) ) {                                    send(sc.read(channel) ? "1" : "0");                } else if ( "write".equalsIgnoreCase(verb) ) {                                    // VT: FIXME: Watch for exceptions                                        sc.write(channel, value);                    send("OK");                }            }        }    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -