Blame view

src/utils/plc/guitalens_observatory/run_goc.py 13.7 KB
ac31ddb1   Alain Klotz   New celme documen...
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
# -*- 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

96e2b8ea   Alain Klotz   Ameliorations sur...
122
123
124
125
126
# === Configuration of security
delay_to_open_limit = 900
wind_speed_ms_limit = 5/3.6
tmp_cielcor_lim = -5

ac31ddb1   Alain Klotz   New celme documen...
127
# === Main loop
96e2b8ea   Alain Klotz   Ameliorations sur...
128
greenled_state = 0
ac31ddb1   Alain Klotz   New celme documen...
129
t0 = time.time()
96e2b8ea   Alain Klotz   Ameliorations sur...
130
131
t0closing = time.time() - delay_to_open_limit
delay_to_open = 0
ac31ddb1   Alain Klotz   New celme documen...
132
t0file = 0
96e2b8ea   Alain Klotz   Ameliorations sur...
133
t0wind = 0
ac31ddb1   Alain Klotz   New celme documen...
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
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):
96e2b8ea   Alain Klotz   Ameliorations sur...
218
        if (tmp_cielcor > tmp_cielcor_lim):
ac31ddb1   Alain Klotz   New celme documen...
219
220
221
           meteo_conditions = meteo_conditions +1
    if (err_rg11==0) and (rain_state==1):
        meteo_conditions = meteo_conditions +2
96e2b8ea   Alain Klotz   Ameliorations sur...
222
    if (err_cv7==0) and (wind_speed_ms>wind_speed_ms_limit):
ac31ddb1   Alain Klotz   New celme documen...
223
224
225
226
227
228
229
230
231
        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()
96e2b8ea   Alain Klotz   Ameliorations sur...
232
233
    rep.new_status("PLC","20181014_0854")
    rep.append_entity("PLC_STATUS", "Raspberry", "20181014_0854", "Guitalens Observatory",date_iso_utc)
ac31ddb1   Alain Klotz   New celme documen...
234
235
236
237
238
239
240
    # --- 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")
96e2b8ea   Alain Klotz   Ameliorations sur...
241
242
243
244
    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")
ac31ddb1   Alain Klotz   New celme documen...
245
246
247
248
249
    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)")
96e2b8ea   Alain Klotz   Ameliorations sur...
250
251
252
    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")
ac31ddb1   Alain Klotz   New celme documen...
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
    # --- 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
96e2b8ea   Alain Klotz   Ameliorations sur...
319
    delay_to_open = 0
ac31ddb1   Alain Klotz   New celme documen...
320
    if (mode_came_msg=="Auto") and (err_came==0):
96e2b8ea   Alain Klotz   Ameliorations sur...
321
        delay_to_open = time.time()-t0closing;
ac31ddb1   Alain Klotz   New celme documen...
322
323
324
325
326
327
328
        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)
96e2b8ea   Alain Klotz   Ameliorations sur...
329
330
            if (meteo_conditions>0):
                t0closing = time.time()
ac31ddb1   Alain Klotz   New celme documen...
331
        else:
96e2b8ea   Alain Klotz   Ameliorations sur...
332
            # --- Il fait nuit mais pas beau
ac31ddb1   Alain Klotz   New celme documen...
333
334
335
336
337
338
339
340
341
            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:
96e2b8ea   Alain Klotz   Ameliorations sur...
342
                # --- Il fait nuit et il fait beau
ac31ddb1   Alain Klotz   New celme documen...
343
                if (roof_state_msg != 'Opened'):
96e2b8ea   Alain Klotz   Ameliorations sur...
344
                    if (delay_to_open>delay_to_open_limit):
ac31ddb1   Alain Klotz   New celme documen...
345
                        # --- Cela fait + de 600s que le toit avait ete prealablement ferme
96e2b8ea   Alain Klotz   Ameliorations sur...
346
                        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))
ac31ddb1   Alain Klotz   New celme documen...
347
348
349
350
                        if roof_action == True:
                            driver_came.do_open_roof(27)
                        time.sleep(delay_roof_sec)
                    else:
96e2b8ea   Alain Klotz   Ameliorations sur...
351
                        print("==> Il fait nuit, il fait beau {} mais -{}s ({:.0f}) depuis la precedente fermeture.".format(meteo_conditions,delay_to_open_limit,delay_to_open))
ac31ddb1   Alain Klotz   New celme documen...
352
353
354

    # === Wait 1 seconds before the next read
    time.sleep(1)