-
Notifications
You must be signed in to change notification settings - Fork 1
/
realtime.c
149 lines (120 loc) · 3.8 KB
/
realtime.c
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
/* vim:set expandtab! ts=4: */
#include "eeprom.h"
#include <time.h>
#include <unistd.h>
#include "record.h"
#define BUFSIZE 32768
void print_usage() {
fprintf(stderr, "Usage: realtime /dev/ttyS0\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
WEATHERSTATION ws;
unsigned char data[BUFSIZE];
char* serial_device;
int sensors;
int block_size = 0;
int data_offset = 0x64;
int start_adr;
int record_interval;
int skip, skip_offset;
int sequential = 0;
Record r;
Record rnext;
time_t t;
struct tm *tm;
memset(data, 0xAA, BUFSIZE);
if (argc != 2) {
fprintf(stderr, "E: no serial device specified.\n");
print_usage();
}
serial_device = argv[1];
// need root for (timing) portio
if (geteuid() != 0) {
fprintf(stderr, "E: this program needs root privileges to do direct port I/O.\n");
exit(EXIT_FAILURE);
}
t = time(NULL);
tm = localtime(&t);
if (tm == NULL) {
perror("localtime");
exit(EXIT_FAILURE);
}
// Setup serial port
ws = open_weatherstation(serial_device);
// read config
nanodelay();
eeprom_seek(ws, 0);
eeprom_read(ws, data, data_offset);
// config check
sensors = data[0x0C];
sensors++;
if (sensors == 4 || sensors == 5) block_size = 15;
if (sensors == 6) block_size = 20;
printf("Using sensors=%d\n", sensors);
if (block_size == 0) {
fprintf(stderr,"E: dont understand this format, found sensors=%d\n", sensors);
exit(EXIT_FAILURE);
}
printf("Saved time: %02X:%02X \n", data[1], data[0]);
/* data 2-5 seem to be the date */
skip = ((data[0xA] & 0x0F) * 100) + ((data[0x09]>>4) * 10) + (data[0x09] & 0x0F);
printf("RecordCount: %d (other interesting shid: %02X %02X )\n", skip, data[0x0B], data[0x0A] & 0xF0);
printf("Scanning for two connected records\n");
start_adr = data_offset;
while(start_adr < (data_offset + block_size*50)) {
int read_len = (2*block_size);
eeprom_seek(ws, start_adr);
eeprom_read(ws, data + start_adr, read_len);
record_parse(data+data_offset, &r, sensors);
record_parse(data+data_offset+block_size, &rnext, sensors);
record_interval = rnext.time_m - r.time_m;
if (record_interval > 0 && record_interval < 30) {
break;
}
record_interval = -1;
start_adr += read_len;
}
if (record_interval == -1) {
fprintf(stderr,"E: can't discover recording interval\n");
exit(EXIT_FAILURE);
}
printf("%02d.%02d.20%02d %02d:%02d \n", r.date_d, r.date_m, r.date_y, r.time_h, r.time_m);
printf("%02d.%02d.20%02d %02d:%02d \n", rnext.date_d, rnext.date_m, rnext.date_y, rnext.time_h, rnext.time_m);
printf("Recording interval: %d\n", record_interval);
skip = 0;
if (tm->tm_year-(2000+r.date_y) > 1 || tm->tm_mon-r.date_m > 1) {
// too far in the future
sequential = 1;
}
if (tm->tm_hour-r.time_h > 1) {
skip += (tm->tm_hour-r.time_h)*60/record_interval;
printf("hours off: %d\n", (tm->tm_hour-r.time_h));
skip += (tm->tm_min-r.time_m)/record_interval;
}
if (tm->tm_hour-r.time_h == 0 && tm->tm_min-r.time_m > (2*record_interval)) {
printf("only correcting minutes\n");
skip += (tm->tm_min-r.time_m)/record_interval;
}
skip -= 5;
printf("skip=%d, seq=%d\n", skip, sequential);
if (skip > 1100 || skip < 0) {
sequential = 1;
}
if (sequential == 1) {
printf("Falling back to sequential read.\n");
printf("not implemented ;)\n");
} else {
printf("Jumping to record %d\n", skip);
// now read from guessed record position
skip_offset = data_offset + skip*block_size;
eeprom_seek(ws, skip_offset);
eeprom_read(ws, data+skip_offset, block_size*2);
record_parse(data+skip_offset, &r, sensors);
printf("%02d.%02d.20%02d %02d:%02d ",
r.date_d, r.date_m, r.date_y, r.time_h, r.time_m);
printf("\n");
}
close_weatherstation(ws);
return(0);
}