Issue
Code backup
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
import serial
|
||||
import struct
|
||||
import csv
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# ================= CONFIG =================
|
||||
PORT = "COM3" # <-- cambia
|
||||
BAUD = 921600
|
||||
OUT_CSV = "imu_log.csv"
|
||||
|
||||
FRAME_FMT = "<H I 6h 6h H" # little-endian
|
||||
FRAME_SIZE = struct.calcsize(FRAME_FMT)
|
||||
MAGIC = 0xABCD
|
||||
|
||||
# ================= CRC ====================
|
||||
def crc16_xor(data: bytes) -> int:
|
||||
c = 0
|
||||
for b in data:
|
||||
c ^= b
|
||||
return c & 0xFFFF
|
||||
|
||||
# ================= SERIAL =================
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
|
||||
buffer = bytearray()
|
||||
|
||||
start_wall_time = None
|
||||
start_ts_us = None
|
||||
|
||||
print("Listening...")
|
||||
|
||||
try:
|
||||
with open(OUT_CSV, "w", newline="") as f:
|
||||
writer = csv.writer(f)
|
||||
writer.writerow([
|
||||
"timestamp",
|
||||
"imu1_ax","imu1_ay","imu1_az","imu1_gx","imu1_gy","imu1_gz",
|
||||
"imu2_ax","imu2_ay","imu2_az","imu2_gx","imu2_gy","imu2_gz"
|
||||
])
|
||||
|
||||
while True:
|
||||
buffer += ser.read(1024)
|
||||
|
||||
while len(buffer) >= FRAME_SIZE:
|
||||
# cerca MAGIC
|
||||
if buffer[0] != 0xCD or buffer[1] != 0xAB:
|
||||
buffer.pop(0)
|
||||
continue
|
||||
|
||||
frame = buffer[:FRAME_SIZE]
|
||||
buffer = buffer[FRAME_SIZE:]
|
||||
|
||||
# unpack
|
||||
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
|
||||
|
||||
# CRC check
|
||||
if crc16_xor(frame[:-2]) != crc:
|
||||
continue
|
||||
|
||||
# inizializza tempo base
|
||||
if start_wall_time is None:
|
||||
start_wall_time = datetime.now()
|
||||
start_ts_us = ts_us
|
||||
|
||||
# timestamp assoluto coerente con ESP
|
||||
delta_us = ts_us - start_ts_us
|
||||
ts = start_wall_time + timedelta(microseconds=delta_us)
|
||||
|
||||
writer.writerow([
|
||||
ts.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3],
|
||||
*imu
|
||||
])
|
||||
|
||||
# logging si può escludere
|
||||
print(
|
||||
ts.strftime("%H:%M:%S.%f")[:-3],
|
||||
"| 1:", tuple(imu[:6]),
|
||||
"| 2:", tuple(imu[6:])
|
||||
)
|
||||
except KeyboardInterrupt:
|
||||
ser.close()
|
||||
print("Stopped")
|
||||
@@ -0,0 +1,69 @@
|
||||
import serial
|
||||
import struct
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# ================= CONFIG =================
|
||||
PORT = "COM17" # <-- cambia
|
||||
BAUD = 2000000
|
||||
OUT_FILE = "imu_log.txt"
|
||||
|
||||
FRAME_FMT = "<H I 6f 6f H"
|
||||
# FRAME_FMT = "<H I 6h 6h H"
|
||||
FRAME_SIZE = struct.calcsize(FRAME_FMT)
|
||||
MAGIC = 0xABCD
|
||||
|
||||
# ================= CRC ====================
|
||||
def crc16_xor(data: bytes) -> int:
|
||||
c = 0
|
||||
for b in data:
|
||||
c ^= b
|
||||
return c & 0xFFFF
|
||||
|
||||
# ================= SERIAL =================
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
buffer = bytearray()
|
||||
|
||||
start_wall_time = None
|
||||
start_ts_us = None
|
||||
|
||||
print("Listening...")
|
||||
|
||||
with open(OUT_FILE, "w", encoding="utf-8") as f:
|
||||
while True:
|
||||
buffer += ser.read(1024)
|
||||
|
||||
while len(buffer) >= FRAME_SIZE:
|
||||
# ricerca MAGIC (0xABCD little-endian)
|
||||
if buffer[0] != 0xCD or buffer[1] != 0xAB:
|
||||
buffer.pop(0)
|
||||
continue
|
||||
|
||||
frame = buffer[:FRAME_SIZE]
|
||||
buffer = buffer[FRAME_SIZE:]
|
||||
|
||||
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
|
||||
|
||||
if crc16_xor(frame[:-2]) != crc:
|
||||
continue
|
||||
|
||||
# tempo base
|
||||
if start_wall_time is None:
|
||||
start_wall_time = datetime.now()
|
||||
start_ts_us = ts_us
|
||||
|
||||
delta_us = ts_us - start_ts_us
|
||||
ts = start_wall_time + timedelta(microseconds=delta_us)
|
||||
|
||||
imu1 = imu[:6]
|
||||
imu2 = imu[6:]
|
||||
|
||||
line = (
|
||||
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
|
||||
f"|1:{','.join(map(str, imu1))}"
|
||||
f"|2:{','.join(map(str, imu2))}\n"
|
||||
)
|
||||
|
||||
f.write(line)
|
||||
f.flush() # rimuovi se vuoi più performance
|
||||
|
||||
print(line.strip())
|
||||
@@ -0,0 +1,92 @@
|
||||
import serial
|
||||
import struct
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
# ================= CONFIG =================
|
||||
PORT = "COM17" # <-- cambia
|
||||
BAUD = 2000000
|
||||
OUT_FILE = "imu_log.txt"
|
||||
|
||||
# Formato frame ESP32 (raw)
|
||||
FRAME_FMT = "<H I 6h 6h H" # magic, ts_us, imu1 6x int16, imu2 6x int16, crc
|
||||
FRAME_SIZE = struct.calcsize(FRAME_FMT)
|
||||
MAGIC_BYTES = b'\xCD\xAB'
|
||||
|
||||
# Conversione accelerometro e giroscopio
|
||||
ACC_LSB_PER_G = 2048.0
|
||||
G_CONST = 9.80665
|
||||
GYRO_LSB_PER_DPS = 16.4
|
||||
DEG2RAD = 0.017453292519943295
|
||||
|
||||
# ================= CRC ====================
|
||||
def crc16_xor(data: bytes) -> int:
|
||||
c = 0
|
||||
for b in data:
|
||||
c ^= b
|
||||
return c & 0xFFFF
|
||||
|
||||
# ================= SERIAL =================
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
buffer = bytearray()
|
||||
|
||||
start_wall_time = None
|
||||
start_ts_us = None
|
||||
|
||||
print("Listening...")
|
||||
|
||||
def convert_acc(raw):
|
||||
return round(((raw / ACC_LSB_PER_G) * G_CONST)/10, 2)
|
||||
|
||||
def convert_gyro(raw):
|
||||
return round((raw / GYRO_LSB_PER_DPS) * DEG2RAD, 2)
|
||||
|
||||
with open(OUT_FILE, "w", encoding="utf-8") as f:
|
||||
while True:
|
||||
buffer += ser.read(1024)
|
||||
|
||||
while True:
|
||||
idx = buffer.find(MAGIC_BYTES)
|
||||
if idx == -1:
|
||||
buffer.clear()
|
||||
break
|
||||
if idx > 0:
|
||||
buffer = buffer[idx:]
|
||||
if len(buffer) < FRAME_SIZE:
|
||||
break
|
||||
|
||||
frame = buffer[:FRAME_SIZE]
|
||||
buffer = buffer[FRAME_SIZE:]
|
||||
|
||||
magic, ts_us, *imu_raw, crc = struct.unpack(FRAME_FMT, frame)
|
||||
|
||||
if crc16_xor(frame[:-2]) != crc:
|
||||
print("CRC error (resync)")
|
||||
continue
|
||||
|
||||
# Base timestamp
|
||||
if start_wall_time is None:
|
||||
start_wall_time = datetime.now()
|
||||
start_ts_us = ts_us
|
||||
|
||||
delta_us = ts_us - start_ts_us
|
||||
ts = start_wall_time + timedelta(microseconds=delta_us)
|
||||
|
||||
# Split raw dati
|
||||
imu1_raw = imu_raw[:6]
|
||||
imu2_raw = imu_raw[6:]
|
||||
|
||||
# Conversione in m/s² e rad/s
|
||||
imu1 = [convert_acc(imu1_raw[0]), convert_acc(imu1_raw[1]), convert_acc(imu1_raw[2]),
|
||||
convert_gyro(imu1_raw[3]), convert_gyro(imu1_raw[4]), convert_gyro(imu1_raw[5])]
|
||||
imu2 = [convert_acc(imu2_raw[0]), convert_acc(imu2_raw[1]), convert_acc(imu2_raw[2]),
|
||||
convert_gyro(imu2_raw[3]), convert_gyro(imu2_raw[4]), convert_gyro(imu2_raw[5])]
|
||||
|
||||
line = (
|
||||
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
|
||||
f"|1,{','.join(f'{v:.2f}' for v in imu1)}"
|
||||
f"|2,{','.join(f'{v:.2f}' for v in imu2)}\n"
|
||||
)
|
||||
|
||||
f.write(line)
|
||||
f.flush()
|
||||
print(line.strip())
|
||||
@@ -0,0 +1,25 @@
|
||||
import serial
|
||||
from datetime import datetime
|
||||
|
||||
PORT = "COM3" # oppure "/dev/ttyUSB0"
|
||||
BAUDRATE = 115200
|
||||
LOG_FILE = "serial_log.txt"
|
||||
|
||||
ser = serial.Serial(PORT, BAUDRATE, timeout=1)
|
||||
|
||||
print("In ascolto sulla seriale... Ctrl+C per uscire")
|
||||
|
||||
with open(LOG_FILE, "a", encoding="utf-8") as f:
|
||||
try:
|
||||
while True:
|
||||
line = ser.readline().decode(errors="ignore").strip()
|
||||
if line:
|
||||
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
|
||||
out = f"[{timestamp}] {line}"
|
||||
print(out)
|
||||
f.write(out + "\n")
|
||||
f.flush()
|
||||
except KeyboardInterrupt:
|
||||
print("\nChiusura...")
|
||||
finally:
|
||||
ser.close()
|
||||
@@ -0,0 +1,32 @@
|
||||
import serial
|
||||
import struct
|
||||
import time
|
||||
|
||||
# configurazione porta
|
||||
PORT = 'COM3' # cambia se serve
|
||||
BAUD = 921600
|
||||
|
||||
# struttura Sample = 1 uint32 + 2 IMUData
|
||||
# IMUData = 6 int16
|
||||
# Formato struct: < = little-endian
|
||||
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
|
||||
sample_size = struct.calcsize(fmt)
|
||||
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
print(f"Listening on {PORT}...")
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = ser.read(sample_size)
|
||||
if len(data) != sample_size:
|
||||
continue
|
||||
|
||||
s = struct.unpack(fmt, data)
|
||||
ts = s[0]
|
||||
imu1 = s[1:7]
|
||||
imu2 = s[7:13]
|
||||
|
||||
print(f"{ts} | 1:{imu1} | 2:{imu2}")
|
||||
except KeyboardInterrupt:
|
||||
ser.close()
|
||||
print("Closed")
|
||||
@@ -0,0 +1,39 @@
|
||||
import serial
|
||||
import struct
|
||||
|
||||
# ---------------- CONFIG ----------------
|
||||
PORT = 'COM3' # aggiorna con la tua COM
|
||||
BAUD = 921600
|
||||
|
||||
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
|
||||
sample_size = struct.calcsize(fmt)
|
||||
|
||||
# ---------------- INIT ------------------
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
print(f"Listening on {PORT}...")
|
||||
|
||||
start_ts = None # primo timestamp ricevuto
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = ser.read(sample_size)
|
||||
if len(data) != sample_size:
|
||||
continue # pacchetto incompleto
|
||||
|
||||
# ---- unpack del pacchetto ----
|
||||
s = struct.unpack(fmt, data)
|
||||
ts = s[0] # ts dell'ESP32 in microsecondi
|
||||
imu1 = s[1:7]
|
||||
imu2 = s[7:13]
|
||||
|
||||
# ---- calcolo timestamp relativo ----
|
||||
if start_ts is None:
|
||||
start_ts = ts
|
||||
rel_time = (ts - start_ts) / 1_000_000 # in secondi
|
||||
|
||||
# ---- stampa dati ----
|
||||
print(f"{rel_time:.6f}s | 1:{imu1} | 2:{imu2}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
ser.close()
|
||||
print("Closed")
|
||||
@@ -0,0 +1,46 @@
|
||||
import serial
|
||||
import struct
|
||||
import datetime
|
||||
import time
|
||||
|
||||
# ---------------- CONFIG ----------------
|
||||
PORT = 'COM3' # aggiorna con la tua COM
|
||||
BAUD = 921600
|
||||
|
||||
fmt = '<I6h6h' # ts, imu1(6h), imu2(6h)
|
||||
sample_size = struct.calcsize(fmt)
|
||||
|
||||
# ---------------- INIT ------------------
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
print(f"Listening on {PORT}...")
|
||||
|
||||
start_ts = None
|
||||
start_time = None # tempo assoluto all’inizio
|
||||
|
||||
try:
|
||||
while True:
|
||||
data = ser.read(sample_size)
|
||||
if len(data) != sample_size:
|
||||
continue # pacchetto incompleto
|
||||
|
||||
# ---- unpack del pacchetto ----
|
||||
s = struct.unpack(fmt, data)
|
||||
ts = s[0] # ts dell'ESP32 in microsecondi
|
||||
imu1 = s[1:7]
|
||||
imu2 = s[7:13]
|
||||
|
||||
# ---- inizializza riferimento tempo assoluto ----
|
||||
if start_ts is None:
|
||||
start_ts = ts
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
# ---- calcola tempo assoluto basato sul ts progressivo ----
|
||||
delta_us = ts - start_ts
|
||||
abs_time = start_time + datetime.timedelta(microseconds=delta_us)
|
||||
|
||||
# ---- stampa dati con timestamp leggibile ----
|
||||
print(f"{abs_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]} | 1:{imu1} | 2:{imu2}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
ser.close()
|
||||
print("Closed")
|
||||
@@ -0,0 +1,72 @@
|
||||
import serial
|
||||
import struct
|
||||
import datetime
|
||||
import csv
|
||||
|
||||
PORT = 'COM3'
|
||||
BAUD = 921600
|
||||
|
||||
MAGIC = 0xABCD
|
||||
FRAME_FMT = '<HI6h6hH'
|
||||
FRAME_SIZE = struct.calcsize(FRAME_FMT)
|
||||
|
||||
def crc16(data: bytes) -> int:
|
||||
c = 0
|
||||
for b in data:
|
||||
c ^= b
|
||||
return c
|
||||
|
||||
ser = serial.Serial(PORT, BAUD, timeout=1)
|
||||
buffer = bytearray()
|
||||
|
||||
start_ts = None
|
||||
start_time = None
|
||||
|
||||
csv_file = open('imu_log.csv', 'w', newline='')
|
||||
writer = csv.writer(csv_file)
|
||||
writer.writerow([
|
||||
'timestamp',
|
||||
'imu1_ax','imu1_ay','imu1_az','imu1_gx','imu1_gy','imu1_gz',
|
||||
'imu2_ax','imu2_ay','imu2_az','imu2_gx','imu2_gy','imu2_gz'
|
||||
])
|
||||
|
||||
print("Listening...")
|
||||
|
||||
try:
|
||||
while True:
|
||||
buffer += ser.read(512)
|
||||
|
||||
while len(buffer) >= FRAME_SIZE:
|
||||
if buffer[0:2] != MAGIC.to_bytes(2, 'little'):
|
||||
buffer.pop(0)
|
||||
continue
|
||||
|
||||
frame = buffer[:FRAME_SIZE]
|
||||
buffer = buffer[FRAME_SIZE:]
|
||||
|
||||
unpacked = struct.unpack(FRAME_FMT, frame)
|
||||
crc_rx = unpacked[-1]
|
||||
crc_calc = crc16(frame[:-2])
|
||||
|
||||
if crc_rx != crc_calc:
|
||||
continue # frame corrotto
|
||||
|
||||
ts_us = unpacked[1]
|
||||
|
||||
if start_ts is None:
|
||||
start_ts = ts_us
|
||||
start_time = datetime.datetime.now()
|
||||
|
||||
abs_time = start_time + datetime.timedelta(
|
||||
microseconds=(ts_us - start_ts)
|
||||
)
|
||||
|
||||
writer.writerow([
|
||||
abs_time.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3],
|
||||
*unpacked[2:14]
|
||||
])
|
||||
|
||||
except KeyboardInterrupt:
|
||||
csv_file.close()
|
||||
ser.close()
|
||||
print("Stopped")
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
import serial
|
||||
import struct
|
||||
import math
|
||||
|
||||
# --- impostazioni ---
|
||||
G = 9.80665
|
||||
ACC_LSB = 2048.0
|
||||
GYRO_LSB = 16.4
|
||||
|
||||
def acc_raw_to_ms2(raw):
|
||||
return (raw / ACC_LSB) * G
|
||||
|
||||
def gyro_raw_to_rad(raw):
|
||||
return (raw / GYRO_LSB) * (math.pi / 180.0)
|
||||
|
||||
# apri seriale
|
||||
ser = serial.Serial('COM8', 2000000)
|
||||
|
||||
frame_format = '<HIhhhhhhHH' # magic, ts, imu1(ax..gz), imu2(ax..gz), crc
|
||||
frame_size = struct.calcsize(frame_format)
|
||||
|
||||
while True:
|
||||
buf = ser.read(frame_size)
|
||||
if len(buf) != frame_size:
|
||||
continue
|
||||
|
||||
unpacked = struct.unpack(frame_format, buf)
|
||||
magic, ts = unpacked[0], unpacked[1]
|
||||
imu1_raw = unpacked[2:8]
|
||||
imu2_raw = unpacked[8:14]
|
||||
|
||||
# conversione accelerometro e giroscopio
|
||||
imu1 = [round(acc_raw_to_ms2(imu1_raw[0]), 2),
|
||||
round(acc_raw_to_ms2(imu1_raw[1]), 2),
|
||||
round(acc_raw_to_ms2(imu1_raw[2]), 2),
|
||||
round(gyro_raw_to_rad(imu1_raw[3]), 2),
|
||||
round(gyro_raw_to_rad(imu1_raw[4]), 2),
|
||||
round(gyro_raw_to_rad(imu1_raw[5]), 2)]
|
||||
|
||||
imu2 = [round(acc_raw_to_ms2(imu2_raw[0]), 2),
|
||||
round(acc_raw_to_ms2(imu2_raw[1]), 2),
|
||||
round(acc_raw_to_ms2(imu2_raw[2]), 2),
|
||||
round(gyro_raw_to_rad(imu2_raw[3]), 2),
|
||||
round(gyro_raw_to_rad(imu2_raw[4]), 2),
|
||||
round(gyro_raw_to_rad(imu2_raw[5]), 2)]
|
||||
|
||||
print(f"t={ts} imu1={imu1} imu2={imu2}")
|
||||
@@ -0,0 +1,180 @@
|
||||
#!/usr/bin/python3
|
||||
|
||||
import serial
|
||||
import time
|
||||
import json
|
||||
import base64
|
||||
import tarfile
|
||||
import paho.mqtt.client as mqtt
|
||||
import tempfile
|
||||
import os
|
||||
import threading
|
||||
import socket
|
||||
from datetime import datetime, timedelta
|
||||
import logging
|
||||
import sys
|
||||
import struct
|
||||
|
||||
# === CONFIG LOGGING ===
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(levelname)s | %(message)s",
|
||||
stream=sys.stdout
|
||||
)
|
||||
|
||||
# === CONFIG ===
|
||||
SERIAL_PORTS = ["/dev/esp_1", "/dev/esp_2", "/dev/esp_3", "/dev/esp_4"] # aggiungi altre se servono
|
||||
BAUDRATE = 2000000
|
||||
DURATION = 300
|
||||
CLIENT_ID = socket.gethostname()
|
||||
BROKER = "kiot-mqtts.pal.it"
|
||||
PORT = 8883
|
||||
TOPIC = "paliot/devs"
|
||||
MAX_RETRIES = 30
|
||||
USERNAME = "svcEMQXPortal"
|
||||
PASSWORD = "n$IYAnkYCG7M#7zcJod23OS#"
|
||||
STARTDATETIME = datetime.utcnow().isoformat() + "Z"
|
||||
|
||||
# === BIN FRAME CONFIG ===
|
||||
FRAME_FMT = "<H I 6h 6h H"
|
||||
FRAME_SIZE = struct.calcsize(FRAME_FMT)
|
||||
MAGIC = 0xABCD
|
||||
|
||||
# === UTILS ===
|
||||
def crc16_xor(data: bytes) -> int:
|
||||
c = 0
|
||||
for b in data:
|
||||
c ^= b
|
||||
return c & 0xFFFF
|
||||
|
||||
def reboot_machine():
|
||||
logging.critical(">> Riavvio macchina per mancanza connessione")
|
||||
os.system("reboot")
|
||||
|
||||
# === SERIAL CAPTURE (BINARIO → LOG TESTO) ===
|
||||
def capture_serial(port, output_dir):
|
||||
log_path = os.path.join(output_dir, f"{os.path.basename(port)}.log")
|
||||
buffer = bytearray()
|
||||
|
||||
start_wall_time = None
|
||||
start_ts_us = None
|
||||
|
||||
try:
|
||||
with serial.Serial(port, BAUDRATE, timeout=1) as ser, \
|
||||
open(log_path, "w", encoding="utf-8") as f:
|
||||
|
||||
start = time.time()
|
||||
|
||||
while time.time() - start < DURATION:
|
||||
buffer += ser.read(1024)
|
||||
|
||||
while len(buffer) >= FRAME_SIZE:
|
||||
if buffer[0] != 0xCD or buffer[1] != 0xAB:
|
||||
buffer.pop(0)
|
||||
continue
|
||||
|
||||
frame = buffer[:FRAME_SIZE]
|
||||
buffer = buffer[FRAME_SIZE:]
|
||||
|
||||
magic, ts_us, *imu, crc = struct.unpack(FRAME_FMT, frame)
|
||||
|
||||
if crc16_xor(frame[:-2]) != crc:
|
||||
continue
|
||||
|
||||
if start_wall_time is None:
|
||||
start_wall_time = datetime.utcnow()
|
||||
start_ts_us = ts_us
|
||||
|
||||
delta_us = ts_us - start_ts_us
|
||||
ts = start_wall_time + timedelta(microseconds=delta_us)
|
||||
|
||||
imu1 = imu[:6]
|
||||
imu2 = imu[6:]
|
||||
|
||||
line = (
|
||||
f"{ts.strftime('%Y-%m-%d %H:%M:%S.%f')[:-3]}"
|
||||
f"|1,{','.join(map(str, imu1))}"
|
||||
f"|2,{','.join(map(str, imu2))}\n"
|
||||
)
|
||||
|
||||
f.write(line)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"[{port}] Errore seriale: {e}")
|
||||
|
||||
return log_path
|
||||
|
||||
# === FILE UTILS ===
|
||||
def compress_directory(directory):
|
||||
tar_path = os.path.join(directory, "logs.tar.gz")
|
||||
with tarfile.open(tar_path, "w:gz") as tar:
|
||||
for filename in os.listdir(directory):
|
||||
if filename.endswith(".log"):
|
||||
tar.add(os.path.join(directory, filename), arcname=filename)
|
||||
return tar_path
|
||||
|
||||
def file_to_base64(file_path):
|
||||
with open(file_path, "rb") as f:
|
||||
return base64.b64encode(f.read()).decode("utf-8")
|
||||
|
||||
def build_payload(encoded_log):
|
||||
return {
|
||||
"clientId": CLIENT_ID,
|
||||
"dateTime": STARTDATETIME,
|
||||
"log": encoded_log
|
||||
}
|
||||
|
||||
# === MQTT SENDER ===
|
||||
def send_mqtt(payload):
|
||||
retries = 0
|
||||
while retries < MAX_RETRIES:
|
||||
try:
|
||||
client = mqtt.Client(client_id=CLIENT_ID)
|
||||
client.username_pw_set(USERNAME, PASSWORD)
|
||||
client.tls_set()
|
||||
client.connect(BROKER, PORT, 60)
|
||||
client.loop_start()
|
||||
client.publish(TOPIC, json.dumps(payload))
|
||||
client.loop_stop()
|
||||
client.disconnect()
|
||||
logging.info(">> Payload MQTT inviato con successo.")
|
||||
return True
|
||||
except Exception as e:
|
||||
retries += 1
|
||||
logging.warning(f"MQTT publish failed ({retries}/{MAX_RETRIES}): {e}")
|
||||
|
||||
if retries == MAX_RETRIES:
|
||||
reboot_machine()
|
||||
return False
|
||||
|
||||
time.sleep(5)
|
||||
return False
|
||||
|
||||
# === MAIN ===
|
||||
def main():
|
||||
temp_dir = tempfile.mkdtemp(prefix="serial_logs_")
|
||||
threads = []
|
||||
|
||||
for port in SERIAL_PORTS:
|
||||
t = threading.Thread(target=capture_serial, args=(port, temp_dir))
|
||||
t.start()
|
||||
threads.append(t)
|
||||
|
||||
for t in threads:
|
||||
t.join()
|
||||
|
||||
logging.info(">> Tutte le seriali hanno completato la registrazione.")
|
||||
|
||||
tar_file = compress_directory(temp_dir)
|
||||
encoded = file_to_base64(tar_file)
|
||||
payload = build_payload(encoded)
|
||||
send_mqtt(payload)
|
||||
|
||||
for filename in os.listdir(temp_dir):
|
||||
os.remove(os.path.join(temp_dir, filename))
|
||||
os.rmdir(temp_dir)
|
||||
|
||||
logging.info(">> Operazione completata.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,22 @@
|
||||
piLogger.py codice aggiornato del serialLogger presente nella rpi in impianto
|
||||
mentre in PIO/Projects c'è il nuovo fw per le esp, per ottenere un tempo di resa del dato ogni 2ms
|
||||
|
||||
result line
|
||||
2026-02-10 14:43:15.566|1,496,-292,16500,-219,19,132|2,168,-16700,-864,105,59,-162
|
||||
|
||||
|
||||
[
|
||||
"2026-02-10 14:43:15.566", timestamp utc
|
||||
(
|
||||
[
|
||||
1, 'OrientationId'
|
||||
496, 'ax'
|
||||
-292, 'ay'
|
||||
16500, 'az'
|
||||
-219, 'gx'
|
||||
19, 'gy'
|
||||
132 'gz'
|
||||
]
|
||||
),
|
||||
(2, [168,-16700,-864,105,59,-162])
|
||||
]
|
||||
Reference in New Issue
Block a user