#!/usr/bin/env python3 """ Cariflex - OpenADR VEN (Virtual End Node) Reçoit les signaux DSR du VTN et les transmet à FlexMeasures. """ import asyncio import logging from datetime import datetime, timezone, timedelta from openleadr import OpenADRClient, enable_default_logging import requests import re enable_default_logging() logger = logging.getLogger("openleadr") FM_HOST = "https://cariflex.digitribe.fr" FM_EMAIL = "admin@digitribe.fr" FM_PASSWORD = "Digitribe972" VEN_ID = "Cariflex-VEN" VTN_URL = "http://localhost:8081" # Sensor IDs in FM SENSOR_CONSUMPTION_PRICE = 84 SENSOR_LOAD_CONTROL = 86 def fm_login(): session = requests.Session() session.verify = False r = session.get(f"{FM_HOST}/login") match = re.search(r']*csrf_token[^>]*value="([^"]+)"', r.text) if match: csrf = match.group(1) r = session.post(f"{FM_HOST}/login", data={ "email": FM_EMAIL, "password": FM_PASSWORD, "csrf_token": csrf, "remember": "y" }, allow_redirects=True) if "dashboard" in r.url: return session return None def post_sensor_data(session, sensor_id, value, unit, start, duration="PT1H"): r = session.post( f"{FM_HOST}/api/v3_0/sensors/{sensor_id}/data", json={"values": [value], "start": start, "duration": duration, "unit": unit}, timeout=30 ) return r.status_code in [200, 201, 202] async def main(): client = OpenADRClient( ven_id=VEN_ID, ven_name=VEN_ID, vtn_url=VTN_URL, ) logger.info(f"Starting Cariflex VEN: {VEN_ID}") logger.info(f"Connecting to VTN: {VTN_URL}") # Login to FM session = fm_login() if session: logger.info("Logged in to FlexMeasures") else: logger.error("Failed to login to FlexMeasures") return # Add event handler @client.on_event async def handle_event(event): logger.info(f"Received event: {event}") # Extract signal data for signal in event.get("event_signals", []): signal_name = signal.get("signal_name") for interval in signal.get("intervals", []): payload = interval.get("signal_payload", 0) dtstart = interval.get("dtstart", datetime.now(timezone.utc)) if signal_name == "ENERGY_PRICE": price = round(float(payload), 2) success = post_sensor_data( session, SENSOR_CONSUMPTION_PRICE, price, "EUR/MWh", dtstart.isoformat() if isinstance(dtstart, datetime) else str(dtstart) ) logger.info(f"Price {price} EUR/MWh: {success}") elif signal_name == "LOAD_CONTROL": success = post_sensor_data( session, SENSOR_LOAD_CONTROL, round(float(payload), 2), "%", dtstart.isoformat() if isinstance(dtstart, datetime) else str(dtstart) ) logger.info(f"Load control {payload}: {success}") return "optIn" # Run the client await client.run() if __name__ == "__main__": asyncio.run(main())