summaryrefslogtreecommitdiffstats
path: root/srv/c.c
blob: f402a288e1792ae3872a8319a527ebcb3c934b74 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <sys/stat.h>
#include <inttypes.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <unistd.h>
#define S0(x) (x ? x : "")
struct entry {
	uint64_t time __attribute__((packed));
	uint64_t value __attribute__((packed));
} __attribute__((packed));
int najdi (struct entry * db, int first, int last, long long int čas) {
	if (first == last)
		return first;
	if (abs(first-last) == 1) {
		if (labs(čas/1000-first*1000) < labs(čas/1000-last*1000))
			return first;
		else
			return last;
	}
	if ((long long int) be64toh(db[(first+last)/2].time/1000) > čas*1000)
		return najdi(db, (first+last)/2, last, čas);
	else
		return najdi(db, first, (first+last)/2-1, čas);
}
int main (int argc, char ** argv) {
	int r = 0;
	if (argc < 1+2)
		error_at_line(1, 0, __FILE__, __LINE__,
"uporaba: %s db infor/preveri/rast/seštevek [natančnost] [začetek UNIX] [konec UNIX]\n\t"
"informacije: pove UNIXus prvega in UNIXus zadnjega zapisa\n\t"
"preveri: pove, če čas ni naraščajoč in kdaj se je števec resetiral\n\t"
"rast: TSV s podatki <UNIXus>:<Wh skupno> najgosteje na [natančnost=0] ms\n\t"
"seštevek: TSV s podatki <UNIXus>:<vatnih ur v [natančnost=10e3] ms>\n\t"
"če je nastavljena okoljska spremenljivka SEK, bodo izhodni časi v UNIX sekundah",
			S0(argv[0]));
	int fd = -1;
	struct entry * db = NULL;
	if ((fd = open(argv[1], O_RDONLY | O_CLOEXEC)) == -1)
		error_at_line(2, 0, __FILE__, __LINE__, "open");
	struct stat statbuf;
	if (fstat(fd, &statbuf) == -1) {
		error_at_line(0, errno, __FILE__, __LINE__, "fstat");
		r = 3;
		goto r;
	}
	unsigned entries = statbuf.st_size / sizeof(struct entry);
	if (!(db = mmap(NULL, statbuf.st_size, PROT_READ, MAP_SHARED, fd, 0))) {
		error_at_line(0, errno, __FILE__, __LINE__, "mmap");
		r = 4;
		goto r;
	}
	if (argv[2][0] == 'i') {
		uint64_t začetek = be64toh(db[0].time);
		uint64_t konec = be64toh(db[entries-1].time);
		char * enota = "us";
		if (getenv("SEK")) {
			začetek /= 1e6;
			konec /= 1e6;
			enota = "";
		}
		printf("začetek\t%" PRIu64 " UNIX%s\t%" PRIu64 " Wh\nkonec\t%" PRIu64 " UNIX%s\t%" PRIu64 " Wh\nzapisov: %u\n", začetek, enota, be64toh(db[0].value), konec, enota, be64toh(db[entries-1].value), entries);
		goto r;
	}
	if (argv[2][0] == 'p') {
		uint64_t prev_time = 0;
		uint64_t prev_value = 0;
		for (unsigned i = 0; i < entries; i++) {
			if (be64toh(db[0].time) < prev_time)
				printf("čas se je zavrtel nazaj: i=%u a=%" PRIu64 " b=%" PRIu64 "\n", i, prev_time, be64toh(db[0].time));
			if (be64toh(db[0].value) < prev_value)
				printf("števec se je resetiral: i=%u a=%" PRIu64 " b=%" PRIu64 "\n", i, prev_value, be64toh(db[0].value));
			prev_time = be64toh(db[0].time);
			prev_value = be64toh(db[0].value);
		}
		goto r;
	}
	unsigned long long natančnost = 0;
	if (argv[2][0] == 's')
		natančnost = 10e3;
	if (argc >= 1+3)
		natančnost = atoi(argv[3]);
	unsigned začetek = 0;
	if (argc >= 1+4)
		začetek = najdi(db, 0, entries-1, atoi(argv[4]));
	unsigned konec = entries-1;
	if (argc >= 1+5)
		konec = najdi(db, 0, entries-1, atoi(argv[5]));
	if (argv[2][0] == 's') {
		uint64_t us = 0;
		uint64_t Wh = 0;
		unsigned long long prev_time = be64toh(db[začetek].time);
		unsigned long long prev_value = be64toh(db[začetek].value);
		for (unsigned i = začetek; i <= konec; i++) {
			if (us + (be64toh(db[i].time)-prev_time) >= natančnost*1000) {
				uint64_t čas_začetek = be64toh(db[i].time)-us;
				uint64_t čas_konec = be64toh(db[i].time);
				if (getenv("SEK")) {
					čas_začetek /= 1e6;
					čas_konec /= 1e6;
				}
				printf("%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\t%" PRIu64 "\n", čas_začetek, Wh, čas_konec, us);
				us = 0;
				Wh = 0;
			}
			us += (be64toh(db[i].time)-prev_time);
			Wh += (be64toh(db[i].value)-prev_value);
			prev_time = be64toh(db[i].time);
			prev_value = be64toh(db[i].value);
		}
	} else {
		unsigned long long prev_print = 0;
		for (unsigned i = začetek; i <= konec; i++) {
			if (be64toh(db[i].time)-prev_print > natančnost*1000) {
				uint64_t čas = be64toh(db[i].time);
				if (getenv("SEK"))
					čas /= 1e6;
				printf("%" PRIu64 "\t%" PRIu64 "\n", čas, be64toh(db[i].value));
				prev_print = be64toh(db[i].time);
			}
		}
	}
r:
	if (db != NULL)
		if (munmap(db, statbuf.st_size) == -1)
			error_at_line(98, errno, __FILE__, __LINE__, "munmap");
	if (fd == -1)
		if (close(fd) == -1)
			error_at_line(99, errno, __FILE__, __LINE__, "fclose");
	return r;
}