Line data Source code
1 : /********************************************************************\
2 :
3 : Name: mhist.c
4 : Created by: Stefan Ritt
5 :
6 : Contents: MIDAS history display utility
7 :
8 : \********************************************************************/
9 :
10 : #include "midas.h"
11 : #include "msystem.h"
12 : #include "history.h"
13 : #include "mstrlcpy.h"
14 :
15 : #define CALLOC(num, type) (type*)calloc((num),sizeof(type))
16 : #define FREE(ptr) free(ptr); (ptr)=NULL;
17 :
18 : BOOL binary_time;
19 :
20 : #if 0
21 : void tmp()
22 : {
23 : time_t tm;
24 :
25 : time(&tm);
26 : tm = ss_time();
27 : hs_dump(1, (DWORD) tm - 3600, (DWORD) tm, 0, FALSE);
28 : }
29 :
30 : /*------------------------------------------------------------------*/
31 :
32 : TAG temp_tag[] = {
33 : {"Temperatures", TID_FLOAT, 100},
34 : {"Humidity", TID_FLOAT, 99},
35 : {"Pressure1", TID_FLOAT, 1},
36 : };
37 :
38 : TAG hv_tag[] = {
39 : {"HV", TID_FLOAT, 100},
40 : };
41 :
42 : float hist[200];
43 : float hv[100];
44 : TAG tag[10];
45 : void write_hist_speed()
46 : /* write some history */
47 : {
48 : DWORD start_time, act_time;
49 : int i, j, bytes;
50 :
51 : hs_define_event(1, "Temperature", temp_tag, sizeof(temp_tag));
52 : hs_define_event(2, "HV", hv_tag, sizeof(hv_tag));
53 :
54 : start_time = ss_millitime();
55 : j = bytes = 0;
56 : do {
57 : for (i = 0; i < 100; i++) {
58 : hist[i] = (float) j;
59 : hs_write_event(1, hist, sizeof(hist));
60 : hs_write_event(2, hv, sizeof(hv));
61 : }
62 :
63 : j += 2 * i;
64 : bytes += (sizeof(hist) + sizeof(hv)) * i;
65 : act_time = ss_millitime();
66 :
67 : printf("%d\n", ss_time());
68 :
69 : } while (act_time - start_time < 10000);
70 :
71 : printf("%d events (%d kB) per sec.\n", j / (act_time - start_time) * 1000,
72 : bytes / 1024 / (act_time - start_time) * 1000);
73 : }
74 :
75 : void generate_hist()
76 : /* write some history */
77 : {
78 : int i, j;
79 :
80 : hs_define_event(1, "Temperature", temp_tag, sizeof(temp_tag));
81 : hs_write_event(1, hist, sizeof(hist));
82 :
83 : hs_define_event(2, "HV", hv_tag, sizeof(hv_tag));
84 : hs_write_event(2, hv, sizeof(hv));
85 :
86 : for (i = 0; i < 10; i++) {
87 : hist[0] = (float) i;
88 : hist[1] = i / 10.f;
89 : hs_write_event(1, hist, sizeof(hist));
90 :
91 : for (j = 0; j < 100; j++)
92 : hv[j] = j + i / 10.f;
93 : hs_write_event(2, hv, sizeof(hv));
94 : printf("%d\n", ss_time());
95 : ss_sleep(1000);
96 : }
97 : }
98 : #endif
99 :
100 : /*------------------------------------------------------------------*/
101 0 : static INT query_params(MidasHistoryInterface* mh,
102 : std::string* event_name,
103 : DWORD * start_time, DWORD * end_time, DWORD * interval,
104 : char *var_name, DWORD * var_type,
105 : INT * var_n_data, DWORD * index)
106 : {
107 : DWORD status, hour;
108 : int var_index;
109 : int rd;
110 :
111 0 : time_t t = 0;
112 :
113 0 : std::vector<std::string> events;
114 0 : status = mh->hs_get_events(t, &events);
115 :
116 0 : if (status != HS_SUCCESS) {
117 0 : printf("hs_get_events() error %d\n", status);
118 0 : return status;
119 : }
120 :
121 0 : printf("Available events:\n");
122 0 : for (unsigned i = 0; i < events.size(); i++) {
123 0 : printf("%d: %s\n", i, events[i].c_str());
124 : }
125 :
126 0 : if (events.size() == 0)
127 0 : return HS_FILE_ERROR;
128 0 : else if (events.size() == 1)
129 0 : *event_name = events[0];
130 : else {
131 : int i;
132 0 : printf("\nSelect event: ");
133 0 : rd = scanf("%d", &i);
134 0 : if (rd != 1)
135 0 : return HS_FILE_ERROR;
136 0 : *event_name = events[i];
137 : }
138 :
139 0 : std::vector<TAG> tags;
140 0 : status = mh->hs_get_tags(event_name->c_str(), t, &tags);
141 :
142 0 : if (status != HS_SUCCESS) {
143 0 : printf("hs_get_tags() error %d\n", status);
144 0 : return status;
145 : }
146 :
147 0 : printf("\nAvailable variables:\n");
148 :
149 0 : for (unsigned j = 0; j < tags.size(); j++)
150 0 : if (tags[j].n_data > 1)
151 0 : printf("%d: %s[%d]\n", j, tags[j].name, tags[j].n_data);
152 : else
153 0 : printf("%d: %s\n", j, tags[j].name);
154 :
155 0 : *index = var_index = 0;
156 0 : if (tags.size() > 1) {
157 0 : printf("\nSelect variable (0..%d,-1 for all): ", (int)tags.size() - 1);
158 0 : rd = scanf("%d", &var_index);
159 0 : if (rd != 1)
160 0 : return HS_FILE_ERROR;
161 0 : if (var_index >= (int)tags.size())
162 0 : var_index = tags.size() - 1;
163 : } else {
164 0 : var_index = 0;
165 : }
166 :
167 0 : var_name[0] = 0;
168 :
169 0 : if (var_index >= 0) {
170 0 : mstrlcpy(var_name, tags[var_index].name, NAME_LENGTH);
171 0 : *var_type = tags[var_index].type;
172 0 : *var_n_data = tags[var_index].n_data;
173 :
174 0 : if (tags[var_index].n_data > 1 && tags[var_index].type != TID_STRING) {
175 0 : printf("\nSelect index (0..%d): ", tags[var_index].n_data - 1);
176 0 : rd = scanf("%d", index);
177 0 : if (rd != 1)
178 0 : return HS_FILE_ERROR;
179 : }
180 : }
181 :
182 0 : printf("\nHow many hours: ");
183 0 : rd = scanf("%d", &hour);
184 0 : if (rd != 1)
185 0 : return HS_FILE_ERROR;
186 0 : *end_time = ss_time();
187 0 : *start_time = (*end_time) - hour * 3600;
188 :
189 0 : printf("\nInterval [sec]: ");
190 0 : rd = scanf("%d", interval);
191 0 : if (rd != 1)
192 0 : return HS_FILE_ERROR;
193 0 : printf("\n");
194 :
195 0 : return HS_SUCCESS;
196 0 : }
197 :
198 : /*------------------------------------------------------------------*/
199 : #if 0
200 : INT file_display_vars(const char *file_name)
201 : {
202 : DWORD status, i, j, bytes, n, nv, ltime, n_bytes, name_size, id_size;
203 :
204 : ltime = 0;
205 : if (file_name[0]) {
206 : struct tm tms;
207 :
208 : memset(&tms, 0, sizeof(tms));
209 : tms.tm_hour = 12;
210 : tms.tm_year = 10 * (file_name[0] - '0') + (file_name[1] - '0');
211 : if (tms.tm_year < 90)
212 : tms.tm_year += 100;
213 : tms.tm_mon = 10 * (file_name[2] - '0') + (file_name[3] - '0') - 1;
214 : tms.tm_mday = 10 * (file_name[4] - '0') + (file_name[5] - '0');
215 : ltime = (DWORD) ss_mktime(&tms);
216 : }
217 :
218 : status = hs_count_events(ltime, &n);
219 : if (status != HS_SUCCESS)
220 : return status;
221 :
222 : name_size = n * NAME_LENGTH;
223 : id_size = n * sizeof(INT);
224 : char* event_name = (char*)malloc(name_size);
225 : INT* event_id = (INT*)malloc(id_size);
226 : hs_enum_events(ltime, event_name, (DWORD *) & name_size, event_id,
227 : (DWORD *) & id_size);
228 :
229 : for (i = 0; i < n; i++) {
230 : printf("\nEvent ID %d: %s\n", event_id[i], event_name + i * NAME_LENGTH);
231 : hs_count_vars(ltime, event_id[i], &nv);
232 : bytes = nv * NAME_LENGTH;
233 : n_bytes = nv * sizeof(DWORD);
234 : char* var_names = (char*)malloc(bytes);
235 : DWORD* var_n = (DWORD*)malloc(nv * sizeof(DWORD));
236 :
237 : hs_enum_vars(ltime, event_id[i], var_names, &bytes, var_n, &n_bytes);
238 : for (j = 0; j < nv; j++)
239 : if (var_n[j] > 1)
240 : printf("%d: %s[%d]\n", j, var_names + j * NAME_LENGTH, var_n[j]);
241 : else
242 : printf("%d: %s\n", j, var_names + j * NAME_LENGTH);
243 :
244 : free(var_n);
245 : free(var_names);
246 : }
247 :
248 : free(event_name);
249 : free(event_id);
250 :
251 : return HS_SUCCESS;
252 : }
253 : #endif
254 :
255 : /********************************************************************/
256 0 : static INT hs_fdump(const char *file_name, DWORD id, BOOL binary_time)
257 : /********************************************************************\
258 :
259 : Routine: hs_fdump
260 :
261 : Purpose: Display history for a given history file
262 :
263 : Input:
264 : char *file_name Name of file to dump
265 : DWORD event_id Event ID
266 : BOOL binary_time Display DWORD time stamp
267 :
268 : Output:
269 : <screen output>
270 :
271 : Function value:
272 : HS_SUCCESS Successful completion
273 : HS_FILE_ERROR Cannot open history file
274 :
275 : \********************************************************************/
276 : {
277 : int fh;
278 : INT n;
279 : time_t ltime;
280 : HIST_RECORD rec;
281 : char event_name[NAME_LENGTH];
282 :
283 : /* open file, add O_BINARY flag for Windows NT */
284 0 : fh = open(file_name, O_RDONLY | O_BINARY, 0644);
285 0 : if (fh < 0) {
286 0 : cm_msg(MERROR, "hs_fdump", "cannot open file %s", file_name);
287 0 : return HS_FILE_ERROR;
288 : }
289 :
290 : /* loop over file records in .hst file */
291 : do {
292 0 : n = read(fh, (char *) &rec, sizeof(rec));
293 0 : if (n == 0)
294 0 : break; // end of file
295 0 : if (n < 0) {
296 0 : printf("Error reading \"%s\", errno %d (%s)\n", file_name, errno, strerror(errno));
297 0 : break;
298 : }
299 0 : if (n != (int)sizeof(rec)) {
300 0 : printf("Error reading \"%s\", truncated data, requested %d bytes, read %d bytes\n", file_name, (int)sizeof(rec), n);
301 0 : break;
302 : }
303 :
304 : /* check if record type is definition */
305 0 : if (rec.record_type == RT_DEF) {
306 : /* read name */
307 0 : n = read(fh, event_name, sizeof(event_name));
308 0 : if (n != sizeof(event_name)) {
309 0 : printf("Error reading \"%s\", truncated data or error, requested %d bytes, read %d bytes, errno %d (%s)\n", file_name, (int)sizeof(rec), n, errno, strerror(errno));
310 0 : break;
311 : }
312 :
313 0 : if (rec.event_id == id || id == 0)
314 0 : printf("Event definition %s, ID %d\n", event_name, rec.event_id);
315 :
316 : /* skip tags */
317 0 : lseek(fh, rec.data_size, SEEK_CUR);
318 : } else {
319 : /* print data record */
320 : char str[32];
321 0 : if (binary_time) {
322 0 : sprintf(str, "%d ", rec.time);
323 : } else {
324 0 : ltime = (time_t) rec.time;
325 : char ctimebuf[32];
326 0 : ctime_r(<ime, ctimebuf);
327 0 : mstrlcpy(str, ctimebuf + 4, sizeof(str));
328 0 : str[15] = 0;
329 : }
330 0 : if (rec.event_id == id || id == 0)
331 0 : printf("ID %d, %s, size %d\n", rec.event_id, str, rec.data_size);
332 :
333 : /* skip data */
334 0 : lseek(fh, rec.data_size, SEEK_CUR);
335 : }
336 :
337 0 : } while (TRUE);
338 :
339 0 : close(fh);
340 :
341 0 : return HS_SUCCESS;
342 : }
343 :
344 0 : static INT display_vars(MidasHistoryInterface* mh, time_t t)
345 : {
346 0 : std::vector<std::string> events;
347 0 : int status = mh->hs_get_events(t, &events);
348 :
349 0 : if (status != HS_SUCCESS) {
350 0 : printf("hs_get_events() error %d\n", status);
351 0 : return status;
352 : }
353 :
354 0 : for (unsigned i = 0; i < events.size(); i++) {
355 0 : printf("\nEvent \'%s\'\n", events[i].c_str());
356 :
357 0 : std::vector<TAG> tags;
358 0 : status = mh->hs_get_tags(events[i].c_str(), t, &tags);
359 :
360 0 : if (status != HS_SUCCESS) {
361 0 : printf("hs_get_tags() error %d\n", status);
362 0 : continue;
363 : }
364 :
365 0 : for (unsigned j = 0; j < tags.size(); j++)
366 0 : if (tags[j].n_data > 1)
367 0 : printf("%d: %s[%d]\n", j, tags[j].name, tags[j].n_data);
368 : else
369 0 : printf("%d: %s\n", j, tags[j].name);
370 0 : }
371 :
372 0 : return HS_SUCCESS;
373 0 : }
374 :
375 : /*------------------------------------------------------------------*/
376 0 : static void display_single_hist(MidasHistoryInterface* mh,
377 : const char* event_name,
378 : time_t start_time, time_t end_time, time_t interval,
379 : const char *var_name, int index)
380 : /* read back history */
381 : {
382 0 : time_t *tbuffer = NULL;
383 0 : double *buffer = NULL;
384 : int n;
385 0 : int status = 0;
386 0 : int hs_status = 0;
387 :
388 0 : status = mh->hs_read(start_time, end_time, interval, 1, &event_name, &var_name, &index, &n, &tbuffer, &buffer, &hs_status);
389 :
390 0 : if (status != HS_SUCCESS) {
391 0 : printf("hs_read() error %d\n", status);
392 0 : return;
393 : }
394 :
395 0 : if (hs_status != HS_SUCCESS) {
396 0 : printf("hs_read() cannot read event, status %d\n", hs_status);
397 0 : return;
398 : }
399 :
400 0 : if (n == 0)
401 0 : printf("No data for event \"%s\" variable \"%s\" found in specified time range\n", event_name, var_name);
402 :
403 0 : for (int i = 0; i < n; i++) {
404 : char str[256];
405 :
406 0 : if (binary_time)
407 0 : sprintf(str, "%d %.16g", (int)tbuffer[i], buffer[i]);
408 : else {
409 : char ctimebuf[32];
410 0 : ctime_r(&tbuffer[i], ctimebuf);
411 0 : sprintf(str, "%s %.16g", ctimebuf + 4, buffer[i]);
412 : }
413 :
414 0 : char* s = strchr(str, '\n');
415 0 : if (s)
416 0 : *s = ' ';
417 :
418 0 : printf("%s\n", str);
419 : }
420 :
421 0 : free(tbuffer);
422 0 : free(buffer);
423 : }
424 :
425 : /*------------------------------------------------------------------*/
426 :
427 0 : static void display_range_hist(MidasHistoryInterface* mh,
428 : const char* event_name,
429 : time_t start_time, time_t end_time, time_t interval,
430 : const char *var_name, int index1, int index2)
431 : /* read back history */
432 : {
433 0 : INT status = 0;
434 :
435 0 : if (index2 < index1) {
436 0 : printf("Wrong specified range (low>high)\n");
437 0 : return;
438 : }
439 :
440 0 : int nvars = index2 - index1 + 1;
441 :
442 0 : const char** en = CALLOC(nvars, const char*);
443 0 : const char** vn = CALLOC(nvars, const char*);
444 0 : int* in = CALLOC(nvars, int);
445 :
446 0 : for (int i=0; i<nvars; i++) {
447 0 : en[i] = event_name;
448 0 : vn[i] = var_name;
449 0 : in[i] = index1 + i;
450 : }
451 :
452 0 : int* n = CALLOC(nvars, int);
453 0 : time_t** tbuffer = CALLOC(nvars, time_t*);
454 0 : double** vbuffer = CALLOC(nvars, double*);
455 0 : int* hs_status = CALLOC(nvars, int);
456 :
457 0 : status = mh->hs_read(start_time, end_time, interval, nvars, en, vn, in, n, tbuffer, vbuffer, hs_status);
458 :
459 0 : if (status != HS_SUCCESS) {
460 0 : printf("Cannot read history data, hs_read() error %d\n", status);
461 0 : return;
462 : }
463 :
464 0 : for (int i=0; i<nvars; i++) {
465 0 : if (n[i] == 0)
466 0 : printf("No data for event \"%s\" variable \"%s\" index %d found in specified time range\n", event_name, var_name, index1+i);
467 0 : else if (hs_status[i] != HS_SUCCESS)
468 0 : printf("Cannot read event \"%s\" variable \"%s\" index %d, status %d\n", event_name, var_name, index1+i, hs_status[i]);
469 : }
470 :
471 0 : printf("mhist for Var:%s[%d:%d]\n", var_name, index1, index2);
472 0 : for (int i = 0; i < n[0]; i++) {
473 0 : if (binary_time)
474 0 : printf("%d ", (int)tbuffer[0][i]);
475 : else {
476 : char str[256];
477 0 : time_t ltime = (time_t) tbuffer[0][i];
478 : char ctimebuf[32];
479 0 : ctime_r(<ime, ctimebuf);
480 0 : sprintf(str, "%s", ctimebuf + 4);
481 0 : str[20] = '\t';
482 0 : printf("%s", str);
483 : }
484 :
485 0 : for (int j = 0, idx = index1; idx < index2 + 1; idx++, j++) {
486 0 : putchar('\t');
487 0 : printf("%.16g", vbuffer[j][i]);
488 : }
489 :
490 0 : putchar('\n');
491 : }
492 :
493 0 : for (int i=0; i<nvars; i++) {
494 0 : FREE(tbuffer[i]);
495 0 : FREE(vbuffer[i]);
496 : }
497 :
498 0 : FREE(n);
499 0 : FREE(tbuffer);
500 0 : FREE(vbuffer);
501 0 : FREE(hs_status);
502 :
503 0 : FREE(en);
504 0 : FREE(vn);
505 0 : FREE(in);
506 : }
507 :
508 : /*------------------------------------------------------------------*/
509 :
510 0 : static void display_all_hist(MidasHistoryInterface* mh,
511 : const char* event_name,
512 : time_t start_time, time_t end_time, time_t interval)
513 : /* read back history */
514 : {
515 0 : INT status = 0;
516 :
517 0 : std::vector<TAG> tags;
518 0 : status = mh->hs_get_tags(event_name, start_time, &tags);
519 :
520 0 : if (status != HS_SUCCESS) {
521 0 : printf("Cannot get list of variables for event \'%s\', hs_get_tags() error %d\n", event_name, status);
522 0 : return;
523 : }
524 :
525 0 : for (unsigned j = 0; j < tags.size(); j++) {
526 0 : if (tags[j].n_data > 1)
527 0 : printf("%d: %s[%d]\n", j, tags[j].name, tags[j].n_data);
528 : else
529 0 : printf("%d: %s\n", j, tags[j].name);
530 : }
531 :
532 0 : int xvars = 0;
533 :
534 0 : for (unsigned i=0; i<tags.size(); i++) {
535 0 : if (tags[i].n_data == 1) {
536 0 : xvars++;
537 : } else {
538 0 : for (unsigned j=0; j<tags[i].n_data; j++) {
539 0 : xvars++;
540 : }
541 : }
542 : }
543 :
544 0 : const char** en = CALLOC(xvars, const char*);
545 0 : const char** vn = CALLOC(xvars, const char*);
546 0 : int* in = CALLOC(xvars, int);
547 0 : int* n_data = CALLOC(xvars, int);
548 :
549 0 : int nvars = 0;
550 :
551 0 : for (unsigned i=0; i<tags.size(); i++) {
552 0 : if (tags[i].name[0] == '/') // skip system tags
553 0 : continue;
554 0 : if (tags[i].n_data == 1) {
555 0 : en[nvars] = event_name;
556 0 : vn[nvars] = tags[i].name;
557 0 : in[nvars] = 0;
558 0 : n_data[nvars] = tags[i].n_data;
559 0 : nvars++;
560 : } else {
561 0 : for (unsigned j=0; j<tags[i].n_data; j++) {
562 0 : en[nvars] = event_name;
563 0 : vn[nvars] = tags[i].name;
564 0 : in[nvars] = j;
565 0 : n_data[nvars] = tags[i].n_data;
566 0 : nvars++;
567 : }
568 : }
569 : }
570 :
571 0 : assert(nvars <= xvars);
572 :
573 0 : int* n = CALLOC(nvars, int);
574 0 : time_t** tbuffer = CALLOC(nvars, time_t*);
575 0 : double** vbuffer = CALLOC(nvars, double*);
576 0 : int* hs_status = CALLOC(nvars, int);
577 :
578 0 : status = mh->hs_read(start_time, end_time, interval, nvars, en, vn, in, n, tbuffer, vbuffer, hs_status);
579 :
580 0 : if (status != HS_SUCCESS) {
581 0 : printf("Cannot read history data, hs_read() error %d\n", status);
582 0 : return;
583 : }
584 :
585 0 : int nread = n[0];
586 :
587 0 : bool ok = true;
588 0 : bool no_data = true;
589 :
590 0 : for (int i=0; i<nvars; i++) {
591 0 : if (n[i] == 0) {
592 0 : printf("No data for event \"%s\" variable \"%s\" index %d found in specified time range\n", en[i], vn[i], in[i]);
593 0 : ok = false;
594 0 : } else if (hs_status[i] != HS_SUCCESS) {
595 0 : printf("Cannot read event \"%s\" variable \"%s\" index %d, status %d\n", en[i], vn[i], in[i], hs_status[i]);
596 0 : ok = false;
597 0 : } else if (n[i] != nread) {
598 0 : printf("Number of entries for event \"%s\" variable \"%s\" index %d is %d instead of %d\n", en[i], vn[i], in[i], n[i], nread);
599 0 : ok = false;
600 0 : no_data = false;
601 : } else {
602 0 : no_data = false;
603 : }
604 : }
605 :
606 0 : if (no_data) {
607 0 : printf("No data, nothing to print\n");
608 0 : return;
609 : }
610 :
611 0 : if (!ok) {
612 0 : printf("Cannot print history data because of timestamp skew\n");
613 0 : return;
614 : }
615 :
616 0 : printf("Event \'%s\', %d variables, %d entries\n", event_name, nvars, nread);
617 :
618 0 : printf("Time ");
619 0 : printf("\t");
620 0 : for (int i=0; i<nvars; i++) {
621 0 : if (n_data[i] == 1) {
622 0 : printf("\t");
623 0 : printf("%s ", vn[i]);
624 : } else {
625 0 : printf("\t");
626 0 : printf("%s[%d] ", vn[i], in[i]);
627 : }
628 : }
629 0 : printf("\n");
630 :
631 0 : for (int i = 0; i < nread; i++) {
632 0 : if (binary_time)
633 0 : printf("%d ", (int)tbuffer[0][i]);
634 : else {
635 : char buf[256];
636 0 : time_t ltime = (time_t) tbuffer[0][i];
637 : char ctimebuf[32];
638 0 : ctime_r(<ime, ctimebuf);
639 0 : sprintf(buf, "%s", ctimebuf + 4);
640 0 : char* c = strchr(buf, '\n');
641 0 : if (c)
642 0 : *c = 0; // kill trailing '\n'
643 0 : printf("%s", buf);
644 0 : putchar('\t');
645 : }
646 :
647 0 : for (int j=0; j<nvars; j++) {
648 0 : if (tbuffer[j][i] != tbuffer[0][i]) {
649 0 : printf("Cannot print history data because of timestamp skew\n");
650 0 : return;
651 : }
652 0 : putchar('\t');
653 0 : printf("%.16g", vbuffer[j][i]);
654 : }
655 :
656 0 : putchar('\n');
657 : }
658 :
659 0 : for (int i=0; i<nvars; i++) {
660 0 : FREE(tbuffer[i]);
661 0 : FREE(vbuffer[i]);
662 : }
663 :
664 0 : FREE(n);
665 0 : FREE(tbuffer);
666 0 : FREE(vbuffer);
667 0 : FREE(hs_status);
668 :
669 0 : FREE(en);
670 0 : FREE(vn);
671 0 : FREE(in);
672 0 : FREE(n_data);
673 0 : }
674 :
675 : /*------------------------------------------------------------------*/
676 0 : static DWORD convert_time(char *t)
677 : /* convert date in format YYMMDD[.HHMM[SS]] into decimal time */
678 : {
679 : struct tm tms;
680 : INT isdst;
681 :
682 0 : ss_tzset(); // required for localtime_r()
683 :
684 0 : memset(&tms, 0, sizeof(tms));
685 :
686 0 : tms.tm_year = 10 * (t[0] - '0') + (t[1] - '0');
687 0 : tms.tm_mon = 10 * (t[2] - '0') + (t[3] - '0') - 1;
688 0 : tms.tm_mday = 10 * (t[4] - '0') + (t[5] - '0');
689 0 : if (tms.tm_year < 90)
690 0 : tms.tm_year += 100;
691 0 : if (t[6] == '.') {
692 0 : tms.tm_hour = 10 * (t[7] - '0') + (t[8] - '0');
693 0 : tms.tm_min = 10 * (t[9] - '0') + (t[10] - '0');
694 0 : if (t[11])
695 0 : tms.tm_sec = 10 * (t[11] - '0') + (t[12] - '0');
696 : }
697 :
698 0 : time_t ltime = ss_mktime(&tms);
699 :
700 : /* correct for dst */
701 0 : localtime_r(<ime, &tms);
702 :
703 0 : isdst = tms.tm_isdst;
704 0 : memset(&tms, 0, sizeof(tms));
705 0 : tms.tm_isdst = isdst;
706 :
707 0 : tms.tm_year = 10 * (t[0] - '0') + (t[1] - '0');
708 0 : tms.tm_mon = 10 * (t[2] - '0') + (t[3] - '0') - 1;
709 0 : tms.tm_mday = 10 * (t[4] - '0') + (t[5] - '0');
710 0 : if (tms.tm_year < 90)
711 0 : tms.tm_year += 100;
712 0 : if (t[6] == '.') {
713 0 : tms.tm_hour = 10 * (t[7] - '0') + (t[8] - '0');
714 0 : tms.tm_min = 10 * (t[9] - '0') + (t[10] - '0');
715 0 : if (t[11])
716 0 : tms.tm_sec = 10 * (t[11] - '0') + (t[12] - '0');
717 : }
718 :
719 0 : ltime = (DWORD) ss_mktime(&tms);
720 :
721 0 : return (DWORD)ltime;
722 : }
723 :
724 0 : void usage()
725 : {
726 0 : printf("\nusage: mhist [-e Event Name] [-v Variable Name]\n");
727 0 : printf(" [-i Index] index of variables which are arrays\n");
728 0 : printf(" [-i Index1:Index2] index range of variables which are arrays (max 50)\n");
729 0 : printf(" [-t Interval] minimum interval in sec. between two displayed records\n");
730 0 : printf(" [-h Hours] display between some hours ago and now\n");
731 0 : printf(" [-d Days] display between some days ago and now\n");
732 0 : printf(" [-f File] specify history file explicitly\n");
733 0 : printf(" [-s Start date] specify start date YYMMDD[.HHMM[SS]]\n");
734 0 : printf(" [-p End date] specify end date YYMMDD[.HHMM[SS]]\n");
735 0 : printf(" [-l] list available events and variables\n");
736 0 : printf(" [-b] display time stamp in decimal format\n");
737 0 : exit(1);
738 : }
739 :
740 0 : int main(int argc, char *argv[])
741 : {
742 : DWORD status;
743 0 : DWORD start_time = 0;
744 0 : DWORD end_time = 0;
745 0 : DWORD interval = 0;
746 0 : DWORD index1 = 0;
747 0 : DWORD index2 = 0;
748 : INT i, var_n_data;
749 : BOOL list_query;
750 : DWORD var_type;
751 : char var_name[NAME_LENGTH];
752 0 : std::string path_name;
753 : char *column;
754 0 : BOOL do_hst_file = false;
755 0 : std::string event_name;
756 0 : int debug = 0;
757 :
758 : /* turn off system message */
759 0 : cm_set_msg_print(0, MT_ALL, puts);
760 :
761 0 : var_name[0] = 0;
762 0 : list_query = FALSE;
763 :
764 : HNDLE hDB;
765 : char host_name[256];
766 : char expt_name[256];
767 0 : host_name[0] = 0;
768 0 : expt_name[0] = 0;
769 :
770 0 : MidasHistoryInterface* mh = NULL;
771 :
772 0 : cm_get_environment(host_name, sizeof(host_name), expt_name, sizeof(expt_name));
773 :
774 0 : if (argc == 1) {
775 0 : status = cm_connect_experiment1(host_name, expt_name, "mhist", 0, DEFAULT_ODB_SIZE, 0);
776 0 : assert(status == CM_SUCCESS);
777 :
778 0 : status = cm_get_experiment_database(&hDB, NULL);
779 0 : assert(status == CM_SUCCESS);
780 :
781 0 : status = hs_get_history(hDB, 0, HS_GET_DEFAULT|HS_GET_READER|HS_GET_INACTIVE, debug, &mh);
782 0 : assert(status == HS_SUCCESS);
783 :
784 0 : status = query_params(mh, &event_name, &start_time, &end_time, &interval, var_name, &var_type, &var_n_data, &index1);
785 0 : if (status != HS_SUCCESS)
786 0 : return 1;
787 : } else {
788 : /* at least one argument */
789 0 : end_time = ss_time();
790 0 : start_time = end_time - 3600;
791 0 : interval = 1;
792 0 : index1 = 0;
793 0 : index2 = 0;
794 0 : var_type = 0;
795 0 : event_name = "";
796 0 : binary_time = FALSE;
797 :
798 0 : for (i = 1; i < argc; i++) {
799 0 : if (argv[i][0] == '-' && argv[i][1] == 'b')
800 0 : binary_time = TRUE;
801 0 : else if (argv[i][0] == '-' && argv[i][1] == 'l')
802 0 : list_query = TRUE;
803 0 : else if (argv[i][0] == '-') {
804 0 : if (i + 1 >= argc) {
805 0 : printf("Error: command line switch value after \"%s\" is missing\n", argv[i]);
806 0 : usage();
807 0 : } else if (argv[i+1][0] == '-') {
808 0 : printf("Error: command line switch value after \"%s\" starts with a dash: %s\n", argv[i], argv[i+1]);
809 0 : usage();
810 0 : } else if (strncmp(argv[i], "-e", 2) == 0) {
811 0 : event_name = argv[++i];
812 0 : } else if (strncmp(argv[i], "-v", 2) == 0) {
813 0 : strcpy(var_name, argv[++i]);
814 0 : } else if (strncmp(argv[i], "-i", 2) == 0) {
815 0 : if ((column = strchr(argv[++i], ':')) == NULL) {
816 0 : index1 = atoi(argv[i]);
817 0 : index2 = 0;
818 : } else {
819 0 : *column = 0;
820 0 : index1 = atoi(argv[i]);
821 0 : index2 = atoi(column + 1);
822 : }
823 0 : } else if (strncmp(argv[i], "-h", 2) == 0) {
824 0 : start_time = ss_time() - atoi(argv[++i]) * 3600;
825 0 : } else if (strncmp(argv[i], "-d", 2) == 0) {
826 0 : start_time = ss_time() - atoi(argv[++i]) * 3600 * 24;
827 0 : } else if (strncmp(argv[i], "-s", 2) == 0) {
828 0 : start_time = convert_time(argv[++i]);
829 0 : } else if (strncmp(argv[i], "-p", 2) == 0) {
830 0 : end_time = convert_time(argv[++i]);
831 0 : } else if (strncmp(argv[i], "-t", 2) == 0) {
832 0 : interval = atoi(argv[++i]);
833 0 : } else if (strncmp(argv[i], "-f", 2) == 0) {
834 0 : path_name = argv[++i];
835 0 : do_hst_file = true;
836 : }
837 : } else {
838 0 : printf("Error: unknown command line switch: %s\n", argv[i]);
839 0 : usage();
840 : }
841 : }
842 : }
843 :
844 0 : if (do_hst_file) {
845 0 : hs_fdump(path_name.c_str(), atoi(event_name.c_str()), binary_time);
846 0 : return 0;
847 : }
848 :
849 0 : if (!mh) {
850 0 : status = cm_connect_experiment1(host_name, expt_name, "mhist", 0, DEFAULT_ODB_SIZE, 0);
851 0 : assert(status == CM_SUCCESS);
852 :
853 0 : status = cm_get_experiment_database(&hDB, NULL);
854 0 : assert(status == CM_SUCCESS);
855 :
856 0 : status = hs_get_history(hDB, 0, HS_GET_DEFAULT|HS_GET_READER|HS_GET_INACTIVE, debug, &mh);
857 0 : if (status != HS_SUCCESS) {
858 0 : printf("hs_connect() error %d\n", status);
859 0 : return 1;
860 : }
861 : }
862 :
863 : /* -l listing only */
864 0 : if (list_query) {
865 0 : display_vars(mh, 0);
866 : }
867 : /* -v given takes -e -s -p -t -b */
868 0 : else if (var_name[0] == 0) {
869 : // hs_dump(event_id, start_time, end_time, interval, binary_time);
870 0 : display_all_hist(mh, event_name.c_str(), start_time, end_time, interval);
871 : }
872 : /* Interactive variable display */
873 0 : else if (index2 == 0)
874 0 : display_single_hist(mh, event_name.c_str(), start_time, end_time, interval, var_name, index1);
875 : else
876 0 : display_range_hist(mh, event_name.c_str(), start_time, end_time, interval, var_name, index1, index2);
877 :
878 0 : delete mh;
879 :
880 0 : cm_disconnect_experiment();
881 :
882 0 : return 0;
883 0 : }
884 :
885 : /* emacs
886 : * Local Variables:
887 : * tab-width: 8
888 : * c-basic-offset: 3
889 : * indent-tabs-mode: nil
890 : * End:
891 : */
|