129 lines
4.7 KiB
Python
129 lines
4.7 KiB
Python
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) |