import paho.mqtt.client as mqtt import json import time import math import random # MQTT Broker settings MQTT_BROKER = "hp.henrypump.cloud" MQTT_TOPIC = "v1/devices/me/telemetry" # Data simulation settings DATA_INTERVAL = 10 * 60 # 10 minutes #SINE_WAVE_PERIOD = 3600 # 1 hour #RANDOM_MIN = 0 #RANDOM_MAX = 100 SHUTDOWN_DURATION = 30 * 60 # 30 minutes # Load data points configuration from JSON file with open('/Users/nico/Documents/GitHub/HP_InHand_IG502/code snippets/datapoints.json') as f: datapoints_config = json.load(f) # Shutdown state variables shutdown_active = False shutdown_start_time = 0 # MQTT Client setup client = mqtt.Client(client_id="rpiSim") client.username_pw_set(username="henrypumptest2") client.connect(MQTT_BROKER) def reconnect_to_broker(): if not client.is_connected(): try: client.reconnect() except Exception as e: print(f"Error reconnecting to broker: {e}") time.sleep(1) def round_to_nearest_ten_minutes(ts): return ts - (ts % 600000) + 600000 * ((ts // 600000) % 10) """ def generate_sine_wave_value(t, period, amplitude=1, offset=0): return amplitude * math.sin(2 * math.pi * t / period) + offset """ def generate_sine_wave_value(datapoint): amplitude = datapoints_config[datapoint]['amplitude'] frequency = datapoints_config[datapoint]['frequency'] phase = random.uniform(0, .5)#datapoints_config[datapoint]['phase'] offset = datapoints_config[datapoint]['offset'] value = amplitude * math.sin((time.time() * frequency) + phase) + offset if shutdown_active: return max(0, value - (time.time() - shutdown_start_time) / 60) else: return value """ def generate_random_value(min_val, max_val): return random.uniform(min_val, max_val) """ def generate_random_value(datapoint): min_val = datapoints_config[datapoint]['min'] max_val = datapoints_config[datapoint]['max'] value = random.uniform(min_val, max_val) if shutdown_active: return max(0, value - (time.time() - shutdown_start_time) / 60) else: return value def constant_value(datapoint): return datapoints_config[datapoint]["value"] def get_shutdown_state(): global shutdown_active global shutdown_start_time if shutdown_active: if time.time() - shutdown_start_time > SHUTDOWN_DURATION: shutdown_active = False else: return True else: if random.random() < 0.01: # 1% chance of entering shutdown state shutdown_active = True shutdown_start_time = time.time() return False """def get_datapoint_value(key, value_type): global shutdown_active if shutdown_active: if key == "value1": return max(0, value_type - (time.time() - shutdown_start_time) / 60) elif key == "value2": return False else: return 0 else: if key == "value1": return generate_sine_wave_value(time.time(), SINE_WAVE_PERIOD) elif key == "value2": return generate_random_value(0, 1) > 0.5 else: return generate_random_value(RANDOM_MIN, RANDOM_MAX) """ # Helper function to split the payload into chunks def chunk_payload(payload, chunk_size=20): chunked_values = list(payload["values"].items()) for i in range(0, len(chunked_values), chunk_size): yield { "ts": payload["ts"], "values": dict(chunked_values[i:i+chunk_size]) } while True: now = int(time.time()) if now % 600 == 0: ts = now * 1000 get_shutdown_state() """ values = { "value1": get_datapoint_value("value1", generate_sine_wave_value), "value2": get_datapoint_value("value2", generate_random_value), "value3": get_datapoint_value("value3", generate_random_value) }""" values = {} for datapoint in datapoints_config: if datapoints_config[datapoint]['type'] == 'sine_wave': values[datapoint] = generate_sine_wave_value(datapoint) elif datapoints_config[datapoint]['type'] == 'random': values[datapoint] = generate_random_value(datapoint) elif datapoints_config[datapoint]['type'] == 'constant': values[datapoint] = constant_value(datapoint) payload = {"ts": ts, "values": values} # Reconnect to broker if disconnected reconnect_to_broker() try: for chunk in chunk_payload(payload=payload): client.publish(MQTT_TOPIC, json.dumps(chunk)) time.sleep(2) print(f"Published data at {ts}: {payload}") except Exception as e: print(f"ERROR in Publish: {e}") time.sleep(1)