Skip to content

Commit abf960c

Browse files
committed
feat: Running Lightning instance in its own thread to be non blocking
1 parent ce606b3 commit abf960c

File tree

3 files changed

+155
-122
lines changed

3 files changed

+155
-122
lines changed

DFRobot_AS3935_ordinary.py

Lines changed: 0 additions & 120 deletions
This file was deleted.

lightning.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
'''
2+
# @file DFRobot_AS3935_ordinary.py
3+
# @brief SEN0290 Lightning Sensor
4+
# @n This sensor can detect lightning and display the distance and intensity of the lightning within 40 km
5+
# @n It can be set as indoor or outdoor mode.
6+
# @n The module has three I2C, these addresses are:
7+
# @n AS3935_ADD1 0x01 A0 = 1 A1 = 0
8+
# @n AS3935_ADD2 0x02 A0 = 0 A1 = 1
9+
# @n AS3935_ADD3 0x03 A0 = 1 A1 = 1
10+
# @copyright Copyright (c) 2010 DFRobot Co.Ltd (http://www.dfrobot.com)
11+
# @licence The MIT License (MIT)
12+
# @author [TangJie](jie.tang@dfrobot.com)
13+
# @version V1.0.2
14+
# @date 2019-09-28
15+
# @url https://github.com/DFRobor/DFRobot_AS3935
16+
'''
17+
18+
import sys
19+
sys.path.append('../')
20+
import time
21+
from DFRobot_AS3935_Lib import DFRobot_AS3935
22+
import RPi.GPIO as GPIO
23+
from datetime import datetime
24+
from logger import Logger
25+
import os
26+
from mqtt_client import MQTTClient
27+
import threading
28+
29+
logger_instance = Logger(location=os.getenv('STATION_NAME'))
30+
mqtt_client_instance = MQTTClient(host="localhost", port=1883)
31+
32+
#I2C address
33+
AS3935_I2C_ADDR1 = 0X01
34+
AS3935_I2C_ADDR2 = 0X02
35+
AS3935_I2C_ADDR3 = 0X03
36+
37+
#Antenna tuning capcitance (must be integer multiple of 8, 8 - 120 pf)
38+
AS3935_CAPACITANCE = 96
39+
IRQ_PIN = 7
40+
41+
#Indoor/outdoor mode selection
42+
AS3935_INDOORS = 0
43+
AS3935_OUTDOORS = 1
44+
AS3935_MODE = AS3935_INDOORS
45+
46+
#Enable/disable disturber detection
47+
AS3935_DIST_DIS = 0
48+
AS3935_DIST_EN = 1
49+
AS3935_DIST = AS3935_DIST_EN
50+
51+
GPIO.setmode(GPIO.BOARD)
52+
53+
sensor = DFRobot_AS3935(AS3935_I2C_ADDR3, bus = 1)
54+
if (sensor.reset()):
55+
print("init sensor sucess.")
56+
else:
57+
print("init sensor fail")
58+
while True:
59+
pass
60+
61+
#Configure sensor
62+
sensor.manual_cal(AS3935_CAPACITANCE, AS3935_MODE, AS3935_DIST)
63+
64+
class Lightning:
65+
_instance = None
66+
_lock = threading.Lock()
67+
_station_id = ""
68+
69+
def __new__(cls, *args, **kwargs):
70+
with cls._lock: # Thread-safe singleton
71+
if cls._instance is None:
72+
cls._instance = super(Lightning, cls).__new__(cls)
73+
cls._instance._initialized = False
74+
cls._instance.running = False
75+
return cls._instance
76+
77+
def __init__(self, station_id):
78+
if not getattr(self, '_initialized', False):
79+
super().__init__()
80+
self.running = False
81+
self._initialized = True
82+
self._station_id = station_id
83+
84+
85+
def begin_lightning_detection(self):
86+
87+
88+
# Connect the IRQ and GND pin to the oscilloscope.
89+
# uncomment the following sentences to fine tune the antenna for better performance.
90+
# This will dispaly the antenna's resonance frequency/16 on IRQ pin (The resonance frequency will be divided by 16 on this pin)
91+
# Tuning AS3935_CAPACITANCE to make the frequency within 500/16 kHz plus 3.5% to 500/16 kHz minus 3.5%
92+
#
93+
# sensor.setLco_fdiv(0)
94+
# sensor.set_irq_output_source(3)
95+
96+
#view all register data
97+
#sensor.print_all_regs()
98+
#Set to input mode
99+
GPIO.setup(IRQ_PIN, GPIO.IN)
100+
#Set the interrupt pin, the interrupt function, rising along the trigger
101+
GPIO.add_event_detect(IRQ_PIN, GPIO.RISING, callback = self.callback_handle)
102+
logger_instance.log.info("start lightning detect.")
103+
104+
while self.running:
105+
time.sleep(1.0)
106+
107+
def run(self):
108+
self.running = True
109+
self.begin_lightning_detection()
110+
111+
def stop(self):
112+
logger_instance.log.info("Shutting lightning thread down")
113+
self.running = False
114+
115+
def callback_handle(self, channel):
116+
global sensor
117+
time.sleep(0.005)
118+
intSrc = sensor.get_interrupt_src()
119+
if intSrc == 1:
120+
lightning_distKm = sensor.get_lightning_distKm()
121+
logger_instance.log.info('Lightning occurs!')
122+
logger_instance.log.info('Distance: %dkm'%lightning_distKm)
123+
124+
lightning_energy_val = sensor.get_strike_energy_raw()
125+
logger_instance.log.info('Intensity: %d '%lightning_energy_val)
126+
127+
128+
data = {
129+
"distance": lightning_distKm,
130+
"distanceFormat": "km",
131+
"intensity": lightning_energy_val,
132+
"stationId": self.station_id,
133+
"timestamp": time.time()
134+
}
135+
136+
logger_instance.log.info(data)
137+
mqtt_client_instance.publish("weather/lightning", data)
138+
139+
elif intSrc == 2:
140+
logger_instance.log.info('Disturber discovered!')
141+
elif intSrc == 3:
142+
logger_instance.log.info('Noise level too high!')
143+
else:
144+
pass

