根据 RSSI 值查找标记的最近嗅探器



我有一个场景,我在网状网络中跟踪蓝牙标签,我想知道在任何给定的时间点,标签最接近哪个nodeId(嗅探器((根据rssi值(。

给定一个正在运行的数据窗口:

{ mac: '123', nodeId: 1, rssi: 1 }
{ mac: '456', nodeId: 2, rssi: 3 }

我的想法是我想从 mac 获取最新的 3 个读数,找到具有最高rssi值的读数,然后输出它,并且只有当它改变了上次输出的nodeIdmac时。我下面的代码几乎就在那里,但是当有多个 mac 地址时,事情开始变得混乱。

你能给我指出一个方向吗?我想我也需要按 Mac 分组?

const { from } = require('rxjs');
const {
window,
map,
windowCount,
mergeAll,
max,
distinctUntilKeyChanged,
groupBy,
mergeMap,
toArray
} = require('rxjs/operators');
const source = from([
{ mac: '123', nodeId: 1, rssi: 1 },
{ mac: '123', nodeId: 2, rssi: 2 },
{ mac: '123', nodeId: 1, rssi: 4 },
{ mac: '123', nodeId: 1, rssi: 3 },
{ mac: '123', nodeId: 3, rssi: 2 },
{ mac: '123', nodeId: 1, rssi: 2 },
{ mac: '123', nodeId: 1, rssi: 8 },
{ mac: '123', nodeId: 2, rssi: 8 },
{ mac: '456', nodeId: 2, rssi: 10 },
{ mac: '123', nodeId: 2, rssi: 11 },
{ mac: '123', nodeId: 3, rssi: 9 },
{ mac: '456', nodeId: 3, rssi: 9 },
{ mac: '123', nodeId: 2, rssi: 11 },
{ mac: '123', nodeId: 3, rssi: 9 },
{ mac: '456', nodeId: 3, rssi: 9 },
{ mac: '123', nodeId: 3, rssi: 10 }
]);
const GROUP_BY = 'nodeId';
const COMPARE_KEY = 'rssi';
const WINDOW = 3;
const comparer = field => (a, b) => (a[field] < b[field] ? -1 : 1);
source
.pipe(
groupBy(metric => metric[GROUP_BY]),
mergeMap(group => group.pipe(toArray())),
mergeAll(),
windowCount(WINDOW),
map(metric => metric.pipe(max(comparer(COMPARE_KEY)))),
mergeAll(),
distinctUntilKeyChanged(COMPARE_KEY)
)
.subscribe(e => {
console.log(e);
});

编辑@Dorus很棒,并清理了所有内容,这似乎正在解决问题:

const GROUP_BY = 'mac';
const COMPARE_KEY = 'rssi';
const BUFFER_SIZE = 3;
const DISTINCT_BY_FIELDS = ['nodeId', 'mac'];
const comparer = field => (a, b) => (a[field] < b[field] ? -1 : 1);
const distinctFieldsComparer = fields => (x, y) => fields.every(field => x[field] === y[field]);
source
.pipe(
groupBy(metric => metric[GROUP_BY]),
mergeMap(group =>
group.pipe(
bufferCount(BUFFER_SIZE, 1),
mergeMap(metric => from(metric).pipe(max(comparer(COMPARE_KEY)))),
distinctUntilChanged(distinctFieldsComparer(DISTINCT_BY_FIELDS))
)
)
)
.subscribe(e => {
console.log(e);
});

您当前的代码很接近,实际上我可以重用其中的大部分。

出错的是,group.pipe(toArray())只会在组完成时发出(并且仅在源完成时发生(。您要做的是获得一个滑动窗口。您可以使用bufferCount(BUFFER_SIZE, 1).它将每 1 个项目发出最后 3 个项目,从而允许您在每次组获得新项目时检查最后 3 个项目。

const GROUP_BY = 'mac';
const DISTINCT_BY = 'nodeId';
const COMPARE_KEY = 'rssi';
const distinctComparer = field => (x, y) => x[field] === y[field];
const BUFFER_SIZE = 3;
const comparer = field => (a, b) => (a[field] < b[field] ? -1 : 1);
source.pipe(
groupBy(metric => metric[GROUP_BY])
mergeMap(grp => grp.pipe(
bufferCount(BUFFER_SIZE, 1)),
mergeMap(metric => from(metric).pipe(max(comparer(COMPARE_KEY))))
distinctUntilChanged(distinctComparer(DISTINCT_BY))
)  
)

另外,我认为您想比较并获得小组的最大收益。为此,您需要将所有内容都放在处理各个组的 mergeMap 中。

最新更新