MiBeeNvr v0.3.1: Multi-Protocol Streaming and Native Xiaomi Camera Support

9 min read
#XQ|A lot of work went into the releases after v0.2.0. v0.3.x brings several major updates: native Xiaomi camera support, recording archiving, multi-protocol streaming architecture (WebRTC/HTTP-FLV/RTMP/SRT/LL-HLS), and a wave of security hardening. The architectural evolution from external dependencies to built-in implementation, from single protocol to full protocol support, was much more complex than I expected. The previous post introduced v0.2.0’s 15 new features (v0.2.0 Update). If you haven’t read the first post, start with MiBeeNvr Introduction. v0.3.0 focuses on deep Xiaomi camera integration, and v0.3.1 builds on that with a complete multi-protocol streaming architecture. For the full changelog, see GitHub Release Notes.
NVR Go Xiaomi Camera Smart Home RTSP CS2 WebRTC HTTP-FLV RTMP SRT
Continue reading →

Embedded ANC: ESP32 Practice

8 min read
The ESP32-S3’s dual-core Xtensa LX7 processor with vector instruction set extensions is well-suited for the real-time DSP workloads required by embedded ANC. Combined with the ESP-DSP library, efficient adaptive filtering becomes practical on this platform. I2S Microphone Capture ANC requires at least two synchronous input channels: a reference microphone (capturing ambient noise) and an error microphone (capturing residual error). The ESP32-S3 I2S peripheral supports simultaneous multi-channel ADC data reception. Configuring it for 16-bit, 16 kHz sampling suffices for consumer-grade ANC.
ESP32 ESP32-S3 ESP-DSP I2S FreeRTOS ANC
Continue reading →

From Compliance to Real-Time Defense: The Evolution of security-collector-exporter

6 min read
The Origin: Compliance Check Hassles Anyone in operations knows there’s no escaping one hurdle for domestic servers: Cybersecurity Level Protection (GB/T 22239-2019, commonly known as “Level Protection 2.0”). Whether you’re Level 3 or Level 2, auditors come asking about these things: Is SSH root login disabled? Are password policies compliant? Is the firewall on? Is SELinux enforcing? Are there expired accounts? What’s the password validity period? Which ports are open? Are there high-risk services running? Are audit logs enabled? How long are they retained? There are plenty of compliance check tools on the market—search GitHub and you’ll find a bunch: Golin, EvaluationTools, Linux-Security-Compliance-Check, etc. But they all share one limitation: Run once, get a report, done. You check compliance today, and someone changes sshd_config tomorrow, turns off the firewall, installs a backdoor service—you’d never know.
Prometheus EBPF Linux Security Monitoring Compliance Go Exporter
Continue reading →

YOLO Deployment: Model Export and Multi-Platform Deployment

