Thu, 24 Apr 2014 19:49:30 +0200
Deamon code added
1 | 1 | /***************************************************************************** |
2 | * Copyright (C) 2014 | |
3 | * | |
4 | * Michiel Broek <mbroek at mbse dot eu> | |
5 | * | |
6 | * This file is part of the mbsePi-apps | |
7 | * | |
8 | * This is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the | |
10 | * Free Software Foundation; either version 2, or (at your option) any | |
11 | * later version. | |
12 | * | |
13 | * mbsePi-apps is distributed in the hope that it will be useful, but | |
14 | * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 | * General Public License for more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License | |
19 | * along with EC-65K; see the file COPYING. If not, write to the Free | |
20 | * Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. | |
21 | *****************************************************************************/ | |
22 | ||
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
23 | #include "../lib/mbselib.h" |
1 | 24 | #include "main.h" |
25 | ||
26 | ||
6 | 27 | #define STATUS_CONNECTING 0 |
28 | #define STATUS_CONNACK_RECVD 1 | |
29 | #define STATUS_WAITING 2 | |
30 | ||
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
31 | /* Global variables for use in callbacks. */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
32 | static int qos = 0; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
33 | static int status = STATUS_CONNECTING; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
34 | static int mid_sent = 0; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
35 | static int last_mid = -1; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
36 | static int last_mid_sent = -1; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
37 | static bool connected = true; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
38 | static bool disconnect_sent = false; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
39 | static bool shutdown = false; |
12 | 40 | static pid_t pgrp, mypid; |
6 | 41 | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
42 | extern bool debug; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
43 | extern sys_config Config; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
44 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
45 | int server(void); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
46 | void help(void); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
47 | void die(int); |
6 | 48 | |
49 | ||
1 | 50 | void help(void) |
51 | { | |
12 | 52 | fprintf(stdout, "mbsePi-apps thermometers v%s starting\n\n", VERSION); |
1 | 53 | fprintf(stdout, "Usage: thermomeneters [-d] [-h]\n"); |
12 | 54 | fprintf(stdout, " -d --debug Debug and run in foreground\n"); |
1 | 55 | fprintf(stdout, " -h --help Display this help\n"); |
56 | } | |
57 | ||
58 | ||
59 | ||
60 | void die(int onsig) | |
61 | { | |
62 | switch (onsig) { | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
63 | case SIGHUP: syslog(LOG_NOTICE, "Got SIGHUP, shutting down"); |
1 | 64 | break; |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
65 | case SIGINT: syslog(LOG_NOTICE, "Keyboard interrupt, shutting down"); |
1 | 66 | break; |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
67 | case SIGTERM: syslog(LOG_NOTICE, "Got SIGTERM, shutting down"); |
1 | 68 | break; |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
69 | default: syslog(LOG_NOTICE, "die() on signal %d", onsig); |
1 | 70 | } |
71 | ||
6 | 72 | shutdown = true; |
73 | } | |
74 | ||
75 | ||
76 | ||
77 | void my_connect_callback(struct mosquitto *mosq, void *obj, int result) | |
78 | { | |
79 | if (!result) { | |
80 | status = STATUS_CONNACK_RECVD; | |
81 | } else { | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
82 | syslog(LOG_NOTICE, "my_connect_callback: %s\n", mosquitto_connack_string(result)); |
6 | 83 | } |
84 | } | |
85 | ||
86 | ||
87 | ||
88 | void my_disconnect_callback(struct mosquitto *mosq, void *obj, int rc) | |
89 | { | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
90 | if (shutdown) { |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
91 | syslog(LOG_NOTICE, "Acknowledged DISCONNECT from %s", Config.mosq_host); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
92 | connected = false; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
93 | } else { |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
94 | /* |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
95 | * The remove server was brought down. We must keep running |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
96 | */ |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
97 | syslog(LOG_NOTICE, "Received DISCONNECT from %s but we want to run", Config.mosq_host); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
98 | /* |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
99 | * We need a temp state |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
100 | */ |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
101 | } |
6 | 102 | } |
103 | ||
104 | ||
105 | ||
106 | void my_publish_callback(struct mosquitto *mosq, void *obj, int mid) | |
107 | { | |
108 | last_mid_sent = mid; | |
109 | } | |
110 | ||
111 | ||
112 | ||
113 | void my_log_callback(struct mosquitto *mosq, void *obj, int level, const char *str) | |
114 | { | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
115 | syslog(LOG_NOTICE, "MQTT: %s", str); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
116 | printf("MQTT: %s\n", str); |
1 | 117 | } |
118 | ||
119 | ||
120 | ||
121 | int main(int argc, char *argv[]) | |
122 | { | |
12 | 123 | int rc, c, i; |
124 | pid_t frk; | |
1 | 125 | |
126 | while (1) { | |
127 | int option_index = 0; | |
128 | static struct option long_options[] = { | |
129 | {"debug", 0, 0, 'c'}, | |
130 | {"help", 0, 0, 'h'}, | |
131 | {0, 0, 0, 0} | |
132 | }; | |
133 | ||
134 | c = getopt_long(argc, argv, "dh", long_options, &option_index); | |
135 | if (c == -1) | |
136 | break; | |
137 | ||
138 | switch (c) { | |
6 | 139 | case 'd': debug = true; |
1 | 140 | break; |
141 | case 'h': help(); | |
142 | return 1; | |
143 | } | |
144 | } | |
145 | ||
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
146 | openlog("thermometers", LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_USER); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
147 | syslog(LOG_NOTICE, "mbsePi-apps thermometers v%s starting", VERSION); |
12 | 148 | if (debug) |
149 | fprintf(stdout, "mbsePi-apps thermometers v%s starting\n", VERSION); | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
150 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
151 | if (rdconfig()) { |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
152 | fprintf(stderr, "Error reading configuration\n"); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
153 | syslog(LOG_NOTICE, "halted"); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
154 | return 1; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
155 | } |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
156 | |
1 | 157 | /* |
158 | * Catch all the signals we can, and ignore the rest. Note that SIGKILL can't be ignored | |
159 | * but that's live. This daemon should only be stopped by SIGTERM. | |
160 | * Don't catch SIGCHLD. | |
161 | */ | |
162 | for (i = 0; i < NSIG; i++) { | |
163 | if ((i != SIGCHLD) && (i != SIGKILL) && (i != SIGSTOP)) | |
164 | signal(i, (void (*))die); | |
165 | } | |
166 | ||
12 | 167 | |
168 | if (debug) { | |
169 | /* | |
170 | * For debugging run in foreground. | |
171 | */ | |
172 | rc = server(); | |
173 | } else { | |
174 | /* | |
175 | * Server initialization is complete. Now we can fork the | |
176 | * daemon and return to the user. We need to do a setpgrp | |
177 | * so that the daemon will no longer be assosiated with the | |
178 | * users control terminal. This is done before the fork, so | |
179 | * that the child will not be a process group leader. Otherwise, | |
180 | * if the child were to open a terminal, it would become | |
181 | * associated with that terminal as its control terminal. | |
182 | */ | |
183 | if ((pgrp = setpgid(0, 0)) == -1) { | |
184 | syslog(LOG_NOTICE, "setpgpid failed"); | |
185 | } | |
186 | ||
187 | frk = fork(); | |
188 | switch (frk) { | |
189 | case -1: | |
190 | syslog(LOG_NOTICE, "Daemon fork failed: %s", strerror(errno)); | |
191 | syslog(LOG_NOTICE, "Finished, rc=1"); | |
192 | exit(1); | |
193 | case 0: /* | |
194 | * Run the daemon | |
195 | */ | |
196 | fclose(stdin); | |
197 | if (open("/dev/null", O_RDONLY) != 0) { | |
198 | syslog(LOG_NOTICE, "Reopen of stdin to /dev/null failed"); | |
199 | _exit(2); | |
200 | } | |
201 | fclose(stdout); | |
202 | if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 1) { | |
203 | syslog(LOG_NOTICE, "Reopen of stdout to /dev/null failed"); | |
204 | _exit(2); | |
205 | } | |
206 | fclose(stderr); | |
207 | if (open("/dev/null", O_WRONLY | O_APPEND | O_CREAT,0600) != 2) { | |
208 | syslog(LOG_NOTICE, "Reopen of stderr to /dev/null failed"); | |
209 | _exit(2); | |
210 | } | |
211 | mypid = getpid(); | |
212 | rc = server(); | |
213 | break; | |
214 | /* Not reached */ | |
215 | default: | |
216 | /* | |
217 | * Here we detach this process and let the child | |
218 | * run the deamon process. | |
219 | */ | |
220 | syslog(LOG_NOTICE, "Starting daemon with pid %d", frk); | |
221 | exit(0); | |
222 | } | |
223 | } | |
224 | ||
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
225 | syslog(LOG_NOTICE, "Finished, rc=%d", rc); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
226 | return rc; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
227 | } |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
228 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
229 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
230 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
231 | int server(void) |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
232 | { |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
233 | char *id = NULL, *state = NULL; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
234 | struct mosquitto *mosq = NULL; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
235 | char hostname[256], buf[1024]; |
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
236 | int temp, rc, deviation, keepalive = 60; |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
237 | unsigned int max_inflight = 20; |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
238 | char err[1024]; |
10 | 239 | w1_therm *tmp1, *old1; |
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
240 | char *device, *alias, line[60], *p = NULL; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
241 | FILE *fp; |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
242 | |
6 | 243 | /* |
244 | * Initialize mosquitto communication | |
245 | */ | |
246 | mosquitto_lib_init(); | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
247 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
248 | /* |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
249 | * Build MQTT id |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
250 | */ |
6 | 251 | hostname[0] = '\0'; |
252 | gethostname(hostname, 256); | |
253 | hostname[255] = '\0'; | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
254 | |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
255 | id = xstrcpy((char *)"thermometers/"); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
256 | id = xstrcat(id, hostname); |
6 | 257 | if(strlen(id) > MOSQ_MQTT_ID_MAX_LENGTH) { |
258 | /* | |
259 | * Enforce maximum client id length of 23 characters | |
260 | */ | |
261 | id[MOSQ_MQTT_ID_MAX_LENGTH] = '\0'; | |
262 | } | |
1 | 263 | |
6 | 264 | mosq = mosquitto_new(id, true, NULL); |
265 | if(!mosq) { | |
266 | switch(errno) { | |
267 | case ENOMEM: | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
268 | syslog(LOG_NOTICE, "mosquitto_new: Out of memory"); |
6 | 269 | break; |
270 | case EINVAL: | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
271 | syslog(LOG_NOTICE, "mosquitto_new: Invalid id"); |
6 | 272 | break; |
273 | } | |
274 | mosquitto_lib_cleanup(); | |
275 | return 1; | |
276 | } | |
277 | ||
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
278 | if (debug) { |
6 | 279 | mosquitto_log_callback_set(mosq, my_log_callback); |
280 | } | |
281 | ||
282 | /* | |
283 | * Set our will | |
284 | */ | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
285 | state = xstrcpy((char *)"clients/"); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
286 | state = xstrcat(state, hostname); |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
287 | state = xstrcat(state, (char *)"/thermometers/state"); |
6 | 288 | sprintf(buf, "0"); |
12 | 289 | if ((rc = mosquitto_will_set(mosq, state, strlen(buf), buf, qos, true))) { |
6 | 290 | if (rc == MOSQ_ERR_INVAL) { |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
291 | syslog(LOG_NOTICE, "mosquitto_will_set: input parameters invalid"); |
6 | 292 | } else if (rc == MOSQ_ERR_NOMEM) { |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
293 | syslog(LOG_NOTICE, "mosquitto_will_set: Out of Memory"); |
6 | 294 | } else if (rc == MOSQ_ERR_PAYLOAD_SIZE) { |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
295 | syslog(LOG_NOTICE, "mosquitto_will_set: invalid payload size"); |
6 | 296 | } |
297 | mosquitto_lib_cleanup(); | |
298 | return rc; | |
299 | } | |
300 | ||
301 | mosquitto_max_inflight_messages_set(mosq, max_inflight); | |
302 | mosquitto_connect_callback_set(mosq, my_connect_callback); | |
303 | mosquitto_disconnect_callback_set(mosq, my_disconnect_callback); | |
304 | mosquitto_publish_callback_set(mosq, my_publish_callback); | |
305 | ||
12 | 306 | if ((rc = mosquitto_connect(mosq, Config.mosq_host, Config.mosq_port, keepalive))) { |
6 | 307 | if (rc == MOSQ_ERR_ERRNO) { |
308 | strerror_r(errno, err, 1024); | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
309 | syslog(LOG_NOTICE, "mosquitto_connect: error: %s", err); |
6 | 310 | } else { |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
311 | syslog(LOG_NOTICE, "mosquitto_connect: unable to connect (%d)", rc); |
6 | 312 | } |
313 | mosquitto_lib_cleanup(); | |
314 | return rc; | |
315 | } | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
316 | syslog(LOG_NOTICE, "Connected with %s:%d", Config.mosq_host, Config.mosq_port); |
6 | 317 | |
318 | /* | |
319 | * Initialise is complete, report our presence state | |
320 | */ | |
321 | mosquitto_loop_start(mosq); | |
322 | sprintf(buf, "1"); | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
323 | rc = mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, 1); |
6 | 324 | |
12 | 325 | if (debug) |
326 | fprintf(stdout, (char *)"Enter loop, connected %d\n", connected); | |
327 | ||
6 | 328 | do { |
329 | if (status == STATUS_CONNACK_RECVD) { | |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
330 | /* |
12 | 331 | * Here send our 1-wire sensors values |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
332 | */ |
10 | 333 | for (tmp1 = Config.w1therms; tmp1; tmp1 = old1) { |
334 | old1 = tmp1->next; | |
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
335 | |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
336 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
337 | * Build path and alias topic |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
338 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
339 | device = xstrcpy((char *)"/sys/bus/w1/devices/"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
340 | device = xstrcat(device, tmp1->master); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
341 | device = xstrcat(device, (char *)"/"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
342 | device = xstrcat(device, tmp1->name); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
343 | device = xstrcat(device, (char *)"/w1_slave"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
344 | alias = xstrcpy((char *)"sensor/temperature/"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
345 | alias = xstrcat(alias, hostname); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
346 | alias = xstrcat(alias, (char *)"/"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
347 | alias = xstrcat(alias, tmp1->master); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
348 | alias = xstrcat(alias, (char *)"/"); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
349 | alias = xstrcat(alias, tmp1->alias); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
350 | |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
351 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
352 | * Read sensor data |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
353 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
354 | if ((fp = fopen(device, "r"))) { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
355 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
356 | * The output looks like: |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
357 | * 72 01 4b 46 7f ff 0e 10 57 : crc=57 YES |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
358 | * 72 01 4b 46 7f ff 0e 10 57 t=23125 |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
359 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
360 | fgets(line, 50, fp); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
361 | line[strlen(line)-1] = '\0'; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
362 | if ((line[36] == 'Y') && (line[37] == 'E')) { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
363 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
364 | * CRC is Ok, continue |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
365 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
366 | fgets(line, 50, fp); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
367 | line[strlen(line)-1] = '\0'; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
368 | strtok(line, (char *)"="); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
369 | p = strtok(NULL, (char *)"="); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
370 | rc = sscanf(p, "%d", &temp); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
371 | if ((rc == 1) && (tmp1->lastval != temp)) { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
372 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
373 | * It is possible to have read errors or extreme values. |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
374 | * This can happen with bad connections so we compare the |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
375 | * value with the previous one. If the difference is too |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
376 | * much, we don't send that value. That also means that if |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
377 | * the next value is ok again, it will be marked invalid too. |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
378 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
379 | deviation = (temp + tmp1->lastval) / 10; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
380 | if ((tmp1->lastval == 0) || |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
381 | (tmp1->lastval && (temp > (tmp1->lastval - deviation)) && (temp < (tmp1->lastval + deviation)))) { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
382 | /* |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
383 | * Temperature is changed and valid, update and publish this. |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
384 | */ |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
385 | sprintf(buf, "%.1f", temp / 1000.0); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
386 | if ((rc = mosquitto_publish(mosq, &mid_sent, alias, strlen(buf), buf, qos, 0))) { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
387 | if (rc == MOSQ_ERR_NO_CONN) |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
388 | mosquitto_reconnect(mosq); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
389 | else |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
390 | syslog(LOG_NOTICE, "mainloop: error %d from mosquitto_publish", rc); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
391 | } |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
392 | } else { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
393 | if (debug) |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
394 | syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, tmp1->lastval, temp); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
395 | } |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
396 | tmp1->lastval = temp; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
397 | } |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
398 | } else { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
399 | syslog(LOG_NOTICE, "sensor %s/%s CRC error", tmp1->master, tmp1->name); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
400 | } |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
401 | fclose(fp); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
402 | tmp1->present = 1; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
403 | } else { |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
404 | tmp1->present = 0; |
12 | 405 | if (debug) |
406 | printf("sensor %s is missing\n", tmp1->name); | |
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
407 | } |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
408 | |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
409 | free(device); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
410 | device = NULL; |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
411 | free(alias); |
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
412 | alias = NULL; |
10 | 413 | } |
11
f78f313b1d34
Working reading thermometers and sending data to a MQTT server.
Michiel Broek <mbroek@mbse.eu>
parents:
10
diff
changeset
|
414 | usleep(1000000); |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
415 | |
6 | 416 | if (shutdown) { |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
417 | /* |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
418 | * Final publish 0 to clients/<hostname>/thermometers/state |
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
419 | */ |
6 | 420 | sprintf(buf, "0"); |
8
e584bc0177df
Server communication seems ok, can handle server shutdowns too.
Michiel Broek <mbroek@mbse.eu>
parents:
7
diff
changeset
|
421 | mosquitto_publish(mosq, &mid_sent, state, strlen(buf), buf, qos, true); |
6 | 422 | last_mid = mid_sent; |
423 | status = STATUS_WAITING; | |
424 | } | |
425 | } else if (status == STATUS_WAITING) { | |
12 | 426 | if (debug) |
427 | fprintf(stdout, (char *)"Waiting\n"); | |
6 | 428 | if (last_mid_sent == last_mid && disconnect_sent == false) { |
429 | mosquitto_disconnect(mosq); | |
430 | disconnect_sent = true; | |
431 | } | |
432 | usleep(100000); | |
433 | } | |
434 | rc = MOSQ_ERR_SUCCESS; | |
435 | ||
12 | 436 | } while (rc == MOSQ_ERR_SUCCESS && connected); |
437 | ||
438 | if (debug) | |
439 | fprintf(stdout, (char *)"Out of loop\n"); | |
6 | 440 | |
441 | mosquitto_loop_stop(mosq, false); | |
442 | mosquitto_destroy(mosq); | |
443 | mosquitto_lib_cleanup(); | |
444 | ||
12 | 445 | return rc; |
1 | 446 | } |
447 |