Skip to content

Commit

Permalink
Merge pull request #3 from carlosmolinet/feature/flow-rate
Browse files Browse the repository at this point in the history
Add flow rate feature
  • Loading branch information
zweckj authored Nov 16, 2024
2 parents 6edb18c + 48363c5 commit 8569828
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions aioacaia/acaiascale.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import logging
import time

from collections import deque
from collections.abc import Awaitable, Callable

from dataclasses import dataclass
Expand Down Expand Up @@ -94,6 +95,10 @@ def __init__(
self._device_state: AcaiaDeviceState | None = None
self._weight: float | None = None

# flow rate
self.weight_history: deque[tuple[float, float]] = deque(maxlen=20) # Limit to 20 entries


# queue
self._queue: asyncio.Queue = asyncio.Queue()
self._add_to_queue_lock = asyncio.Lock()
Expand Down Expand Up @@ -138,6 +143,46 @@ def timer(self) -> int:
return 0

return int(self._timer_stop - self._timer_start)

@property
def flow_rate(self) -> float | None:
now = time.time()
flows = []

# Remove old readings (more than 5 seconds)
self.weight_history = [
(t, w) for t, w in self.weight_history if now - t <= 5
]

if len(self.weight_history) < 4:
return None

# Calculate flow rates using 3 readings ago
for i in range(3, len(self.weight_history)):
prev_time, prev_weight = self.weight_history[i - 3]
curr_time, curr_weight = self.weight_history[i]

time_diff = curr_time - prev_time
weight_diff = curr_weight - prev_weight


# Validate weight difference and flow rate limits
flow = weight_diff / time_diff
if flow <= 20.0: # Flow rate limit
flows.append(flow)

if not flows:
return None

# Compute the Exponential Moving Average (EMA)
alpha = 2 / (len(flows) + 1) # EMA weighting factor
ema = flows[0] # Initialize EMA with the first flow rate

for flow in flows[1:]:
ema = alpha * flow + (1 - alpha) * ema

_LOGGER.debug("Flow rate: %.2f g/s", ema)
return ema

def device_disconnected_handler(
self,
Expand Down Expand Up @@ -438,6 +483,16 @@ async def on_bluetooth_data_received(

elif isinstance(msg, Message):
self._weight = msg.value
timestamp = time.time()

# Check if weight is increasing before appending
if not self.weight_history or msg.value > self.weight_history[-1][1]:
self.weight_history.append((timestamp, msg.value))
elif msg.value < self.weight_history[-1][1] - 1:
# Clear history if weight decreases (1gr margin error)
self.weight_history.clear()
self.weight_history.append((timestamp, msg.value))

if msg.timer_running is not None:
self.timer_running = msg.timer_running
_LOGGER.debug("Got weight %s", str(msg.value))
Expand Down

0 comments on commit 8569828

Please sign in to comment.