ac_controller.java

来自「这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统」· Java 代码 · 共 793 行 · 第 1/2 页

JAVA
793
字号
        }    }        /**     * Broadcast the notification about the change in the running mode.     *     * @param stage New running mode.     */    private final void modeChanged(int mode) {            for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ACListener)i.next()).modeChanged(this, mode);        }    }        /**     * Broadcast the notification about the change in the running stage.     *     * @param stage New running stage.     */    private final void stageChanged(int stage) {            for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ACListener)i.next()).stageChanged(this, stage);        }    }        private final void fanSpeedChanged(double value) {            for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ACListener)i.next()).fanSpeedChanged(this, value);        }    }    protected void startup() throws Throwable {            if ( driver instanceof PassiveService ) {                    PassiveService ps = (PassiveService)driver;                    if ( false )            if ( !ps.start().waitFor() ) {                            throw new IllegalStateException("Could not start the AC driver, check the logs");            }                        // VT: FIXME: Check if it works as a dependant later            // addDependant(ps);        }            // Now we can set the mode                int mode = abstraction.mode;                // Skew the mode so setMode() will work properly                abstraction.mode = 2;                setMode(mode);                // Let's be nice and tell the possible listeners about our stage and        // speed, 'cause otherwise they won't know...                stageChanged(hardware.stage);        fanSpeedChanged(hardware.speed);    }    protected void execute() throws Throwable {            while ( isEnabled() ) {                    try {                        Command c = (Command)theQueue.waitObject(10000);                                complain(LOG_NOTICE, CH_AC, "Executing: " + c);                                boolean ok = false;                                while ( !ok ) {                                    try {                                            c.run();                        ok = true;                                            } catch ( Throwable t ) {                                            complain(LOG_ERR, CH_AC, "Failed to execute " + c + ", cause:", t);                    }                                        if ( !ok ) {                                            // Let's give them some time to come around                                                // VT: FIXME: Rerty count shouldn't be exceeded,                        // otherwise we'll just be stuck here forever                                                Thread.sleep(1000);                    }                }                                complain(LOG_INFO, CH_AC, "Completed: " + c);                        } catch ( InterruptedException iex ) {                            if ( "heartbeat".equals(iex.getMessage()) ) {                            // Send the current status to the listeners so they don't                // become frustrated                                modeChanged(hardware.mode);                stageChanged(hardware.stage);                fanSpeedChanged(hardware.speed);                                } else {                                    throw iex;                }            }        }    }    protected void shutdown(Throwable cause) throws Throwable {            if ( driver instanceof PassiveService ) {                    ((PassiveService)driver).stop().waitFor();        }            complain(LOG_ERR, CH_AC, "IMPLEMENT THE SHUTDOWN: SWITCH OFF EVERYTHING");    }        protected abstract class Command {            abstract void run() throws Throwable;    }        protected class ChangeMode extends Command {            int mode;                ChangeMode(int mode) {                    if ( mode < -1 || mode > 1 ) {                            throw new IllegalArgumentException("Invalid mode: " + mode);            }                        this.mode = mode;        }                void run() throws Throwable {                    // Set stage to 0            // Switch off the fan            // Wait            // Change the mode            // Update timestamp                        // Set stage to 0                        complain(LOG_INFO, CH_AC, "Stopping the compressor...");            new ChangeStage(0).run();                        complain(LOG_INFO, CH_AC, "Stopping the fan...");            new ChangeFanSpeed(0).run();                        // Figure out how long we have to wait                        long lastOp = System.currentTimeMillis() - timestamp.mode;            long wait = (lastOp > delay.mode) ? 0 : (delay.mode - lastOp);                        complain(LOG_INFO, CH_AC, "wait: " + wait);                        if ( wait > 0 ) {                            Thread.sleep(wait);            }                        driver.setMode(mode);            hardware.mode = mode;                        timestamp.mode = System.currentTimeMillis();                        // VT: NOTE: We're not setting the stage back if the unit was            // working. If so, there will be subsequent commands that will            // take care of this, because mode change definitely means stage            // change.        }                public String toString() {                    return "Mode change to " + mode;        }    }    protected class ChangeStage extends Command {            int stage;                ChangeStage(int stage) {                    if ( stage < 0 ) {                            throw new IllegalArgumentException("Invalid stage: " + stage);            }                        this.stage = stage;        }                void run() throws Throwable {                    // Wait            // Change the stage            // Update timestamp                        // Figure out how long we have to wait                        long lastOp = System.currentTimeMillis() - timestamp.stage;            long wait = (lastOp > delay.stage) ? 0 : (delay.stage - lastOp);                        complain(LOG_INFO, CH_AC, "wait: " + wait);                        if ( wait > 0 ) {                            Thread.sleep(wait);            }                        // FIXME: If the stage is not 0 and the fan speed is 0, refuse            // and complain                        driver.setStage(stage);            hardware.stage = stage;                        timestamp.stage = System.currentTimeMillis();        }                public String toString() {                    return "Stage change to " + stage;        }    }    protected class ChangeFanSpeed extends Command {            double speed;                ChangeFanSpeed(double speed) {                    if ( speed < 0 || speed > 1 ) {                            throw new IllegalArgumentException("Invalid fan speed: " + speed);            }                        this.speed = speed;        }                void run() throws Throwable {                    // Wait            // Change the fan speed            // Update timestamp                        // Figure out how long we have to wait                        long lastOp = System.currentTimeMillis() - timestamp.fan;            long wait = (lastOp > delay.fan) ? 0 : (delay.fan - lastOp);                        complain(LOG_INFO, CH_AC, "wait: " + wait);                        if ( wait > 0 ) {                            Thread.sleep(wait);            }                        driver.setFanSpeed(speed);            hardware.speed = speed;                        timestamp.fan = System.currentTimeMillis();        }                public String toString() {                    return "Fan speed change to " + speed;        }    }        protected class ACState {            /**         * Defines whether we are in a heating or cooling mode.         *         * <code>1</code> means heating, <code>-1</code> means cooling,         * <code>0</code> means off.         *         * The default value is <code>0</code>, however, it may be overridden         * by the configuration (and for Arizona, it better be cooling;).         */        int mode;                /**         * The current compressor stage.         *         * This has the same value for heating and cooling, however, the         * interpretation will be different.         *         * <p>         *         * Value of 0 means that the unit is off, value of 1 means first         * stage, value of 2 means second stage, and so on. The stage value         * is always non-negative.         */        int stage;                /**         * Fan speed.         *         * <p>         *         * 0 is off, 1 is full, anything in between should be configured (VT:         * FIXME: this is not done yet) according to the real hardware         * configuration.         */        double speed;    }        /**     * Time constants related to mode, stage and fan speed change.     */    private class Time {            long mode;        long stage;        long fan;    }        /**     * A queue that allows inspecting and removing the queue elements out of     * order, as well as timed wait.     */    protected class TransparentQueue extends SimpleQueue {            public Iterator iterator() {                    return theQueue.iterator();        }        /**         * Wait for the object from the queue, then remove and return it.         *         * This method blocks until the object is available, or timeout         * expires.         *         * @return The first object from the queue.         *         * @exception InterruptedException if the wait was interrupted.         * Also, if the timeout expires, the same exception will be thrown,         * with the message being a literal string "heartbeat".         */        public synchronized Object waitObject(long timeout) throws InterruptedException {                    if ( timeout <= 0 ) {                            throw new IllegalArgumentException("Timeout must be positive, value given was " + timeout);            }                        long deadline = System.currentTimeMillis() + timeout;                    while ( theQueue.isEmpty() ) {                            wait(timeout);                                long now = System.currentTimeMillis();                                if ( now >= deadline ) {                                    // No need to be specific about what exactly did we miss                    // and by how much                                        throw new InterruptedException("heartbeat");                }                                timeout = deadline - now;            }                        return theQueue.removeFirst();        }            }}

⌨️ 快捷键说明

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