double_scalar and float_scalar
from TangoTest — only process the pair if both arrive in the same polling
window. Discard if either fails."
rxcpp::observable<>::interval(500ms)
.flat_map([](long) {
// Both reads fire on background threads in parallel
return rxcpp::observable<>::zip(
[](double a, float b) { return process(a, b); },
rxtango::read_attribute<double>(
device, "double_scalar"),
rxtango::read_attribute<float>(
device, "float_scalar")
);
})
.subscribe([](auto result) { publish(result); });
double_scalar at PERIODIC events, compute a 5-sample
sliding average, and write back only if it deviates more than 10% from the
last written value."
push_event()rxtango::monitor_attribute<double>(
device, "double_scalar", "periodic")
// sliding window — no deque, no index arithmetic
.buffer(5, 1)
.map([](const auto& w) {
return std::accumulate(
w.begin(), w.end(), 0.0) / w.size();
})
// skip write if within 10% of last value
.distinct_until_changed(
[](double p, double c) {
return std::abs(c-p)/p < 0.1; })
.flat_map([](double avg) {
return rxtango::write_attribute<double>(
device, "double_scalar_w", avg); });
rxcpp::observable<>::merge(
rxtango::monitor_attribute<double>(
dev1, "double_scalar"),
rxtango::monitor_attribute<double>(
dev2, "double_scalar"),
rxtango::monitor_attribute<double>(
dev3, "double_scalar")
)
.filter([](double v) {
return std::abs(v) > THRESHOLD; })
.subscribe([](double v) {
notify_operator(v); });
Single-shot reads via read_attribute();
writes via write_attribute();
commands via command_inout();
push events via subscribe_event() + Tango::CallBack.
read_attribute<T> · write_attribute<T>
· execute_command<R,A>
Dispatched on std::thread; emits one value then completes.
monitor_attribute<T> — EventCallback
bridges the cppTango event thread to rxcpp::subscriber<T>
via std::mutex. Dispose calls
unsubscribe_event().
flat_map · zip · merge ·
buffer · filter · scan ·
sample_with_time · distinct_until_changed
Write-back, alarm, HMI update, file sink — pure functions, no shared state, ReactiveX contract verified.
TangoClient chain; no intermediate variables.
rxtango::TangoClient()
.read(device, "double_scalar")
.map([](std::any v) -> std::any {
return std::any_cast<double>(v) * 1.0328;
})
.write(device, "double_scalar_w")
.subscribe(
[](std::any v) {
std::cout << std::any_cast<double>(v);
});
./build/tests/verify_contract