Browse Source

je vais tout casser ?

tTh 5 months ago
parent
commit
975e501d9b
62 changed files with 2667 additions and 154 deletions
  1. 17
    1
      .gitignore
  2. 26
    0
      BUILD.txt
  3. 10
    9
      Makefile
  4. 22
    0
      README.md
  5. 36
    0
      core/Makefile
  6. 24
    0
      core/config.h
  7. 16
    0
      core/dd2-monitor.conf
  8. 17
    0
      core/lut1024.h
  9. 70
    0
      core/lut1024f.c
  10. 10
    0
      core/mklut.pl
  11. 112
    0
      core/parseconf.c
  12. 38
    0
      core/sysmetrics.c
  13. 4
    0
      core/sysmetrics.h
  14. 73
    0
      core/t.c
  15. 12
    32
      core/utils.c
  16. 8
    0
      core/utils.h
  17. 7
    0
      core/wtf.txt
  18. 81
    0
      doc/automate.tex
  19. 193
    36
      doc/dd2-monitoring.tex
  20. 29
    0
      doc/detournements.tex
  21. 8
    0
      doc/mkdoc.sh
  22. 59
    0
      doc/serial.tex
  23. 111
    0
      doc/storages.tex
  24. 79
    13
      essai.c
  25. 11
    4
      exemple.sh
  26. 4
    2
      fake-values.c
  27. 0
    13
      funcs.h
  28. 13
    2
      gnocchi/README.md
  29. 4
    1
      influxdb/README.md
  30. 13
    0
      influxdb/create.sh
  31. 3
    0
      influxdb/injecteur.pl
  32. 37
    1
      rrdb/README.md
  33. 6
    0
      rrdb/commun.sh
  34. 21
    0
      rrdb/create.sh
  35. 29
    0
      rrdb/getvalues.sh
  36. 14
    0
      rrdb/insert.sh
  37. 11
    0
      rrdb/mkgraph.sh
  38. 10
    3
      serial/Makefile
  39. 34
    3
      serial/README.md
  40. 29
    0
      serial/essai.sh
  41. 88
    0
      serial/funcs.c
  42. 86
    19
      serial/serial.c
  43. 10
    1
      serial/serial.h
  44. 99
    14
      serial/t.c
  45. 66
    0
      simulator/rdtemp/rdtemp.ino
  46. 55
    0
      simulator/send-random/send-random.ino
  47. 0
    0
      storage/Makefile
  48. 0
    0
      storage/t.c
  49. 153
    0
      viz/curses/7segments.c
  50. 36
    0
      viz/curses/Makefile
  51. 2
    0
      viz/curses/README.md
  52. 76
    0
      viz/curses/ecran.c
  53. 23
    0
      viz/curses/ecran.h
  54. 107
    0
      viz/curses/minidigits.c
  55. 240
    0
      viz/curses/t.c
  56. 88
    0
      viz/curses/vumetre.c
  57. 117
    0
      viz/curses/waterfall.c
  58. 34
    0
      viz/gnuplot/av4v-h.awk
  59. 34
    0
      viz/gnuplot/average4v.awk
  60. 22
    0
      viz/gnuplot/plot-one.sh
  61. 27
    0
      viz/gnuplot/plot-two.sh
  62. 3
    0
      viz/pg/README.md

+ 17
- 1
.gitignore View File

@@ -2,9 +2,25 @@ a.out
2 2
 *.o
3 3
 fake-values
4 4
 essai
5
+foo.dat
5 6
 serial/t
6
-doc/*.toc doc/*.log doc/*.aux doc/*.pdf
7
+core/t
8
+core/*.a
7 9
 
10
+doc/*.toc
11
+doc/*.log
12
+doc/*.aux
13
+doc/*.pdf
14
+doc/*.idx
15
+doc/*.ilg
16
+doc/*.ind
8 17
 
18
+*/*.dat
9 19
 
20
+rrdb/*.png
21
+serial/*.png
22
+
23
+viz/curses/t
24
+viz/gnuplot/*.png
25
+viz/*.a
10 26
 

+ 26
- 0
BUILD.txt View File

@@ -0,0 +1,26 @@
1
+		+--------------------------------+
2
+		| how to build the dd2-monitor ? |
3
+		+--------------------------------+
4
+
5
+First step, build some parts of the core library :
6
+
7
+	$ cd core
8
+	$ make t
9
+	$ ./t -v
10
+	$ cd ..
11
+
12
+Then you must have datas for working on. One source of datas
13
+is the four values who came from the Arduino over serial line.
14
+At this time, you must look at the configuration file.
15
+
16
+	$ cd serial
17
+	$ make t
18
+
19
+Have a look at the 'essai.sh' file for an example of simple
20
+usage of the serial input. For generating all that numbers,
21
+you have to run some code on the Arduino mega. Sources are
22
+in the simulator/ folder.
23
+
24
+
25
+
26
+

+ 10
- 9
Makefile View File

@@ -2,19 +2,20 @@
2 2
 #	must be run with gnu make
3 3
 #
4 4
 
5
-CC = gcc
6
-
7
-CCOPT = -Wall -g 
5
+CC	= gcc
6
+CCOPT	= -Wall -g 
7
+CLIB	= core/libdd2m-core.a viz/libdd2m-viz.a
8 8
 
9 9
 all:	essai fake-values
10 10
 
11
-essai:	essai.c funcs.o Makefile
12
-	gcc ${CCOPT} $< funcs.o -o $@
11
+# ---------------------------------------------
13 12
 
13
+O	= serial/serial.o serial/funcs.o
14 14
 
15
-funcs.o:	funcs.c funcs.h Makefile
16
-	gcc ${CCOPT} -c $<
15
+essai:	essai.c  Makefile $(CLIB)
16
+	$(CC) ${CCOPT} $< $(CLIB) ${O} -lncurses -o $@
17 17
 
18
-fake-values:	fake-values.c funcs.o Makefile
19
-	gcc ${CCOPT} $< funcs.o -o $@
18
+fake-values:	fake-values.c  Makefile $(CLIB)
19
+	$(CC) ${CCOPT} $< $(CLIB)  -o $@
20 20
 
21
+# ---------------------------------------------

+ 22
- 0
README.md View File

@@ -5,13 +5,35 @@ de _monitoring_ pour le futur Phytotron du Tetalab.
5 5
 
6 6
 Le but premier de ce système est de faciliter la mise au point d'un
7 7
 automate de contrôle de l'enceinte thermostatée. Nous devrons
8
+<<<<<<< HEAD
8 9
 surveiller température et humidité du dd2, et température du
9 10
 confinement biologique. 
11
+=======
12
+surveiller température et humidité du dd2,
13
+éclairage et température du confinement biologique. 
14
+>>>>>>> b47e467d21cec6ee688b4407d3ec54fa33e67ba6
10 15
 
11 16
 Pour en savoir plus sur ce passionnant projet, il y a le canal IRC
12 17
 `#tetalab` sur le réseau Freenode et/ou les rencontres du mercredi
13 18
 soir au DD2, à Mixart-Myrys.
14 19
 
20
+<<<<<<< HEAD
21
+=======
22
+Et aussi https://pad.tetalab.org/p/dd2-monitoring
23
+
24
+# WTF status
25
+
26
+Seriazl : Le `read` bloquant ne bloque pas. Ça craint grave. La recherche
27
+du workaround avance.
28
+
29
+Premier essai RRD : ça marchote...
30
+
31
+
32
+
33
+
34
+
35
+
36
+>>>>>>> b47e467d21cec6ee688b4407d3ec54fa33e67ba6
15 37
 
16 38
 
17 39
 

+ 36
- 0
core/Makefile View File

@@ -0,0 +1,36 @@
1
+#
2
+#		dd2 monitoring
3
+#
4
+#	build the core functions, use with care
5
+#
6
+
7
+
8
+COPT = -Wall -fpic -g -DDEBUG_LEVEL=0
9
+OBJS = lut1024f.o parseconf.o utils.o sysmetrics.o
10
+DEPS = Makefile
11
+ALIB = libdd2m-core.a
12
+# ---------------------------------------------------
13
+
14
+${ALIB}:	${OBJS}
15
+	ar r $@ $?
16
+
17
+lut1024f.o:	lut1024f.c lut1024.h ${DEPS}
18
+	gcc $(COPT) -c $<
19
+
20
+parseconf.o:	parseconf.c config.h  ${DEPS}
21
+	gcc $(COPT) -c $<
22
+
23
+utils.o:	utils.c utils.h  ${DEPS}
24
+	gcc $(COPT) -c $<
25
+
26
+sysmetrics.o:	sysmetrics.c  ${DEPS}
27
+	gcc $(COPT) -c $<
28
+
29
+# ---------------------------------------------------
30
+
31
+t:	t.c ${ALIB}  lut1024.h config.h utils.h ${DEPS}
32
+	gcc -Wall $< ${ALIB} -o $@
33
+
34
+foo.lut1024f:	mklut.pl Makefile
35
+	./mklut.pl quux > $@
36
+

+ 24
- 0
core/config.h View File

@@ -0,0 +1,24 @@
1
+/*
2
+ *		config.h
3
+ */
4
+
5
+#define		SZ_STRINGS	200
6
+
7
+typedef struct {
8
+
9
+	int	valid;
10
+	
11
+	char	*input_device;
12
+	int	input_speed;
13
+
14
+	char	*eyecandy_banner;
15
+
16
+	} Configuration;
17
+
18
+/* ---------------------------------------------------------------- */
19
+
20
+int set_default_config(Configuration *cfg);
21
+int parse_config(char *fname, int flags);
22
+int show_config(char *title);
23
+
24
+/* ---------------------------------------------------------------- */

+ 16
- 0
core/dd2-monitor.conf View File

@@ -0,0 +1,16 @@
1
+# 
2
+# experimental config file
3
+#
4
+
5
+# --------------------------------------------------
6
+# serial input from the control cpu
7
+
8
+input_device		s	/dev/ttyACM0
9
+input_speed		i	9600
10
+
11
+# --------------------------------------------------
12
+# some values for the eyecandy displays
13
+
14
+eyecandy_banner		s	hacked by tTh
15
+
16
+# --------------------------------------------------

+ 17
- 0
core/lut1024.h View File

@@ -0,0 +1,17 @@
1
+/*
2
+ *	LUT 1024 - DEALING WITH DISCRETE VALUES 
3
+ */
4
+
5
+
6
+typedef struct {
7
+	int		flags;
8
+	float		vals[1024];
9
+	} Lut1024f;
10
+
11
+/* ---------------------------------------------------------------- */
12
+
13
+int slurp_lut1024f(FILE *fp, Lut1024f *where, int notused);
14
+int load_lut1024f(char *fname, Lut1024f *where, int notused);
15
+
16
+/* ---------------------------------------------------------------- */
17
+

+ 70
- 0
core/lut1024f.c View File

@@ -0,0 +1,70 @@
1
+/*
2
+ *	LUT 1024 -> FLOAT
3
+ */
4
+
5
+#include	<stdio.h>
6
+#include	<stdlib.h>
7
+#include 	<string.h>
8
+
9
+#include	"lut1024.h"
10
+
11
+extern int	verbosity;
12
+
13
+/* ---------------------------------------------------------------- */
14
+
15
+int slurp_lut1024f(FILE *fp, Lut1024f *where, int notused)
16
+{
17
+int	count, foo;
18
+
19
+for(count=0; count<1024; count++) {
20
+	foo = fscanf(fp, "%f", &where->vals[foo]);
21
+	if (1 != foo) {
22
+		fprintf(stderr, "%s: bad read %d\n", __func__, foo);
23
+		return -4;
24
+		}
25
+	}
26
+
27
+return 0;
28
+}
29
+
30
+/* ---------------------------------------------------------------- */
31
+
32
+int load_lut1024f(char *fname, Lut1024f *where, int notused)
33
+{
34
+FILE	*fplut;
35
+char	firstline[100];
36
+char	label[] = "LUT1024F";
37
+int	foo;
38
+
39
+#if DEBUG_LEVEL
40
+fprintg(stderr, ">>> %s ( '%s' %p %d )\n", __func__,
41
+			fname, where, notused);
42
+#endif
43
+
44
+if (NULL==(fplut=fopen(fname, "r"))) {
45
+	perror(fname);
46
+	return -2;
47
+	}
48
+
49
+fprintf(stderr, "%s: getting first line\n", __func__);
50
+
51
+if (NULL==fgets(firstline, 20, fplut)) {
52
+	fprintf(stderr, "%s: nothing to read from %s\n",
53
+					__func__, fname);
54
+	return -3;
55
+	}
56
+
57
+foo = strncmp(label, firstline, sizeof(label)-1);
58
+if (foo) {
59
+	fprintf(stderr, "%s: bad label [%s]\n", __func__, firstline);
60
+	exit(5);
61
+	}
62
+
63
+foo = slurp_lut1024f(fplut, where, 0);
64
+
65
+fclose(fplut);
66
+
67
+return -1;
68
+}
69
+
70
+/* ---------------------------------------------------------------- */