12 min read
Model Export (17 Format Support) Ultralytics Unified Export API python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from ultralytics import YOLO model = YOLO("yolo26n.pt") # ========== Export Various Formats ========== # 1. ONNX (Cross-platform Universal) model.export(format="onnx", simplify=True, dynamic=True) # 2. TensorRT (Best for NVIDIA GPU) model.export(format="engine", half=True, workspace=4) # 3. OpenVINO (Best for Intel CPU) model.export(format="openvino", half=True) # 4. CoreML (Apple Devices) model.export(format="coreml", int8=True) # 5. TFLite (Android/iOS Mobile) model.export(format="tflite", int8=True) # 6. NCNN (Mobile) model.export(format="ncnn") # 7. PaddlePaddle model.export(format="paddle") Version Export Compatibility Format YOLOv8 YOLO11 YOLO26 ONNX ✅ ✅ ✅ Best TensorRT ✅ ✅ ✅ No NMS, Simpler OpenVINO ✅ ✅ ✅ TFLite ✅ ✅ ✅ NCNN ✅ ✅ ✅ Python Deployment Practice ONNX Runtime Deployment python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import onnxruntime as ort import cv2 import numpy as np # Load ONNX model session = ort.InferenceSession( "yolo26n.onnx", providers=["CUDAExecutionProvider", "CPUExecutionProvider"] ) def preprocess(image, imgsz=640): """Image preprocessing""" img = cv2.resize(image, (imgsz, imgsz)) img = img.transpose(2, 0, 1) / 255.0 return img[np.newaxis].astype(np.float32) # Inference image = cv2.imread("test.jpg") input_data = preprocess(image) outputs = session.run(None, {"images": input_data}) # YOLO26 Special Note: No NMS post-processing needed! # Output is already the final detection results TensorRT Python Deployment python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 import tensorrt as trt import pycuda.driver as cuda import pycuda.autoinit import numpy as np import time # ========== 1. Engine Loading & Context Creation ========== TRT_LOGGER = trt.Logger(trt.Logger.WARNING) runtime = trt.Runtime(TRT_LOGGER) with open("yolo26n.engine", "rb") as f: engine = runtime.deserialize_cuda_engine(f.read()) context = engine.create_execution_context() # ========== 2. CUDA Memory Allocation ========== stream = cuda.Stream() bindings = [] for i in range(engine.num_io_tensors): name = engine.get_tensor_name(i) shape = engine.get_tensor_shape(name) dtype = trt.nptype(engine.get_tensor_dtype(name)) size = trt.volume(shape) host_mem = cuda.pagelocked_empty(size, dtype) # Host pinned memory device_mem = cuda.mem_alloc(host_mem.nbytes) # Device VRAM bindings.append({"name": name, "host": host_mem, "device": device_mem, "shape": shape, "size": size, "dtype": dtype}) # ========== 3. Async Inference Loop ========== def async_infer(input_blob): # H2D copy np.copyto(bindings[0]["host"], input_blob.ravel()) cuda.memcpy_htod_async(bindings[0]["device"], bindings[0]["host"], stream) # Set tensor addresses and execute context.set_tensor_address(bindings[0]["name"], int(bindings[0]["device"])) context.set_tensor_address(bindings[1]["name"], int(bindings[1]["device"])) context.execute_async_v3(stream.handle) # D2H copy cuda.memcpy_dtoh_async(bindings[1]["host"], bindings[1]["device"], stream) stream.synchronize() return bindings[1]["host"].copy() # ========== 4. Performance Benchmark ========== def benchmark(warmup=10, runs=100): dummy = np.random.randn(1, 3, 640, 640).astype(np.float32) for _ in range(warmup): async_infer(dummy) latencies = [] for _ in range(runs): t0 = time.perf_counter() async_infer(dummy) latencies.append((time.perf_counter() - t0) * 1000) latencies.sort() print(f"TensorRT FP16 | Mean: {np.mean(latencies):.1f}ms | " f"P50: {latencies[runs//2]:.1f}ms | " f"P99: {latencies[int(runs*0.99)]:.1f}ms | " f"Throughput: {1000/np.mean(latencies):.0f} FPS") benchmark() OpenVINO Deployment with Benchmarking python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import openvino as ov import cv2 import numpy as np import time # ========== 1. ONNX → OpenVINO Conversion ========== # Ultralytics unified export: # model.export(format="openvino", half=True) core = ov.Core() model = core.read_model("yolo26n_openvino/yolo26n.xml") # ========== 2. CPU Inference ========== compiled_cpu = core.compile_model(model, device_name="CPU") infer_request = compiled_cpu.create_infer_request() def openvino_infer(image): img = cv2.resize(image, (640, 640)) blob = img.transpose(2, 0, 1)[np.newaxis].astype(np.float32) / 255.0 outputs = infer_request.infer({"images": blob}) return outputs[next(iter(outputs))] # ========== 3. Async Pipeline (Throughput Optimized) ========== def async_pipeline(images, num_requests=4): """Multi-request async inference pipeline""" requests = [core.compile_model(model, "CPU").create_infer_request() for _ in range(num_requests)] results = [None] * len(images) def completion_callback(request, userdata): idx = userdata results[idx] = request.get_output_tensor().data.copy() for req in requests: req.set_callback(completion_callback) for i, img in enumerate(images): req = requests[i % num_requests] req.start_async({"images": preprocess(img)}, userdata=i) for req in requests: req.wait() return results # ========== 4. CPU vs NPU Benchmark Comparison ========== def benchmark_openvino(): dummy = np.random.randn(1, 3, 640, 640).astype(np.float32) for device in ["CPU", "AUTO"]: compiled = core.compile_model(model, device) req = compiled.create_infer_request() # Warmup (avoid first-inference kernel compilation overhead) for _ in range(20): req.infer({"images": dummy}) times = [] for _ in range(200): t0 = time.perf_counter() req.infer({"images": dummy}) times.append((time.perf_counter() - t0) * 1000) times.sort() print(f"OpenVINO {device}: " f"Mean {np.mean(times):.1f}ms | " f"P99 {times[int(199*0.99)]:.1f}ms | " f"{1000/np.mean(times):.0f} FPS") benchmark_openvino() NCNN Mobile Deployment NCNN is Tencent’s open-source mobile inference framework supporting ARM NEON and Vulkan GPU acceleration.
YOLO Model Deployment ONNX TensorRT Edge Computing
Continue reading →

