Skip to content

Commit d3a6a0e

Browse files
authored
Merge pull request #34 from jef41/bugfix
RC 0.1.2 testing
2 parents 0048be9 + 7da5690 commit d3a6a0e

16 files changed

+396
-275
lines changed

bridge/lib/bridge_main.py

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
''' works in principle with async
2-
could look at running wifi from core1 - doesn't seem to work
3-
look at running ble collection on core1
4-
nearly at __version__ 1.0.0
5-
requires some code tidying - remove comments & old commented out code that is not used
1+
''' central handler holds most coros & passes data between
62
'''
73
import logging
84
import gc
@@ -56,13 +52,13 @@ def __init__(self):
5652
def initialised(self):
5753
return self.rtc
5854

59-
async def bridge_main(self, onboard_led, providers, simulate_beacons: bool = False):
55+
async def bridge_main(self, onboard_led, simulate_beacons: bool = False):
6056
gc.collect()
6157
self.onboard_led = onboard_led
62-
if providers is None:
63-
self.providers = self.get_providers()
64-
else:
65-
self.providers = providers
58+
#if providers is None:
59+
# self.providers = self.set_providers()
60+
#else:
61+
# self.providers = providers
6662
# add any webhooks defined in config
6763
# todo !! not currently implemented/tested
6864
self.webhook_providers = self._get_webhook_providers()
@@ -80,7 +76,7 @@ async def bridge_main(self, onboard_led, providers, simulate_beacons: bool = Fal
8076
provider__start_message = provider.start() #todo look into this
8177
if not provider__start_message:
8278
provider__start_message = ''
83-
self.logger.info("...started: {} {}".format(provider, provider__start_message))
79+
self.logger.info(f"...started: {provider} {provider__start_message}")
8480
# find configured colours
8581
for colour in provider.col_dest.keys():
8682
if colour not in self.enabled_colours:
@@ -125,7 +121,7 @@ async def bridge_main(self, onboard_led, providers, simulate_beacons: bool = Fal
125121
print('Trapped cancelled error.')
126122
raise
127123
except KeyboardInterrupt:
128-
# todo: is this actioned here? investigate
124+
# this is not usually actioned here, calling async coro captures the KB interrupt
129125
print("cancelling tasks...")
130126
self.handler.cancel()
131127
self.scanner.cancel()
@@ -165,9 +161,9 @@ async def _scan_for_ibeacons(self, simulate=False):
165161
await task # then wait for task to complete
166162
#res = await asyncio.gather(t1,t2, return_exceptions=True)
167163
except asyncio.TimeoutError: # These only happen if return_exceptions is False
168-
print('Timeout') # With the default times, cancellation occurs first
164+
logger.warning('scanner Timeout') # With the default times, cancellation occurs first
169165
except asyncio.CancelledError:
170-
print('Cancelled')
166+
logger.warning('scanner Cancelled')
171167
#asyncio.sleep_ms(randrange(100, 750))
172168
#pckt_complete = True
173169
else:
@@ -179,9 +175,10 @@ async def _scan_for_ibeacons(self, simulate=False):
179175
async for result in scanner:
180176
if result.adv_data and result.adv_data[5:11] == iBeacon_prefix:
181177
#print("match")
182-
rssi = result.rssi
178+
#rssi = result.rssi
183179
# Extract and process iBeacon data
184180
#await _beacon_callback(iBeacon_data, rssi, simulate)
181+
#print(f"RSSI:{result.rssi}")
185182
iBeacon_data = iBeaconStatus(result.adv_data, result.rssi, result.device.addr_hex())
186183
#print(iBeacon_data)
187184
await self._beacon_callback(iBeacon_data, simulate)
@@ -322,8 +319,7 @@ def _get_webhook_providers(self):
322319
webhook_providers.append(WebhookCloudProvider(url, self.config))
323320
return webhook_providers
324321

325-
def get_providers(self, network=False):
326-
#
322+
def set_providers(self, network=False):
327323
if network:
328324
normal_providers = [
329325
#PrometheusCloudProvider(self.config),
@@ -342,7 +338,7 @@ def get_providers(self, network=False):
342338
CSVFileProvider(self.config),
343339
]
344340
self.logger.warning('No network credentials specified. Enabling local CSV logging only.')
345-
return normal_providers
341+
self.providers = normal_providers
346342

347343
def get_time(self):
348344
result = False
@@ -361,24 +357,28 @@ def max_av_period(providers, colours):
361357
# this is how many records from each tilt that will be saved
362358
# called once per colour?
363359
col_max = {}
364-
max_av = 0
360+
max_av = 30
365361
try:
366362
for provider in providers:
367363
#print(f"*** colours {colours}")
368364
for colour in colours:
369-
#print(f"*** test {provider}: {colour}, {provider.col_dest.keys()}")
370-
if colour in provider.col_dest.keys() and provider.averaging_period >= max_av -1:
371-
#print(f"*** colour match: {colour}")
372-
max_av = provider.averaging_period + 1 # so if passed 0 then this will still work
373-
col_max[colour] = max_av
365+
# print(f"*** test {provider}: {colour}, {provider.col_dest.keys()}")
366+
if colour in provider.col_dest.keys() and provider.averaging_period > max_av:
367+
# print(f"*** colour match: {colour}")
368+
#max_av = provider.averaging_period + 1 # so if passed 0 then this will still work
369+
# keep a minimum of 30 secs worth or readings
370+
#max_av = provider.averaging_period + 1 if max_av < 30 else max_av
371+
#col_max[colour] = max_av
372+
max_av = provider.averaging_period
374373
#print(f"*** {col_max}")
375374
else:
376375
#print(f"*** no match {colour} av_period {provider.averaging_period}")
377376
pass
377+
col_max.update({colour: max_av})
378378
except Exception as e:
379379
self.logger.error(f"max_av_period error: {e}")
380380
raise
381-
#logger.debug(f"col_max: {col_max}")
381+
#print(f"col_max: {col_max}")
382382
return col_max
383383

384384
async def debug_memory(logger):

bridge/lib/configuration/bridge_config.py

Lines changed: 54 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ def __init__(self, data: dict):
1414
self.wifi_check_interval = 3600
1515
# Debug log
1616
self.debug_log = [20, 1]
17-
# Queue
18-
self.queue_size = 15
19-
self.queue_empty_sleep_seconds = 1
20-
self.averaging_period = 30 # 0 21000
17+
# Defaults
18+
self.default_averaging_period = 30
19+
self.default_temp_unit = "C"
2120
# Broadcast Data ranges
2221
self.temp_range_min = 32
2322
self.temp_range_max = 212
@@ -28,8 +27,6 @@ def __init__(self, data: dict):
2827
self.webhook_limit_rate = 1
2928
self.webhook_limit_period = 1
3029
# CSV File
31-
#self.csv_log_max_kb = 60
32-
self.csv_log_temp_unit = "C"
3330
self.csv_log_period = 60
3431
self.csv_bkp_count = 4
3532
#self.csv_log_averaging_period = 60
@@ -80,22 +77,71 @@ def update(self, data: dict):
8077

8178
def get_original_gravity(self, colour: str):
8279
return self.__dict__.get(colour + '_original_gravity')
80+
#return getattr(self,colour + '_original_gravity', None)
8381

84-
def get_temp_offset(self, colour: str):
85-
return self.__dict__.get(colour + '_temp_offset', 0)
82+
#def get_temp_offset(self, colour: str):
83+
# return self.__dict__.get(colour + '_temp_offset', 0)
8684

8785
def get_brew_name(self, colour: str):
8886
return self.__dict__.get(colour + '_name', colour)
87+
#return getattr(self, colour + '_name', colour)
8988

9089
def get_gravity_offsets(self, colour: str):
9190
''' return a list of offsets
9291
where in each pair 1st value = raw, 2nd value = reference point;
9392
[[1.002,1.000],[1.107,1.100]]
9493
'''
9594
cal_vals = self.__dict__.get(colour + '_gravity_offsets')
95+
#cal_vals = getattr(self, colour + '_gravity_offsets')
9696
return cal_vals
9797

98+
def get_temp_offsets(self, colour: str):
99+
''' return a list of offsets
100+
index 0 is 'F' or 'C'
101+
each following pair 1st value = raw, 2nd value = reference point;
102+
['C', [5.5,5.0],[25.1,25.0]]
103+
'''
104+
#cal_vals = list(self.__dict__.get(colour + '_temp_offsets'))
105+
cal_vals = list(getattr(self, colour + '_temp_offsets', []))
106+
# make a new variable, not pointer to same one
107+
try:
108+
if cal_vals[0].upper() == 'C':
109+
#convert to F
110+
cal_vals.pop(0)
111+
cal_vals =[[(temp * 9/5) + 32 for temp in pair] for pair in cal_vals]
112+
else:
113+
cal_vals.pop(0)
114+
except Exception as e:
115+
cal_vals = None
116+
# print(e)
117+
raise type(e)(f"Error in bridge config: {e}") from e
118+
finally:
119+
#print(f"cal vals:{cal_vals}")
120+
return cal_vals
121+
122+
def get_temp_unit(self, lookup_key, name=False):
123+
''' Look up a provider temp_unit key in config, fall back to default config.temp_unit,
124+
and return either a single char or the full name (e.g., C or celsius).
125+
'''
126+
#temp_unit = self.__dict__.get(lookup_key, getattr(self, "default_temp_unit", "C"))
127+
temp_unit = getattr(self, lookup_key, self.default_temp_unit)
128+
129+
if temp_unit not in ("C", "c", "F", "f"):
130+
raise ValueError(f"{lookup_key} temp unit must be specified as 'C' or 'F'")
98131

132+
if temp_unit in ("C", "c"):
133+
return "celsius" if name else "C"
134+
135+
return "fahrenheit" if name else "F"
136+
137+
def get_averaging_period(self, lookup_key):
138+
''' look up the provider averaging period,
139+
if not present fall back to the default averaging period
140+
return an integer of seconds
141+
'''
142+
#return self.__dict__.get(lookup_key, getattr(self, lookup_key, self.default_averaging_period))
143+
return getattr(self, lookup_key, self.default_averaging_period)
144+
99145
@staticmethod
100146
def load(additional_config: dict = None):
101147
file_path = "/config.json"

bridge/lib/indicator.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,38 @@
1+
''' manage the Pico onboard LED
2+
TODO could verify that we are on a Pico & if not try to import the pin number from pin_mapping
3+
'''
14
from machine import Pin
25
import time
36
import asyncio
47

8+
59
class Status():
6-
'''
7-
an indicator LED
8-
'''
910
STATUS_OK = (10,3000)
1011
WIFI_CONNECTING = (10,400)
1112
WIFI_CONNECTED = (200,800)
1213
WIFI_DISCONNECTED = (800,200)
1314
STARTUP = (500,0)
14-
def __init__(self):
15+
STATUS_ERROR = (500,0)
16+
'''
17+
an indicator LED
18+
'''
19+
def __init__(self, status=STARTUP):
1520
self.led = Pin('LED', Pin.OUT)
16-
self.on_period = self.STARTUP[0] #ms
17-
self.off_period = self.STARTUP[1] #ms
21+
self.on_period = status[0] #ms
22+
self.off_period = status[1] #ms
1823
self.blinky = asyncio.create_task(self._blink_led())
1924
#asyncio.run(self._start())
2025

2126
async def _blink_led(self):
2227
#led = Pin('LED', Pin.OUT)
28+
#print("called led blink")
2329
while True:
2430
if self.off_period == 0:
31+
#print("led solid on")
2532
self.led.on() # otherwsie acts as a sort of 'busy' indicator
26-
await asyncio.sleep_ms(100)
33+
await asyncio.sleep_ms(self.on_period+10)
2734
else:
35+
#print("led blink")
2836
self.led.on()
2937
await asyncio.sleep_ms(self.on_period)
3038
self.led.off()
@@ -46,8 +54,11 @@ async def off(self):
4654
self.blinky.cancel()
4755
self.led.off()
4856

49-
async def _start(self):
50-
self.blinky = asyncio.create_task(self._blink_led())
57+
#async def _start(self):
58+
# self.blinky = asyncio.create_task(self._blink_led())
59+
60+
def on(self):
61+
self.led.on()
5162

5263

5364
async def test():

bridge/lib/models/provider_timer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def __init__(self):
1616

1717
def add(self, provider, period, adjust=None):
1818
#adjust = None if adjust == 0 else adjust # ensure we don't set invalid adjustment period
19+
# the initial call sends the averagin_period to adjust
1920
adjust = 10 if adjust == 0 else adjust # ensure we don't set invalid adjustment period, set to small value to force initial upload
2021
self.timer_list[provider] = self._get_new_timer(period, adjust)
2122

@@ -55,14 +56,15 @@ def __init__(self, default_period, adjust=None):
5556
# in which case call with default_period=900, adjust=300
5657
self.upload_due = asyncio.Event()
5758
#self.upload_due.clear()
58-
self.default_period = default_period*1000 if default_period else 1000 # default to 1 second if averaging set to 0
59+
#self.default_period = default_period*1000 if default_period else 10000 # default to 10s secs if averaging set to 0
60+
self.default_period = default_period*1000 # change to ms
5961
self.adjusted = False
6062
if adjust is not None:
6163
adjust = adjust*1000
6264
self.adjusted = True
6365
self.reinit(self.default_period if adjust is None else adjust)
6466
#self.upload_timer = Timer(period=self.default_period, mode=Timer.PERIODIC, callback=self.provider_callback)
65-
logger.debug(f"timer created with period {self.default_period if adjust is None else adjust}")
67+
logger.debug(f"timer created with {"adjusted" if adjust else "default"} period {self.default_period//1000 if adjust is None else adjust//1000}secs")
6668

6769
def provider_callback(self, timer):
6870
# set the thread safe flag

bridge/lib/models/tilt_history.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,10 +210,19 @@ def get_most_recent(self, limit):
210210
startb = self._wi - self.record_len
211211
stopb =-1 * self.record_len
212212
stepb = -1 * self.record_len
213+
latest_i = 0 if startb < 0 else startb
213214
#print(f"start, stop, step {startb}, {stopb}, {stepb}")
214-
for latest_i in range(startb, stopb, stepb):
215-
#latest_i = self._wi - self.record_len
216-
#print(f"*** testing {latest_i}")
215+
steps = self._size / self.record_len
216+
#print(f"steps:{steps}, mv:{self._size}")
217+
#for latest_i in range(startb, stopb, stepb):
218+
for i in range(steps):
219+
#print(f"get byte {latest_i}")
220+
# latest_i = (steps + 1) * startb
221+
# #latest_i = self._wi - self.record_len
222+
# #print(f"*** testing {latest_i}")
223+
# Loop through it 7 bytes at a time, starting from index 0 and then moving backwards
224+
# Loop: Start from index 0, then move backwards in steps of 7
225+
#for i in [0] + list(range(len(byte_array) - 7, 0, -7)):
217226
q_timestmp = mv_data[0+latest_i] | mv_data[1+latest_i]<<8 | mv_data[2+latest_i]<<16 | mv_data[3+latest_i]<<24
218227
logger.debug(f"timestamp:{q_timestmp} limit:{limit}")
219228
if q_timestmp > int(limit): # we have a match
@@ -223,6 +232,8 @@ def get_most_recent(self, limit):
223232
#logger.debug(f"{mv_data[4+i]} {mv_data[5+i]} {mv_data[6+i]}")
224233
num_results += 1
225234
break
235+
# Move backwards with wrap-around
236+
latest_i = (latest_i - self.record_len) % self._size
226237
except Exception as e:
227238
logger.debug(f"Error in get_most_recent: {e}")
228239
raise e

0 commit comments

Comments
 (0)