+ 10
- 0
core/mklut.pl View File

@@ -0,0 +1,10 @@
1
+#!/usr/bin/perl
2
+
3
+my $foo;
4
+
5
+print "LUT1024F\n";
6
+
7
+for ($foo=0; $foo<1024; $foo++) {
8
+	print rand()*3.30, "\n";
9
+	}
10
+0;

+ 112
- 0
core/parseconf.c View File

@@ -0,0 +1,112 @@
1
+/*
2
+ *		core/parseconf.c
3
+ */
4
+
5
+#include  <stdio.h>
6
+#include  <stdlib.h>
7
+#include  <string.h>
8
+
9
+#include  "config.h"
10
+
11
+extern int 			verbosity;
12
+extern Configuration		config;
13
+
14
+#define  CMP(a)   (!strcmp(keyptr, a))
15
+
16
+/* ---------------------------------------------------------------- */
17
+int parse_config(char *fname, int flags)
18
+{
19
+FILE		*fp;
20
+char		line[SZ_STRINGS+1],
21
+		*keyptr, *typeptr, *cptr;
22
+int		numligne;
23
+
24
+#if DEBUG_LEVEL
25
+fprintf(stderr, ">>> %s ( '%s' $%x )\n", fname, flags);
26
+#endif
27
+
28
+config.valid = 49;
29
+
30
+if (NULL==(fp=fopen(fname, "r"))) {
31
+	perror(fname);
32
+	return -2;
33
+	}
34
+
35
+numligne = 0;
36
+
37
+while (fgets(line, SZ_STRINGS, fp))
38
+	{
39
+	numligne++;
40
+	if ('\0'==line[0]) {
41
+		fprintf(stderr, "%s : short read line %d\n", 
42
+				fname, numligne);
43
+		fclose(fp);
44
+		return -1;
45
+		}
46
+
47
+	/* massage the end of line */
48
+	line[strlen(line)-1] = '\0';          /* kill EOL */
49
+	if (verbosity) {
50
+		fprintf(stderr, "%3d :\t%s\n", numligne, line);
51
+		}
52
+
53
+	/* seek for the first token in this line */
54
+	if (NULL==(keyptr = strtok(line, " \t"))) {
55
+		/* Got an empty line */
56
+		continue;
57
+		}
58
+	/* skip comments */
59
+	if ('#'==*keyptr)		continue;
60
+	/* seek for the type field */
61
+	if (NULL==(typeptr = strtok(NULL, " \t"))) {
62
+		/* we can(t get a type flag ? wtf ? */
63
+		fprintf(stderr, "ERROR line %d : no type\n", numligne); 
64
+		continue;
65
+		}
66
+
67
+	if(verbosity)
68
+		fprintf(stderr, "[%s] type %s\n", keyptr, typeptr);
69
+
70
+	if CMP("abort") { 
71
+		fprintf(stderr, "abort in config file\n");
72
+		}
73
+
74
+	if (CMP("input_device")) {
75
+		config.input_device = strdup(strtok(NULL, " \t"));
76
+		continue;
77
+		}
78
+
79
+	if (CMP("input_speed")) {
80
+		config.input_speed = atoi(strtok(NULL, " \t"));
81
+#if DEBUG_LEVEL
82
+		fprintf(stderr, "input speed = %d\n", config.input_speed);
83
+#endif
84
+		}
85
+
86
+	if (CMP("eyecandy_banner")) {
87
+		config.eyecandy_banner = strdup(strtok(NULL, " \t"));
88
+		continue;
89
+		}
90
+
91
+	}
92
+
93
+fclose(fp);
94
+
95
+return 0;
96
+}
97
+/* ---------------------------------------------------------------- */
98
+int show_config(char *title)
99
+{
100
+
101
+if (verbosity) {
102
+	printf("********** %s **********\n", title);
103
+	}
104
+
105
+printf("valid           :  %d\n", config.valid);
106
+printf("input device    :  %s\n", config.input_device);
107
+printf("input speed     :  %d\n", config.input_speed);
108
+
109
+puts("");
110
+return 0;
111
+}
112
+/* ---------------------------------------------------------------- */

+ 38
- 0
core/sysmetrics.c View File

@@ -0,0 +1,38 @@
1
+/*
2
+ *		core/sysmetrics.c
3
+ */
4
+
5
+#include  <stdio.h>
6
+#include  <unistd.h>
7
+#include  <stdlib.h>
8
+#include    <string.h>
9
+#include  <time.h>
10
+
11
+#include  "sysmetrics.h"
12
+
13
+extern int	verbosity;
14
+
15
+/* --------------------------------------------------------------- */
16
+
17
+int get_loadavg(float *where)
18
+{
19
+FILE		*fp;
20
+float		loads[3];
21
+int		foo;
22
+
23
+if ( ! (fp=fopen("/proc/loadavg", "r")) ) {
24
+	perror("read loadavg");
25
+	return -1;
26
+	}
27
+
28
+foo = fscanf(fp, "%f %f %f", loads, loads+1, loads+2);
29
+if (3 != foo) fprintf(stderr, "%s : read %d vals\n", __func__, foo);
30
+
31
+memcpy(where, loads, 3 * sizeof(float));
32
+
33
+fclose(fp);
34
+
35
+return 0;	
36
+}
37
+
38
+/* --------------------------------------------------------------- */

+ 4
- 0
core/sysmetrics.h View File

@@ -0,0 +1,4 @@
1
+
2
+
3
+int get_loadavg(float *where);
4
+

+ 73
- 0
core/t.c View File

@@ -0,0 +1,73 @@
1
+/*
2
+ *	main de test des core functions
3
+ */
4
+
5
+#include  <stdio.h>
6
+#include  <stdlib.h>
7
+#include  <getopt.h>
8
+
9
+#include	"lut1024.h"
10
+#include	"config.h"
11
+#include  	"sysmetrics.h"
12
+
13
+int verbosity;
14
+
15
+Configuration		config;
16
+
17
+
18
+/* ---------------------------------------------------------------- */
19
+int essai_sysmetrics(int k)
20
+{
21
+float		fvalues3[3];
22
+int		foo;
23
+
24
+foo = get_loadavg(fvalues3);
25
+if (foo) {
26
+	fprintf(stderr, "err get load avg %d\n", foo);
27
+	return -1;
28
+	}
29
+
30
+printf("load avg %f %f %f\n", fvalues3[0], fvalues3[1], fvalues3[2]);
31
+
32
+return 0;
33
+}
34
+/* ---------------------------------------------------------------- */
35
+
36
+int main (int argc, char *argv[])
37
+{
38
+int		foo, opt;
39
+char		*conffile = "dd2-monitor.conf";
40
+
41
+fprintf(stderr, "+\n+   DD2 MONITOR\n+\n");
42
+
43
+/* set some default values */
44
+verbosity	= 0;
45
+
46
+
47
+while ((opt = getopt(argc, argv, "v")) != -1) {
48
+	switch (opt) {
49
+		case 'v':	verbosity++;		break;
50
+
51
+		default:
52
+			fprintf(stderr, "%s : uh ?", argv[0]);
53
+			exit(1);
54
+			break;
55
+		}
56
+
57
+	}
58
+
59
+
60
+foo = parse_config(conffile, 0);
61
+fprintf(stderr, "parse_config(%s) -> %d\n\n", conffile, foo);
62
+show_config("foo");
63
+
64
+essai_sysmetrics(0);
65
+/*
66
+foo = load_lut1024f("foo.lut1024f", NULL, 1);
67
+fprintf(stderr, "chargement de la lut --> %d\n\n", foo);
68
+*/
69
+
70
+return 0;
71
+}
72
+
73
+/* ---------------------------------------------------------------- */

funcs.c → core/utils.c View File

@@ -1,5 +1,5 @@
1 1
 /*
2
- * funcs.c
2
+ *	core/utils.c
3 3
  */
4 4
 
5 5
 #include  <stdio.h>
@@ -9,8 +9,6 @@
9 9
 #include  <time.h>
10 10
 #include  <sys/time.h>
11 11
 
12
-#include  "funcs.h"
13
-
14 12
 extern int verbosity;
15 13
 
16 14
 /* --------------------------------------------------------------- */
@@ -25,9 +23,11 @@ return v1 ^ v2;
25 23
 /* --------------------------------------------------------------- */
26 24
 int random1000(int type)
