Dörrbrytar-loggning

Moderators: hekj, Telldus

Post Reply
liverpoolarn
Posts: 65
Joined: Thu Jan 18, 2018 11:08 am

Dörrbrytar-loggning

Post by liverpoolarn » Thu Jan 18, 2018 11:08 am

Har införskaffat en dörrbrytare (lär bli fler) som jag tänkte logga och visa i en graf (likt de för sensorer).

I de som finns i "Visa sensor"-värden-tråden så går det bara logga ett värde per minut och det är ju lite långt när man mäter "öppettider" för en dörrbrytare. Det är ju oftast så att de bara är öppna ett par sekunder.

Jag har "återanvänt" precis samma tillvägagångssätt för detta för att adda informartionen i en graf som för sensorerna och det funkar prima, förutom problemet då att det loggas data "per sekund" istället för minut.

Följande kod för att läsa in värden till grafen:

Code: Select all

sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
         StringTokenizer st1 = new StringTokenizer(buf.toString(), "\n");
         while (st1.hasMoreTokens()) {
            StringTokenizer st2 = new StringTokenizer(st1.nextToken().replaceAll("\t\t", "\t?\t"), "\t");
            if (st2.hasMoreTokens()) {
               String timestamp = st2.nextToken();
               Date date = sdf.parse(timestamp, new ParsePosition(0));
               if (date != null) {
                  cal.setTime(date);
                  int year = cal.get(Calendar.YEAR);
                  int month = cal.get(Calendar.MONTH) + 1;
                  int day = cal.get(Calendar.DAY_OF_MONTH);
                  int hour = cal.get(Calendar.HOUR_OF_DAY);
                  int minute = cal.get(Calendar.MINUTE);
                  int gNdx = 0;
                  while (st2.hasMoreTokens() && gNdx < labels.length) {
                     String value = st2.nextToken().replace(',', '.');
                     if (!value.equals("?")) {
                        try {
                           double d = Double.parseDouble(value);
                           SensorChart.addValue(gNdx, year, month, day, hour, minute, d);
                           dataAdded = true;
                        } catch(NumberFormatException nfe) {
                           // ignore
                        }
                     }
                     gNdx = gNdx + 1;
                  }
               }
            }
         }
Jag har testat att lägga till :ss efter "yyyy-MM-dd HH:mm" samt int second = cal.get(Calendar.SECOND); och SensorChart.addValue(gNdx, year, month, day, hour, minute, second, d);

Men jag får inte det att funka då. Tiderna är loggade i formatet "2013-07-25 15:15:37 1
2013-07-25 15:19:41 0".

Tack på förhand!

/Henke

hekj
Posts: 992
Joined: Thu Jan 18, 2018 11:08 am
Location: Stockholm
Contact:

Re: Dörrbrytar-loggning

Post by hekj » Thu Jan 18, 2018 11:08 am

Jag har lagt till en ny metod i SensorGraph.
public static void addValue(int ndx, int year, int month, int day, int hour, int minute, int second, double value)
Finns att hämta här.
http://nexahome.se/SensorChart.class
http://nexahome.se/SensorChart.java

Uppdatera din bsh kod med valda bitar...