MiBeeNvr v0.3.0: One-Click Xiaomi Camera Integration, Recordings Never Lost

3 min read
Got Xiaomi cameras at home? Want to keep your recordings on your own storage instead of relying on the cloud? As someone with several Xiaomi cameras at home, I always had one frustration: every time I wanted to check the footage from my doorbell camera, I had to log into Xiaomi Cloud, wait for ages while it loaded, and it would often just spin. Plus, cloud storage charges by the day — it adds up over the month. And if you swap cameras, all your old recordings are gone. Pretty frustrating.
NVR Xiaomi Camera Smart Home Recording Open Source
Continue reading →

security-collector-exporter v0.3.0: Real-Time Security Monitoring with eBPF

8 min read
From Static to Real-Time The previous article introduced security-collector-exporter v0.1.0 — turning Linux security configuration states into Prometheus metrics. But v0.1.0 is essentially “snapshot-based”: periodically reading /etc, /proc, capturing the static configuration at a single point in time. There’s an area of security operations that snapshots can’t cover: real-time security events. Someone running a reverse shell, a process escalating privileges, an abnormal network connection, someone loading a kernel module — these events happen and pass; you’d never see them at your next scrape.
Prometheus EBPF Linux Security Monitoring Go Exporter
Continue reading →

Embedded ANC: STM32 in Practice

11 min read
Hardware Architecture Implementing real-time ANC begins with selecting the right hardware platform. The controller must complete adaptive filtering within microseconds while managing multiple audio data streams. Module Function Typical Choice Main Controller Executes adaptive algorithm STM32F4/F7, ESP32-S3, nRF5340 Reference Mic Captures ambient noise Knowles SPH0645, Infineon IM69D130 Error Mic Captures residual noise Knowles SPH0645, TDK ICS-43434 Audio DAC Outputs anti-noise signal ES9218, PCM5102 Amplifier Drives speaker Class-D The reference microphone sits outside the earcup and captures external ambient noise as the algorithm’s reference input. The error microphone sits inside the earcup near the speaker, capturing residual noise for evaluating cancellation performance and driving adaptive updates. The audio DAC converts the digital anti-noise signal to analog, which is amplified by a Class-D amplifier to drive the speaker.
STM32 CMSIS-DSP DFSDM MEMS Embedded ANC
Continue reading →

YOLO Advanced Optimization: Lightweight, Quantization and Accuracy

