Files
templates/python/set_devices/ump_logger_demo.py

58 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""Синтетические записи УМП для проверки графиков без подключения платы."""
import math
from set_devices import ump_logger as codec
def sample(time_ms, period_ms=20):
"""Повторяемый цикл: пуск, разгон 6–16 мА, отключение и спад тока."""
phase = time_ms % 6000
started = 1000 <= phase < 5000
reset = 5000 <= phase < 5300
# Как в прошивке: фронт команды включает выход на 1000 мс.
start_out = 1000 <= phase < 2000
stop_out = 5000 <= phase < 6000
ramp = max(0, min(2500, phase - 1000))
if started:
current = 6 + 10 * ramp / 2500 + 0.2 * math.sin(phase / 90)
elif phase >= 5000:
current = 4 + 12 * max(0, 1 - (phase - 5000) / 300)
else:
current = 4
words = [0] * codec.WORDS
words[0], words[1] = time_ms & 65535, (time_ms >> 16) & 65535
words[2] = 1 | (0x100 if 5000 <= phase < 5000 + period_ms else 0)
words[3] = (int(started) << 7) | (int(reset) << 6)
words[4] = int(1200 <= phase < 5100) | (int(started) << 1) | (int(reset) << 2)
words[5] = int(start_out) | (int(stop_out) << 1) | (int(started) << 2)
words[6] = (2000 - phase) if start_out else ((6000 - phase) if stop_out else 0)
words[7] = max(0, 250 - phase)
words[8] = round(500 + (current - 4) * 3000 / 16)
words[9] = round(current * 10)
for channel in range(4):
measured = round(120 * math.sin(phase / (180 + channel * 70) + channel))
words[10 + channel] = measured & 65535
words[14 + channel] = (1 << channel) if 5100 <= phase < 5400 else 0
words[36 + channel] = 2048 + measured * 4
words[18:24] = [0xE07F, words[3], 6, 16, (time_ms // 100) & 65535, 0]
words[24:31] = [6, 16, 500, 3500, 2000, 500, 3500]
words[31:36] = [ramp if started else 0, 2500, 60, 160, round(ramp * 1000 / 2500)]
return codec.sample(words)
def capture(period_ms):
"""Пример архива: до 399 точек предыстории, отключение и 1 с после него."""
before = list(range(5000, -1, -period_ms))[1:400][::-1]
after = list(range(5000 + period_ms, 6000, period_ms)) + [6000]
available = codec.CAPACITY - len(before) - 1
truncated = len(after) > available
if truncated:
after = after[:available - 1] + after[-1:]
records = [sample(t, period_ms) for t in before + [5000] + after]
# Последний снимок относится к концу постинтервала, а не новому циклу.
records[-1]['event'] = 5 | (0x200 if truncated else 0)
records[-1]['post_truncated'] = int(truncated)
records[-1]['off_trigger'] = 0
return records