Code: Select all

      String inp_path = "C:/apps/nexahome/";
      String out_path = "C:/apps/nexahome/";
      
      String title = "Door open [minutes]";
      String special_name = "door";
      
      String[] labels = { "Door1" };
      String[] colors = { "blue" };
      
      int length = 640;
      int height = 480;

      boolean dataAdded = false;
      
      Long[] previousMillis = new Long[labels.length];

      String output = out_path + "mySensorChart_" + special_name + ".png";

      Color color;

      SensorChart.initGraph(labels.length, 1);
      for (int gNdx = 0; gNdx < labels.length; gNdx++) {
         String txt = colors[gNdx].toLowerCase();
         if ("white".equals(txt)) {
            color = Color.white;
         } else if ("lightgray".equals(txt)) {
            color = Color.lightGray;
         } else if ("gray".equals(txt)) {
            color = Color.gray;
         } else if ("darkgray".equals(txt)) {
            color = Color.darkGray;
         } else if ("black".equals(txt)) {
            color = Color.black;
         } else if ("red".equals(txt)) {
            color = Color.red;
         } else if ("pink".equals(txt)) {
            color = Color.pink;
         } else if ("orange".equals(txt)) {
            color = Color.orange;
         } else if ("yellow".equals(txt)) {
            color = Color.yellow;
         } else if ("green".equals(txt)) {
            color = Color.green;
         } else if ("magenta".equals(txt)) {
            color = Color.magenta;
         } else if ("cyan".equals(txt)) {
            color = Color.cyan;
         } else{
            color = Color.blue;
         }
         SensorChart.initSeries(gNdx, labels[gNdx], color);
      }

      Calendar cal = Calendar.getInstance();
      int back = 1;
      cal.add(Calendar.DAY_OF_YEAR, -back);
      for (int dNdx = 0; dNdx <= back; dNdx++) {
         StringBuffer buf = new StringBuffer();
         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
         File f = new File(inp_path + special_name + "_" + sdf.format(cal.getTime()) + ".txt");
         if (f.exists()) {
            BufferedReader br = null;
            try {
               br = new BufferedReader(new FileReader(f));
               String line = null;
               do {
                  line = br.readLine();
                  if (line != null) {
                     buf.append(line);
                     buf.append("\n");
                  }
               } while(line != null);
            } catch (IOException e) {
               e.printStackTrace();
            } finally {
               try {
                  if (br != null) {
                     br.close();
                  }
               } catch (IOException e) {
                  e.printStackTrace();
               }
            }
            sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            StringTokenizer st1 = new StringTokenizer(buf.toString(), "\n");
            while (st1.hasMoreTokens()) {
               StringTokenizer st2 = new StringTokenizer(st1.nextToken().replaceAll("\t\t", "\t?\t"), "\t");
               if (st2.hasMoreTokens()) {

                  String timestamp = st2.nextToken();
                  Date date = sdf.parse(timestamp, new ParsePosition(0));
                  if (date != null) {
                     cal.setTime(date);
                     int year = cal.get(Calendar.YEAR);
                     int month = cal.get(Calendar.MONTH) + 1;
                     int day = cal.get(Calendar.DAY_OF_MONTH);
                     int hour = cal.get(Calendar.HOUR_OF_DAY);
                     int minute = cal.get(Calendar.MINUTE);
                     int second = cal.get(Calendar.SECOND);
                     int gNdx = 0;
                     while (st2.hasMoreTokens() && gNdx < labels.length) {
                        String value = st2.nextToken().replace(',', '.');
                        if (!value.equals("?")) {
                           try {
                              
                              double d = Double.parseDouble(value);
                              
                              if (d == 1.0) {
                                 previousMillis[gNdx] = new Long(date.getTime());
                                 d = 0.0;

                              } else if (d == 0.0 && previousMillis[gNdx] != null) {
                                 d = ((double)(date.getTime() - previousMillis[gNdx].longValue())) / 1000 / 60;
                                 SensorChart.addValue(gNdx, year, month, day, hour, minute, second, d);
                                 previousMillis[gNdx] = null;
                                 second = second + 1;
                                 d = 0.0;
                              }
                              
                              if (d > 5) {
                                 d = 5;  // the "y" value to max 5 minutes
                              }
                              
                              SensorChart.addValue(gNdx, year, month, day, hour, minute, second, d);
                              dataAdded = true;
                              
                           } catch(NumberFormatException nfe) {
                              // ignore
                           }
                        }
                        gNdx = gNdx + 1;
                     }
                  }
               }
            }
         }
         cal.add(Calendar.DAY_OF_YEAR, 1);
      }

      if (dataAdded) {
         SensorChart.process("", title, length, height, output);
      } else {
         System.out.println("No data added to graph");
      }
   }
Jag testade koden med följande data.

door_2013-08-01.txt
2013-08-01 07:20:35 1
2013-08-01 07:20:55 0
2013-08-01 15:15:37 1
2013-08-01 15:19:41 0
2013-08-01 20:03:20 1
2013-08-01 20:03:25 0
Kurvans höjd (y-axel) visar antalet minuter dörren har varit öppen.

liverpoolarn
Posts: 65
Joined: Thu Jan 18, 2018 11:08 am

Re: Dörrbrytar-loggning

Post by liverpoolarn » Thu Jan 18, 2018 11:08 am

Sweet mannen! Tackar så hjärtligt! :)

/Henke

liverpoolarn
Posts: 65
Joined: Thu Jan 18, 2018 11:08 am

Re: Dörrbrytar-loggning

Post by liverpoolarn » Thu Jan 18, 2018 11:08 am

Lyckas inte få till det men sekunderna på så vis jag haft koden innan... är det något jag MÅSTE ändra för att det ska lira vidare?

Jag får följande felmeddelande:
2013-08-04 22:03:29 There was an error in evaluating the script (mypage.bsh): Sourced file: mypage.bsh : Condition evaluates to void type : at Line: 191 : in file: mypage.bsh : dataAdded

