thermferm/units.c

changeset 182
dd69ccba8fa8
parent 181
4099412fca09
child 183
6c3accd7e60e
equal deleted inserted replaced
181:4099412fca09 182:dd69ccba8fa8
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
23 #include "thermferm.h"
24 #include "devices.h"
25 #include "units.h"
26 #include "xutil.h"
27
28
29 extern int debug;
30 extern sys_config Config;
31 extern int my_shutdown;
32
33 extern const char UNITMODE[5][8];
34
35
36
37 int read_w1_28(char *address, int *val)
38 {
39 devices_list *device;
40 int tmp;
41
42 for (device = Config.devices; device; device = device->next) {
43 if (strcmp(address, device->uuid) == 0) {
44 tmp = device->value;
45 *val = tmp;
46 return device->present;
47 }
48 }
49
50 return DEVPRESENT_NO;
51 }
52
53
54
55 #ifdef HAVE_WIRINGPI_H
56 PI_THREAD (my_units_loop)
57 #else
58 void *my_units_loop(void *threadid)
59 #endif
60 {
61 units_list *unit;
62 int rc, temp, deviation;
63
64 /*
65 * Initialize units for processing
66 */
67 for (unit = Config.units; unit; unit = unit->next) {
68 /*
69 * Safety, turn everything off
70 */
71 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = 0;
72 if (unit->profile && (int)unit->prof_started && (unit->mode == UNITMODE_PROFILE)) {
73 syslog(LOG_NOTICE, "Starting unit %s profile %s", unit->name, unit->profile);
74 } else if (unit->mode == UNITMODE_BEER) {
75 syslog(LOG_NOTICE, "Starting unit %s beer cooler at %.1f degrees", unit->name, unit->beer_set);
76 } else if (unit->mode == UNITMODE_FRIDGE) {
77 syslog(LOG_NOTICE, "Starting unit %s as refridgerator at %.1f degrees", unit->name, unit->fridge_set);
78 } else if (unit->mode == UNITMODE_NONE) {
79 syslog(LOG_NOTICE, "Starting unit %s in inactive state", unit->name);
80 } else {
81 syslog(LOG_NOTICE, "Starting unit %s in off state", unit->name);
82 }
83 }
84
85 syslog(LOG_NOTICE, "Thread my_units_loop started");
86 if (debug)
87 fprintf(stdout, "Thread my_units_loop started\n");
88
89 /*
90 * Loop forever until the external shutdown variable is set.
91 */
92 for (;;) {
93
94 if (my_shutdown)
95 break;
96
97 /*
98 * Update the state of all fermenter units
99 */
100 for (unit = Config.units; unit; unit = unit->next) {
101
102 if (my_shutdown)
103 break;
104
105 if (unit->air_address) {
106 rc = read_w1_28(unit->air_address, &temp);
107 if (rc == DEVPRESENT_YES) {
108 /*
109 * It is possible to have read errors or extreme values.
110 * This can happen with bad connections so we compare the
111 * value with the previous one. If the difference is too
112 * much, we don't send that value. That also means that if
113 * the next value is ok again, it will be marked invalid too.
114 * Maximum error is 40 degrees for now.
115 */
116 deviation = 40000;
117 if ((unit->air_temperature == 0) ||
118 (unit->air_temperature && (temp > (int)unit->air_temperature - deviation) && (temp < ((int)unit->air_temperature + deviation)))) {
119 unit->air_temperature = temp;
120 unit->air_state = 0;
121 } else {
122 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->air_temperature, temp);
123 if (debug) {
124 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->air_temperature, temp);
125 }
126 }
127 } else if (rc == DEVPRESENT_ERROR) {
128 unit->air_state = 1;
129 } else {
130 unit->air_state = 2;
131 }
132 }
133 if (my_shutdown)
134 break;
135
136 if (unit->beer_address) {
137 rc = read_w1_28(unit->beer_address, &temp);
138 if (rc == DEVPRESENT_YES) {
139 deviation = 40000;
140 if ((unit->beer_temperature == 0) ||
141 (unit->beer_temperature && (temp > (int)unit->beer_temperature - deviation) && (temp < ((int)unit->beer_temperature + deviation)))) {
142 unit->beer_temperature = temp;
143 unit->beer_state = 0;
144 } else {
145 syslog(LOG_NOTICE, "deviation error deviation=%d, old=%d new=%d", deviation, unit->beer_temperature, temp);
146 if (debug) {
147 fprintf(stdout, "deviation error deviation=%d, old=%d new=%d\n", deviation, unit->beer_temperature, temp);
148 }
149 }
150 } else if (rc == DEVPRESENT_ERROR) {
151 unit->beer_state = 1;
152 } else {
153 unit->beer_state = 2;
154 }
155 }
156 if (my_shutdown)
157 break;
158
159 }
160 usleep(100000);
161 }
162
163 /*
164 * Stop units processing in a neat way
165 */
166 for (unit = Config.units; unit; unit = unit->next) {
167 /*
168 * Turn everything off
169 */
170 unit->heater_state = unit->cooler_state = unit->fan_state = unit->door_state = 0;
171 device_out(unit->heater_address, unit->heater_state);
172 device_out(unit->cooler_address, unit->cooler_state);
173 device_out(unit->fan_address, unit->fan_state);
174 syslog(LOG_NOTICE, "Stopped unit %s mode %s", unit->name, UNITMODE[unit->mode]);
175 }
176
177 syslog(LOG_NOTICE, "Thread my_units_loop stopped");
178 if (debug)
179 fprintf(stdout, "Thread my_units_loop stopped\n");
180 return 0;
181 }
182
183

mercurial