11 min read
Model Lightweighting Strategies Model Size Selection Model Parameters (M) mAP CPU Inference Use Cases YOLO26n 2.8 38.9 Fastest Edge devices, Embedded YOLO26s 9.4 48.2 Very fast Mobile, Web YOLO26m 21.8 53.1 Medium Server, High performance YOLO11n 2.6 39.6 Fast Lightweight deployment YOLOv8n 3.2 37.3 Baseline General purpose Knowledge Distillation python 1 2 3 4 5 6 7 8 9 10 # Large model as teacher, small model as student teacher = YOLO("yolo26x.pt") student = YOLO("yolo26n.yaml") # Distillation training (Ultralytics built-in support) student.train( data="data.yaml", distill="yolo26x.pt", # Teacher model distill_ratio=0.5, # Distillation loss ratio ) Model Pruning Structured vs Unstructured Pruning Type Method Sparsity Pattern Hardware Acceleration Compression Ratio Unstructured Weight pruning Random sparse Difficult (special HW needed) High Structured Channel pruning Regular sparse Native acceleration Medium Torch Prune Channel Pruning Example python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import torch import torch.nn.utils.prune as prune # L1 unstructured pruning on conv layers model = YOLO("yolo26n.pt") for name, module in model.model.named_modules(): if isinstance(module, torch.nn.Conv2d): prune.l1_unstructured(module, name="weight", amount=0.3) prune.remove(module, "weight") # Make pruning permanent # Channel pruning with torch-pruning library # pip install torch-pruning import torch_pruning as tp model = YOLO("yolo26n.pt").model DG = tp.DependencyGraph() DG.build_dependency(model, example_inputs=torch.randn(1, 3, 640, 640)) # Prune 20% channels by L1 norm pruning_plan = DG.get_pruning_plan( model.model[4], tp.prune_conv, pruning_dim=0, # Output channel dimension idxs=list(range(0, 64, 5)) # Keep every 5th channel ) pruning_plan.exec() Pruning Ratio Guidelines Model Safe Ratio Aggressive Ratio mAP Drop YOLO26n ≤20% 20-40% <1% / 2-5% YOLO26s ≤30% 30-50% <1% / 3-6% YOLO26m ≤40% 40-60% <1% / 3-8% YOLOv8n ≤20% 20-35% <1% / 2-4% Model Pruning and Quantization Export Time Quantization python 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 model = YOLO("yolo26n.pt") # INT8 quantization (requires calibration data) model.export( format="engine", # TensorRT int8=True, data="data.yaml", # Calibration dataset batch=8, ) # ONNX dynamic quantization model.export( format="onnx", dynamic=True, simplify=True, ) TensorRT INT8 Calibration Step-by-Step Calibration Dataset Preparation INT8 quantization requires representative calibration data to determine activation value ranges:
YOLO Model Optimization Knowledge Distillation Model Quantization Edge Deployment
Continue reading →

From Hashmod to Jump Consistent Hash — stream-metrics-route Hash Algorithm Upgrade

12 min read
Introduction In the previous article, we reviewed the three-year evolution of stream-metrics-route and mentioned that the “dual hashmod scheduling” is the core scheduling mechanism of the entire gateway. However, during continuous production operation, one fatal flaw of hashmod became increasingly obvious—every scaling operation triggers full data redistribution. This article documents the decision process of migrating from hash % N (hashmod) to Jump Consistent Hash, including the candidate algorithms evaluated, why Jump Hash was ultimately chosen, and the specific impact before and after migration.
VictoriaMetrics Prometheus Consistent Hashing Stream-Metrics-Route Distributed Systems
Continue reading →

IMU Fundamentals: Accelerometer and Gyroscope

4 min read
Opening post of the Motion Sensing series. Sensors are the window through which embedded systems perceive the physical world, and the IMU (Inertial Measurement Unit) is the most common type. This article skips heavy theory — just how MEMS sensors work, how to wire them, how to read data, and what the numbers actually look like. IMU Coordinate System The diagram below defines the three axes of the IMU — all formulas and discussions that follow are based on this coordinate system:
IMU Accelerometer Gyroscope MEMS Motion Sensing
Continue reading →