Jag skulle egentligen vilja fortsätta ha 0-1 för när brytaren öppnas och stängs bara så att man får en exakt likadan graf som för temperaturen bara... min tanke är att för att åstadkomma detta göra dubbla tidstämplar när dörren öppnas resp stängs. Så när dörren stängs så läggs dels ett värde 1 (öppet) när detta inträffar och sedan någon sekund senare även värdet 0 (stängt). När dörren öppnas igen så läggs ett värde 0 till och sedan värdet 1 några sekunder senare. På så vis skulle jag få en tydlig graf som visar typ OM (och ungefär när) dörren öppnats. Mer noggrannt behöver det inte vara.

EDIT: Råkade pasta in fel felmeddelande.

/Henke

hekj
Posts: 992
Joined: Thu Jan 18, 2018 11:08 am
Location: Stockholm
Contact:

Re: Dörrbrytar-loggning

Post by hekj » Thu Jan 18, 2018 11:08 am

liverpoolarn wrote:Lyckas inte få till det men sekunderna på så vis jag haft koden innan... är det något jag MÅSTE ändra för att det ska lira vidare?

Jag får följande felmeddelande:
2013-08-04 22:03:29 There was an error in evaluating the script (mypage.bsh): Sourced file: mypage.bsh : Condition evaluates to void type : at Line: 191 : in file: mypage.bsh : dataAdded
Ser du något konstigt på rad 191?

Det är lättare att felsöka om du visa din kod.

liverpoolarn
Posts: 65
Joined: Thu Jan 18, 2018 11:08 am

Re: Dörrbrytar-loggning

Post by liverpoolarn » Thu Jan 18, 2018 11:08 am

Kanske är lättare ja...

Code: Select all

temp = false;
temp2 = false;
fukt = false;
forrad = false;

params = getData("mypage.params_");
if (params != null) {
//echo(params);
   var len = Integer.parseInt(params);
   for (int ndx = 1; ndx <= len; ndx++) {
      param = getData("mypage.param" + ndx + "_");
//echo(param);

      if (param.equals("mypage=temp")) {
         temp = true;
      } else if (param.equals("mypage=temp2")) {
         temp2 = true;
      } else if (param.equals("mypage=fukt")) {
         fukt = true;
      } else if (param.equals("mypage=forrad")) {
         forrad = true;
      }

   }
} else {
   echo("mypage.params_ == null");
}

