Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
15 arune 1
/*
2
 * File created by arune
3
 * at 2004-jan-02 18:00:08
4
 */
5
package Macbeth.Modules.modTempFetcher;
6
 
7
import javax.swing.*;
8
import java.awt.*;
9
import java.awt.event.*;
10
import java.util.HashMap;
11
import java.util.Iterator;
12
import java.math.BigDecimal;
13
import java.io.*;
14
 
15
 
16
import Macbeth.System.*;
17
import Macbeth.Utilities.UByte;
18
import Macbeth.Utilities.MyDateTime;
19
import Macbeth.Utilities.DataRepository;
20
import Macbeth.XML.XMLDataHandler;
21
 
22
/**
23
 *
24
 *
25
 *
26
 *
27
 *
28
 *
29
 * @author arune
30
 * @version 1.0
31
 */
32
 
33
public class modTempFetcher extends MbModule { //implements MbModuleGUI {
34
    //The sensordata that we receive via XML
35
    private UByte[] receivedBytes;
36
    //Interval between the data collecting. default frequency is every 60th second
37
    private int timerInterval = 60;
38
    private int nrOfSamples = 0;
39
    //our data request timer
40
    private Timer requestDataTimer;
41
 
42
    private HashMap sensors;
43
 
44
    private HashMap sensorNodes;
45
 
46
    private boolean parsingARNEXML;
47
 
48
    //A GUI for our module.
49
    private GUI gui;
50
    //Is our GUI currently visible or not?
51
    private boolean guiVisible = false;
52
 
53
    /**
54
     * Creates a new instance of modTempFetcher.
55
     */
56
    public modTempFetcher() {
57
        //construct MbModule
58
        super();
59
        //todo: ?
60
        receivedBytes = new UByte[6];
61
        parsingARNEXML = false;
62
        gui = new GUI();
63
        requestDataTimer = null;
64
        sensors = new HashMap(8);
65
        sensorNodes = new HashMap(8);
66
        //we depend on the ARNE-module
67
        addDependency("ARNE");
68
        //register our packet data handler
69
        setPacketDataHandler(new PacketDataHandler());
70
    }
71
 
72
    /**
73
     * Gets the name of the component.
74
     * @return The name of the component.
75
     */
76
    public String name() {
77
        return "TempFetcher";
78
    }
79
 
80
    /**
81
     * Gets the description of the component.
82
     * @return The description of the component.
83
     */
84
    public String description() {
85
        return "Collects temperature data from ARNE bus";
86
    }
87
 
88
    /**
89
     * This method sets default values on all _required_ data
90
     * fields in the data repository.
91
     */
92
    protected void initDataFields() {
93
        options.putField("timerinterval", "60");
94
        options.putField("samples", "5");
95
    }
96
 
97
    /**
98
     * Starts up this module.
99
     */
100
    public void startup() throws MbStartupException {
101
        //start up MbModule
102
        super.startup();
103
        //get options from data repository
104
        timerInterval = Integer.parseInt(options.getField("timerinterval"));
105
        nrOfSamples = Integer.parseInt(options.getField("samples"));
106
 
107
        if (timerInterval > 0) {
108
            TimerListener lyssnare = new TimerListener();
109
            requestDataTimer = new Timer(1000 * timerInterval, lyssnare);
110
            requestDataTimer.start();
111
        }
112
 
113
        if (nrOfSamples <= 0) {
114
            nrOfSamples = 1;    //to not cause div by 0
115
        }
116
 
117
        DataRepository.DataList list = dataRepository.getList("sensors");
118
        Iterator it = list.items();
119
        while (it.hasNext()) {
120
            DataRepository.DataListItem item = (DataRepository.DataListItem) it.next();
121
            String sensorName = item.getField("name");
122
            String sensorLogPath = item.getField("logpath");
123
            UByte sensorIdentByte = UByte.parseUByte(item.getField("identbyte"));
124
            boolean printToDisplay = Boolean.valueOf(item.getField("printtodisplay")).booleanValue();
125
            sensors.put(sensorName, new TempSensor(sensorName, sensorIdentByte, sensorLogPath, nrOfSamples, printToDisplay));
126
        }
127
 
128
        list = dataRepository.getList("sensornodes");
129
        it = list.items();
130
        while (it.hasNext()) {
131
            DataRepository.DataListItem item = (DataRepository.DataListItem) it.next();
132
            String nodeName = item.getField("name");
133
            sensorNodes.put(nodeName, nodeName);
134
        }
135
 
136
 
137
    }
138
 
139
    /**
140
     * Shuts down this module.
141
     */
142
    public void shutdown() {
143
        //stop timer if it's running
144
        if (requestDataTimer!=null) {
145
            if (requestDataTimer.isRunning()) {
146
                requestDataTimer.stop();
147
            }
148
        }
149
        //shut down MbModule
150
        super.shutdown();
151
    }
152
 
153
 
154
 
155
    private void handleSensor(UByte[] bytes, int index) {
156
        final int D1 = -40; final double D2 = 0.01;
157
        //start searching on index
158
        //match first byte (byte index) with any of the sensors identbyte
159
        if (!sensors.isEmpty()) {
160
            TempSensor actualSensor = null;
161
            Iterator it = sensors.keySet().iterator();
162
            while (it.hasNext()) {
163
                //_debug.println("handleSensor, looping through sensors");
164
                String key = (String) it.next();
165
                TempSensor f = (TempSensor) sensors.get(key);
166
                if (f != null) {
167
                    //_debug.println("handleSensor, f:" + f.identByte + " bytes[index]: " + bytes[index]);
168
                    if (f.identByte.equals(bytes[index])) {
169
                        //_debug.println("handleSensor, found an actualSensor");
170
                        actualSensor = f;
171
                    }
172
                }
173
            }
174
 
175
            if (actualSensor != null) {
176
 
177
                int iTemperature = bytes[index+1].shortValue() * 256;
178
                iTemperature = iTemperature + bytes[index+2].shortValue();
179
                double dTemp = (iTemperature * D2) + D1;
180
                //_debug.println(actualSensor.name + " temperature is " + dTemp);
181
                if (actualSensor.addValue(dTemp)) {     //add value and check if ready to get mean
182
                    double dMeanTemp = actualSensor.getMean();
183
                    double dTempRadix2 = round(dMeanTemp, 2);
184
                    double dTempRadix1 = round(dMeanTemp, 1);
185
 
186
                    //kolla actualSensor.printToDisplay, om true ska paket skickas till display
187
                    //data = actualSensor.name " " dTempRadix1
188
                    //obs id, ttl osv!
189
                    //todo: perhaps change id to something based on actualSensor.identbyte?
190
                    if (actualSensor.printToDisplay) {
191
                        MbPacket p = new MbPacket();
192
                        //p.setDestination(new MbLocation("self","PacketReceiver"));
193
                        p.setDestination(new MbLocation("self","SmallDisplays"));
194
                        //ARNE packet in XML-format
195
                        //todo: byt ut gradertecknet mot &deg; eller nĺt
196
                        p.setContents("  <lcdpacket sender=\"" + name()
197
                                            + "\" type=\"textrow\" prio=\"1\" ttl=\"0\" id=\"458328\" data=\""
198
                                            + actualSensor.name + " " + dTempRadix1 + "ß"
199
                                            + "\" />");
200
                        sendPacket(p);
201
                    }
202
 
203
                    //_debug.println("Printing " + dTempRadix1 + " at " + actualSensor.logPath);
204
                    printToFile(dTempRadix1, dTempRadix2, actualSensor.logPath);
205
                }
206
            }
207
        }
208
 
209
    }
210
 
211
    private void handleBytes(UByte[] bytes) {
212
        //_debug.println("handleBytes, bytes.length: " + bytes.length);
213
        if ((bytes.length % 3 == 0) && (bytes.length > 0)) {
214
            //_debug.println("handleBytes, mod ok");
215
            for (int i = 0; i < bytes.length; i = i + 3) {
216
                //_debug.println("handleBytes, calls handleSensor with i = " + i);
217
                handleSensor(bytes, i);
218
            }
219
        }
220
    }
221
 
222
 
223
    private void printToFile(double dataValue1, double dataValue2, String folderPath) {
224
        //create log output stream
225
        PrintStream log;
226
        try {
227
            //Date UTCTime = Date.valueOf("2004-01-08");
228
            long UTCTime = System.currentTimeMillis();
229
            String date = Long.toString(UTCTime);
230
 
231
            log = new PrintStream(new FileOutputStream(folderPath + "\\datetemphumid"));
232
            //log.println(MyDateTime.now("yyyy-MM-dd HH:mm:ss"));
233
            log.println(date.substring(0, date.length()-3));
234
            log.println(doubleToStringSpecial(dataValue2));
235
            log.flush();
236
            log.close();
237
            log = new PrintStream(new FileOutputStream(folderPath + "\\temperature"));
238
            log.println(doubleToStringSpecial(dataValue2));
239
            log.flush();
240
            log.close();
241
            log = new PrintStream(new FileOutputStream(folderPath + "\\temperature_rd"));
242
            log.println(doubleToStringSpecial(dataValue1));
243
            log.flush();
244
            log.close();
245
            log = new PrintStream(new FileOutputStream(folderPath + "\\formated_rd"));
246
            log.println(" ");
247
            log.println(doubleToStringSpecial(dataValue1));
248
            log.flush();
249
            log.close();
250
            log = new PrintStream(new FileOutputStream(folderPath + "\\all-log.txt", true));
251
            log.println(MyDateTime.now("yyyy-MM-dd HH:mm:ss ") +
252
                                        doubleToStringSpecial(dataValue2));
253
            log.flush();
254
            log.close();
255
            log = new PrintStream(new FileOutputStream(folderPath + "\\datetime"));
256
            log.println(MyDateTime.now("yyyy-MM-dd HH:mm:ss"));
257
            log.flush();
258
            log.close();
259
        } catch (FileNotFoundException e) {
260
            _errors.println("Path not found, " + folderPath);
261
        }
262
    }
263
 
264
    public static String doubleToStringSpecial(double value) {
265
        return Double.toString(value).replace('.',',');
266
    }
267
 
268
 
269
    public static double round(double value, int radix) {
270
        BigDecimal bd;
271
        bd = new BigDecimal(value);
272
        bd = bd.setScale(radix,BigDecimal.ROUND_HALF_UP);
273
        return bd.doubleValue();
274
    }
275
 
276
 
277
    /**
278
     * Takes care of XML-data found in incoming packets.
279
     */
280
    private class PacketDataHandler implements XMLDataHandler {
281
        /**
282
         * Called when start of a new element is found in the XML-data.
283
         * Ex: <name attr1="value1" attr2="value2">
284
         * Element name would then be "name" and attribute list
285
         * would contain "value1" and "value2" mapped to the attribute
286
         * names "attr1" and "attr2".
287
         * @param element The name of the element.
288
         * @param attributes The element attributes.
289
         */
290
        public void XMLstartElement(String element, HashMap attributes) {
291
            //Ex: <arnepacket bytes="6">
292
            if (element.equals("arnepacket") && attributes.containsKey("bytes")) {
293
                int bytes = Integer.parseInt((String)attributes.get("bytes"));
294
                //we should always get six bytes from TempNode ('H' RHh RHl 'T' Th Tl)
295
               // if (bytes==6) {
296
                parsingARNEXML = true;
297
                receivedBytes = new UByte[bytes];
298
               // } else {
299
               //     _errors.println("invalid number of bytes in ARNE packet");
300
               // }
301
            }
302
            //Ex: <byte id="1" value="5" />
303
            else if (element.equals("byte") && attributes.containsKey("id") && attributes.containsKey("value")) {
304
                if (parsingARNEXML) {
305
                    short id = Short.parseShort(attributes.get("id").toString());
306
                    //if id is valid
307
                    if (id>0 && id<=receivedBytes.length) {
308
                        //remember byte
309
                        receivedBytes[id-1] = UByte.parseUByte((String)attributes.get("value"));
310
                    } else {
311
                        _errors.println("invalid byte IDs specified");
312
                        parsingARNEXML = false;
313
                    }
314
                } else {
315
                    _errors.println("byte-attribute found outside arnepacket-attribute");
316
                }
317
            }
318
        }
319
 
320
        /**
321
         * Called when end of an element was found in the XML-data.
322
         * Ex: </name> or <test attr="value" />
323
         * @param element The name of the element.
324
         */
325
        public void XMLendElement(String element) {
326
            //Ex: </arnepacket>
327
            if (element.equals("arnepacket")) {
328
                if (parsingARNEXML) {
329
                    parsingARNEXML = false;
330
                    //handle our received bytes now
331
                    handleBytes(receivedBytes);
332
                }
333
            }
334
        }
335
 
336
        public void XMLelementData(String data) {}
337
        public void XMLdocumentStart() {}
338
        public void XMLdocumentEnd() {}
339
    }
340
 
341
 
342
    /**
343
     * Will be called when our GUI should be shown.
344
     */
345
    public void renderGUI(Container drawArea) {
346
        gui.render(drawArea);
347
    }
348
 
349
    /**
350
     * A class for our GUI.
351
     */
352
    class GUI implements ActionListener {
353
 
354
        public void render(Container renderArea) {
355
            //renderArea.setPreferredSize(150, 200);
356
            renderArea.setLayout(new GridLayout(200,1));
357
 
358
            /*btnLampButtons = new JButton[roomObjects.size()];
359
            Iterator it = roomObjects.keySet().iterator();
360
            int i=0;
361
            while (it.hasNext()) {
362
                RoomObject o = (RoomObject)roomObjects.get((String)it.next());
363
                if (o!=null) {
364
                    btnLampButtons[i] = new JButton(o.name);
365
                    btnLampButtons[i].setActionCommand("roomobject:" + o.name);
366
                    btnLampButtons[i].addActionListener(this);
367
                    renderArea.add(btnLampButtons[i]);
368
                    i++;
369
                }
370
            }*/
371
        }
372
 
373
        public void actionPerformed(ActionEvent e) {
374
            //was this a room object-button press?
375
            /*if (e.getActionCommand().startsWith("roomobject:")) {
376
                //split its actioncommand to find out which lamp it was for
377
                String[] tokens = e.getActionCommand().split("roomobject:");
378
                //try to find a room object with this name
379
                RoomObject o = (RoomObject)roomObjects.get(tokens[1]);
380
                //if found
381
                if (o!=null) {
382
                    //toggle corresponding room object
383
                    toggleRoomObject(o.byteValue.shortValue());
384
                }
385
            }*/
386
        }
387
    }
388
 
389
        //En lyssnare för timern
390
    private class TimerListener implements ActionListener {
391
 
392
//      public TimerLyssnare()
393
//      {
394
//      }
395
 
396
       public void actionPerformed(ActionEvent e) {
397
           if (!sensorNodes.isEmpty()) {
398
               Iterator it = sensorNodes.keySet().iterator();
399
               while (it.hasNext()) {
400
                   //_debug.println("timerevent, looping through sensorNodes");
401
                   String f = (String) it.next();
402
                   //String f = (String) sensorNodes.get(key);
403
                   if (f != null) {
404
                       MbPacket p = new MbPacket();
405
                       p.setDestination(new MbLocation("self", "ARNE"));
406
                       p.setContents(  "<arnepacket bytes=\"6\" destnode=\"" + f + "\">" +
407
                                        "<byte id=\"1\" value=\"65\"/>" +    // send 'A', addressing
408
                                        "<byte id=\"2\" value=\"64\"/>" +    // send PC-node-address 0x40
409
                                        "<byte id=\"3\" value=\"0\"/>" +     // send PC-Host 0x00
410
                                        "<byte id=\"4\" value=\"85\"/>" +    // send PC-Module 0x55
411
                                        "<byte id=\"5\" value=\"68\"/>" +    // send 'D', data none
412
                                        "<byte id=\"6\" value=\"80\"/>" +    // send 'P' for poll
413
                                       "</arnepacket>");
414
                       sendPacket(p);
415
 
416
                   }
417
               }
418
           }
419
        }
420
    }
421
}