Migration to UV, introducing db_write, mqtt_ingestion, db_migrations, half working prototype.

This commit is contained in:
Andrej Mickov
2025-10-28 23:14:58 +01:00
parent 5028dae200
commit 0b96c72f45
47 changed files with 2641 additions and 81 deletions

View File

@@ -1,37 +1,67 @@
import redis
import logging
from datetime import datetime
from typing import Optional
from config import Payload
from config import config
logger = logging.getLogger(__name__)
class RedisWriter:
def __init__(self, host: str, port: int, db: int, password: Optional[str] = None):
def __init__(self):
"""Initialize Redis writer with config from environment"""
self.logger = logging.getLogger(__name__)
self.redis_client = redis.StrictRedis(host=host, port=port, db=db, password=password)
self.redis_client = redis.StrictRedis(
host=config.redis.host,
port=config.redis.port,
db=config.redis.db,
password=config.redis.password
)
try:
self.redis_client.ping()
self.logger.info("Connected to Redis server successfully.")
self.logger.info(f"Connected to Redis at {config.redis.host}:{config.redis.port}")
except redis.ConnectionError as e:
self.logger.error(f"Failed to connect to Redis server: {e}")
raise
def write_message(self, topic: str, payload: Payload):
def write_sensor_data(self, device_id: str, sensor_type: str, value: float) -> bool:
"""
Write a message to a Redis stream with the topic and payload.
- Stream: mqtt_stream: {device_id}:{sensor_type}
Write sensor data to Redis streams and latest values hash.
- Stream: mqtt_stream:{device_id}:{sensor_type}
- Hash: mqtt_latest:{device_id}
"""
device_id = payload.device_id
sensor_type = payload.sensor_type
timestamp = datetime.utcnow().isoformat()
stream_key= f"mqtt_stream:{device_id}:{sensor_type}"
stream_key = f"mqtt_stream:{device_id}:{sensor_type}"
hash_key = f"mqtt_latest:{device_id}"
stream_data = {
"value": str(payload),
"source": "mqtt",
"value": str(value),
"timestamp": timestamp
}
try:
message_id = self.redis_client.xadd(stream_key, stream_data,maxlen=1000)
self.logger.info(f"Message written to Redis: {stream_data}")
return message_id
# Write to stream
self.redis_client.xadd(stream_key, stream_data, maxlen=1000)
# Update latest value hash
self.redis_client.hset(hash_key, sensor_type, str(value))
self.redis_client.hset(hash_key, f"{sensor_type}_time", timestamp)
return True
except redis.RedisError as e:
self.logger.error(f"Failed to write message to Redis: {e}")
self.logger.error(f"Failed to write to Redis: {e}")
return False
def health_check(self) -> bool:
"""Check if Redis connection is healthy"""
try:
self.redis_client.ping()
return True
except redis.RedisError:
return False
def close(self):
"""Close Redis connection"""
try:
self.redis_client.close()
self.logger.info("Redis connection closed")
except Exception as e:
self.logger.error(f"Error closing Redis connection: {e}")