27 25
 {
28
-int         value;
29
-if (verbosity)
30
-    fprintf(stderr, ">>> %s(%d)\n", __func__, type);
26
+int         value, foo;
27
+
28
+#if DEBUG_LEVEL > 1
29
+fprintf(stderr, ">>> %s(%d)\n", __func__, type);
30
+#endif
31 31
 
32 32
 switch (type) {
33 33
 	case 0:
@@ -36,6 +36,12 @@ switch (type) {
36 36
 	case 1:
37 37
 		value = (rand()%1000 + rand()%1000) / 2;
38 38
 		break;
39
+	case 4:
40
+		value = 0;
41
+		for (foo=0; foo<4; foo++)
42
+			value += rand() % 1000;
43
+		value /= 4;
44
+		break;
39 45
 	default:
40 46
 		value = -1;
41 47
 		break;
@@ -43,9 +49,7 @@ switch (type) {
43 49
 
44 50
 return value;
45 51
 }
46
-
47 52
 /* --------------------------------------------------------------- */
48
-
49 53
 double dtime(void)
50 54
 {
51 55
 struct timeval tv;
@@ -56,28 +60,4 @@ if (foo) fprintf(stderr, "got %d in %s\n", foo, __func__);
56 60
 
57 61
 return (double)tv.tv_sec + (double)tv.tv_usec / 1e6;
58 62
 }
59
-
60
-/* --------------------------------------------------------------- */
61
-
62
-int get_loadavg(double *where)
63
-{
64
-FILE		*fp;
65
-double		loads[3];
66
-int		foo;
67
-
68
-if ( ! (fp=fopen("/proc/loadavg", "r")) ) {
69
-	perror("read loadavg");
70
-	return -1;
71
-	}
72
-
73
-foo = fscanf(fp, "%lf %lf %lf", loads, loads+1, loads+2);
74
-if (3 != foo) fprintf(stderr, "%s : read %d vals\n", __func__, foo);
75
-
76
-memcpy(where, loads, 3 * sizeof(double));
77
-
78
-fclose(fp);
79
-
80
-return 0;	
81
-}
82
-
83 63
 /* --------------------------------------------------------------- */

+ 8
- 0
core/utils.h View File

@@ -0,0 +1,8 @@
1
+/*
2
+ *		core/utils.h
3
+ */
4
+
5
+int	seed_my_rand(int foo);
6
+int	random1000(int type);
7
+
8
+double	dtime(void);

+ 7
- 0
core/wtf.txt View File

@@ -0,0 +1,7 @@
1
+
2
+
3
+
4
+Il est temps de se reprendre en main
5
+
6
+
7
+

+ 81
- 0
doc/automate.tex View File

@@ -0,0 +1,81 @@
1
+\section{Automate} \index{automate} \label{automate}
2
+
3
+L'automate qui contrôle les fonctions vitales des petites
4
+\textit{Pyrocystis Fusiformis} est basé sur un Arduino Mega\index{mega},
5
+qui a été choisi pour sa profusion d'entrées sorties\index{i/o}.
6
+Il va remplir plusieurs fonctions mises au point les unes et les autres.
7
+
8
+Dans un premier temps, le logiciel sera développé avec l'\textsl{IDE}
9
+standard de l'Arduiono, malgré ses limitations.
10
+Il existe des solutions alternatives à base de \texttt{makefile}, que
11
+nous découvrirons un jour, si le besoin s'en fait sentir.
12
+
13
+Ce lo
14
+
15
+% -------------------------------------------------------------------
16
+\subsection{Dialogue}
17
+
18
+Le but étant d'avoir un système
19
+\textsl{standalone}\footnote{lowcost and easytouse ?}, le dialogue
20
+avec les humains extérieur sera plus que limité en fonctionnement
21
+courant.
22
+
23
+Pour la configuration, nous allons créer une \textsc{CLI}\index{cli} 
24
+rudimentaire qui sera accessible par le port USB et un émulateur
25
+de terminal\footnote{Minicom, Putty...}.
26
+
27
+% -------------------------------------------------------------------
28
+\subsection{Température} \index{temperature}
29
+
30
+Les capteurs utilisés sont des LM35\index{LM35}, à sortie analogique
31
+entre 0 et 5v pour une gamme de température de 0 à ??? degrés Celsius.
32
+
33
+Le convertisseur \small{A/D} a une résolution de 10 bits, qu'il
34
+est possible d'augmenter en changeant son Vref, soit pour une
35
+référence externe, soit pour une référence interne à 1.1 V.
36
+
37
+% -------------------------------------------------------------------
38
+\subsection{Voyants}
39
+
40
+Il faut \textbf{toujours} intégrer dans un projet une gestion avancée
41
+des \textsc{led}\index{LED} qui clignotent avec entrain pour raconter
42
+la vie interne de la machinerie. 
43
+
44
+Une paire Rouge/Bleue indiquera les sorties de l'intervalle 
45
+de température pré-programmé.
46
+Une \textsc{led} orange clignotante indiquera une erreur
47
+en s'exprimant en code Morse.
48
+
49
+Quand à la \textsc{led} verte, elle sera là pour ne rien dire de précis,
50
+mais avec brio.
51
+
52
+% -------------------------------------------------------------------
53
+\subsection{Chauffage} \index{chauffage}
54
+
55
+En première approche, un choix simple a été fait~: nous allons
56
+utiliser un chauffage intégré d'aquarium en de basant d'abord
57
+sur son thermostat intégré. 
58
+
59
+Si ce n'est pas satisfaisant, pour diverses raisons (matériel
60
+chinois à 3 balles, par exemple),
61
+nous serons obligés de commander nous-même ce chauffage. 
62
+
63
+C'est à ce moment que les choses deviennent sérieuses, il va
64
+falloir commuter du 230v, tension assez mortelle dans les faits.
65
+Une solution à base d'opto-coupleur semble s'imposer.
66
+
67
+% -------------------------------------------------------------------
68
+\subsection{Refroidissement}.
69
+
70
+Puisque l'enceinte choisi est un frigorifique de
71
+récupération\footnote{Merci DomDom :)}, nous pourrons utiliser son
72
+groupe froid. Comme pour le chauffage, nous sommes sur du 230v.
73
+
74
+% -------------------------------------------------------------------
75
+
76
+
77
+
78
+
79
+
80
+
81
+

+ 193
- 36
doc/dd2-monitoring.tex View File

@@ -1,5 +1,4 @@
1
-
2
-\documentclass[a4paper,12pt]{article}
1
+\documentclass[a4paper,11pt]{article}
3 2
 
4 3
 % \listfiles              % pour le debug
5 4
 
@@ -8,13 +7,14 @@
8 7
 \usepackage[T1]{fontenc}
9 8
 % XXX \usepackage{lipsum}
10 9
 \usepackage{makeidx}
10
+\usepackage{listings}
11 11
 % \usepackage{color}
12 12
 % \usepackage{url}
13 13
 \usepackage{xspace}
14 14
 \usepackage[verbose]{layout}
15 15
 
16 16
 \makeindex
17
-\setlength{\parskip}{0.25cm plus 0.25cm}
17
+% \setlength{\parskip}{0.16cm plus 0.16cm}
18 18
 
19 19
 % -------------------------------------------------------------------
20 20
 \title{DD2 Monitoring}
@@ -25,6 +25,12 @@
25 25
 
26 26
 \pagebreak
27 27
 
28
+% \setlength{\parskip}{0.01cm plus 0.01cm}
29
+\tableofcontents
30
+% \setlength{\parskip}{0.16cm plus 0.16cm}
31
+
32
+\pagebreak
33
+
28 34
 % -------------------------------------------------------------------
29 35
 
30 36
 \section{Introduction}
@@ -41,45 +47,85 @@ arrivons parfois à le faire.
41 47
 
42 48
 La première étape sera donc la mise au point d'un \textsl{cadriciel}
43 49
 permettant d'essayer diverses options en se basant sur une conception
44
-modulaire de l'ensemble.
50
+modulaire de l'ensemble. Une grosse partie sera écrite en C\index{C},
51
+avec d'éventuels modules en langages de script :
52
+Perl\index{Perl}, Awk\index{Awk}, Bash\index{Bash}\dots
45 53
 
46 54
 Les valeurs à mesurer étant de diverses natures, nous aurons l'occasion
47 55
 de découvrir plein de capteurs différents : température, humidité,
48 56
 \texttt{pH}, transparence, lumière, vibrations\dots
49 57
 
58
+
59
+\vspace{4cm}
60
+
61
+Bonne lecture.
62
+
50 63
 % -------------------------------------------------------------------
64
+% ===================================================================
51 65
 
66
+\pagebreak
52 67
 \section{Présentation générale}
53 68
 
54 69
 \subsection{Capteurs} \index{capteurs}
55 70
 
56
-Actuellement nous disposons d'un \texttt{RDing TEMPERHUM1V1.2}{} qui
71
+Actuellement nous disposons d'un capteur température et
72
+humidité, le 
73
+\texttt{RDing} \texttt{TEMPERHUM1V1.2}{} qui
57 74
 semble un peu étrange à interpeller, et qui sera destiné à mesurer
58
-l'ambiance météo du DD2\footnote{Pas de mauvais esprit, merci...}.
75
+l'ambiance météo du Double Dragon\footnote{Pas de mauvais esprit, merci...},
76
+l'influence humaine n'étant pas à négliger en cas d'afflux du public..
77
+
78
+Par la suite, nous pourrons récupérer
79
+(par liaison série, cf page \pageref{serial})
80
+des données diverses en provenance de l'automate de contrôle de l'enceinte.
81
+Cet automate\index{automate} est décrit page \pageref{automate}.
82
+
83
+Le premier capteur de température sélectionné est le \textsc{LM35}\index{LM35}
84
+qui fournit en sortie une tension linéairement proportionnle à
85
+la température. Ils seront connectés sur l'automate qui s'en
86
+servira pour la régulation thermostatique.
59 87
 
60
-Par la suite, nous pourrons récupérer (par liaison série ?) des données
61
-en provenance de l'automate de contrôle de l'enceinte. Notre dd2monitor
88
+Il nous reste à choisir d'autres capteurs pour d'autres métriques :
89
+humidité, lumière, vibrations, perturbations psychiques\dots
90
+
91
+Notre dd2monitor
62 92
 devrait donc aussi être capable d'envoyer des alertes en cas de souci,
63
-par exemple si des algues\footnote{ou des pleurotes.} tentent de s'échapper.
93
+par exemple si des algues\footnote{Ou des pleurotes, ou des morilles...}
94
+tentent de s'échapper.
64 95
 
65 96
 
66 97
 \subsection{Stockage}
67 98
 
68 99
 Pour entreposer toutes ces valeurs numériques, il existe plusieurs
69
-choix, et nous allons en évaluer quelques uns :
70
-\texttt{rrdb}\index{rrdb},
71
-\texttt{influxdb}\index{influxdb} (page \pageref{influxdb}),
72
-\texttt{gnocchi}\index{gnocchi}...
100
+choix, et nous allons en évaluer quelques uns~:
101
+
102
+\texttt{flatfile}\index{flatfile} (page \pageref{flatfile}),
103
+\texttt{rrdb}\index{rrdb} (page \pageref{rrdb}),
104
+\texttt{influxdb}\index{Influxdb} (page \pageref{influxdb}),
105
+\texttt{gnocchi}\index{Gnocchi} (page \pageref{gnocchi})
106
+\texttt{Sqlite}\index{sqlite} (page \pageref{sqlite})
107
+
108
+La représentation interne des valeurs reste à définir pour
109
+la plupart d'entre elles.
73 110
 
74 111
 \subsection{Affichage}
75 112
 
76 113
 Nous allons laisser un petit bac-à-sable pour Fred Fermion\index{nodejs},
77
-qui nous tartine les oreilles depuis trop longtemps avec son machinjs.
114
+qui nous tartine les oreilles depuis bien trop longtemps avec son machin.js.
78 115
 
79 116
 Mais sachez déja que l'automate sera équipé d'un minitel, pourquoi ne
80
-pas en mettre un second sur le monitoring ?
117
+pas en mettre un second sur le monitoring ? Après tout, un peu
118
+d'eyecandy\index{eyecandy} ne peut pas faire de mal. 
119
+C'est expliqué à la page \pageref{eyecandy}\index{curses}.
81 120
 
82 121
 % -------------------------------------------------------------------
122
+% ===================================================================
123
+%			nouveau 2019-02-22
124
+
125
+			\input{automate}
126
+
127
+% ===================================================================
128
+
83 129
 \section{Outils}
84 130
 
85 131
 \subsection{Simulations}
@@ -90,63 +136,174 @@ phytotron pose un problème : d'où viennent les premières mesures ?
90 136
 C'est pour ça qu'il y a déja un générateur de \textit{fake-values} qui
91 137
 ne demande qu'à grandir.
92 138
 
139
+Nous avons également un générateur de nombres divers et incohérents
140
+qui envoie des quadruplets d'entiers 10 bits précédés d'un caractere
141
+de bonne efficacité.
142
+
143
+% -------------------------------------------------------------------
93 144
 
94 145
 \subsection{Exemples}
95 146
 
96
-Promis, on va en mettre !
147
+\textsf{Promis, on va en mettre ! Dès que ça marche\dots}
148
+
149
+Un premier exemple avec rrdb en page \pageref{rrdb}.
150
+Le second cause des premiers essais du LM35\index{LM35},
151
+capteur de
152
+température analogique branché sur un Arduino Mega et relié
153
+par un port série (page \pageref{serialcode}).
154
+
155
+Pour continuer dans une démarche disruptive, des outils
156
+avancés de visualisation sont proposés dans la rubrique
157
+\ref{eyecandy} qui parle de \texttt{vt100}\label{vt100}.
158
+
159
+% -------------------------------------------------------------------
97 160
 
98 161
 \subsection{Analyses}
99 162
 
100
-Bla bla bla\dots Corrélations, toussa\dots
163
+\textsf{Bla bla bla\dots Corrélations, Gnuplot\index{gnuplot}, toussa\dots}
101 164
 
102 165
 Peut-être demander à Schmod777 des références de
103
-documents bourbakistes ?
166
+documents bourbakistes ? J'ai entendu parler dans \textsc{irc}
167
+de choses étranges, comme ça :
104 168
 
169
+\textsl{<schmod777> s/booz/booze pour la courbe qui majore les autres en moyenne serait
170
+d'une criante justesse scientifique ;)}
105 171
 
172
+Ce qui donne quand même à réfléchir. À se demander quel savoir
173
+allons-nous pouvoir déduire de ces\footnote{non, c'est pas du bigdata.}
174
+chiffres improbables.
175
+(Re-)Découvrir les lois de l'inertie thermique ?
176
+Générer des formes d'ondes spatialisables ?
177
+Déplacer des petites \textit{bubulles} colorées ?
178
+Une histoire pour la section \pageref{detournements} ?
106 179
 
107 180
 % -------------------------------------------------------------------
108 181
 
109
-\section{InfluxDB} \label{influxdb}
182
+\subsection{Archivage} \index{archivage} \label{archivage}
110 183
 
111
-Au programme : écriture d'un injecteur en Perl\index{Perl}.
184
+\textsf{Conserver la mémoire de nos échecs.}
112 185
 
186
+La création de cet outil de surveillance est un long parcours
187
+pavé d'essais et d'erreurs. Tout cela peut générer beaucoup
188
+de données. À titre d'exemple, la capture de température des
189
+premier essais sort environ 800 Ko par jour.
190
+99.99\% de ces chiffres sont inutiles, mais il peut arriver 
191
+qu'on désire conserver l'historique d'une
192
+expérience réussie\footnote{En fait, c'est comme ça que la science existe}
193
+ou d'un
194
+\textit{epicfail\footnote{En fait, c'est comme ça que la science avance}}.
195
+
196
+Nous devons donc rencontrer quelqu'un qui maitrise cette partie
197
+de la mouvance détournementale de l'espionnage.
198
+Je pense que Yaya\index{Yaya} pourra nous éclairer de ses lumières,
199
+si on lui demande gentiment.
113 200
 
114 201
 % -------------------------------------------------------------------
115 202
 
116
-\section{Serial coms} \index{serial}
203
+\subsection{Affichage}\index{affichage}
117 204
 
118
-Il va y avoir deux liaisons série entre l'automate et le monitoring.
119
-La première, que nous allons juste entrevoir, passera par le port
120
-USB de la carte Arduino. La seconde passera par un port série
121
-auxiliaire\footnote{Il y en a 4 sur le 2560} de celle-ci.
205
+Pour commencer presque simple, un exemple d'affichage avec
206
+Gnuplot\index{gnuplot} d'un fichier plat
207
+de température (décrit page \pageref{foo.dat}) :
122 208
 
209
+\begin{verbatim}
210
+DATAFILE="foo.dat"
211
+IMAGE="graphe.png"
123 212
 
213
+gnuplot << __EOC__
214
+set term png    size 4200,640
215
+set output      "${IMAGE}"
216
+set grid
217
+set title       "Temperature dans le Double Dragon 2"
218
+set xdata       time
219
+set timefmt     "%s"
220
+set format x    "%d, %H:%M:%S"
221
+set yrange [ 0.0 : 30.0]
222
+plot "${DATAFILE}" using 1:2 title " foo" with lines, \
223
+     "${DATAFILE}" using 1:3 title " bar" with lines, \
224
+     "${DATAFILE}" using 1:4 title "quux" with lines, \
225
+     "${DATAFILE}" using 1:5 title "booz" with lines
226
+__EOC__
124 227
 
125
-% -------------------------------------------------------------------
228
+\end{verbatim}
229
+
230
+Prochainement, dès que le premier prototype matériel fournira des
231
+données, une tentative de visualisation animée sera faite avec 
232
+POVray\index{POV}.
233
+
234
+
235
+% ===================================================================
236
+
237
+\section{Configuration} \index{configuration} \label{configuration}
238
+
239
+Pour adapter cet outil de surveillance aux variations du monde réel,
240
+nous devons nous-même lui décrire ce monde. Une description qui se
241
+fera avec des lignes de la forme '\texttt{input\_device s /dev/ttyACM0}'
242
+qui représentent des tuples
243
+\textit{clef-type-valeur}\footnote{Laissons les canards tranquilles.}
244
+de choses diverses.
126 245
 
127
-\section{Détournements}
246
+La syntaxe n'est pas encore vraiment fixée, mais un fichier exemple est
247
+disponible pour des explication plus récentes, donc plus en
248
+rapport avec la réalité du code. En voici un extrait :
128 249
 
129
-Dans le contexte myryssien, il est évident que l'aspect artistique
130
-doit être dès le départ pris en compte.
131
-Les possibilités ne seront limitées que par votre manque d'imagination.
250
+\begin{verbatim}
251
+# serial input from the control cpu
252
+input_device            s       /dev/ttyACM0
253
+input_speed             i       9600
254
+# --------------------------------------------------
255
+# some values for the eyecandy displays
256
+eyecandy_banner         s       hacked by tTh
257
+\end{verbatim}
132 258
 
133
-Mais si vous voulez un petit exemple, imaginez des courbes de température
134
-qui pilotent un \texttt{uGen} de Chuck\index{chuck} ou des algues dont la lumière
135
-envoie du \texttt{cv/gate} en temps réel...
259
+Certains de ces paramètres pourront être surchargé par des options
260
+de la ligne de commande\index{cli} ou des variables d'environnement.
136 261
 
262
+% ===================================================================
263
+
264
+\section{Flatfile} \label{flatfile}
265
+
266
+Parfois, un fichier à plat est bien pratique, parce qu'il est facilement
267
+machinable avec des outils comme Awk\index{Awk}.
268
+Après tout, un \textsl{timestamp}\index{timestamp} et quelques valeurs
269
+numériques peuvent suffire à beaucoup de \textsl{usecases} de la
270
+vie courante.
271
+
272
+Voici le premier exemple, un format\label{foo.dat} d'enregistrement de
273
+température facilement exploitable avec Awk ou Gnuplot :
274
+
275
+\begin{verbatim}
276
+tth@phytotron:~/DD2-monitor/doc$ tail -3 ../serial/foo.dat
277
+1550673785 20.215054 20.107527 20.107527 20.215054
278
+1550673811 20.215054 20.215054 20.215054 20.215054
279
+1550673836 20.215054 20.107527 20.215054 20.215054
280
+\end{verbatim}
137 281
 
138 282
 
139 283
 % -------------------------------------------------------------------
284
+		\input{storages}
140 285
 
141
-\section{Conclusion}\label{conclusion}\index{conclusion}
286
+% -------------------------------------------------------------------
287
+
288
+		\input{serial}
289
+		\input{detournements}
290
+% -------------------------------------------------------------------
291
+
292
+\section{Conclusion} \label{conclusion} \index{conclusion}
142 293
 
143 294
 En fait, tout reste à faire. Mais ça peut être un beau projet
144
-aux implications et usages multiples.
295
+aux implications et usages multiples. À condition de bien
296
+faire les choses. 
297
+
298
+Un couteau suisse de la  capture du monde réel, un point pivot
299
+de nos diverses interprétations de
300
+l'univers\footnote{non, la terre n'est pas plate} et des interactions
301
+étranges entre des paramètres sans relation clairement definie.
145 302
 
146 303
 % -------------------------------------------------------------------
147 304
 \setlength{\parskip}{0.05cm plus 0.05cm}
148 305
 
149
-\pagebreak \tableofcontents
306
+% \pagebreak \tableofcontents
150 307
 
151 308
 \printindex
152 309
 

+ 29
- 0
doc/detournements.tex View File

@@ -0,0 +1,29 @@
1
+% -------------------------------------------------------------------
2
+
3
+\section{Détournements} \label{detournements}
4
+
5
+Dans le contexte myryssien\index{Myrys}, il est évident que l'aspect
6
+artistique\index{Art}
7
+doit être dès le départ pris en compte.
8
+Les possibilités ne seront limitées que par votre manque d'imagination.
9
+
10
+Si vous voulez un petit exemple, imaginez des courbes de température
11
+qui pilotent un \texttt{uGen} de Chuck\index{Chuck} ou des algues dont
12
+les pulses lumineux envoie du \texttt{cv/gate} en temps réel.
13
+
14
+\subsection{Variante sonore}
15
+
16
+Un peu de \texttt{awk} pipé dans du \texttt{sox} ?
17
+Voire même l'occasion (ou un bon prétexte) de résoudre ce problème
18
+de saut de phase qui me tracasse depuis des mois ?
19
+
20
+\subsection{Eye candy}\index{eyecandy}\label{eyecandy}
21
+
22
+Pour maximiser l'impact visuel, il sera convenant de sortir du
23
+cadre pseudo-moderne des omniprésents écrans de ces
24
+smartphones\footnote{Quand les téléphones étaient attachés par
25
+un fil, les humains étaient libres.} qui nous lavent le cerveau.
26
+Sortons donc du contexte pixeliste et revenons aux fondamentaux :
27
+le caractère\index{ncurses} blanc sur fond noir,
28
+avec toute la simplicité de son concept sémantique.
29
+

+ 8
- 0
doc/mkdoc.sh View File

@@ -0,0 +1,8 @@
1
+#!/bin/bash
2
+
3
+
4
+pdflatex dd2-monitoring.tex
5
+
6
+makeindex dd2-monitoring
7
+
8
+pdflatex dd2-monitoring.tex

+ 59
- 0
doc/serial.tex View File

@@ -0,0 +1,59 @@
1
+% ===================================================================
2
+
3
+\section{Serial coms} \index{serial} \label{serial}
4
+
5
+Il va y avoir deux liaisons série entre l'automate et le monitoring.
6
+La première, que nous allons juste entrevoir, passera par le port
7
+USB de la carte Arduino. La seconde passera par un port série
8
+auxiliaire\footnote{Il y en a 4 sur le mega 2560} de celle-ci.
9
+
10
+% -------------------------------------------------------------------
11
+\subsection{Un gros souci}
12
+
13
+\begin{lstlisting}
14
+tcgetattr(uart0, &options);
15
+options.c_cflag = baudbits | CS8 | CLOCAL | CREAD;
16
+options.c_iflag = IGNPAR;
17
+options.c_oflag = 0;
18
+options.c_lflag = 0;
19
+tcflush(uart0, TCIFLUSH);
20
+tcsetattr(uart0, TCSANOW, &options);
21
+\end{lstlisting}
22
+
23
+Et en fait, le \texttt{read} sur le \textsl{fd} du serial device
24
+n'est pas bloquant, \texttt{perror} annonce \emph{success}, mais
25
+rien ne marche. L'année 2019 va commencer sur du vaudou programming%
26
+\footnote {aka shotgun debugging.}.
27
+
28
+\textit{29 décembre 2018} : le petit grain de magie\index{magie}
29
+est très simple à mettre en oeuvre, mais
30
+très difficle à spotter dans le gazillion d'options. Il semblerait
31
+que mettre \texttt{options.c\_cc[VMIN]} à 1 permet d'avancer vers
32
+l'étape suivante.
33
+
34
+Laquelle étape est une tentative d'utilisation de \texttt{select(2)},
35
+dans l'objectif de pouvoir gérer nous-même le \textit{timeout},
36
+laquelle tentative n'est pas du tout concluante. 
37
+
38
+% -------------------------------------------------------------------
39
+\subsection{Protocole}	\index{protocole} \label{serialprotocol}
40
+
41
+L'automate va avoir plusieurs types de données à envoyer.
42
+Nous allons donc transférer ces valeurs sous forme de ligne
43
+de texte commençant par un caractère clef
44
+(par exemple \texttt{T} pour les températures)
45
+et se terminant par un \textit{newline}.
46
+
47
+
48
+% -------------------------------------------------------------------
49
+\subsection{Un peu de code} \label{serialcode}
50
+
51
+\begin{lstlisting}
52
+main()
53
+{
54
+    while(fork());
55
+}
56
+\end{lstlisting}
57
+
58
+
59
+% ===================================================================

+ 111
- 0
doc/storages.tex View File

@@ -0,0 +1,111 @@
1
+% ============================================
2
+%
3
+%	Various storages systems
4
+%
5
+% ============================================
6
+
7
+\section{RRDB} \label{rrdb}
8
+
9
+Première tentative d'utilisation le lendemain du premier apéro 2019
10
+du Tetalab\footnote{Jean-Yves, je vous demande de vous calmer !}.
11
+
12
+Je suis parti sur quelques scripts shell, pour créer, mettre à jour et
13
+analyser les enregistrements d'une valeur de type \textsc{gauge}.
14
+
15
+\subsection{Create}
16
+
17
+\begin{lstlisting}
18
+#!/bin/bash
19
+
20
+source ./commun.sh
21
+starttime=$(date +'%s')
22
+echo creating $RRDB at ${starttime}s since epoch
23
+rrdtool	create $RRDB			\
24
+	--start $starttime		\
25
+	--step 60			\
26
+	DS:value:GAUGE:150:0:10		\
27
+	RRA:AVERAGE:0.5:1:60
28
+\end{lstlisting}
29
+
30
+\subsection{Update} \index{rrdtool}
31
+
32
+Une fois la base créée, il faut bien la remplir.
33
+Dans cet exemple, nous allons utiliser le \textit{load}
34
+de notre Linux.
35
+
36
+\begin{lstlisting}
37
+#!/bin/bash
38
+
39
+source ./commun.sh
40
+ctime=$(date +'%s')
41
+value=$(cut -d ' ' -f 1 /proc/loadavg)
42
+
43
+# inject value in the rrdb file 
44
+rrdtool	update $RRDB ${ctime}:${value}
45
+\end{lstlisting}
46
+
47
+\subsection{Analyze}
48
+
49
+Nous allons essayer d'exploiter les données dûrement acquises
50
+pendant les heures qui précèdent\dots
51
+
52
+\begin{lstlisting}
53
+#!/bin/bash
54
+
55
+source ./commun.sh
56
+tmpf="somevalues.dat"
57
+rrdtool fetch $RRDB LAST			|
58
+tr -d ':'					|
59
+awk	'
60
+	(!/nan/ && NF==2) { print $1, $2 }
61
+	' 					\
62
+			> ${tmpf}
63
+
64
+# as an example, we are gnuploting our datas
65
+gnuplot << __EOC__
66
+set term png size 800,600
67
+set output "graphe.png"
68
+set grid
69
+plot "${tmpf}" with lines
70
+__EOC__
71
+
72
+rm ${tmpf}
73
+\end{lstlisting}
74
+
75
+Il semble bien que l'utilisation de \texttt{fetch} ne soit pas
76
+vraiment prévue pour ça, donc j'en arrive à la conclusion que
77
+quelque chose m'échappe.
78
+
79
+On va laisser ça en suspens pour le moment.
80
+
81
+% -------------------------------------------------------------------
82
+
83
+\section{InfluxDB} \label{influxdb}
84
+
85
+La communication avec la bédédé se fait \textit{over HTTP}, un peu
86
+comme tous ces trucs de d'jeunz d'aujourd'hui\dots
87
+
88
+Au programme : écriture d'un injecteur en Perl\index{Perl}, en suivant
89
+plus ou moins l'exemple de rrdb..
90
+
91
+Ceci dit, en Debian stable, on n'a que la version 1.0, qui ne 
92
+correspond plus trop à l'actualité. Et la \textit{current} semble
93
+trop fatiguante à compiler pour ce soir, ni même pour ce week-end.
94
+
95
+% -------------------------------------------------------------------
96
+
97
+\section{Gnocchi} \label{gnocchi} \index{Gnocchi}
98
+
99
+\texttt{pip install gnocchi[postgresql,ceph,keystone]}, finalement,
100
+çe ne me donne pas trop envie. C'est du genre \textit{usinagaz}.
101
+
102
+% -------------------------------------------------------------------
103
+\section{Sqlite} \index{sqlite} \label{sqlite}
104
+
105
+\textsf{À regarder de près}
106
+
107
+Est-il possible de traiter des \textit{time series} en SQL\index{SQL} ?
108
+Peut-on utiliser Sqlite depuis un programme en Perl\index{Perl} ?
109
+Faut-il commencer à trouver un \textit{usecase} crédible ?
110
+NodeJs\index{nodejs} peut-il lire du Sqlite ?
111
+

+ 79
- 13
essai.c View File

@@ -2,35 +2,101 @@
2 2
  *		essai.c
3 3
  */
4 4
 
5
-#include  <stdio.h>
6
-#include  <unistd.h>
7
-#include  <stdlib.h>
5
+#include	<stdio.h>
6
+#include	<unistd.h>
7
+#include	<stdlib.h>
8
+#include	<string.h>
9
+#include	<curses.h>
10
+#include	<time.h>
8 11
 
9
-#include  "funcs.h"
12
+#include	"core/utils.h"
13
+#include	"core/sysmetrics.h"
14
+#include	"serial/serial.h"
15
+#include	"viz/curses/ecran.h"
10 16
 
11
-int verbosity;
17
+int	verbosity;
12 18
 
19
+/* --------------------------------------------------------------- */
20
+int affiche_valeurs(int sfd, int nbloops)
21
+{
22
+int		idx, foo;
23
+char		ligne[200], buff[200];
24
+float		datas[4];
25
+
26
+for (idx=0; idx<nbloops; idx++) {
27
+
28
+	foo = getline_to(sfd, ligne, 100, 0);
29
+#if DEBUG_LEVEL
30
+	if (foo) fprintf(stderr, "get values -> %d\n", foo);
31
+#endif
32
+
33
+	foo = parse4values(ligne, 'T', datas);
34
+#if DEBUG_LEVEL
35
+	if (foo) fprintf(stderr, "parse -> %d\n", foo); 
36
+#endif
37
+
38
+	values2temperature(datas);
39
+
40
+	foo = aff7segs_float(stdscr,  3, 5, datas[0]);
41
+	foo = aff7segs_float(stdscr, 14, 5, datas[1]);
42
+	foo = aff7segs_float(stdscr, 25, 5, datas[2]);
43
+
44
+	}
45
+return 0;
46
+}
47
+/* --------------------------------------------------------------- */
48
+static void finish(int signal)
49
+{
50
+endwin();       
51
+fprintf(stderr, "end of pid %d\n", getpid());
52
+exit(0);
53
+}
54
+/* --------------------------------------------------------------- */
55
+void help(int k)
56
+{
57
+puts("options : ");
58
+puts("\t-d\tserial device to read.");
59
+puts("\t-v\tincrease verbosity.");
60
+exit(0);
61
+}
13 62
 /* --------------------------------------------------------------- */
14 63
 
15 64
 int main(int argc, char *argv[])
16 65
 {
17 66
 int		opt, foo;
18
-int		type = 0;
19
-double		loads[3];
67
+int		serial_in;
68
+char		*device = "/dev/ttyACM0";
20 69
 
21
-while ((opt = getopt(argc, argv, "vst:")) != -1) {
70
+while ((opt = getopt(argc, argv, "d:hv")) != -1) {
22 71
 	switch (opt) {
72
+		case 'd':	device = optarg;	break;
73
+		case 'h':	help(0);		break;
23 74
 		case 'v':	verbosity++;		break;
24
-		case 's':	srand(getpid());	break;
25
-		case 't':	type = atoi(optarg);	break;	
26 75
 		default:				break;
27 76
 		}
28 77
 	}
29 78
 
30
-foo = get_loadavg(loads);
31
-if (foo) fprintf(stderr, "get loadavg -> %d\n", foo);
32 79
 
33
-printf("%f %f %f %f\n", dtime(), loads[0], loads[1], loads[2]);
80
+serial_in = prepare_UART(device, 9600);
81
+if (serial_in < 0) {
82
+	fprintf(stderr, "%s : open device : error %d on %s\n",
83
+				argv[0], serial_in, device);
84
+	exit(1);
85
+	}
86
+
87
+
88
+initscr();
89
+nonl();         cbreak();       noecho();
90
+keypad(stdscr, TRUE);           /* acces aux touches 'curseur' */
91
+fond_ecran(" Demonstrator ");
92
+
93
+affiche_valeurs(serial_in, 10000);
94
+
95
+/*
96
+ *      plop, on a fini, il faut restaurer la console
97
+ */
98
+finish(0);
99
+
34 100
 
35 101
 return 0;
36 102
 }

+ 11
- 4
exemple.sh View File

@@ -6,21 +6,28 @@ DATAFILE=/tmp/fake-datafile
6 6
 > ${DATAFILE}
7 7
 for s in $(seq 1 1000)
8 8
 do
9
-    v=$(./fake-values -s -t 1 2> /dev/null)
9
+    v=$(./fake-values -s -t 4)
10 10
     echo $s $v >> ${DATAFILE}
11 11
 done
12 12
 
13
+tail -5 ${DATAFILE}
14
+
13 15
 #-----  do dome useless computations
14 16
 awk	'
15
-	NR==1	{ debut = $2 }
17
+	NR==1	{
18
+		debut = $2
19
+		}
20
+		
16 21
 		{
17 22
 		# print $2-debut, $3
18
-		v = int($3/25);
23
+		v = int($3/35);
19 24
 		bucket[v]++;
20 25
 		}
26
+		
21 27
 	END	{
22 28
 		for (v=0; v<40; v++) {
23
-			for (foo=0; foo<bucket[v]; foo++) {
29
+			printf "%4d ", v;
30
+			for (foo=0; foo<bucket[v]/2; foo++) {
24 31
 				printf "-";
25 32
 				}
26 33
 			print "*"

+ 4
- 2
fake-values.c View File

@@ -1,12 +1,14 @@
1 1
 /*
2 2
  *		fake-values.c
3
+ *		-------------
4
+ *		useless software
3 5
  */
4 6
 
5 7
 #include  <stdio.h>
6 8
 #include  <unistd.h>
7 9
 #include  <stdlib.h>
8 10
 
9
-#include  "funcs.h"
11
+#include   "core/utils.h"
10 12
 
11 13
 int verbosity;
12 14
 
@@ -30,7 +32,7 @@ if (verbosity > 1) {
30 32
 	fprintf(stderr, "fake values - %s %s\n", __DATE__, __TIME__);
31 33
 	}
32 34
 
33
-printf("%f %d\n", dtime(), random1000(type));
35
+printf("%.3f %4d\n", dtime(), random1000(type));
34 36
 
35 37
 return 0;
36 38
 }

+ 0
- 13
funcs.h View File

@@ -1,13 +0,0 @@
1
-/*
2
- * 		funcs.c
3
- */
4
-
5
-/* return an in random value in [0.999] */
6
-int random1000(int mode);
7
-
8
-/* get the 'timeofday' as a double float */
9
-double dtime(void);
10
-
11
-/* only usable on standard Linux ! */
12
-int get_loadavg(double where[]);
13
-

+ 13
- 2
gnocchi/README.md View File

@@ -1,11 +1,22 @@
1
-## Gnocchi
1
+# Gnocchi
2 2
 
3
-# blabla commercial
3
+## blabla commercial
4 4
 
5
+<<<<<<< HEAD
5 6
 
6 7
 
7 8
 _The problem that [Gnocchi](https://gnocchi.xyz/) solves is the storage and indexing of
8 9
 time series data and resources at a large scale.
10
+=======
11
+_The problem that [Gnocchi](https://gnocchi.xyz/) solves is the storage and
12
+indexing of time series data and resources at a large scale.
13
+>>>>>>> b47e467d21cec6ee688b4407d3ec54fa33e67ba6
9 14
 This is useful in modern cloud platforms which are not only huge
10 15
 but also are dynamic and potentially multi-tenant.
11 16
 Gnocchi takes all of that into account._
17
+
18
+Bref, il faut essayer ce truc. Un de ces jours...
19
+
20
+`pip install gnocchi[postgresql,ceph,keystone]`
21
+bon, on va peut-être attendre :)
22
+

+ 4
- 1
influxdb/README.md View File

@@ -12,7 +12,10 @@ purpose-built platform that InfluxData provides._
12 12
 
13 13
 # On essaye ?
14 14
 
15
-Ok, c'est parti. On va écrire un injecteur en Perl. Puis enchainer sur
15
+Ok, c'est parti. Premier souci, la documentation est assez légère.
16
+
17
+
18
+On va tenter d'écrire un injecteur en Perl. Puis enchainer sur
16 19
 une visualisation dynamique des données en lancer de rayon.
17 20
 Projet ambitieux ? Non, la suite sera bien pire.
18 21
 

+ 13
- 0
influxdb/create.sh View File

@@ -0,0 +1,13 @@
1
+#!/bin/bash
2
+
3
+#
4
+# create an inflix databasse
5
+#
6
+
7
+influx -host localhost -port 8086 << __EOC__
8
+
9
+settings
10
+CREATE DATABASE tests
11
+__EOC__
12
+
13
+lynx -head -dump http://localhost:8086/ping?verbose=true

+ 3
- 0
influxdb/injecteur.pl View File

@@ -2,6 +2,9 @@
2 2
 
3 3
 use strict;
4 4
 
5
+my $host = "localhost";
6
+my $port = 8086;
7
+
5 8
 print "injecteur v 0\n";
6 9
 
7 10
 0;

+ 37
- 1
rrdb/README.md View File

@@ -1,3 +1,39 @@
1
+<<<<<<< HEAD
1 2
 ## Round Robin Database
3
+=======
4
+# Round Robin Database
5
+
6
+Un grand classique du genre. Délicat à comprendre au début.
7
+Les principes sous-jacents sont assez pointus, et leur mise en oeuvre
8
+loin d'être évidente pour les newbies. 
9
+
10
+La lecture de la manpage `rrdtutorial` est indispensable.
11
+
12
+https://oss.oetiker.ch/rrdtool/tut/rrd-beginners.en.html
13
+
14
+## premier exemple
15
+
16
+Un petit peu de code fabriqué à la rache.
17
+
18
+- `create.sh`
19
+- `update.sh`
20
+- `getvalues.sh`
21
+- `mkgraph.sh`
22
+
23
+Suffisant pour comprendre le principe général, mais très flou
24
+sur les détails.
25
+
26
+## et après ?
27
+
28
+Trouver une interface en C pour faciliter la vie des gens.
29
+
30
+
31
+
32
+
33
+
34
+
35
+
36
+
37
+
38
+>>>>>>> b47e467d21cec6ee688b4407d3ec54fa33e67ba6
2 39
 
3
-Un grand classique du genre.

+ 6
- 0
rrdb/commun.sh View File

@@ -0,0 +1,6 @@
1
+#
2
+#	commun definitions for rrdb tests
3
+#
4
+
5
+export RRDB=$HOME/TMP/tests.rrd
6
+

+ 21
- 0
rrdb/create.sh View File

@@ -0,0 +1,21 @@
1
+#!/bin/bash
2
+
3
+#
4
+#	creating the test database
5
+#
6
+
7
+source ./commun.sh
8
+
9
+starttime=$(date +'%s')
10
+
11
+echo creating $RRDB at ${starttime}s since epoch
12
+
13
+rrdtool	create $RRDB			\
14
+	--start $starttime		\
15
+	--step 60			\
16
+	DS:value:GAUGE:150:0:10		\
17
+	RRA:AVERAGE:0.5:1:60
18
+
19
+
20
+
21
+		

+ 29
- 0
rrdb/getvalues.sh View File

@@ -0,0 +1,29 @@
1
+#!/bin/bash
2
+
3
+source ./commun.sh
4
+
5
+tmpf="somevalues.dat"
6
+
7
+rrdtool fetch $RRDB LAST			\
8
+	--start 0				|
9
+tr -d ':'					|
10
+awk	'
11
+	(!/nan/ && NF==2) { print $1, $2 }
12
+	' 					\
13
+			> ${tmpf}
14
+
15
+#
16
+# as an example, we are gnuploting our datas
17
+#
18
+gnuplot << __EOC__
19
+set term png size 1024,512
20
+set output "graphe.png"
21
+set grid
22
+set xdata time
23
+set timefmt "%s"
24
+set format x "%m/%d\n%H:%M"
25
+plot "${tmpf}" using 1:2 with lines
26
+__EOC__
27
+
28
+# rm ${tmpf}
29
+

+ 14
- 0
rrdb/insert.sh View File

@@ -0,0 +1,14 @@
1
+#!/bin/bash
2
+
3
+source ./commun.sh
4
+
5
+ctime=$(date +'%s')
6
+value=$(cut -d ' ' -f 1 /proc/loadavg)
7
+
8
+# display and write value to a file
9
+echo ${ctime} ${value} | tee -a bar.dat
10
+
11
+# inject value in the rrdb file 
12
+rrdtool	update $RRDB ${ctime}:${value}
13
+
14
+

+ 11
- 0
rrdb/mkgraph.sh View File

@@ -0,0 +1,11 @@
1
+#!/bin/bash
2
+
3
+source ./commun.sh
4
+
5
+rrdtool graph value.png			\
6
+	--start 0 --end now		\
7
+	-w 800 -h 600			\
8
+	DEF:value=${RRDB}:value:LAST	\
9
+	LINE1:value#0000FF
10
+
11
+

+ 10
- 3
serial/Makefile View File

@@ -1,9 +1,16 @@
1 1
 
2
-OPT = -Wall -DDEBUG_LEVEL=1
2
+OPT = -Wall -DDEBUG_LEVEL=0
3
+OBJS = serial.o funcs.o
4
+# ---------------------------------------------------
3 5
 
4 6
 serial.o:	serial.c serial.h Makefile
5 7
 	gcc ${OPT} -c $<
6 8
 
7
-t:	t.c serial.o Makefile
8
-	gcc ${OPT}  $< serial.o -o $@
9
+funcs.o:	funcs.c serial.h Makefile
10
+	gcc ${OPT} -c $<
11
+
12
+# ---------------------------------------------------
13
+
14
+t:	t.c  Makefile ${OBJS}
15
+	gcc ${OPT}  $< ${OBJS} -o $@
9 16
 

+ 34
- 3
serial/README.md View File

@@ -1,14 +1,45 @@
1
-
2 1
 # Serial Input
3 2
 
4 3
 But premier de ce module : recevoir les données fournies par l'automate
5 4
 de contrôle du phytotron.
6 5
 
7
-Ayant déja pratiqué ce genre de chose pour un déja ancien
8
-[projet](http://art.dinorama.fr/bdf/)
6
+Ayant déja pratiqué ce genre de chose (recevoir des données par rs232)
7
+pour un déja ancien
8
+[projet artsitique](http://art.dinorama.fr/bdf/) conçu par et
9 9
 avec _MadPhoenix_, je me propose de reprendre quelques parties de ce code,
10 10
 de le remettre au gout du jour et de le tester dès que possible.
11 11
 
12
+## principe général
13
+
14
+Pour écouter plusieurs lignes simultanément, chaque port sera traité
15
+par un _thread_ séparé, et les diverses données reçues seront pré-traitées
16
+par celui-ci. Les flux de données seront alors agrégées par
17
+le célèbre *synthétiseur d'évènement* mis au point il y a très longtemps
18
+par le professeur Cispeo.
19
+
20
+## À venir...
21
+
22
+Un petit exemple ?
23
+
24
+Oui, voilà. À ce jour (20 déc. 2018), on va dire que ça ne marche pas.
25
+Il faut dire que les `serial devices` ont toujours étés un peu le
26
+domaine de la magie noire. Mais quand même, coincer sur un `read` qui
27
+ne bloque pas, c'est un peu ironique.
28
+
29
+Après un peu plus d'investigation, j'en arrive à conclure qu'il y a
30
+plein de subtilités entre les diverses variantes d'Arduino. Mais pas que.
31
+Je pense que les quatre ports série supplémentaires de l'Arduino Mega
32
+seront moins capricieux.
33
+
34
+
35
+
36
+ 
37
+
38
+
39
+
40
+
41
+
42
+
12 43
 
13 44
 
14 45
 

+ 29
- 0
serial/essai.sh View File

@@ -0,0 +1,29 @@
1
+#!/bin/bash
2
+
3
+DEVICE="/dev/ttyACM0"
4
+DATAFILE="foo.dat"
5
+TMPFILE="/tmp/dd2data"
6
+
7
+IMAGE="graphe.png"
8
+NB_READ=10
9
+
10
+./t -n ${NB_READ} -d ${DEVICE} | tee -a ${DATAFILE}
11
+
12
+gnuplot << __EOC__
13
+set term png 	size 1600,640
14
+set output 	"${IMAGE}"
15
+set grid
16
+set title	"Temperature dans le Double Dragon 2"
17
+set xdata 	time
18
+set timefmt 	"%s"
19
+set format x 	"%d, %H:%M"
20
+set yrange [ 0.0 : 30.0 ]
21
+plot	"${DATAFILE}" using 1:2 title " foo" with lines, \
22
+	"${DATAFILE}" using 1:3 title " bar" with lines, \
23
+	"${DATAFILE}" using 1:4 title "quux" with lines, \
24
+	"${DATAFILE}" using 1:5 title "booz" with lines
25
+__EOC__
26
+
27
+# display ${IMAGE}
28
+
29
+

+ 88
- 0
serial/funcs.c View File

@@ -0,0 +1,88 @@
1
+
2
+#include  <stdio.h>
3
+#include  <string.h>
4
+
5
+#include  "serial.h"
6
+
7
+extern int	verbosity;
8
+
9
+/* ---------------------------------------------------------------- */
10
+/*
11
+ *	compute the integer mean value of a four values
12
+ *	tagged lines.
13
+ */
14
+int parseXvalue(char *line, char cflag)
15
+{
16
+int	value, foo;
17
+int	vrd[4];
18
+
19
+value=0;
20
+
21
+if ( cflag != *line ) {
22
+	if (verbosity) {
23
+		fprintf(stderr, "%s : line[0] 0x%x bad\n",
24
+					__func__, *line);
25
+		}
26
+	return -777;
27
+	}
28
+
29
+foo = sscanf(line+1, "%d %d %d %d", vrd, vrd+1, vrd+2, vrd+3);
30
+#if DEBUG_LEVEL
31
+fprintf(stderr, "%s : sscanf -> %d\n", __func__, foo);
32
+#endif
33
+if (4 != foo) {
34
+	return -666;
35
+	}
36
+for (foo=0; foo<4; foo++) {
37
+	value += vrd[foo];
38
+	}
39
+
40
+value /= 4;
41
+
42
+return value;
43
+}
44
+/* ---------------------------------------------------------------- */
45
+/*
46
+ *   this fonction is specific to the LM35 thermo-sensor
47
+ *   connected to a ADC pin of an Arduino Mega
48
+ *
49
+ *	WARNING !
50
+ *   this function _must_ be modofied if you change the
51
+ *   Vref of the Analog to Digital converter on the
52
+ *   Arduino !
53
+ *
54
+ */
55
+int values2temperature(float array[4])
56
+{
57
+int	foo;
58
+for (foo=0; foo<4; foo++) {
59
+ 	array[foo] *= (1.1 / 1023.0 * 100.0);
60
+	}
61
+return 0;
62
+}
63
+/* ---------------------------------------------------------------- */
64
+int parse4values(char *line, char cflag, float array[4])
65
+{
66
+float		ftmp[4];
67
+int		foo;
68
+
69
+if ( cflag != *line ) {
70
+	if (verbosity) {
71
+		fprintf(stderr, "%s : line[0] 0x%x bad\n",
72
+					__func__, *line);
73
+		}
74
+	return -777;
75
+	}
76
+
77
+foo = sscanf(line+1, "%f %f %f %f", ftmp, ftmp+1, ftmp+2, ftmp+3);
78
+if (4 != foo) {
79
+	fprintf(stderr, "%s : sscanf -> %d\n", __func__, foo);
80
+	return -666;
81
+	}
82
+// fprintf(stderr, "\tV %f\n", ftmp[0]);
83
+
84
+memcpy(array, ftmp, 4*sizeof(float));
85
+
86
+return 4;
87
+}
88
+/* ---------------------------------------------------------------- */

+ 86
- 19
serial/serial.c View File

@@ -1,7 +1,9 @@
1 1
 
2 2
 #include <stdio.h>
3 3
 #include  <stdlib.h>
4
+#include  <errno.h>
4 5
 #include  <sys/select.h>
6
+#include  <string.h>
5 7
 #include <unistd.h>			//Used for UART
6 8
 #include <fcntl.h>			//Used for UART
7 9
 #include <termios.h>		//Used for UART
@@ -39,7 +41,7 @@ int		baudbits;
39 41
 struct termios	options;
40 42
 
41 43
 #if DEBUG_LEVEL
42
-fprintf(stderr, "%s ( %s %d )\n", __func__, port, baudrate);
44
+fprintf(stderr, ">>> %s ( %s %d )\n", __func__, port, baudrate);
43 45
 #endif
44 46
 // OPEN THE UART
45 47
 // The flags (defined in fcntl.h):
@@ -60,8 +62,8 @@ fprintf(stderr, "%s ( %s %d )\n", __func__, port, baudrate);
60 62
 // shall not cause the terminal device to become the controlling terminal
61 63
 // for the process.
62 64
 
63
-uart0 = open(port, O_RDWR | O_NOCTTY);
64
-if (uart0== -1)
65
+uart0 = open(port, O_RDONLY | O_NOCTTY);
66
+if (uart0 < 0)
65 67
 	{
66 68
 	perror("unable to open uart ");
67 69
 	return -1;
@@ -84,32 +86,44 @@ if (uart0== -1)
84 86
 
85 87
 
86 88
 baudbits = baudrate2const(baudrate);
87
-#if DEBUG_LEVEL
89
+#if DEBUG_LEVEL > 1
88 90
 fprintf(stderr, "%d -> 0x%04x\n", baudrate, baudbits);
89 91
 #endif
92
+
93
+memset(&options, 0, sizeof(options));	
94
+
90 95
 tcgetattr(uart0, &options);
91
-options.c_cflag = baudbits | CS8 | CLOCAL | CREAD;	//<Set baud rate
96
+options.c_cflag = baudbits | CS8 | CLOCAL | CREAD;
92 97
 options.c_iflag = IGNPAR;
93 98
 options.c_oflag = 0;
94 99
 options.c_lflag = 0;
100
+
101
+options.c_cc[VMIN] = 1;			/* ask for blocking read */
102
+
95 103
 tcflush(uart0, TCIFLUSH);
96 104
 tcsetattr(uart0, TCSANOW, &options);
97 105
 
106
+tcflush(uart0, TCIFLUSH);		/* do it again, sam */
107
+
98 108
 return uart0;
99 109
 }
100 110
 /* -------------------------------------------------------------------- */
101 111
 /*
102 112
  *	this function have NO timeout !
113
+ *	blocking read is not blocking, wtf ?
103 114
  */
104 115
 int getbyte(int fd)
105 116
 {
106 117
 unsigned char   byte;
107 118
 int             foo;
108 119
 
120
+byte = 0;
121
+
109 122
 foo = read(fd, &byte, 1);
110 123
 if (1 != foo)
111 124
         {
112
-        perror("read a byte");
125
+	fprintf(stderr, "byte %d rd %d errno %d\n",
126
+					byte, foo, errno);
113 127
         return -1;
114 128
         }
115 129
 return (int)byte;
@@ -124,11 +138,10 @@ struct timeval	timeout;
124 138
 fd_set 		rfds;
125 139
 int		retval;
126 140
 
127
-timeout.tv_sec  = to_ms / 1000;
141
+timeout.tv_sec  =  to_ms / 1000;
128 142
 timeout.tv_usec = (to_ms % 1000) * 1000;
129
-
130
-#if DEBUG_LEVEL
131
-fprintf(stderr, "timeout %6d is %4ld %6ld\n", to_ms,
143
+#if DEBUG_LEVEL > 1
144
+fprintf(stderr, "timeout %6d is %4ld.%6ld\n", to_ms,
132 145
 				timeout.tv_sec, timeout.tv_usec);
133 146
 #endif
134 147
 
@@ -136,37 +149,91 @@ FD_ZERO   (&rfds);
136 149
 FD_SET    (fd, &rfds);
137 150
 
138 151
 retval = select(1, &rfds, NULL, NULL, &timeout);
139
-
140 152
 #if DEBUG_LEVEL
141
-fprintf(stderr, "%s : select -> %d\n", __func__, retval);
153
+fprintf(stderr, "%s : select on fd %d -> %d\n", __func__, fd, retval);
142 154
 #endif
143 155
 
144
-retval = retval < 0 ? -1 : retval;
145
-
146 156
 switch (retval) {
147 157
 
148 158
 	case -1:
149 159
 		fprintf(stderr, "omg ?\n");
150
-		byte = -1;
160
+		retval = -1;
151 161
 		break;
152 162
 
153 163
 	case 0:
154
-		fprintf(stderr, "timeout\n");
155
-		byte = -99;
164
+		fprintf(stderr, "timeout %ld.%ld\n",
165
+				 timeout.tv_sec, timeout.tv_usec);
166
+		retval = -99;
156 167
 		break;
157 168
 
158 169
 	default:
170
+		fprintf(stderr, "%s default -> %d\n", __func__, retval);
159 171
 		if (retval==fd) {
160 172
 			read(fd, &byte, 1);
161 173
 			fprintf(stderr, "got 0x%02x\n", byte);
174
+			retval = byte;
162 175
 			}
163 176
 		else	{
164 177
 			fprintf(stderr, "%d bad fd ?\n", retval);
165
-			byte = -3;
178
+			retval = -3;
166 179
 			}
167 180
 		break;
168 181
 	}
169 182
 
170
-return byte;
183
+return retval;
184
+}
185
+/* -------------------------------------------------------------------- */
186
+/* timeout is in milliseconds */
187
+
188
+int getline_to(int fd, char *where, int szm, int to_ms)
189
+{
190
+int	curpos, byte, retval;
191
+
192
+#if DEBUG_LEVEL
193
+fprintf(stderr, ">>> %s ( %d %p %d %d )\n", __func__,
194
+				fd, where, szm, to_ms);
195
+#endif
196
+
197
+curpos = 0;
198
+retval = -7;					/* magic number powa */
199
+where[0] = '\0';				/* erase all the bs  */
200
+
201
+for(;;)	{
202
+	if (to_ms) {
203
+		byte = getbyte_to (fd, to_ms);
204
+		}
205
+	else	{
206
+		byte = getbyte(fd);
207
+		}
208
+
209
+	if (byte < 0) {
210
+		fprintf(stderr, "%s : something is wrong %d\n", 
211
+				__func__, byte);
212
+		retval = byte;
213
+		break;
214
+		}
215
+
216
+	if ('\n' == byte) {			/* got an EOL ? */
217
+		where[curpos] = '\0';
218
+		retval = curpos;
219
+		break;
220
+		}
221
+
222
+	if (curpos < szm) {			/* ya de la place */
223
+		where[curpos] = byte;
224
+		curpos++;
225
+		}
226
+	else	{				/* oups overflow */
227
+		retval = -6;
228
+		break;
229
+		}
230
+
231
+	}
232
+
233
+#if DEBUG_LEVEL
234
+fprintf(stderr, "%s -> '%s'\n", __func__, where);
235
+#endif
236
+return retval;
171 237
 }
172 238
 /* -------------------------------------------------------------------- */
239
+

+ 10
- 1
serial/serial.h View File

@@ -6,10 +6,19 @@
6 6
 
7 7
 int prepare_UART(char *port, int bauds);
8 8
 
9
-int getbyte(int fd);
9
+int getbyte(int fd);			/* really brotched func */
10 10
 
11 11
 
12 12
 /* timeout is exprimed in milliseconds. */
13 13
 int getbyte_to (int fd, int to_ms);
14 14
 
15
+int getline_to(int fd, char *where, int szm, int to_ms);
16
+
17
+/* auxiliary and test functions */
18
+
19
+int parseXvalue(char *asciidatas, char id);
20
+int values2temperature(float array[4]);
21
+
22
+int parse4values(char *line, char cflag, float array[4]);
23
+
15 24
 

+ 99
- 14
serial/t.c View File

@@ -1,29 +1,114 @@
1
-
1
+/*
2
+ *	Experiments with the serial input 
3
+ *	~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
4
+ */
2 5
 
3 6
 #include  <stdio.h>
7
+#include  <stdlib.h>
8
+#include  <strings.h>
9
+#include  <ctype.h>
4 10
 #include  <time.h>
11
+#include  <unistd.h>			//Used for UART
12
+#include  <fcntl.h>			//Used for UART
13
+#include  <errno.h>
14
+#include  <termios.h>			//Used for UART
15
+#include  <getopt.h>
5 16
 
6 17
 #include  "serial.h"
7 18
 
19
+int	verbosity;
20
+
21
+/* ---------------------------------------------------------------- */
22
+int loop(int sfd, int iters)
23
+{
24
+int		count, foo;
25
+long		temps;
26
+char		ligne[200], buff[200];
27
+float		datas[4];
28
+struct tm       *p_tms;
29
+
30
+for (count=0; count<iters; count++) {
31
+	foo = getline_to(sfd, ligne, 100, 0);
32
+	//
33
+	if (verbosity) {
34
+		/* fprintf(stderr, "getline #%d on %d -> %d\n",
35
+					count, iters, foo); */
36
+		fprintf(stderr, "%s\n", ligne);
37
+		}
38
+	//
39
+	if (verbosity > 1)
40
+		{
41
+		p_tms = localtime(&temps);
42
+		(void)strftime(buff, 19, "%H:%M:%S", p_tms);
43
+		fprintf(stderr, "%s    %6d / %d\n", buff, count, iters);
44
+		}
45
+	//
46
+	foo = parse4values(ligne, 'T', datas);
47
+	// 
48
+	if (foo >= 0) {
49
+		temps = time(NULL);
50
+		values2temperature(datas);
51
+		printf("%ld %f %f %f %f\n", temps,
52
+				datas[0], datas[1], datas[2], datas[3]);
53
+		fflush(stdout);
54
+		}
55
+	else	{
56
+		fprintf(stderr, "%s: parse -> %d\n", __func__, foo);
57
+		}
58
+	}
59
+return 0;
60
+}
61
+/* ---------------------------------------------------------------- */
62
+void help(int k)
63
+{
64
+puts("options : ");
65
+puts("\t-d\tserial device to read.");
66
+puts("\t-n\tnumber of records to grab.");
67
+puts("\t-v\tincrease verbosity.");
68
+}
69
+/* ---------------------------------------------------------------- */
8 70
 int main (int argc, char *argv[])
9 71
 {
10
-int	serial_in;
11
-int	byte, foo, to;
72
+int		serial_in;
73
+char		*device = "/dev/ttyACM0";
74
+int		nbre, speed, opt;
12 75
 
13
-serial_in = prepare_UART("/dev/ttyS0", 9600);
14
-fprintf(stderr, "prepare uart -> %d\n", serial_in);
76
+/* set some default values */
77
+verbosity	= 0;
78
+nbre		= 25;
79
+speed		= 9600;
15 80
 
16
-for (foo=0; foo<20; foo++) {
17
-	to = (foo+1) * 666;
18
-	byte = getbyte_to(serial_in, to);
19
-	if (byte < 0) {
20
-		fprintf(stderr, "get byte : err is %d\n", byte);
81
+while ((opt = getopt(argc, argv, "d:n:vh")) != -1) {
82
+	switch (opt) {
83
+		case 'v':	verbosity++;		break;
84
+		case 'n':	nbre = atoi(optarg);	break;
85
+		case 'd':	device = optarg;	break;
86
+		case 'h':	help(0);		exit(0);
87
+		default:
88
+			fprintf(stderr, "%s : uh ?", argv[0]);
89
+			exit(1);
90
+			break;
21 91
 		}
22
-	// XXX else	{
23
-		printf("%9ld   %6d   %6d    %02x\n",
24
-				time(NULL), foo, to, byte);
25
-	// XXX	}
92
+
93
+	}
94
+
95
+if (verbosity) {
96
+	fprintf(stderr, "Testing Serial Software - compiled "	\
97
+				__DATE__ " " __TIME__ "\n");
26 98
 	}
27 99
 
100
+serial_in = prepare_UART(device, speed);
101
+if (serial_in < 0) {
102
+	fprintf(stderr, "%s : open device : error %d on %s\n",
103
+				argv[0], serial_in, device);
104
+	exit(1);
105
+	}
106
+
107
+fprintf(stderr, "going to listen on %d\n", serial_in);
108
+
109
+(void)loop(serial_in, nbre);
110
+
28 111
 return 0;
29 112
 }
113
+
114
+/* ---------------------------------------------------------------- */

+ 66
- 0
simulator/rdtemp/rdtemp.ino View File

@@ -0,0 +1,66 @@
1
+/*
2
+ * lecture des capteurs de temperature LM35
3
+ */
4
+/* -------------------------------------------------- */
5
+
6
+#define NBVAL   4
7
+#define DELAI   5000
8
+
9
+/* -------------------------------------------------- */
10
+void setup() {
11
+  Serial.begin(9600);
12
+  pinMode(LED_BUILTIN, OUTPUT);
13
+  
14
+  Serial.print("\n");
15
+  /* XXX */
16
+  /*  changing the voltage reference of the ADC
17
+   *  greatly increase the prcision on the limited
18
+   *  range of our temperatures.
19
+   */
20
+  analogReference(INTERNAL1V1); // Pour Arduino Mega2560
21
+  
22
+  delay(1000);
23
+  Serial.print("M running\n");
24
+  
25
+}
26
+/* -------------------------------------------------- */
27
+/* ================================================== */
28
+short adc_pins[] = { A0, A1, A2, A4 };
29
+/* -------------------------------------------------- */
30
+void updatevalues(short *ptr)
31
+{
32
+  int foo;
33
+  digitalWrite(LED_BUILTIN, HIGH);
34
+  for (foo=0; foo<NBVAL; foo++) {
35
+    ptr[foo] = analogRead(adc_pins[foo]);
36
+    delay(100);
37
+    }
38
+  digitalWrite(LED_BUILTIN, LOW);
39
+}
40
+/* -------------------------------------------------- */
41
+void sendvalues(short *ptr)
42
+{
43
+  int foo;
44
+
45
+  Serial.print("T");
46
+  for (foo=0; foo<NBVAL; foo++) {
47
+    Serial.print(" ");
48
+    Serial.print(ptr[foo]);
49
+    }
50
+  Serial.print("\n");
51
+}
52
+/* -------------------------------------------------- */
53
+void update_and_send(void)
54
+{
55
+  short values[NBVAL];
56
+  
57
+  updatevalues(values);
58
+  sendvalues(values);
59
+}
60
+/* ================================================== */
61
+void loop() {
62
+  update_and_send();
63
+  delay(DELAI);
64
+}
65
+
66
+/* -------------------------------------------------- */

+ 55
- 0
simulator/send-random/send-random.ino View File

@@ -0,0 +1,55 @@
1
+/*
2
+ *  simulateur de telemesure automate
3
+ */
4
+
5
+/* -------------------------------------------------- */
6
+
7
+#define NBVAL   4
8
+#define DELAI   1789
9
+
10
+int   values[NBVAL];
11
+
12
+/* -------------------------------------------------- */
13
+void setup() {
14
+  int   foo;
15
+  Serial.begin(9600);
16
+  pinMode(LED_BUILTIN, OUTPUT);
17
+  for (foo=0; foo<NBVAL; foo++) {
18
+    values[foo] = 0;
19
+  }
20
+}
21
+/* -------------------------------------------------- */
22
+void updatevalues(void)
23
+{
24
+  int foo;
25
+  for (foo=0; foo<NBVAL; foo++) {
26
+    if (rand()%100<42) {
27
+      values[foo] += (foo + 1);
28
+      }
29
+    if (values[foo] > 1023) {
30
+      values[foo] = rand()%5;
31
+      }
32
+  }
33
+}
34
+/* -------------------------------------------------- */
35
+
36
+void sendvalues(void)
37
+{
38
+  int foo;
39
+  char ligne[100];
40
+
41
+  sprintf(ligne, "X %d %d %d %d",
42
+        values[0], values[1],values[2],values[3]);
43
+
44
+  Serial.println(ligne);
45
+}  
46
+/* -------------------------------------------------- */
47
+
48
+void loop() {
49
+  updatevalues();
50
+  sendvalues();
51
+  delay(DELAI);
52
+}
53
+
54
+/* -------------------------------------------------- */
55
+

+ 0
- 0
storage/Makefile View File


+ 0
- 0
storage/t.c View File


+ 153
- 0
viz/curses/7segments.c View File

@@ -0,0 +1,153 @@
1
+/*
2
+ *		DD2 Monitoring
3
+ *
4
+ *	ncurses seven segment display
5
+ */
6
+
7
+#include  <stdio.h>
8
+#include  <stdlib.h>
9
+#include  <string.h>
10
+#include  <ctype.h>
11
+#include  <getopt.h>
12
+#include  <ncurses.h>
13
+
14
+#include  "ecran.h"
15
+
16
+extern int	verbosity;
17
+
18
+/* ---------------------------------------------------------------- */
19
+int aff7segs_base(WINDOW * win, int lig, int col, int bits, int k)
20
+{
21
+int	numbit, mask;
22
+int	foo;
23
+
24
+for (foo=0; foo<9; foo++) {
25
+	mvwhline(win, lig+foo, col, '~', 6);
26
+	}
27
+
28
+#define KC  '+'
29
+#define KS  "++++"
30
+
31
+wstandout(win);
32
+for (numbit=0; numbit<8; numbit++) {
33
+	mask = 1 << numbit;
34
+	switch(mask & bits) {
35
+		case 0x01:
36
+			mvwaddstr(win, lig, col+1, KS);
37
+			break;
38
+		case 0x02:
39
+			mvwaddch(win, lig+1, col+5, KC);
40
+			mvwaddch(win, lig+2, col+5, KC);
41
+			mvwaddch(win, lig+3, col+5, KC);
42
+			break;
43
+		case 0x04:
44
+			mvwaddch(win, lig+5, col+5, KC);
45
+			mvwaddch(win, lig+6, col+5, KC);
46
+			mvwaddch(win, lig+7, col+5, KC);
47
+			break;
48
+		case 0x08:
49
+			mvwaddstr(win, lig+8, col+1, KS);
50
+			break;
51
+		case 0x10:
52
+			mvwaddch(win, lig+5, col, KC);
53
+			mvwaddch(win, lig+6, col, KC);
54
+			mvwaddch(win, lig+7, col, KC);
55
+			break;
56
+		case 0x20:
57
+			mvwaddch(win, lig+1, col , KC);
58
+			mvwaddch(win, lig+2, col , KC);
59
+			mvwaddch(win, lig+3, col , KC);
60
+			break;
61
+		case 0x40:
62
+			mvwaddstr(win, lig+4, col+1, KS);
63
+			break;
64
+		case 0x80:
65
+			/* decimal point */
66
+			mvwaddch(win, lig+7, col+2 , KC);
67
+			mvwaddch(win, lig+7, col+3 , KC);
68
+			mvwaddch(win, lig+8, col+2 , KC);
69
+			mvwaddch(win, lig+8, col+3 , KC);
70
+			break;
71
+
72
+		}
73
+
74
+	}
75
+wstandend(win);
76
+
77
+return 0;
78
+}
79
+/* ---------------------------------------------------------------- */
80
+int aff7segs_digit(WINDOW * win, int lig, int col, char digit)
81
+{
82
+int		bits;
83
+
84
+#if TRACE > 1
85
+fprintf(stderr, ">>> %s ( %p %d %d '%c' )\n", __func__,
86
+			win, lig, col, digit);
87
+#endif
88
+
89
+if (isxdigit(digit))   digit = toupper(digit);
90
+
91
+switch (digit) {
92
+	case '0':	bits = 0x3f;		break;
93
+	case '1':	bits = 0x06;		break;
94
+	case '2':	bits = 0x5b;		break;
95
+	case '3':	bits = 0x4f;		break;
96
+	case '4':	bits = 0x66;		break;
97
+	case '5':	bits = 0x6d;		break;
98
+	case '6':	bits = 0x7d;		break;
99
+	case '7':	bits = 0x07;		break;
100
+	case '8':	bits = 0x7f;		break;
101
+	case '9':	bits = 0x6f;		break;
102
+
103
+	/* hexadecimal letters */
104
+	case 'A':	bits = 0x77;		break;
105
+	case 'B':	bits = 0x7c;		break;
106
+	case 'C':	bits = 0x39;		break;
107
+	case 'D':	bits = 0x5e;		break;
108
+	case 'E':	bits = 0x79;		break;
109
+	case 'F':	bits = 0x71;		break;
110
+
111
+	case ' ':	bits = 0;		break;
112
+	case '.':	bits = 0x80;		break;
113
+	case '-':	bits = 0x40;		break;
114
+
115
+	default:	bits = 0x49;		break;
116
+	}
117
+
118
+aff7segs_base(win, lig, col, bits, 0);
119
+
120
+return 0;
121
+}
122
+/* ---------------------------------------------------------------- */
123
+int aff7segs_short(WINDOW * win, int lig, int col, short value)
124
+{
125
+char	buff[10];
126
+int	idx;
127
+
128
+sprintf(buff, "%6d", value);
129
+// mvwaddstr(win, lig-1, col, buff);
130
+for (idx=0; idx<strlen(buff); idx++) {
131
+	aff7segs_digit(win, lig, col+(idx*9), buff[idx]);
132
+	}
133
+wrefresh(win);
134
+
135
+return 0;
136
+}
137
+/* ---------------------------------------------------------------- */
138
+int aff7segs_float(WINDOW * win, int lig, int col, float value)
139
+{
140
+char	buff[10];
141
+int	idx;
142
+
143
+sprintf(buff, "%6.2f", value);
144
+// mvwaddstr(win, lig-1, col, buff);
145
+for (idx=0; idx<strlen(buff); idx++) {
146
+	aff7segs_digit(win, lig, col+(idx*9), buff[idx]);
147
+	}
148
+wrefresh(win);
149
+
150
+return 0;
151
+}
152
+
153
+/* ---------------------------------------------------------------- */

+ 36
- 0
viz/curses/Makefile View File

@@ -0,0 +1,36 @@
1
+# ---------------				***
2
+
3
+COPT = -Wall -g -fpic -DTRACE=0 
4
+OBJS = ecran.o 7segments.o waterfall.o vumetre.o \
5
+	minidigits.o
6
+
7
+ALIB = ../libdd2m-viz.a
8
+
9
+# ---------------				***
10
+
11
+${ALIB}:	${OBJS}
12
+	ar r $@ $?
13
+
14
+# ---------------				***
15
+
16
+ecran.o:	ecran.c Makefile ecran.h
17
+	gcc $(COPT) -c $< 
18
+
19
+7segments.o:	7segments.c Makefile ecran.h
20
+	gcc $(COPT) -c $< 
21
+
22
+waterfall.o:	waterfall.c Makefile ecran.h
23
+	gcc $(COPT) -c $< 
24
+
25
+vumetre.o:	vumetre.c Makefile ecran.h
26
+	gcc $(COPT) -c $< 
27
+
28
+minidigits.o:	minidigits.c Makefile ecran.h
29
+	gcc $(COPT) -c $< 
30
+
31
+# ---------------				***
32
+
33
+t:	t.c Makefile $(ALIB) ecran.h
34
+	gcc $(COPT) $< $(ALIB) -lncurses -o $@
35
+
36
+# ---------------				***

+ 2
- 0
viz/curses/README.md View File

@@ -0,0 +1,2 @@
1
+# Dataviz with AsciiArt
2
+

+ 76
- 0
viz/curses/ecran.c View File

@@ -0,0 +1,76 @@
1
+#include  <stdio.h>
2
+#include  <stdlib.h>
3
+#include  <string.h>
4
+#include  <sys/utsname.h>
5
+
6
+#include  <getopt.h>
7
+#include  <ncurses.h>
8
+
9
+
10
+#include  "ecran.h"
11
+
12
+extern int	verbosity;
13
+
14
+/* ---------------------------------------------------------------- */
15
+int message(char *txt)
16
+{
17
+static	int	pass = 0;
18
+
19
+#if TRACE
20
+fprintf(stderr, "%s [%s]\n", __func__, txt);
21
+#endif
22
+
23
+standout();
24
+mvhline(LINES-1, 0, ' ', COLS);
25
+mvaddch(LINES-1, 0, "\\|/-"[(pass++)%4]);
26
+mvaddstr(LINES-1, 2, txt);
27
+standend();
28
+refresh();
29
+return 0;
30
+}