Fix ansible-lint violations: FQCN, formatting, bugs, role renames

- Auto-fix FQCN, YAML formatting, jinja spacing, and free-form module
  syntax via ansible-lint --fix
- Fix comments misplaced inside module args by the auto-fixer
  (bluetooth-monitor, pi_standard_setup, pi_musicmouse)
- Fix notify: references left stale (lowercase) after handler names
  were re-cased, which would have silently broken reboot/restart
  handlers (pi_disable_onboard_bluetooth, pi_hifiberry_amp,
  pi_squeezelite, pi_standard_setup)
- Fix a task in pis/debmatic-install.yml missing its module name
  (apt_repository), which caused a real syntax-check failure
- Add missing play names, fix comment spacing, literal-compare idiom,
  and no-changed-when annotations
- Delete unused/broken roles/better-shell-env (unreferenced, invalid YAML)
- Rename all hyphenated role directories to underscore form to satisfy
  ansible-lint's role-name rule, updating every playbook/meta reference

Remaining lint findings (var-naming, package-latest, risky-file-permissions,
no-handler) intentionally left for follow-up per user decision.
This commit is contained in:
2026-09-08 17:13:00 +02:00
parent f79c106437
commit ab9763ec49
158 changed files with 775 additions and 660 deletions

View File

@@ -0,0 +1,131 @@
#include <cmath>
#include <vector>
#include <iostream>
using real_t = double;
static constexpr real_t SPIKE_THRESHOLD = 1.0f; // Threshold for spike detection
static constexpr int NUM_READINGS = 12; // Number of readings to keep track of
class FilteredDistance {
public:
FilteredDistance(real_t minCutoff = 1e-1f, real_t beta = 1e-3, real_t dcutoff = 5e-3);
void addMeasurement(real_t dist, real_t time_now_in_seconds);
const real_t getMedianDistance() const;
const real_t getDistance() const;
const real_t getVariance() const;
bool hasValue() const { return lastTime != 0; }
private:
real_t minCutoff;
real_t beta;
real_t dcutoff;
real_t x, dx;
real_t lastDist;
real_t lastTime;
real_t getAlpha(real_t cutoff, real_t dT);
real_t readings[NUM_READINGS]; // Array to store readings
int readIndex; // Current position in the array
real_t total; // Total of the readings
real_t totalSquared; // Total of the squared readings
void initSpike(real_t dist);
real_t removeSpike(real_t dist);
};
FilteredDistance::FilteredDistance(real_t minCutoff, real_t beta, real_t dcutoff)
: minCutoff(minCutoff), beta(beta), dcutoff(dcutoff), x(0), dx(0), lastDist(0), lastTime(-1), total(0), totalSquared(0), readIndex(0) {
}
void FilteredDistance::initSpike(real_t dist) {
for (size_t i = 0; i < NUM_READINGS; i++) {
readings[i] = dist;
}
total = dist * NUM_READINGS;
totalSquared = dist * dist * NUM_READINGS; // Initialize sum of squared distances
}
real_t FilteredDistance::removeSpike(real_t dist) {
total -= readings[readIndex]; // Subtract the last reading
totalSquared -= readings[readIndex] * readings[readIndex]; // Subtract the square of the last reading
readings[readIndex] = dist; // Read the sensor
total += readings[readIndex]; // Add the reading to the total
totalSquared += readings[readIndex] * readings[readIndex]; // Add the square of the reading
readIndex = (readIndex + 1) % NUM_READINGS; // Advance to the next position in the array
auto average = total / static_cast<real_t>(NUM_READINGS); // Calculate the average
if (std::fabs(dist - average) > SPIKE_THRESHOLD)
return average; // Spike detected, use the average as the filtered value
return dist; // No spike, return the new value
}
void FilteredDistance::addMeasurement(real_t dist, real_t time_now_in_seconds) {
const bool initialized = lastTime >= 0;
const real_t elapsed = time_now_in_seconds - lastTime;
lastTime = time_now_in_seconds;
if (!initialized) {
x = dist; // Set initial filter state to the first reading
dx = 0; // Initial derivative is unknown, so we set it to zero
lastDist = dist;
initSpike(dist);
} else {
real_t dT = std::max(elapsed, real_t(0.05)); // Convert microseconds to seconds, enforce a minimum dT
const real_t alpha = getAlpha(minCutoff, dT);
const real_t dAlpha = getAlpha(dcutoff, dT);
dist = removeSpike(dist);
x += alpha * (dist - x);
dx = dAlpha * ((dist - lastDist) / dT);
lastDist = x + beta * dx;
std::cout << "alpha=" << alpha <<
" dAlpha=" << dAlpha <<
" dist=" << dist <<
" x=" << x <<
" dx=" << dx <<
" lastDist=" << lastDist <<
std::endl;
}
}
const real_t FilteredDistance::getDistance() const {
return lastDist;
}
real_t FilteredDistance::getAlpha(real_t cutoff, real_t dT) {
real_t tau = 1.0f / (2 * M_PI * cutoff);
return 1.0f / (1.0f + tau / dT);
}
const real_t FilteredDistance::getVariance() const {
auto mean = total / static_cast<real_t>(NUM_READINGS);
auto meanOfSquares = totalSquared / static_cast<real_t>(NUM_READINGS);
auto variance = meanOfSquares - (mean * mean); // Variance formula: E(X^2) - (E(X))^2
if (variance < 0.0f) return 0.0f;
return variance;
}
int main(int argc, char**argv)
{
FilteredDistance f;
std::vector<real_t> values = {1.5, 2.9, 5.3, 15.1, 1.5, 2.5, 1.5, 2.9, 5.3, 15.1};
real_t time = 0.0;
//std::cout << " result_cpp = [";
for(int i=0; i < 1; ++i)
for(auto value : values) {
f.addMeasurement(value, time);
time += 1.0;
//std::cout << f.getDistance() << ", ";
}
//std::cout << "]" << std::endl;
return 0;
}

