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

📄 thermostatmodel.java

📁 这是一个以JAVA编写的程序,本人还没有试过,是一个简单的温度控制系统
💻 JAVA
字号:
package net.sf.dz.device.model.impl;import java.util.Iterator;import java.util.HashSet;import java.util.Set;import java.util.StringTokenizer;import org.freehold.jukebox.conf.Configurable;import org.freehold.jukebox.conf.Configuration;import org.freehold.jukebox.logger.LogAware;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.logger.Logger;import org.freehold.jukebox.service.PassiveService;import net.sf.dz.device.model.Thermostat;import net.sf.dz.device.model.ThermostatController;import net.sf.dz.device.model.Unit;import net.sf.dz.event.TemperatureSensorListener;import net.sf.dz.event.ThermostatListener;import net.sf.dz.device.sensor.TemperatureSensor;import net.sf.dz.controller.ProcessController;import net.sf.dz.util.ObjectFactory;/** * The virtual thermostat implementation. * * @author Copyright &copy; <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2002 * @version $Id: ThermostatModel.java,v 1.10 2004/01/20 02:40:34 vtt Exp $ */public final class ThermostatModel extends PassiveService implements TemperatureSensorListener, Thermostat, ThermostatController {    /**     * Log channel to use.     */    protected LogChannel CH_TSTAT;        /**     * Thermostat name.     */    private String name;        /**     * Is this zone allowed to initiate the A/C start.     *     * Default is true.     *     * @see #isVoting     */    private boolean voting = true;        /**     * The current temperature.     *     * @see #currentTemperatureChanged     */    private double currentTemperature;        /**     * Current control signal.     */    private double controlSignal = 0;        /**     * The sensor.     *     * Never queried directly. This object is added to the sensor as a     * listener, and the notifications are {@link #currentTemperatureChanged     * processed} asynchronously.     */    private TemperatureSensor sensor;        /**     * The controller defining this thermostat's behavior.     */    private ProcessController controller;    /**     * Set of listeners.     */    private Set listenerSet = new HashSet();        /**     * Is this thermostat enabled.     *     * If the zone is set to "OFF", the thermostat will still accept the     * notifications, but will not relay the signal to the controller.     */    private boolean enabled = true;        /**     * Is this thermostat on hold.     *     * If it is set to "hold", the {@link #schedule scheduler} will not     * change the settings when the period changes.     */    private boolean hold = false;        /**     * Is it possible to use the zone controlled by this thermostat as a     * dump zone when heating.     *     * <p>     *     * 0 (default) means that this zone shouldn't be used as a dump zone,     * values greater than 0 mean priority, 1 being the highest. The higher     * the priority, the sooner the zone will be used as a dump zone when     * heating.     */    private int dumpHeating = 0;    /**     * Is it possible to use the zone controlled by this thermostat as a     * dump zone when cooling.     *     * <p>     *     * 0 (default) means that this zone shouldn't be used as a dump zone,     * values greater than 0 mean priority, 1 being the highest. The higher     * the priority, the sooner the zone will be used as a dump zone when     * cooling.     */    private int dumpCooling = 0;        /**     * This thermostat's unit.     *     * The reference is required so the schedule event gets a hold of the     * current A/C mode through {@link     * net.sf.dz.device.model.Unit#getAC() unit.getAC()}.     */    private Unit unit;        /**     * Attach to the A/C unit.     *     * @param unit A/C unit to attach to. Can't be <code>null</code>.     */    public void attach(Unit unit) {            this.unit = unit;    }        public Unit getUnit() {            if ( unit == null ) {                    throw new IllegalStateException("Unit must be attached first");        }            return unit;    }        public void configure() throws Throwable {            // Figure out the name.                // Since the name is supplied not for the thermostat, but for the        // zone, we'll have to walk a little bit back on the configuration        // root and extract it from there. The configuration root will look        // something like        // "dz.unit.${unit-name}.zone.${zone-name}.thermostat", in other        // words, the component we're looking for is the next to last. Since        // this happens just once (at configuration time), some calculation        // overhead in order to reduce the complexity is OK.                String trailer = null;        String cursor = null;                for ( StringTokenizer st = new StringTokenizer(getConfigurationRoot(), "."); st.hasMoreTokens(); ) {                    trailer = cursor;            cursor = st.nextToken();        }                // At this point, the trailer contains the thermostat name.                name = trailer;                CH_TSTAT =  new LogChannel("Thermostat/" + getName());                dumpHeating = getConfiguration().getInteger(getConfigurationRoot() + ".dump.heating", 0);        dumpCooling = getConfiguration().getInteger(getConfigurationRoot() + ".dump.cooling", 0);        voting = getConfiguration().getBoolean(getConfigurationRoot() + ".voting.enabled", true);                complain(LOG_INFO, CH_TSTAT, "Dump zone (heat " + dumpHeating + ", cool " + dumpCooling + ")");                createController();        createSensor();                complain(LOG_INFO, CH_TSTAT, "configured");    }        public String getName() {            return name;    }        public void setVoting(boolean voting) {            complain(LOG_INFO, CH_TSTAT, "setVoting: " + voting);        this.voting = voting;        for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ThermostatListener)i.next()).votingStateChanged(this, voting);        }    }        public boolean isVoting() {            return voting;    }        public void setHold(boolean hold) {            complain(LOG_INFO, CH_TSTAT, "setHold: " + hold);        this.hold = hold;        for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ThermostatListener)i.next()).holdStateChanged(this, hold);        }    }        public boolean isOnHold() {            return hold;    }        public void setOn(boolean enabled) {            complain(LOG_INFO, CH_TSTAT, "setOn: " + enabled);            this.enabled = enabled;                for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ThermostatListener)i.next()).enabledStateChanged(this, enabled);        }                // VT: NOTE: With the current implementation of zone controllers,        // the step below is redundant. Let's be paranoid, though.        if ( !enabled ) {                    controlSignalChanged(new Double(0));        } else {                    controlSignalChanged(new Double(controlSignal));        }    }        public boolean isOn() {            return enabled;    }        public int getDumpPriority(int mode) {            if ( !isOn() ) {                    // Override. If the zone is shut off, it can be used as a dump            // zone.                        return 1;        }            switch ( mode ) {                    case -1:                            // cooling            	                return dumpCooling;                        case 1:                            // heating                                return dumpHeating;            default:                            // off                                return 0;        }    }        /**     * Create the thermostat controller.     *     * The controller is instantiated and initialized based on the     * configuration.     */    private void createController() {            String configurationRoot = getConfigurationRoot() + ".controller";        String controllerClass = getConfiguration().getString(configurationRoot + ".class");                try {                    controller = (ProcessController)ObjectFactory.instantiate(controllerClass, ProcessController.class);                        if ( controller instanceof LogAware ) {                            ((LogAware)controller).setLogger(getLogger());            }                        controller.configure(configurationRoot, getConfiguration());                        complain(LOG_DEBUG, CH_TSTAT, "Instantiated controller");                    } catch ( Throwable t ) {                    complain(LOG_ERR, CH_TSTAT, "Can't instantiate controller, root "            	+ configurationRoot            	+ ", class "            	+ controllerClass            	+ ", cause:", t);            	            throw new IllegalArgumentException("Can't instantiate controller, see messages above");        }    }        /**     * Create the temperature sensor driver.     *     * The driver is instantiated and initialized based on the     * configuration.     */    private void createSensor() {            String configurationRoot = getConfigurationRoot() + ".temp_sensor";        String sensorClass = getConfiguration().getString(configurationRoot + ".class");                try {                    sensor = (TemperatureSensor)ObjectFactory.instantiate(sensorClass, TemperatureSensor.class);                        if ( sensor instanceof LogAware ) {                            ((LogAware)sensor).setLogger(getLogger());            }                        sensor.configure(configurationRoot, getConfiguration());            sensor.addListener(this);                        complain(LOG_DEBUG, CH_TSTAT, "Instantiated temperature sensor");                    } catch ( Throwable t ) {                    complain(LOG_ERR, CH_TSTAT, "Can't instantiate temp sensor, root "            	+ configurationRoot            	+ ", class "            	+ sensorClass);            	            throw new IllegalArgumentException("Can't instantiate temp sensor, see messages above");        }    }    public void currentTemperatureChanged(TemperatureSensor source, Object currentTemperatureObject) {            // VT: NOTE: The source is ignored because we have just one sensor        // connected. More than one will never happen because if even        // there's a need to have more than one sensor per zone, their        // readings will be combined and presented by an entity like        // AggregateTemperatureSensor, so the logic will not change.                if ( source != sensor ) {                    throw new IllegalStateException("Got a notification from someone else's sensor");        }                // VT: FIXME: At this point, we'll just complain if the reading is        // not available. Later, we'll have to open the dumper for this zone        // and exclude it from the zone controller logic.                if ( currentTemperatureObject == null              || !(currentTemperatureObject instanceof Double) ) {                         complain(LOG_WARNING, CH_TSTAT, "Sensor failure: " + currentTemperatureObject);            controlSignalChanged(currentTemperatureObject);            return;        }            currentTemperature = ((Double)currentTemperatureObject).doubleValue();                // VT: NOTE: Do not be tempted to remove compute() from the logic if        // this zone is not enabled - it may seem a pointless calculation,        // but it's not. Since the process controller is a time sensitive        // entity, it will keep calculating the *correct* value of the        // signal, which needs to be done even if it is not currently used.                controlSignal = controller.compute(System.currentTimeMillis(), currentTemperature);                if ( enabled ) {                    controlSignalChanged(new Double(controlSignal));        } else {                    controlSignalChanged(new Double(0));        }    }        /**     * Broadcast the notification about the {@link #controlSignal control     * signal} change to the {@link #listenerSet listener set}.     *     * This may be a result of receiving a {@link #currentTemperatureChanged     * temperature change notification} or control action ({@link     * #setOn setOn()}).     *     * @param enabled Current state of {@link #enabled enabled}.     */    private void controlSignalChanged(Object signal) {            // complain(LOG_INFO, CH_TSTAT, "CO: " + signal);            for ( Iterator i = listenerSet.iterator(); i.hasNext(); ) {                    ((ThermostatListener)i.next()).controlSignalChanged(this, signal);        }    }        /**     * Get the adjusted {@link #controlSignal control signal} value.     *     * @return If {@link #enabled enabled}, the value of the {@link     * #controlSignal control signal}, otherwise 0.     */    public double getControlSignal() {            return enabled ? controlSignal : 0;    }        public ProcessController getController() {            return controller;    }        public void addListener(ThermostatListener l) {            listenerSet.add(l);    }        public TemperatureSensor getSensor() {            return sensor;    }        protected void startup() throws Throwable {            if ( unit == null ) {                    throw new IllegalStateException("Unit must be attached first");        }            if ( sensor instanceof PassiveService ) {                    ((PassiveService)sensor).start().waitFor();        }        complain(LOG_INFO, CH_TSTAT, "Started");    }        protected void shutdown(Throwable cause) {        }        public String toString() {            return "Thermostat[" + getName() + ": " + controller.getSetpoint() + "]";    }        public LogChannel getLogChannel() {            return CH_TSTAT;    }        public int compareTo(Object other) {            if ( !(other instanceof Thermostat) ) {                    if ( other == null ) {                            throw new ClassCastException("null argument");                            } else {                            throw new ClassCastException("Expected " + getClass().getName() + ", got " + other.getClass().getName());            }        }                return getName().compareTo(((Thermostat)other).getName());    }}

⌨️ 快捷键说明

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