weather-service.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import bme280_sensor
22
from mqtt_client import MQTTClient
3-
from DFRobot_AS3935_ordinary import begin_lightning_detection
3+
from lightning import Lightning
44
from wind_direction import WindDirection
55
from wind import WindSpeed
66
from rainfall import Rainfall
@@ -25,6 +25,7 @@ def main():
2525
wind_direction_instance = WindDirection()
2626
wind_speed_instance = WindSpeed()
2727
rainfall_instance = Rainfall()
28+
lightning_instance = None
2829

2930
wind_direction_thread = threading.Thread(target=wind_direction_instance.run)
3031
wind_speed_thread = threading.Thread(target=wind_speed_instance.run)
@@ -56,7 +57,11 @@ def main():
5657
sleep(2)
5758
continue
5859

59-
begin_lightning_detection(mqtt_client_instance._station_id)
60+
if lightning_instance == None:
61+
lightning_instance = Lightning(mqtt_client_instance._station_id)
62+
lightning_thread = threading.Thread(target=lightning_instance.run)
63+
lightning_thread.start()
64+
6065
logger_instance.log.info('Fetching data')
6166
weather_data = bme280_sensor.get_all_data()
6267
rainfall = rainfall_instance.get_current_rainfall()
@@ -94,5 +99,9 @@ def main():
9499
wind_speed_thread.join(timeout=5)
95100
rainfall_thread.join(timeout=5)
96101

102+
if lightning_instance != None:
103+
lightning_instance.stop()
104+
lightning_thread.join(timeout=5)
105+
97106
if __name__ == "__main__":
98107
main()

0 commit comments

Comments
 (0)