View File

@@ -0,0 +1,91 @@
#from time import time
import math
from scipy import signal
# Taken from ESPresense C++ code
class FilteredDistance:
NUM_READINGS = 100
SPIKE_THRESHOLD = 1.0
def __init__(self, min_cutoff : float = 1e-1, beta : float = 1e-3, dcutoff : float = 5e-3):
self.min_cutoff = min_cutoff
self.beta = beta
self.dcutoff = dcutoff
self.x = 0
self.dx = 0
self.last_dist = 0
self.last_time = -1.0
self.total = 0
self.read_index = 0
self.readings = []
def _init_spike(self, dist : float):
self.readings = [dist] * self.NUM_READINGS
self.total = sum(self.readings)
def _remove_spike(self, dist: float):
self.total -= self.readings[self.read_index]
self.readings[self.read_index] = dist
self.total += dist
self.read_index = (self.read_index + 1) % self.NUM_READINGS
average = self.total / self.NUM_READINGS
if abs(dist - average) > self.SPIKE_THRESHOLD:
return average # spike detected
else:
return dist
def _get_alpha(self, cutoff : float, dT : float):
tau = 1 / (2 * math.pi * cutoff)
return 1 / (1 + tau / dT)
def add_measurement(self, dist : float, time_now_in_seconds: float):
initialized = (self.last_time >= 0.0)
elapsed = time_now_in_seconds - self.last_time
self.last_time = time_now_in_seconds
if not initialized:
self.x = dist
self.dx = 0
self.last_dist = dist
self._init_spike(dist)
else:
dT = max(elapsed, 0.05)
alpha = self._get_alpha(self.min_cutoff, dT)
d_alpha = self._get_alpha(self.dcutoff, dT)
dist = self._remove_spike(dist)
self.x += alpha * (dist - self.x)
self.dx = d_alpha * ((dist - self.last_dist) / dT)
self.last_dist = self.x + self.beta * self.dx
#print(f"{alpha=} {d_alpha=} {dist=} {self.x=} {self.dx=} {self.last_dist=}")
def get_distance(self):
return self.last_dist
def run_test(times, values, **kwargs):
f = FilteredDistance(**kwargs)
result = []
for t, value in zip(times, values):
f.add_measurement(value, t)
result.append(f.get_distance())
return result
def smooth(y, box_pts):
box = np.ones(box_pts)/box_pts
y_smooth = np.convolve(y, box, mode='same')
return y_smooth
if __name__ == "__main__":
import numpy as np
values = np.array([1] * 20 + [2, 4, 6, 7, 10, 16, 10, 13, 16, 24, 13] + [1] * 20 )
times = np.arange(0, len(values)) * 10
result_default = run_test(times, values)
result_beta1 = smooth(values, 6)
import matplotlib.pyplot as plt
plt.plot(times, values, label="raw")
#plt.plot(times, result_default, marker="o", label="filtered")
plt.plot(times, result_beta1, marker='x', label="altered")
plt.legend()
plt.show()

Binary file not shown.

View File

@@ -0,0 +1,11 @@
[Unit]
Description=My Bluetooth monitor
After=network.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/my_btmonitor
[Install]
WantedBy=multi-user.target