if (temp || temp2 || fukt || forrad) {

   import java.awt.Color;
   import java.io.BufferedReader;
   import java.io.File;
   import java.io.FileReader;
   import java.io.IOException;
   import java.text.ParsePosition;
   import java.text.SimpleDateFormat;
   import java.util.Calendar;
   import java.util.Date;
   import java.util.StringTokenizer;

   addClassPath("C:/apps/nexahome/jcommon-1.0.17.jar");
   addClassPath("C:/apps/nexahome/jfreechart-1.0.14.jar");
   addClassPath("C:/apps/nexahome/.");

   String[] temp_labels = { "Framsidan", "BaksidanKok", "BaksidanGuestroom" };
   String[] temp_colors = { "red", "yellow", "orange" };

   String[] temp2_labels = { "Gillestugan" };
   String[] temp2_colors = { "black" };

   String[] fukt_labels = { "Ellas", "Kok", "Gillestugan", "Guestroom" };
   String[] fukt_colors = { "red", "yellow", "black", "orange" };

   String[] forrad_labels = { "Forrad", };
   String[] forrad_colors = { "blue" };

   int length = 2000;
   int height = 500;
   String title = null;
   String output= null;
   String[] labels = null;
   String[] colors = null;
   special_name = null;

   if (temp) {
      title = "Temperatur";
      labels = temp_labels;
      colors = temp_colors;
      special_name = "temp";
   } else if (temp2) {
      title = "Temperatur 2";
      labels = temp2_labels;
      colors = temp2_colors;
      special_name = "temp2";
   } else if (fukt) {
      title = "Fukt";
      labels = fukt_labels;
      colors = fukt_colors;
      special_name = "fukt";
   } else {
      title = "Forrad";
      labels = forrad_labels;
      colors = forrad_colors;
      special_name = "forrad";
   }

   output = path + "mySensorChart_" + special_name + ".png";

   SensorChart.initGraph(labels.length, 1);
   for (int gNdx = 0; gNdx < labels.length; gNdx++) {
      txt = colors[gNdx].toLowerCase();
      if ("white".equals(txt)) {
         color = Color.white;
      } else if ("lightgray".equals(txt)) {
         color = Color.lightGray;
      } else if ("gray".equals(txt)) {
         color = Color.gray;
      } else if ("darkgray".equals(txt)) {
         color = Color.darkGray;
      } else if ("black".equals(txt)) {
         color = Color.black;
      } else if ("red".equals(txt)) {
         color = Color.red;
      } else if ("pink".equals(txt)) {
         color = Color.pink;
      } else if ("orange".equals(txt)) {
         color = Color.orange;
      } else if ("yellow".equals(txt)) {
         color = Color.yellow;
      } else if ("green".equals(txt)) {
         color = Color.green;
      } else if ("magenta".equals(txt)) {
         color = Color.magenta;
      } else if ("cyan".equals(txt)) {
         color = Color.cyan;
      } else{
         color = Color.blue;
      }
      SensorChart.initSeries(gNdx, labels[gNdx], color);
   }

   Calendar cal = Calendar.getInstance();
   int back = 7;
   cal.add(Calendar.DAY_OF_YEAR, -back);
   for (int dNdx = 0; dNdx <= back; dNdx++) {
      StringBuffer buf = new StringBuffer();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
      File f = new File(path + special_name + "_" + sdf.format(cal.getTime()) + ".txt");
      if (f.exists()) {
         BufferedReader br = null;
         try {
            br = new BufferedReader(new FileReader(f));
            String line = null;
            do {
               line = br.readLine();
               if (line != null) {
                  buf.append(line);
                  buf.append("\n");
               }
            } while(line != null);
         } catch (IOException e) {
            e.printStackTrace();
         } finally {
            try {
               if (br != null) {
                  br.close();
               }
            } catch (IOException e) {
               e.printStackTrace();
            }
         }
         sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
         StringTokenizer st1 = new StringTokenizer(buf.toString(), "\n");
         while (st1.hasMoreTokens()) {
            StringTokenizer st2 = new StringTokenizer(st1.nextToken().replaceAll("\t\t", "\t?\t"), "\t");
            if (st2.hasMoreTokens()) {
               String timestamp = st2.nextToken();
               Date date = sdf.parse(timestamp, new ParsePosition(0));
               if (date != null) {
                  cal.setTime(date);
                  int year = cal.get(Calendar.YEAR);
                  int month = cal.get(Calendar.MONTH) + 1;
                  int day = cal.get(Calendar.DAY_OF_MONTH);
                  int hour = cal.get(Calendar.HOUR_OF_DAY);
                  int minute = cal.get(Calendar.MINUTE);
				  int second = cal.get(Calendar.SECOND);
                  int gNdx = 0;
                  while (st2.hasMoreTokens() && gNdx < labels.length) {
                     String value = st2.nextToken().replace(',', '.');
                     if (!value.equals("?")) {
                        try {
                           double d = Double.parseDouble(value);
                           SensorChart.addValue(gNdx, year, month, day, hour, minute, second, d);
                           dataAdded = true;
                        } catch(NumberFormatException nfe) {
                           // ignore
                        }
                     }
                     gNdx = gNdx + 1;
                  }
               }
            }
         }
      }
      cal.add(Calendar.DAY_OF_YEAR, 1);
   }

   if (dataAdded) {
      SensorChart.process("", title, length, height, output);
   } else {
      echo("No data added to graph!");
   }
}
Rad 191 är "if (dataAdded) { ".

Detta ger fel endast i forrad-caset (dörrbrytaren). Temp o fuktloggningarna funkar.

hekj
Posts: 992
Joined: Thu Jan 18, 2018 11:08 am
Location: Stockholm
Contact:

Re: Dörrbrytar-loggning

Post by hekj » Thu Jan 18, 2018 11:08 am

Du saknar initiering av variabeln dataAdded, lägg in nedanstående kod på raden ovanför "Calendar cal = Calendar.getInstance();"

Code: Select all

      boolean dataAdded = false;

liverpoolarn
Posts: 65
Joined: Thu Jan 18, 2018 11:08 am

Re: Dörrbrytar-loggning

Post by liverpoolarn » Thu Jan 18, 2018 11:08 am

Japp du har ju så rätt i detta... anledningen till att det blev ett "no data added" var ju att jag labbade med mer än 7 dagar gammal data. Därav sprang den aldrig in i for-satsen och satte variabeln till true. Detta inträffar ju aldrig för temp o fuktvärdena då de hela tiden skickar in nya värden.

Nu funkar det fint! Finns ju lite att fila på men nu har man datat lagrat i txt-filen och man kan få en graf på dem och det var huvudsyftet. Nu ska vi se om man kan få till någon sorts visning av värdena i text-format.

En annan sak som skulle vara önskvärd vore ju att läsa in värdena till en databas så att det inte blir så fasligt massa filer och att man då lättare kan få fram medelvärden och max-min etc. Samt att man kanske då kan visa värdena på en websida enklare. Är inläsning till mysql eller mssql något som är görbart från nexahome?
De guider jag läst är från tellstick-net där detta görs...

Post Reply