📄 thermostatserverproxy.java
字号:
package net.sf.dz.view.tcp.server;import java.io.PrintWriter;import java.util.Iterator;import java.util.Set;import java.util.StringTokenizer;import org.freehold.jukebox.logger.LogChannel;import org.freehold.jukebox.logger.Logger;import org.freehold.jukebox.scheduler.Task;import org.freehold.jukebox.scheduler.TaskListener;import net.sf.dz.controller.ProcessController;import net.sf.dz.controller.ProcessControllerListener;import net.sf.dz.controller.ProcessControllerStatus;import net.sf.dz.event.ThermostatListener;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.device.sensor.TemperatureSensor;import net.sf.dz.scheduler.Schedule;import net.sf.dz.scheduler.ScheduleEvent;/** * @author Copyright © <a href="mailto:vt@freehold.crocodile.org">Vadim Tkachenko</a> 2001-2002 * @version $Id: ThermostatServerProxy.java,v 1.22 2004/02/03 20:47:26 vtt Exp $ */public class ThermostatServerProxy extends AbstractServerProxy implements Thermostat, ProcessControllerListener, TaskListener { public final static LogChannel CH_TSP = new LogChannel("Thermostat/proxy"); private Unit unit; private Thermostat ts; public ThermostatServerProxy(Logger logger, Unit unit, Thermostat ts) { super(logger); // VT: FIXME: Check the argument sanity this.unit = unit; this.ts = ts; } public String getName() { return ts.getName(); } public boolean isVoting() { return ts.isVoting(); } public boolean isOn() { return ts.isOn(); } public boolean isOnHold() { return ts.isOnHold(); } public int getDumpPriority(int mode) { return ts.getDumpPriority(mode); } public double getControlSignal() { return ts.getControlSignal(); } public void addListener(ThermostatListener listener) { } public ProcessController getController() { // VT: FIXME: Can we expose the target instead of the proxy? Remains // to be determined... return ts.getController(); } public TemperatureSensor getSensor() { // VT: FIXME: Can we expose the target instead of the proxy? Remains // to be determined... return ts.getSensor(); } public void currentTemperatureChanged(TemperatureSensor source, Object temp) { // VT: FIXME: Huh? Turns out we didn't even use the second argument? String message = "status:unit:" + unit.getName() + ":zone:" + getName() + ":temperature:"; if ( !(temp instanceof Double) ) { // VT: FIXME: This is ugly - handling should be uniform across all the code message += "E "; } message += temp.toString(); if ( false ) try { message += Double.toString(ts.getSensor().getCurrentTemperature()); } catch ( Throwable t ) { // Whatever it was, the exception message will contain the cause message += "E:" + t.getMessage(); } send(message); } public void processControllerStatusChanged(ProcessController source, ProcessControllerStatus status) { send("status:unit:" + unit.getName() + ":zone:" + getName() + ":controller:status:" + ts.getController().getSetpoint() + ":" + status); } public Unit getUnit() { return unit; } public void setpointChanged(ProcessController source, double setpoint) { processControllerStatusChanged(source, null); } public void renderReflection(PrintWriter pw) { pw.println(" <zone name=\"" + ts.getName() + "\">"); pw.println(" </zone>"); } public void dumpState(PrintWriter pw) { pw.print("status:unit:" + unit.getName() + ":zone:" + getName() + ":temperature:"); try { pw.println(Double.toString(ts.getSensor().getCurrentTemperature())); } catch ( Throwable t ) { // Whatever it was, the exception message will contain the cause pw.println("E:" + t.getMessage()); } pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":hold:" + ts.isOnHold()); pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":on:" + ts.isOn()); pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":voting:" + ts.isVoting()); pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":controller:status:" + ts.getController().getSetpoint() + ":" + ts.getController().getStatus()); dumpSchedule(pw); } private void dumpSchedule(PrintWriter pw) { Schedule s = unit.getSchedule(ts); if ( s == null ) { // VT: We've complained enough about not having the schedule now return; } final String dayName[] = { "SU", "MO", "TU", "WE", "TH", "FR", "SA" }; for ( int day = 0; day < 7; day++ ) { Set eventSet = s.getEvents(day); for ( Iterator i = eventSet.iterator(); i.hasNext(); ) { ScheduleEvent se = (ScheduleEvent)i.next(); pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":schedule:event:" + se.renderStatus()); } } ScheduleEvent se = s.getCurrentEvent(); // VT: NOTE: Let's take a shortcut. It is possible to use the same // procedure to parse the event string tokenizer on the client side, // so let's just dump the status and let the client figure it out. pw.println("status:unit:" + unit.getName() + ":zone:" + getName() + ":schedule:current:" + se.renderStatus()); } public void listen(PrintWriter pw) { super.listen(pw); ts.getSensor().addListener(this); ts.getController().addListener(this); } public void parse(StringTokenizer st) { String target = st.nextToken(); String op = st.nextToken(); if ( target.equals("controller") ) { if ( op.equals("setpoint") ) { ts.getController().setSetpoint(Double.parseDouble(st.nextToken())); } else { throw new IllegalArgumentException("Unknown controller operation '" + op + "'"); } } else if ( target.equals("on") ) { if ( op.equals("true") ) { ((ThermostatController)ts).setOn(true); } else { ((ThermostatController)ts).setOn(false); } } else if ( target.equals("hold") ) { if ( op.equals("true") ) { ((ThermostatController)ts).setHold(true); } else { ((ThermostatController)ts).setHold(false); } } else if ( target.equals("voting") ) { if ( op.equals("true") ) { ((ThermostatController)ts).setVoting(true); } else { ((ThermostatController)ts).setVoting(false); } } else if ( target.equals("schedule") ) { Schedule schedule = unit.getSchedule(ts); // Find the event in question. Matching criteria are the day // offset and the name, the rest will have to be adjusted. String day = st.nextToken(); String name = st.nextToken(); String hours = st.nextToken(); String minutes = st.nextToken(); String setpoint = st.nextToken(); String enabled = st.nextToken(); String voting = st.nextToken(); String dumpPriority = st.nextToken(); // Find the day offset int dayOffset = 0; for ( ; dayOffset < 7; dayOffset++ ) { if ( day.equals(Schedule.days[dayOffset]) ) { break; } } complain(LOG_DEBUG, CH_TSP, "Resolving event: " + dayOffset + ":" + name); Set events = schedule.getEvents(dayOffset); // Find the event now ScheduleEvent targetEvent = null; for ( Iterator i = events.iterator(); i.hasNext(); ) { ScheduleEvent event = (ScheduleEvent)i.next(); if ( event.getName().equals(name) ) { targetEvent = event; break; } } if ( targetEvent == null ) { throw new IllegalArgumentException("Can't resolve event " + day + ":" + name); } complain(LOG_NOTICE, CH_TSP, "Found event: " + targetEvent); // It's possible that the event that's just been sent to us is // no different from the one that we have, due to Swing // peculiarities. Let's check if it is... double setpointValue = Double.parseDouble(setpoint); boolean enabledValue = enabled.equals("on"); boolean votingValue = voting.equals("voting"); int dumpPriorityValue = Integer.parseInt(dumpPriority); // Pain: have to render the time in milliseconds... long startOffset = ((Long.parseLong(hours) * 60) + Long.parseLong(minutes)) * 60 * 1000; // VT: FIXME: See if the time is different if ( (targetEvent.getSetpoint() != setpointValue) || (targetEvent.isOn() != enabledValue) || (targetEvent.isVoting() != votingValue) || (targetEvent.getDumpPriority() != dumpPriorityValue) || (targetEvent.getStartOffset() != startOffset) ) { targetEvent.setSetpoint(setpointValue); targetEvent.setOn(enabledValue); targetEvent.setVoting(votingValue); targetEvent.setDumpPriority(dumpPriorityValue); targetEvent.setStartOffset(startOffset); send("status:unit:" + unit.getName() + ":zone:" + getName() + ":schedule:event:" + targetEvent.renderStatus()); complain(LOG_NOTICE, CH_TSP, "Modded event: " + targetEvent); schedule.reschedule(); schedule.sync(); } } else { throw new IllegalArgumentException("Unknown target '" + target + "'"); } } 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()); } public void taskScheduled(Task t) { complain(LOG_DEBUG, CH_TSP, "Scheduled: " + t); } public void taskRemoved(Task t) { complain(LOG_DEBUG, CH_TSP, "Removed: " + t); } public void taskExecuted(Task t) { complain(LOG_DEBUG, CH_TSP, "Executed: " + t); ScheduleEvent se = (ScheduleEvent)t.getDescriptor(); send("status:unit:" + unit.getName() + ":zone:" + getName() + ":schedule:current:" + se.renderStatus()); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -