run_goc.py
13.7 KB
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
# -*- coding: utf-8 -*-
import time
import socket
import struct
import sys
import os
# --- Interaction with Raspberry GPIO
import fcntl
import driver_rg11
import driver_cv7
import driver_dht22
import driver_mlx
import driver_came
import driver_mife
# --- update the path of Python for util modules
py_path = os.sys.path
py_pwd = os.getcwd()
py_pwd = os.getcwd() + "/../.."
if (py_pwd not in py_path):
(os.sys.path).append(py_pwd)
import celme
import report
# === Some debug states
roof_action = True
delay_roof_sec = 20
oled_action = True
# === Init OLED
if (oled_action == True):
import Adafruit_SSD1306
from PIL import Image
from PIL import ImageDraw
from PIL import ImageFont
# Raspberry Pi pin configuration:
RST = 24
# 128x64 display with hardware I2C:
disp = Adafruit_SSD1306.SSD1306_128_64(rst=RST)
# Initialize library.
disp.begin()
# Clear display.
disp.clear()
disp.display()
# Create blank image for drawing.
# Make sure to create image with mode '1' for 1-bit color.
width = disp.width
height = disp.height
panel1 = Image.new('1', (width, height))
panel2 = Image.new('1', (width, height))
#logo = Image.open("logo1.ppm").convert('1').resize((128,32),3)
#création d'un objet font
fontpath = "/usr/share/fonts/truetype/dejavu/DejaVuSansMono-Bold.ttf"
font1 = ImageFont.truetype(fontpath,10)
# Get drawing object to draw on image.
draw1 = ImageDraw.Draw(panel1)
draw2 = ImageDraw.Draw(panel2)
# Draw a black filled box to clear the image.
draw1.rectangle((0,0,width,height), outline=0, fill=0)
#disp.image(logo)
#disp.display()
# =======================================
def valid_yesno (err_int):
if err_int==0:
return "yes"
else:
return "no"
# =======================================
def compute_error_code (err_int):
if err_int==0:
return "0"
else:
return "1"
# =======================================
def get_ip_address(ifname):
"""Lecture de l'adresse IP du Raspberry.
Exemple:
get_ip_address('eth0')
"""
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915,
struct.pack('256s', ifname[:15])
)[20:24])
# =======================================
def get_sunelev():
date = celme.Date("now")
site = celme.Site("GPS 2 E 43 148")
skyobj= {'planet':'Sun'}
outputs = ['elev']
target = celme.Target()
target.define(skyobj)
output0s = ['ra','dec']
results = target.ephem(date,site,output0s)
ra = results['RA']
dec = results['DEC']
skyobj= {'RA':ra , 'DEC':dec }
target.define(skyobj)
results = target.ephem(date,site,outputs)
elev = results['ELEV']
return elev
# === print the current Python version
try:
print (sys.version)
except:
pass
# === print the IP address
try:
print("IP = ",get_ip_address('eth0'))
except:
pass
# === Configuration of security
delay_to_open_limit = 900
wind_speed_ms_limit = 5/3.6
tmp_cielcor_lim = -5
# === Main loop
greenled_state = 0
t0 = time.time()
t0closing = time.time() - delay_to_open_limit
delay_to_open = 0
t0file = 0
t0wind = 0
while True:
# === Blink the green led
if greenled_state == 0:
driver_mife.do_led_green(18,1)
greenled_state = 1
else:
driver_mife.do_led_green(18,0)
greenled_state = 0
# === Clear the OLED displays
try:
draw1.rectangle((0,0,width,height), outline=0, fill=0)
draw2.rectangle((0,0,width,height), outline=0, fill=0)
except:
pass
# === Get Sun elevation
sunelev = get_sunelev();
# === Init the error supercode
err = 0
# === Get RG11 data
err_rg11, power_mife_rg11, rain_state, rain_state, power_mife_msg, rain_state_msg, pin34, pin36, pin38 = driver_rg11.get_data(19,20,25,0)
oled_rain = "RG11 : "
if (err_rg11>0):
print("RG11 err=",err_rg11)
err+=1
oled_rain += "Err"+str(err_rg11)
else:
oled_rain += rain_state_msg
# === Get CV7 data
err_cv7, power_mife_cv7, wind_dir_deg, wind_speed_ms, wind_tmp_degC, power_mife_msg, msg_wind, msg_temp = driver_cv7.get_data("/dev/ttyS0", 25,0)
oled_wind_speed = "Wind : "
oled_wind_dir = "Wind dir : "
if (err_cv7>0):
print("CV7 err=",err_cv7)
err+=2
oled_wind_speed += "Err"+str(err_cv7)
oled_wind_dir += "Err"+str(err_cv7)
else:
oled_wind_speed += '{:.2f}'.format(wind_speed_ms)+" m/s"
oled_wind_dir += '{:3.0f}'.format(wind_dir_deg)+ " deg"
# === Get DHT22 data
err_dht22, tmp, hum, seuil, data = driver_dht22.get_data(13,0)
oled_tmp = "Temp : "
oled_hum = "Humidity : "
if (err_dht22>0):
print("DHT22 err=",err_dht22)
err+=4
oled_tmp += "Err"+str(err_dht22)
oled_hum += "Err"+str(err_dht22)
else:
oled_tmp += "{:.1f}".format(tmp) + " degC"
oled_hum += "{:.0f}".format(hum) + " %"
# === Get MLX data
err_mlx, tmp_ciel, tmp_boit, raw_data_ciel, raw_data_boit =driver_mlx.get_data(0)
tmp_cielcor = tmp_ciel - tmp_boit * 0.7;
oled_skytmp = "Sky temp : "
if (err_mlx>0):
print("mlx err =",err_mlx)
err+=8
oled_skytmp += "Err"+str(err_mlx)
else:
oled_skytmp += "{:.2f}".format(tmp_ciel)+" degC"
# === Get Came data
err_came, power_came, mode_came, roof_state, power_came_msg, mode_came_msg, roof_state_msg, pin48, pin39, pin41,pin31 = driver_came.get_data(26,22,5,6,1)
oled_came1 = "Roof mode : "
oled_came2 = "Roof state : "
if (err_came>0):
oled_came1 += "Err"+str(err_mlx)
oled_came2 += "Err"+str(err_mlx)
else:
oled_came1 += mode_came_msg
oled_came2 += roof_state_msg
# === Compute the meteo conditions
meteo_conditions = 0
if (err_mlx==0):
if (tmp_cielcor > tmp_cielcor_lim):
meteo_conditions = meteo_conditions +1
if (err_rg11==0) and (rain_state==1):
meteo_conditions = meteo_conditions +2
if (err_cv7==0) and (wind_speed_ms>wind_speed_ms_limit):
meteo_conditions = meteo_conditions +4
if (err_rg11==1):
# --- critical error
meteo_conditions = meteo_conditions +8
# === Json status
date = celme.Date("now")
date_iso_utc = date.iso();
rep = report.Status_json()
rep.new_status("PLC","20181014_0854")
rep.append_entity("PLC_STATUS", "Raspberry", "20181014_0854", "Guitalens Observatory",date_iso_utc)
# --- Json device Came
rep.append_device("Came", "roof_controler", "S/N_A5EM", compute_error_code(err_came))
rep.append_value( "Error_code", "int",str(err_came),"","","0=OK 1=PowerPB 2=SwitchPB")
rep.append_value( "Power_input", "int",str(power_came),"","","0=0Volt 1=24Volts")
rep.append_value( "Mode_came", "int",str(mode_came),"","","0=Manual 1=Auto")
rep.append_value( "Roof_state", "int",str(roof_state),"","","0=Closed 1=Opened 2=Intermediate")
rep.append_value( "Meteo_conditions", "int",str(meteo_conditions),"","","0=OK +1=Clouds +2=Rain +4=Wind +8=CriticalError")
rep.append_value( "Delay_to_open", "int","{:.0f}".format(delay_to_open),"s","","Current delay to open since the meteo became OK")
rep.append_value( "Security_delay_to_open", "int","{:.0f}".format(delay_to_open_limit),"s","","Limit delay to open since the meteo becomes OK")
rep.append_value( "SkyTemperatureCor_lim", "float","{:+.2f}".format(tmp_cielcor_lim),"degC","","Limit of the corrected temperature of the sky to close roof")
rep.append_value( "Wind_speed_lim", "float","{:.2f}".format(wind_speed_ms_limit),"m/s","","Limit of wind speed to close the roof")
rep.append_value( "Sun_elevation", "float","{:+.3f}".format(sunelev),"deg","","Local elevation of the Sun")
# --- Json device CV7
rep.append_device("CV7", "weather_station", "S/N_09172419", compute_error_code(err_cv7))
rep.append_value( "Error_code", "int",str(err_cv7),"","","0=OK 1=SerialPB 2=FramePB")
rep.append_value( "Power_input", "int",str(power_mife_cv7),"","","0=0Volt 1=12Volts (Power from MiFe board)")
rep.append_value( "Wind_dir", "float","{:.2f}".format(wind_dir_deg),"degrees","Wind_direction","0=North 90=East")
rep.append_value( "Wind_speed", "float","{:.2f}".format(wind_speed_ms),"m/s","Wind_speed","Wind speed from ultrasonic sensors")
rep.append_value( "OutsideTemperature", "float","{:+.2f}".format(wind_tmp_degC),"degC","Temperature_outside","Temperature of the anemometer")
# --- Json device DHT22
rep.append_device("DHT22", "weather_station", "MiFe_DHT1_1", compute_error_code(err_dht22))
rep.append_value( "Error_code", "int",str(err_dht22),"","","0=OK 1=CheksumPB 2=LengthPB 3=NodataPB")
rep.append_value( "Temperature", "float","{:+.0f}".format(tmp),"degC","Temperature_outside","Temperature inside PLC box")
rep.append_value( "Humidity", "float","{:.0f}".format(hum),"percent","Humidity_outside","Humidity inside PLC box")
# --- device RG11
rep.append_device("RG11", "weather_station", "S/N_207588", compute_error_code(err_rg11))
rep.append_value( "Error_code", "int",str(err_rg11),"","","0=OK +1=PowerPB +2=NopowerPB +4=AllonePB")
rep.append_value( "RainSate", "int",str(rain_state),"","Rain_boolean","0=Dry 1=Rain 2=Unknown")
# --- device MLX90614
rep.append_device("MLX90614", "weather_station", "1", compute_error_code(err_mlx))
rep.append_value( "Error_code", "int",str(err_mlx),"","","0=OK 1=DataPB")
rep.append_value( "SkyTemperature", "float","{:+5.2f}".format(tmp_ciel),"degC","","Temperature of the sky")
rep.append_value( "CanTemperature", "float","{:+5.2f}".format(tmp_boit),"degC","","Temperature of the TO can")
rep.append_value( "SkyTemperatureCor", "float","{:+5.2f}".format(tmp_cielcor),"degC","Temperature_sky","Corrected temperature of the sky")
# --- save the Json status report
rep.save_json("/var/www/html/meteo/plc_guitalens.json")
# === String of results
date_jd_utc = date.jd();
date_digits_utc = date.digits(0)
msg_gene = "{:13.5f} {} {:+6.2f} {:2d} {:1d} ".format(date_jd_utc, date_digits_utc, sunelev,err,meteo_conditions)
msg_came = "{:2d} {:1d} {:1d} {:1d} ".format(err_came, power_came, mode_came, roof_state)
msg_mlx = "{:2d} {:+6.2f} {:+6.2f} {:+6.2f} ".format(err_mlx, tmp_ciel, tmp_boit, tmp_cielcor)
msg_rg11 = "{:2d} {:1d} {:1d} ".format(err_rg11, power_mife_rg11, rain_state)
msg_dht22 = "{:2d} {:+3.0f} {:3.0f} ".format(err_dht22, tmp, hum)
msg_cv7 = "{:2d} {:1d} {:3.0f} {:6.2f} {:+3.0f} ".format(err_cv7, power_mife_cv7, wind_dir_deg, wind_speed_ms, wind_tmp_degC)
msg = msg_gene + msg_came + msg_mlx + msg_rg11 + msg_dht22 + msg_cv7
print(msg)
# === File for web site
try:
dt = time.time()-t0file;
if (dt>30):
dateymdhms= date.ymdhms()
fic = "/var/www/html/meteo/meteo_{:04d}{:02d}{:02d}.txt".format(dateymdhms[0],dateymdhms[1],dateymdhms[2])
fichier = open(fic,"a")
fichier.write(msg)
fichier.write("\n")
fichier.close()
t0file = time.time()
except:
pass
# === Display OLED
try:
dt = time.time()-t0;
if (dt<6):
draw1.text((0, 10),oled_came1, font=font1, fill=255)
draw1.text((0, 20),oled_skytmp, font=font1, fill=255)
draw1.text((0, 30),oled_tmp, font=font1, fill=255)
draw1.text((0, 40),oled_hum, font=font1, fill=255)
disp.image(panel1)
elif (dt<12):
draw2.text((0, 10),oled_came2, font=font1, fill=255)
draw2.text((0, 20),oled_wind_speed, font=font1, fill=255)
draw2.text((0, 30),oled_wind_dir, font=font1, fill=255)
draw2.text((0, 40),oled_rain, font=font1, fill=255)
disp.image(panel2)
else:
t0 = time.time()
disp.display()
except:
pass
# === Roof action according security rules
delay_to_open = 0
if (mode_came_msg=="Auto") and (err_came==0):
delay_to_open = time.time()-t0closing;
if (sunelev>0):
# --- Il fait jour
if (roof_state_msg != 'Closed'):
print("==> Il fait jour et le toit n'est pas ferme. On ferme.")
if roof_action == True:
driver_came.do_close_roof(23)
time.sleep(delay_roof_sec)
if (meteo_conditions>0):
t0closing = time.time()
else:
# --- Il fait nuit mais pas beau
if (meteo_conditions>0):
# --- Il ne fait pas beau
if (roof_state_msg != 'Closed'):
print("==> Il fait nuit, il ne fait pas beau {} et le toit n'est pas ferme. On ferme.".format(meteo_conditions))
if roof_action == True:
driver_came.do_close_roof(23)
time.sleep(delay_roof_sec)
t0closing = time.time()
else:
# --- Il fait nuit et il fait beau
if (roof_state_msg != 'Opened'):
if (delay_to_open>delay_to_open_limit):
# --- Cela fait + de 600s que le toit avait ete prealablement ferme
print("==> Il fait nuit, il fait beau {} depuis +{}s et le toit n'est pas ouvert. On ouvre.".format(meteo_conditions,delay_to_open_limit))
if roof_action == True:
driver_came.do_open_roof(27)
time.sleep(delay_roof_sec)
else:
print("==> Il fait nuit, il fait beau {} mais -{}s ({:.0f}) depuis la precedente fermeture.".format(meteo_conditions,delay_to_open_limit,delay_to_open))
# === Wait 1 seconds before the next read
time.sleep(1)