mirror of
https://github.com/l5yth/potato-mesh.git
synced 2026-10-30 19:41:58 +01:00
spec: update test fixtures (#517)
* spec: update test fixtures * app: address review comments
This commit is contained in:
8 files changed
+78656
-8150
No files matched your search
@@ -0,0 +1,282 @@
|
||||
[
|
||||
{
|
||||
"id":"5fe4ee3640b6361f9ee9b012c68c5413248370d51b27866886e644a7f1b2ca4f",
|
||||
"domain":"map.meshdresden.eu",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvdy3TNMSF0y+F5hwxD5D\n+qboueS1kY5DL6cjEai/7pS12Og5rQAgbGEBjmBJh5cdW02y2hr2gs8XcWzFGcRz\nMYwaFK7fTJtpTVbJ7ZXK2FR8a5DBIT0/c6ldTL5fDxJTyLUVqdC/yz1gn9VgO+jf\nN6HYZI2d6jsA5a9+qbc2E+w1mZ7rbZ7eY573vxVYmfAQP4d8fFuTgpVcDEbNNBjX\nR2W4S5k5Hs9WTL5TU8l45TbGzfB2HSpqahzs9XQ/5clF/fn5fm76dv0aSyoqbKq2\nl91V8zlWc2HBpC0cCj98MY0RLa8fdfXAtn/MOHCbTcCxwLSxJxRfZ5mdcP1+Dy8t\nwQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Mesh Dresden",
|
||||
"version":"0.5.6",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":51.0,
|
||||
"longitude":13.61,
|
||||
"lastUpdateTime":1764035531,
|
||||
"isPrivate":false,
|
||||
"signature":"bpIaRq+X7YNON7ziQErU6JbGAxZ/UlbIdpvvct/7jajnVa7+rn4r4fCP/Bk+7r1DaHGBzpvi4F7K8sILFEDL5b8ZONFSgXOG0Y8r/UOu5kFt+ZffTqvERk+GZHFI9XLSPAW97CpD4rnoZq7xNiohTtCNTGg3O057i5J7S+aKrt+E3aGsOHK52GDsfW2odnLuMtGTkST/lbPEdjPSHAgiRn+jmnn1legpcQZtfrjFjf+n0kODRUKLtAcUJMl4V+SR/okqbhJgNBupaxxxTUguCTgxlRc/IHt4Ty8JGaUBqS9HKaItlUBEC47rPIvLKhI3JrUW1elqxeYC2uYOoQNtFg=="
|
||||
},
|
||||
{
|
||||
"id":"e07c6fc04aec13295f57a47fedfdab949099ad983a1ef690cad2c504c0902d70",
|
||||
"domain":"map.meshrheinland.de",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2FmZ+ZqX6BpGvhYpBUz6\n8H+bAI7B1rX9D8UoYfu7oBtql1D85/UzO2GOJBpcXf9m84FZAjvyC7ZPTBzfL4Tj\nMe2thB1UsbKEm5iBg1A/NcMFbtaBLUXduUxNATDYANB3WwkpWKQiLsZ5cJgfuFWq\nb3RlRGc//FnEoGjmu/YdhnhG8eAu1G8FJAYlz27rPM98+TN3NCgwNL6Ye2hPWH6B\naUK3Sz+6/n60+wqlqo/1sC5TZE6qDFInnYglHF5jZMjq4yFtTOsxo00JNzmsihx/\nxBFVLiIxwtNi2AHtMZmQaJ6T6kca3/Bzkqti6+zMMntdBaZMTMgO8ThRAUSCHyMM\nmQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Mesh Rheinland",
|
||||
"version":"0.5.6",
|
||||
"channel":"#ShortSlow",
|
||||
"frequency":"868MHz",
|
||||
"latitude":50.71288282,
|
||||
"longitude":7.05035462,
|
||||
"lastUpdateTime":1764044758,
|
||||
"isPrivate":false,
|
||||
"signature":"Tw251mm5M+K6gSoAjOaeqRwSoytHt1BbqGVrT3vTWE3o0OrjuIO53/Qy67DJ/KOSW/IfNqAzxw2GADgng4fjRNkPo07czPNCxK3tX8CnDhXL90dgMUyRTrNldUUENwDT7+ghdjfv6p5+FWqPdkBBeecpQXz3xk20eW77sIyVjqcJlSTssoBzkNPijjCHOOYp7dhoanaNFSo/Cwn3wPEBJuV/mRTOCmeEESbI9L5qMF6pq75Co+jQwP9hDMIvSqSSZYhqho6woNnJ8YPZbCoCqs45QbbPDLTx6svxYQdfMVWm3dS/rss78KRqnrUrQTvZJr2rt8Xw4JJ7NIWPjjkfhA=="
|
||||
},
|
||||
{
|
||||
"id":"346f27a20aacd92d4fbbc2aa77b879a676a2d7f82d25141cdaa6959505ce0e1f",
|
||||
"domain":"map.meshtastic-kiel.de",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz8PED8Xh4OeyNLmT9zI6\ndH1XmsbfYis73ZClBYd58sPZKlx28YOodD2KHPMrm7lY/xaH/t4sefveGO5vX78X\nbp3jDPVXvbMWAlK7gQjb/M4MW4IoAo8qMZn8lzbnXmYHEPv/AFvLP2f9s1lSXtpY\nMMa3KcaDbQiLnJEVpCERnMIcWzySi5gvir7K00y/mCgtz6/C3jMhFO0Tk+TDhkc7\nT6KChDTucJy7G58l0fW5lhF8aHVLb05UAx7HuQf0ZvvrGGrS0GO6+T77KLKp8/yd\njRaxE8x9SotpfHfHb2izkQycVWV4I5cgbwzhCKN2HZARiCy4UKhhuuXV/OYqjlCF\nNQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Meshtastic Kiel",
|
||||
"version":"0.5.5",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":54.32074,
|
||||
"longitude":10.14314,
|
||||
"lastUpdateTime":1764105493,
|
||||
"isPrivate":false,
|
||||
"signature":"hD1ykqFIwbg/lItms3p8R+unyF5JPXAt8zyJSgrl+HQOFacQh+aGBI+hMCsTIh3gV3DgMfCb8LM6ny4CaDkndqVKTrx33j/dQoM9LQaIf1DOVDjbVwdtn37Ld1qqZXhg09PmVPhqg32uFvTSFs3yv6y72T9i8ozBr5w5AHdBtV3lUdpYD/GSLwxRFGg5rO+FK5CztvpgDZLiB498WUIlNbDkxhUJYUUYd0bVpXbywaJ+xmXFauzcq2DU+OHaOdmuWPzqGC+db+uerrK1R5f7ag6zUbF21mgZ4iQWnsWelD2WyDePt8FCDrqEOycV2pPlZ3Op6apFF9JvDDkQOBM9fA=="
|
||||
},
|
||||
{
|
||||
"id":"aeaf8abf2b4d44498c2cda6e2ebe4d2c83c00208163c6b981aed508d498fa366",
|
||||
"domain":"map.meshtastic-krd.ru",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxaQQV295xIRsiSe+UuJO\n9tq7yV+oUoTNYnvjJsCxvgSKovVJIIZN/Lmcx3P+Dse+lY4WaGKLP9eiIcTXeNjT\nhLJ5rHmVubVGZsVS6l/wInJXvRULKgdTYbZN3f7wlgf+mew9NHYE+tkmR2da7I6O\nbXb6rRdoj67ukGkFfCpfijuzY9sya/Z9LQqfezMnHOmAoHxvhTndWqwINoKcCaY8\nqYdwSR+YnDE0gbwx2zUg2o5hmCdAh2EqsF4EfiOXdcnYoVmQkCOnB9dunkWOzVtD\nrIcwTLxSQEVV46Wb6qhqdQqEeDaQfuEXfFNIi6Ho5mnu7Lf89PeCvtERmuio7u71\nIQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Krasnodar MeshMap",
|
||||
"version":"v0.5.3",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":45.04363,
|
||||
"longitude":39.00739,
|
||||
"lastUpdateTime":1764056911,
|
||||
"isPrivate":false,
|
||||
"signature":"m/TZjdZm32dg4xjwcyC0VcCqlwUCoxfk54JKGhBduY/+4Pkc1MFCcnzsJXCsTp8sswXM2t/qaulqtEuAercTBJxfJq4wzDn9R6L+IWjcEOqBjPF3OHUAM94kduuVDb3myUaPRN/6p+Xjj1S77wytOeAQ0EhtmUEAzZntkMk/jA+2AokW5mHLvbIufRIVQjjvUfsNFJvL0OVWeeGiFIcUL9ZN4ZwCnMatFGSNah0RIpFcxge4ENofFMuF46Suem5hshMGTtpHVMm2iSbANhaccPrfD1767YvdaFAziS6ID8j0oP59fN1cvovgwOxBri+806QQoOONwdkt/Nv1QrOHYw=="
|
||||
},
|
||||
{
|
||||
"id":"82292441e3188b54be1b2c1962a20aad7b1e5ce9e61ce65bbf6b30b6f6d37904",
|
||||
"domain":"map.meshtastic.spb.ru",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2JqB5p+yIKbwItNc13ri\n8rW+Z7d1Qrofjt160pIMmALmsT4O6SrdRrQwFmoZEL7pP1zwyrpyV+V2pjHK33NJ\nD+Eh89+bCPskILJfNyfxcHPVb/xPVBaEpFjAOJJ4VYKFAE7G3pTb+TluB37wHDre\ncY1ewV4/2sasTxmzWQoelpz0a3MJ/oGdCBKi8OwYAthxLzk9WVZmAmDWliEezpzr\nE0chri13RoegOKGkl5340yHTJh8m46UpaWanRgjGye9sU3ml7MIvcckjsm+zokrv\n0qyF615EM8bAHGsn5jAre666St4eO1kuiJcNK+Z5lDVTQknSH9wwWCX9wWQ1YhIF\nxQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"SPB Meshtastic Map from RE50",
|
||||
"version":"v0.5.4",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"869.075MHz",
|
||||
"latitude":59.951298,
|
||||
"longitude":30.315806,
|
||||
"lastUpdateTime":1764092137,
|
||||
"isPrivate":false,
|
||||
"signature":"KfgBgjqc6PS6ps4VDuDnX7l+qwfMhPc5zv36VWLQ77hgnkwLuB/97OL+AfV/d94imMOYqWyGu1MMrbkeavAhoMBkpyjs1DB+ABk9Pn/GXcu4kVILL1speJ2DnNLiv1piycJmdAjOBV9X9Nnw5V4oXjOSXfL7tO3MEjaubRlzu9Jex7cXCYrO+pCTwQMZZCuUgJKVg1B2FWgxWeR1uU/ToB9tFRi2WlaR8AIlEq4wiHq/wpJyPDlYwvgS7TiJ9oRyxC+zsULC+B0TQ1dXPHViDOrmaeAsYWbPhtJh4lfZht+pxWxqlG9jguDySHAU/EoqEK/hOZedZGXtt2TXvUsdkA=="
|
||||
},
|
||||
{
|
||||
"id":"92dd330d801bb817afa8f5ba9c78152e24221bd83c30d864cae39d5429ebf110",
|
||||
"domain":"mesh.fux.is",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2bGkm/Ab//iSHmP05ZSy\n0A7D+OZ8htqG647giTNjAh6KESPQsV5qFIAm/0Aqa/vKyWYfMYMBlRu0fVcat74o\n5JqEJJTSYcipfOYzzgQqIIUswwNniLzwG5OLsIhYpnVs13gLJ6GRJJhklWFjAZiV\nxNbZKDFF1NWJoxGYVuo+TcKQ2j7TxzHTsE0rtx85WPexGZwAAL7eicquapwdAtyj\nHLrBXdUtC/TqOKhh5Qa8v5KAAs/pM8+mWglQMUigpQdB4D4rh3kecGFXwXn/WUb5\nxUGgz7Oa7HpyJUQbkzCPmfovS4G9+tCMn8sWFxvE/pQyMK4O5PyDnxkIwEfBkgNP\n0QIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"[DE] Rhein-Neckar Mesh",
|
||||
"version":"0.5.6",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":49.487457,
|
||||
"longitude":8.46604,
|
||||
"lastUpdateTime":1764084339,
|
||||
"isPrivate":false,
|
||||
"signature":"ijW8TwvPT2JLyGVUZ/SvaQNBuPoULroRO0wKkLVCfCXoUHfv9lMXs+s+OTTvSdBsnM1Rqpt+oh8CoS7rF7HzOKBahywOOeihuK8p1uBDMNlTm3c5k0+vZHHpPdGGL2QvaN5LYfZ+k96F+mxnJSOTm2RZv+iS15bc/i1I0TjM5lE+MWOgOwkiykqKmU0GGWc4kmAiTT3k6dhmRwWtpDOzPxXCvwb8iwAf4/ObzTfRLp9fYSCkDkLxcoCTmSo8PDLq+H1IGP+5jQPeUvCKKJcIvYznT4psWxF8I8G85zT1ME6rqC8bU+oRoM1mFhsxPUDS83JQtGhzqt6hk0sLtcVt4A=="
|
||||
},
|
||||
{
|
||||
"id":"811ef6a4184c7e1562196b378071fef4119d6d4c1bdf8ef79089f1de5516885b",
|
||||
"domain":"mesh.hotellink.ru",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArxjRS/TJkWhkClhW5wKJ\nMwtWzkIo/qRs6tsHrK3eOE7EAAHEaN2EemlK3A1rYvphsQtkSN7nbAWrfeJcUP9i\nycWiEYcwSQTcjZ7tKynHnxc1IWkLFDUEEJSmXXyKSzf7/eq/C9426zPXn4aCx/6b\njkhslKivgBGht6a7XBomVoY3Q4ekCucIzLY2534U9CyB5OhMuE9JNiwQyvfyPe5v\nimvII07hVvE0PHWkWai4E9l8ktFIKQZzvPP2SQqEmpjHIo9h1QaRujjKW6JhenMk\nZb9CBGqcmMs9J4vjWVsAROmCsI5L3yv21bBWKSQn0E6elGnwf7qnVWD59KagY5cP\nJwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Saint-Petersburg MeshMap",
|
||||
"version":"v0.5.3",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":59.934423,
|
||||
"longitude":30.311212,
|
||||
"lastUpdateTime":1764027925,
|
||||
"isPrivate":false,
|
||||
"signature":"ig+tk6xcjdmktrG1P3TNXwLC0Fxlky2nqNlEMGd49wfjDU6DmklR3u+OBbQR3tjF6YlcL9VxMEODtrfKsDQv7ajZANwBLdU7Re8VyAoLAWTztCFAUvlOUcKWV/Jt69aCPRHIlqIy4uQNjparDyptwo7SDQcAd56bpc1LyTlJn65OyfbIpC7MQqn+Xnttm7z4jo3EZEya2Vo+WljBw47lNjT73FdT0Lg+7XK6cB0S1voLKt50/apJtMht+L+2sM9rEcfokzdnbXqYZLK1QBL/p1IXJvN7CGGLLs57+8K8ZBzhxqMjRO4AxDVLD8Sq3MxS3MNBOofrnuP52aw7T2Ee+A=="
|
||||
},
|
||||
{
|
||||
"id":"a8d7ed2ec68c872f33b55a99291cad0bb0bb6731248c9e8fe6becaf3dbaf58eb",
|
||||
"domain":"mesh.kynai.net",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAr6QvP8PMgNzUOTTlFI8+\n1JKZuL8EZy6Uju7jxXl+3/0yT5J7bNXzsSW3JGzbsrOlkrr3BudbX8ahHGGKo5pL\n78Y4wQZ+086q1ckYzN5fEjLm2EeXQ76QFFNIAFE3D1MmhvrOXMxddNx6c0bptenz\neppCm1kuft+oL+OEJJYZ+dgkzsxSeagEwgECR376emmKeB4MxnO2h0Nf2djVSVnZ\nj2LdOdxgHWhh4z2ZTOTMXUALiolMFQUHHqDunJBItkgGcF97rZVdhM4XuFxSlpBj\nHMYrkrlHXqLu4/BXLUr4d47UCz4ctDGQCRblgmz0MsyeYqKQliJmsrv3AXiKXAjZ\nKQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Meshtastic Madrid",
|
||||
"version":"0.5.6",
|
||||
"channel":"#MediumFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":40.41831,
|
||||
"longitude":-3.70275,
|
||||
"lastUpdateTime":1764080459,
|
||||
"isPrivate":false,
|
||||
"signature":"hdCvQU62U10FvjBGkR9zeJToRKwS2dWr4C1TyU/7ShyswbKOVSInQmcCFDLhcOS29XcAfT+4phvuR7XacX3CXpDMsVz9wUC6QT3ru7UhgKYr6GqBGUxQsiEHXqaN6YVLaFElQKzhicfLGU735Qen4vPRLMBSKygpRbqs/A31h4n6YrFqgP7BgKQKCmlpPXohLQifqVv/YwLicWBrHkM12g9zYq12O8Y3qH2z21Cp1Q37tA0CIW1YsSCvlChfAddJ6rFISFrgvVDbDzGI1kE4MjYLNULYn5mP9rmpR3kCXb7etlXr3F8xVYXCvZEOm/QfAkReapqy0THo2O1f/d9qaQ=="
|
||||
},
|
||||
{
|
||||
"id":"128a612a38a7b086bc41f43a3cb26158495a2f74c05b7fff0c8b81732bd54c5e",
|
||||
"domain":"mesh.lora.ms",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4+eYZjp6QiSCeIIBFOLA\nfjxNqg/IqdUIrizOXS/UBfNWMBsnWhamBwm6l1FQ8ZiD1EKmEPdKlpDyNorAUHov\n3jsUgYsB63aZ+cjHID3lHLHAxOmWF+Fdeej09MmJNq4jyudE3fgjTdf+1C6HXGHF\nMXqk4F6md37GJ0pGVonNzLR5GA7CRZS4+tuHlwEUR8LbCxPIadza64PdAFtJvuPB\nda+h2JnuSeRErxWei4jqaYYqTwfwBAd+iEoUSLmvxmD8UHYUn9UEo94Q4TnWIopY\nJh+5ajKNgRNYM2hhw1ZSG9immfjvc3DGk30D3pERGlb7UJuk+bFKs1IwsmdK5HVC\nqQIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"lora.ms",
|
||||
"version":"v0.5.5-rc2+10-b84764c",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":51.962,
|
||||
"longitude":7.625,
|
||||
"lastUpdateTime":1764096892,
|
||||
"isPrivate":false,
|
||||
"signature":"jRkvR6ZMRaTj/VhtbHEs/DU6Plt7tK+gtHtR2uJuXXdC2xP9VCAzB5MLEn1dcw6QV1Y7twVF2a0e9uASQWWYt/kyHghZatq6GinV5uOBzv1+jm4iqmFYyMZkTwqhFjGNmgBDOO3+jbuFtQri2chf1GIlCKQqnV7mi6XBuFdUSLlqs0sdi24sTT4Uys2VYuF5FM9D7LQ/aHFlzF2DMIHK86ScUgEhtdZRC5zxTHzg4+YZgmRBF6F5bH0EYnOdaGrMXmJX6wM6WmXrMnKPbxiXxFsEbtASpXDwHn4kkHnI+mygPl8tAhska0/JWnzK0sG1jn0b7dhDomyBxIQr1In2uw=="
|
||||
},
|
||||
{
|
||||
"id":"b2ce736f0390c5da08b71d055b2e6d05355b74831c57dc07b22e79b4ceb02bef",
|
||||
"domain":"mesh.qrp.ro",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8CiUkygd8IdNLZ1tqtgC\nE763F8KvBNBdklruZb0wRWtDz6gEB1ndQ1T59udpDICTwy4SqUZWbMinaZsClGa3\n6p+PY2jMC3y+WF0hsuPQ/RwI1OYG7SGoU21X5hpkrB83+2pPXcFWuo+OtKXAzEty\nSr9FLECCA5pZHJS+DlYHYeWXd45YU6UH/JBT82E6qRSwiOdVlr8c6uyBRIIA1vdv\ns6hmAASeWHXbftT6rTvB7Ss01q38fni4YSB5Iv9F0Qyki1bS26yg8Ik7ieb/ncgo\niBGwbi1j0ur4TTF9nnqvYQaqrTWl6RG5iZsHw/jl9G/Aujpq+ssWillVXS1r8fXM\nuwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Meshtastic Romania",
|
||||
"version":"0.5.6",
|
||||
"channel":"#radioamator - #LongFast",
|
||||
"frequency":"433MHz - 868MHz",
|
||||
"latitude":45.603112,
|
||||
"longitude":24.735904,
|
||||
"lastUpdateTime":1764106976,
|
||||
"isPrivate":false,
|
||||
"signature":"DggUf7J2h4WRl/oPtvYfKPVN8kiyMmJJejqsDpMCM87tXOmV0LCyYLFR7SvqZslcZhUfgB6x/5hxlb2TwPYq0L/CsY3DObB++GdIWmNcC4Zvb/JxegmHkrjsA8EnyUXyfELpKjvz9XOyxfug2N/A4jvqszrivS3VMdWDelC76/eD/czLDLBh/wm5RJMKkAckh+5HSH6aSlK30iPGK2g8XOyOy6d3ghRYwjQxHyDGGNhAyFPbReVHWLkDu4bVHLVo/2J7HPPzyB5g172/yYH1XoBc3y1rwm5RYpN4W1HnWLyn96+FaQqlJq7jMHIVxHIdDHxej78qUoa1j8u3QoRmkQ=="
|
||||
},
|
||||
{
|
||||
"id":"181853cbca021d8ffc9c27b8f21d692ad01eb43dad9ae2b05ed8a9bc87cc917f",
|
||||
"domain":"mesh.r1cbw.ru",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuEg7/LEz7HUZ2K5eP5En\n1/sD9cElq8GeliHVeYqknHDYxKi5E/hrmYin/xQA8IETPucIneLV+sihPN4A2cdf\nSGnQtLGZxiLHRkWZYYyQAyRcSKbhi87XZOqQK+qC/dd44087ruH21bTVsgxtpWBo\nCMU99JD3N3c95m2bb6/VLSizK9SKsZLKREv+7gRymkSHspOKnQaauPj1Ke0yPo5S\n+klquRApKf1scrDMiWy3SA8LOahcWyZR/82QPLQkXrV/5QVaSRe0KrRLyb92mCA4\nedMCDQjRCd2i0HonGMf5ikpEURL2cB7YtNAs0CleFQTqs4hFbcMa905PZiKgDoHg\n7wIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Yanino-1 Meshtastic Network",
|
||||
"version":"v0.5.3",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"869.075MHz",
|
||||
"latitude":59.9523328,
|
||||
"longitude":30.5922047,
|
||||
"lastUpdateTime":1763579931,
|
||||
"isPrivate":false,
|
||||
"signature":"PxYezt08/r/ZNoMc1yjfgRJ6EgH1gK/ERWOofy4PMrmmoRbNmZs33MCxNDDaS2UsgMdCzpe9tqKPhRlQZUJ8QyZz7IV9t3vVnOS46QNPsBNJi76XWnG+rAYTu0bUIJTOmIp06OmiEot1ocCca/BE9N/NjA+07bqrpDXz3iDz5d2M065BHcc+r2SqmtBzMPNPDLe46yqf8lPv1vFrD+Mdd0fbJVMBuq2gHXNjT5QNTFV9Ztt36W5WGMgVN/wNKn/r4JisUlkA/uMHPjqAkFlgOUZra0Bpy5Cl6Q9DW1paHqxrfDFznPQO6fXacf1hpV5LhleUUlGN59n0KlyrFP0egg=="
|
||||
},
|
||||
{
|
||||
"id":"fa22823dbd2628002d236954347e45402401aac30770e2d6c4f822360abc448e",
|
||||
"domain":"mspm.invalid-domain.org",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqrmDDlpov0uXu94hLFNV\n8ByWrsa2GbQ9BiV1tEJodKch+/PIO0HWG7jslJJO+E2UIQ+LrrCPMbgb928SwHuQ\njuTvUjouXKJkB2v06qqRQ77hRGQIqzYEuAztsh3VWinw4ux8pGMegbCAjJQzBTy6\n8GGHpdP5pvIu6l4Jn+G0vkBr5jkwQinx6HnvYqJS+9lK1Hz3OE1tYjePhiz1V09k\nKw1Zqpr0KbWkS0Ywjc9MWH6m370NRh1qzF+N6gbrnQkGoc+vIi3kHZcjzjbNHnsb\neYZuWFBeuLD5TiPwPdm44LckVUriWdERoT2oOwIzwxxuapblDx9TcWqmYR+MVU8c\nCwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"MSPM",
|
||||
"version":"0.5.5",
|
||||
"channel":"#MediumFast",
|
||||
"frequency":"913.125MHZ",
|
||||
"latitude":44.97269652411355,
|
||||
"longitude":-93.2602843583228,
|
||||
"lastUpdateTime":1764094130,
|
||||
"isPrivate":false,
|
||||
"signature":"L6aopRCFYF8IcY2c05XoFVUhLbX6ZMo+WYAvUh3sjWead0JyTAHXIzCK4OukZtTkmBHqMM4tieSMJW6RJpibtbsIP/ByDsCOwAGqSj6Oi9kiESImX/QeC8ZLjix5Cmby84Gl92npbRlE8/UlL8+na8FVhlMksyYsb5hTqJRZbsdFOVemYq2j0qNH3T3lei4IgPncr9pAskXON4jyjXxmAohNh+tWn8bgaON22Exa94e4JST3/X7sNRRaAWosAGaL4PrctAmZs6Hs8I/bf1jaVqauHejd4PotD1n+t02lK+5oKSySaz2XbbCrv0X+evCxqpv42k01wD4xGnOY0cuM/w=="
|
||||
},
|
||||
{
|
||||
"id":"f1788f830865962f41c9839dccc1197568e114f090a16c60ce94b631cae4fb7a",
|
||||
"domain":"potato.ringo.ws",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtmXrfI+5JkvYic3EBvz1\nyyCF9Ebj8N5PAQDIymfSpM1cir4LIZMCU9Aeh0tbkQChlXwiu3R4Qt2d23hVyH5j\ndPn6/rxF4ILJ9evkOB64Jr7ZDxBpgGm/JMUnEBGaq9+lEDW6jDbccqnyJsK1Ak4/\nHEamxyoPEOu/pUlzhavItT732+FW380DNkv2HwnygtPL1qXtKPU0EV4xRq7fZenC\ni0FKBPKJG+NezZBn3W6NI1KteuZArTVvkkT8g96Mp0Lc6nSZ+VEEBTwxHX6pR731\nJpbdU+6GjyWJ44MeVlbTcxuWdKBg5ltNb0TZoOh9z314rZ0Ic3tnMeZA2m9Fwybb\nYwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Ekb mesh",
|
||||
"version":"0.5.5",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":56.8519,
|
||||
"longitude":60.6122,
|
||||
"lastUpdateTime":1764084665,
|
||||
"isPrivate":false,
|
||||
"signature":"hSjAbYYy3tJZTnZQALAUaxWJvqdFYU/rTeVNbct2q9Ti4SYrB2+rIGoFZWbgZqvmzmRdbEcSTMK1xsmFS5TFCxCPiDT7VopMnSMY/LWMXJbmTfCiuBJfESVawfrDXzVheFR3oFLYTn3IklDSCH7jpOMBpkFDuzM1AgHjic56upN7GYDoAhwBIUSPomOohhLeQABbMBcKvNm5QuweyKRY8G7PKQGrjERvOPi7CEI97WPgqzq+ycOEKa/o0MbpRygJZn9T9Iq5cbaoGudv8geF7zbjoZd1x4XOHkuboyHkJTppoysir3goBI6U6S55JQ26H+xuBNq8JG/Yf4GR+Fi6tg=="
|
||||
},
|
||||
{
|
||||
"id":"55a9ccee75de853e28fe3e1438a09ba8e4629fb5788832036d9cb1aeda1b1b36",
|
||||
"domain":"potato.theldti.com",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2LAPqNDTZhnUK1tNjHmB\nrGk8jPGU2Zq75PMc33mMDZaZTwFsPjCMAT/0+XDpgjCwUVhDqe8ZagD3AKb66Mvk\nRTS3uJIQZWQHZS4gfp2phIG/k5RJJB/IPV340Q78lQ27E8qeWC9nLWHVdFCmowrS\nCWfeGZSzQnEdS4C2JmJsft9VeggEIGO4DuAIDLmdilwV6kNx/xEeH12tzoY0joBv\nzslYiW7x5pBaZZSn9R44oBZBBOSO4Z3KyXoiS5ykcnS1JIjJTau+C/a5XoSYityR\nn+aN88YPytrjg8p72k9twQ6CZ7WzYB24fmXNrNrKf7RYOHJTEpdtOjOHX9KaYw2l\nBwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Meshtastic Alt IL Community - The Israeli Mesh",
|
||||
"version":"0.5.6",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"919.375",
|
||||
"latitude":32.0805216,
|
||||
"longitude":34.7807083,
|
||||
"lastUpdateTime":1764090682,
|
||||
"isPrivate":false,
|
||||
"signature":"pIz0XeYHgsviwFZIMnXL3AiO4A0VUV+4kevP9V7QV1jJl/dfODF10m7zCuhpPLK7EdHpZAhVsquPbb03sWuLJy7x58nms14UGkc3dB3jJ6Elft7E1D3Q+tPzxRU3Z8i74K7PJ9BLCboKhvKgsFdiRl+mJcdqb3Osf8m5sMenJjR/xF44xq4kvtl2oug6OU2cjSMNyM/OoLFK/Ag/YGzq17nrM5DgairsTmAb+Lp/IKUaWkRvh+Tmt6VbZqghurDidHZht8hhUs3Db86+dlARj0T9jaw3qQQDQourxv8nDdfLWNZLD4GipGOsSeQOHHunIl719NFtDTPN9eeWdchdXg=="
|
||||
},
|
||||
{
|
||||
"id":"87553a5e1f7b7c883b19b97764c72399bd359fb26e09fbd32a9e4febd0b8301d",
|
||||
"domain":"potato.tnmesh.org",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAh5CvMnfCGHOhVm+64bFy\nB/djkDO68XHvFM/gXCHda+lVZtunDdjncYtZXqIuPZ4JGPYxmqrMf1IyI5LKZ9fU\nfKKxC++vgnrs7508k79AHpIaJgAs/dpY1A/GEmKguSZ7FxTvPzcbPGnOH1tlJHyP\nK9McEiSpDfJ+DL6ezknZs7LI61tIK5omao1wRkHxbR6wCHedhPRAVqxsbRCHF6Zc\n+JLj/UFSXLdmY4RRL1ei7ykJXFdon5dfySr6WrWxfoMf4EMYsbze9PSiK8UjVsBH\nerD58e6awo8NEq558PQjDONGYmrk4mIxlCgaNN8OpglYEPkbsMy+wT68qkg71aMf\nTwIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Tennessee Meshtastic Network",
|
||||
"version":"v0.5.5",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"915MHz",
|
||||
"latitude":36.1627,
|
||||
"longitude":-86.7816,
|
||||
"lastUpdateTime":1764093408,
|
||||
"isPrivate":false,
|
||||
"signature":"gqIqpKyJ66fDYVlarosCGHFKMs58pH0rA8xfisOUVaSoEoFxJDyE+ybKLQn7fcb4pc+V3zJRMpypOHbkKLOH5tNOgFK7mEY+1CUKuJ3fk6HGnnwxuU8aNzOw8cpUy8S+Bq02wBgLQq5J8u8X1B1Futj47oU5+FOfHJnADjWKpynJcQ3FcBq2/dvgp6xUl29aEKKI8qpu0lUC8TfErogzsw5svllZ2TZ3vCUJn2lJ6+/soiHTAntfg9zCVz5u7U5bxmkcFKAIGYRg3KfIgQtufWpYjUq5a5Z64SALCvfhKccAbPqcDhT+jK1ULC8B29zp1BxeutUxQjFjpXmznHOgPQ=="
|
||||
},
|
||||
{
|
||||
"id":"5a3cc5815d09687c742ff27210f66133c8a89a26bbae662a7cc8b3e9074168ed",
|
||||
"domain":"potato.varna.radio",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1maZcARwozutUrboPnLF\neAL6ibW7oV2qxvx3vCy9uM37OkHap2b7Hx0P1mrf1bYGIK5qvP6hUiCr5Soe19Ta\nhQUawHTxJgqQCzYS9OC4QUm24LMp4q7ZT5cfmdvDBMjSoAQ9yhyrTZc0TS8LSd+H\nrgXJntc9/JM/aQO+5cZqlDhbNnnYKJj0mRSDYmkE5ali4YkEFn2AiYtsAAYLfzgc\nC3zzPQpSJ3i7XIigRCucBEL5wQgtszaVm4nO5GudKXJwIKq45Cz9etSZYenD2/P7\ne+TSyS0EPgZ3oORSYEFDpo6p19DOaMfR9OfZFbZJ9H1eq+PHmd9aNJzYXVxXbVKK\n4wIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Varna Mesh",
|
||||
"version":"v0.5.5",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":43.222428,
|
||||
"longitude":27.912604,
|
||||
"lastUpdateTime":1764103542,
|
||||
"isPrivate":false,
|
||||
"signature":"aj1pIihCQcmGKERtM1tPcIQzAhLNRN7HrhDwhcMCLeutAN27omna2pY3WI7Mx0QtQugsSesXXhDQ/yjgmeXyVZl0+OiZOv5SvMzVYvUKnUSt2j6ueqJMsX26mXH2TFlKAWiZxi3SMBj6tMmIqcPBsEzXPfNcfo7jdA5NSJ2okP8WUELEV3wNtIGFkWOK1hWGexnprR8kIokioMCd/+AvPgSDFxW9egrao44NRQnvHEHjCw47b68gGyuqlARjIVNDKXrPhQHWfDeFTC4OWgib+5TSVfjixlplp4Pl7FppsjPbkubTzUR+SgbNuXzeYovHoTnAsWGBPU2TtKFxbsIP+A=="
|
||||
},
|
||||
{
|
||||
"id":"7dd9af5d2ac893efcea473866b4dbd98a5ef0e89fb5807a0c345ff3c9902e273",
|
||||
"domain":"potatomesh.jmrp.io",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzeBnJ/jPYQW+jq+UOxQO\ni2rF9Qhn2qKlsrLbemvfyb9q7tbb4ZD6pQed9OpqdHFBrycnf0iVoaPS0Tw9FNXb\n4wqUPQItjRqPQNTLmNpZlHeJCE1/ORcyRQiWJo0p7ZhkSRKWdCwqLYM9NoJn36Mh\npaNOjnJvadLUhwI87lzP+rJYxSCHDKHaBBCz8tB5brMUWnbpUH0WHUJhjv8X6jf6\n56j5Af9WhdGaX+YjQCMY9Loh1+3VH/ayesojoRR3nBHvWnQY7cbRzhsw5NX6gQRL\nVY39EX4QYOvJS1EU1EHQPkcl/gqtIJVuvAEDVrQ1uC2KKqdEVy/2qx83VMP8tunv\n3QIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"[ES] Valencia, Rafelbunyol",
|
||||
"version":"0.5.6",
|
||||
"channel":"#LongFast/#MediumFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":39.585449,
|
||||
"longitude":-0.336276,
|
||||
"lastUpdateTime":1764002445,
|
||||
"isPrivate":false,
|
||||
"signature":"EcMXp1UoFwFQOPrPDPeuTq48VlC05p66eR4L7JwOXGAWFCo7791pl6Zdry0JeI1tImkS4Vz0NNikRDfqUAKsh64eykPq2FNQPb+uRnD8JZ9xiB24xBY9lbUxfXc0PgMSSOuM1MYPGwpSDwguDCuLc4t0eCk3Wc7x8uPClpadxasVwFDTwD2rkwxwa7LQOWD5f4TzYpEZH77Fb0QpGYZKwBrt11bIX4IfnKo2p6fSFbfrGgtS9zAM8SUzzXO+L4zYd79IxYVvl79ulLxc1mPL3H0DH5pemoJrGj8iRlPHs76dFglZJpWe9o0MX1mN50GzVZcFJQsldnGZJHjD/z3VVA=="
|
||||
},
|
||||
{
|
||||
"id":"50ede1bea9fc64698742bf00ceeff89e7d7c09d1592ca193b07aad1e4f4c91dd",
|
||||
"domain":"potatomesh.net",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvA6yuxpgT5wygE4tmsai\nciFZLzu+bMKjpHEbI/mq1ri7Y0dntFd4Z51OeZoIQVcNGjq5GmCnTroLlH+PKxR5\nBB4Ipxq1hgsjtVT7jhQGat9DFWmu/8hKt0LL7s2pQJEAOalJvmdjoWhvSK57jf8o\nPmjh5UQnj/HI/k2zwHi1pZFJuFbZrUX7dAJTEH7im8jHKbh0Fm6x5Wj017MnCAeb\nc5+b8oQQXQKB+JGv57KNfQotwKmuuAqAj5WcCt08bKNgCcEsxEltZSADslIpL6pi\na8I8ZRIGJg9VpwwzFh8ifWbKXiml9wa4ZOVTSPzUlzaX181fhgaiFvV/nKPJeh6q\n4wIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"BerlinMesh",
|
||||
"version":"v0.5.6-rc2",
|
||||
"channel":"#MediumFast",
|
||||
"frequency":"868MHz",
|
||||
"latitude":52.50289,
|
||||
"longitude":13.40419,
|
||||
"lastUpdateTime":1764108301,
|
||||
"isPrivate":false,
|
||||
"signature":"NfkeowuQdprrXYf91WvExaSzzqUVKVHmC+KbKsl7FZsrADundS41B5GuSu9xTz03CNhE4PrdB9jGoSIhFcAAkY6fO8N5q0GZNXRMtlcWcMeyvz4zrb0ntsDtTD3ieUbDEFYwaHT4aIoEz1mbjwU3TrTQhsEx0/JSqF8z02gZTTZHdZKYPWbBcPp5y4/kA3O0gbA28rcNnC41fkvxUEiyH/nY9EM9JUdG/j587t3gWen/lOa2gSnfePIwIdUlRk590snoQnX6bIwvd0dW5ZUjr9XN1OTN9R27XNyQkxig45yLe6DKcmvawnIfqqWvv77ucNg9V/GeeEMuoFBhGp+fqQ=="
|
||||
},
|
||||
{
|
||||
"id":"aa37ff9b4a0d66230b14bcea980b6cc95f929326baa4bb7138b761c2f6d00c64",
|
||||
"domain":"potatomesh.urspringer.de",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAiTl7UTSs7P49IfBoS/Ns\nipAYusPImhmhlg44kRVjhoTomPzn8VFN4np9ekpP8J0kBZ24hnV0n+eC/6RFhwyd\nlR09IvxIdjDcdxU+UTa46K2ta/kkga32k5iaG1Z2OaXDm14KgglcvbB/V7sqIRHJ\nXcYlfOIqXbhfnZpBRF08/zLw1YmktjUWCwr2ZloHPkfWHNjC/PlnNo50g0p0fKKq\nQkF9uLhriSCRO4K3J4SasSRCEk6pvDFWeA15Xprca6cMGHavIpCuVuzwvaduYm2o\nmd8ScB7y61lSRjxyusCC1ir6GonRu7HZPyIEj4FsxVTPK/Vd3A/SPHWDrKyspgei\n4wIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"Mesh Hessen (Maintal)",
|
||||
"version":"0.5.5",
|
||||
"channel":"#ShortSlow",
|
||||
"frequency":"868MHz",
|
||||
"latitude":50.1306942,
|
||||
"longitude":8.8447884,
|
||||
"lastUpdateTime":1763637532,
|
||||
"isPrivate":false,
|
||||
"signature":"QqScuL4EmClZ+thrA4BFyJyj2Fa+t5no2Q3PAYHpgY0l0AllYbmW0vc9ifFLbqdHwmFnoyQtD4BnoofZGl1poasoEVRF3twr0IEJtgb9pdOvmISwAOSr2WN/sLlguFxdBo/xrDzfbKiZrt8GQXN3U+eM6Kaay4apoIJcpjSC1uCkEcACnTWNvLcgKGWoBQWWB7R45ZIzNkkr9Lxn+gm7myqSrz9DMkY8p6KW2qB/TgKzEppLdy2eHxXEZGONrWohnHwJvhzXNDj7+M+wy/EScPaQEPy6Ij8OliymkhJOaLWSz7D026vFgCCq9XE/AlRbB3a8gRy0s2s+7SZNtjMg6Q=="
|
||||
},
|
||||
{
|
||||
"id":"d7b1f776aec81cab87bf2e7c90a3143882d60d9c42fd64f4b0fdc413553ac85a",
|
||||
"domain":"tovvel.nl",
|
||||
"pubkey":"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsnR6kxgyFjKZJPmxiSWU\nISwPpz4e5ldbQ8bX5NGww75zdbUuCtgkFKcx5jczuAmcv2KPJWooLqu4E7n+mQvV\nWDl//Zio6oV/XE3Ac3Mc7xFk+51VrDq1PNTJdT1zLtrmsd9RgHBFWnpi3zes7pUe\nXdFocla2Ny2ByVozKWic0kgT3GZqGpbjeFp5mKXamKbXx4Sq/wZXcYg4ecr0Wz1a\nNToUucURL5jb/acQ5PF9WQn1RxUy/DmUaMcisPJmPNzdvGd+FAjR6PuTXTsGd7ul\nxlDqtv62RTWk4qJnp/sW2BNvcKjSjP8Ta4cFBwZW8EIrQ1MrEaLCcgnBPX5tsijY\nywIDAQAB\n-----END PUBLIC KEY-----\n",
|
||||
"name":"GrunnMesh",
|
||||
"version":"0.5.5",
|
||||
"channel":"#LongFast",
|
||||
"frequency":"868 MHz",
|
||||
"latitude":53.2192,
|
||||
"longitude":6.5683,
|
||||
"lastUpdateTime":1764085936,
|
||||
"isPrivate":false,
|
||||
"signature":"LJFGPso4bkSaMcLxJeiJOaVDVjCpXfzT/IhP/0ZmalyYloPS6dlQhgxyOfN4q7NM56fY1Gpl7nwYsPn7AHUaBZWY/rw86+FqvzagbuB29VOh6S+/VPNNcixUuF0nrlyMYKPt6dUknSbcBKLtEOKpu6U+b9C/7TcAb+lyAIMTxCev3x+z5n7eW0ZXiQ6XMRVVUZVfackY0SJrh+QXQfQ2xHgOfAbllQ2mjCUFAAvWemEOWwmZOjTHvvNe3xP8zXUaJlHc69xOwtvGpXWhA++OUAs30CKVdiqnyDyf8XBkr4lVHltAoK1rIeTdtXWwLqQD/LjT0iHGm8MmpRSKNu0UFA=="
|
||||
}
|
||||
]
|
||||
+15082
-3904
File diff suppressed because it is too large.
Load diff
+766
-14
@@ -1,20 +1,772 @@
|
||||
[
|
||||
{
|
||||
"node_id": "!7c5b0920",
|
||||
"rx_time": 1758884186,
|
||||
"node_broadcast_interval_secs": 1800,
|
||||
"last_sent_by": "!9e99f8c0",
|
||||
"neighbors": [
|
||||
{ "node_id": "!2b22accc", "snr": -6.5, "rx_time": 1758884106 },
|
||||
{ "node_id": "!43ba26d0", "snr": -5.0, "rx_time": 1758884120 },
|
||||
{ "node_id": "!69ba6f71", "snr": -13.0, "rx_time": 1758884135 },
|
||||
{ "node_id": "!fa848384", "snr": -14.75, "rx_time": 1758884150 },
|
||||
{ "node_id": "!da6a35b4", "snr": -6.5, "rx_time": 1758884165 }
|
||||
]
|
||||
"node_id":"!7c5b0920",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":-11.0,
|
||||
"rx_time":1764108148,
|
||||
"rx_iso":"2025-11-25T22:02:28Z"
|
||||
},
|
||||
{
|
||||
"node_id": "!cafebabe",
|
||||
"rx_time": 1758883200,
|
||||
"neighbors": []
|
||||
"node_id":"!7c5b0920",
|
||||
"neighbor_id":"!da6556d4",
|
||||
"snr":-3.5,
|
||||
"rx_time":1764108148,
|
||||
"rx_iso":"2025-11-25T22:02:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!7c5b0920",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":-10.5,
|
||||
"rx_time":1764108148,
|
||||
"rx_iso":"2025-11-25T22:02:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!7c5b0920",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-10.5,
|
||||
"rx_time":1764108148,
|
||||
"rx_iso":"2025-11-25T22:02:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!7c5b0920",
|
||||
"neighbor_id":"!da5ec1d8",
|
||||
"snr":-11.0,
|
||||
"rx_time":1764108148,
|
||||
"rx_iso":"2025-11-25T22:02:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!33602324",
|
||||
"snr":-8.25,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!43561304",
|
||||
"snr":-1.5,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!44968f61",
|
||||
"snr":6.25,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":6.75,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!d198a280",
|
||||
"snr":-8.75,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!da5ec1d8",
|
||||
"snr":9.75,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!28978f94",
|
||||
"snr":2.0,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!b03c97a4",
|
||||
"snr":10.75,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!b2a78754",
|
||||
"snr":-0.5,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!1d60dd3c",
|
||||
"neighbor_id":"!b03b3b38",
|
||||
"snr":-9.0,
|
||||
"rx_time":1764108111,
|
||||
"rx_iso":"2025-11-25T22:01:51Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":10.25,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!da627d58",
|
||||
"snr":6.0,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":3.75,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":-5.0,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!433e31b4",
|
||||
"snr":-2.5,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!da6556d4",
|
||||
"snr":-11.75,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!433da0b8",
|
||||
"snr":-13.0,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":9.75,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!da5ec1d8",
|
||||
"snr":-13.0,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d7b74",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":-9.5,
|
||||
"rx_time":1764107957,
|
||||
"rx_iso":"2025-11-25T21:59:17Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!6c290ea7",
|
||||
"neighbor_id":"!9eb0b457",
|
||||
"snr":-6.0,
|
||||
"rx_time":1764107033,
|
||||
"rx_iso":"2025-11-25T21:43:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!6c290ea7",
|
||||
"neighbor_id":"!74b11cbc",
|
||||
"snr":-7.5,
|
||||
"rx_time":1764107033,
|
||||
"rx_iso":"2025-11-25T21:43:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!6c290ea7",
|
||||
"neighbor_id":"!12ea9d7e",
|
||||
"snr":-1.75,
|
||||
"rx_time":1764107033,
|
||||
"rx_iso":"2025-11-25T21:43:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!6c290ea7",
|
||||
"neighbor_id":"!194a7351",
|
||||
"snr":8.25,
|
||||
"rx_time":1764107033,
|
||||
"rx_iso":"2025-11-25T21:43:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!b03cc22c",
|
||||
"snr":-14.75,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!b03d7b74",
|
||||
"snr":-3.5,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!858f81ad",
|
||||
"snr":11.25,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!da63e474",
|
||||
"snr":-8.0,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!4eb3bc8d",
|
||||
"snr":-5.0,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!45cbfc40",
|
||||
"snr":-10.25,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!db528df8",
|
||||
"snr":-6.5,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":7.5,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!bcf10936",
|
||||
"snr":-3.0,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!43b6e530",
|
||||
"neighbor_id":"!43b7c694",
|
||||
"snr":-13.25,
|
||||
"rx_time":1764106673,
|
||||
"rx_iso":"2025-11-25T21:37:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":5.5,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!b03d7b74",
|
||||
"snr":3.5,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!6c73bf84",
|
||||
"snr":-12.0,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":-7.25,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!da6556d4",
|
||||
"snr":-11.5,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!433ad740",
|
||||
"snr":10.0,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!6d022fe7",
|
||||
"snr":-8.0,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!7a6bf888",
|
||||
"snr":-14.5,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":-9.75,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!9a0728b1",
|
||||
"neighbor_id":"!da5ec1d8",
|
||||
"snr":-7.75,
|
||||
"rx_time":1764104539,
|
||||
"rx_iso":"2025-11-25T21:02:19Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!e38969e1",
|
||||
"snr":-11.5,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!1d60dd3c",
|
||||
"snr":-14.75,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!b2a79150",
|
||||
"snr":-5.25,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!b03ceb58",
|
||||
"snr":-13.25,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!6d022fe7",
|
||||
"snr":8.5,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!0c63e027",
|
||||
"neighbor_id":"!b03d1244",
|
||||
"snr":-11.75,
|
||||
"rx_time":1764104506,
|
||||
"rx_iso":"2025-11-25T21:01:46Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!d42e18e8",
|
||||
"snr":10.5,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!da5ec1d8",
|
||||
"snr":-13.25,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!433ef3e8",
|
||||
"snr":-9.5,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!6d022fe7",
|
||||
"snr":-3.25,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!5bcdae60",
|
||||
"snr":-2.5,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":10.5,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":6.0,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!335c9e9c",
|
||||
"snr":1.0,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!d1edc388",
|
||||
"snr":-14.25,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!fa6baed0",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":1.25,
|
||||
"rx_time":1764104227,
|
||||
"rx_iso":"2025-11-25T20:57:07Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":10.25,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!b29f9e2c",
|
||||
"snr":-10.0,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!ea8ee2e0",
|
||||
"snr":-11.5,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!da627d58",
|
||||
"snr":-0.25,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-11.0,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":8.75,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!b03d7b74",
|
||||
"snr":-2.5,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!699ab082",
|
||||
"snr":-14.25,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!d42e18e8",
|
||||
"snr":10.75,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!18de8f57",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":10.75,
|
||||
"rx_time":1764102441,
|
||||
"rx_iso":"2025-11-25T20:27:21Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!d42e18e8",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":-10.25,
|
||||
"rx_time":1764102333,
|
||||
"rx_iso":"2025-11-25T20:25:33Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!d42e18e8",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":10.75,
|
||||
"rx_time":1764102333,
|
||||
"rx_iso":"2025-11-25T20:25:33Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!d42e18e8",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":10.75,
|
||||
"rx_time":1764102333,
|
||||
"rx_iso":"2025-11-25T20:25:33Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!dd7fdb95",
|
||||
"neighbor_id":"!97bae011",
|
||||
"snr":-12.25,
|
||||
"rx_time":1764099533,
|
||||
"rx_iso":"2025-11-25T19:38:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!dd7fdb95",
|
||||
"neighbor_id":"!fe794c32",
|
||||
"snr":-5.25,
|
||||
"rx_time":1764099533,
|
||||
"rx_iso":"2025-11-25T19:38:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!dd7fdb95",
|
||||
"neighbor_id":"!9e95cf60",
|
||||
"snr":11.25,
|
||||
"rx_time":1764099533,
|
||||
"rx_iso":"2025-11-25T19:38:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!dd7fdb95",
|
||||
"neighbor_id":"!44968f61",
|
||||
"snr":11.0,
|
||||
"rx_time":1764099533,
|
||||
"rx_iso":"2025-11-25T19:38:53Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!db528df8",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-12.75,
|
||||
"rx_time":1764095095,
|
||||
"rx_iso":"2025-11-25T18:24:55Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!db528df8",
|
||||
"neighbor_id":"!db52829c",
|
||||
"snr":10.25,
|
||||
"rx_time":1764095095,
|
||||
"rx_iso":"2025-11-25T18:24:55Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!12ea9d7e",
|
||||
"neighbor_id":"!74b11cbc",
|
||||
"snr":-10.75,
|
||||
"rx_time":1764095008,
|
||||
"rx_iso":"2025-11-25T18:23:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!12ea9d7e",
|
||||
"neighbor_id":"!194a7351",
|
||||
"snr":10.5,
|
||||
"rx_time":1764095008,
|
||||
"rx_iso":"2025-11-25T18:23:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!12ea9d7e",
|
||||
"neighbor_id":"!6c290ea7",
|
||||
"snr":-2.25,
|
||||
"rx_time":1764095008,
|
||||
"rx_iso":"2025-11-25T18:23:28Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d10e0",
|
||||
"neighbor_id":"!b03d7b74",
|
||||
"snr":-12.0,
|
||||
"rx_time":1764005122,
|
||||
"rx_iso":"2025-11-24T17:25:22Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d10e0",
|
||||
"neighbor_id":"!433e31b4",
|
||||
"snr":-12.5,
|
||||
"rx_time":1764005122,
|
||||
"rx_iso":"2025-11-24T17:25:22Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d10e0",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":-8.5,
|
||||
"rx_time":1764005122,
|
||||
"rx_iso":"2025-11-24T17:25:22Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d10e0",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-11.5,
|
||||
"rx_time":1764005122,
|
||||
"rx_iso":"2025-11-24T17:25:22Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!b03d10e0",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":5.25,
|
||||
"rx_time":1764005122,
|
||||
"rx_iso":"2025-11-24T17:25:22Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da547468",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-13.75,
|
||||
"rx_time":1763947406,
|
||||
"rx_iso":"2025-11-24T01:23:26Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da547468",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":-5.75,
|
||||
"rx_time":1763947406,
|
||||
"rx_iso":"2025-11-24T01:23:26Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da547468",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":-10.5,
|
||||
"rx_time":1763947406,
|
||||
"rx_iso":"2025-11-24T01:23:26Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!e38969e1",
|
||||
"neighbor_id":"!849a8ba4",
|
||||
"snr":-12.25,
|
||||
"rx_time":1763627064,
|
||||
"rx_iso":"2025-11-20T08:24:24Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!e38969e1",
|
||||
"neighbor_id":"!433ba500",
|
||||
"snr":-7.75,
|
||||
"rx_time":1763627064,
|
||||
"rx_iso":"2025-11-20T08:24:24Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!e38969e1",
|
||||
"neighbor_id":"!6d022fe7",
|
||||
"snr":-14.5,
|
||||
"rx_time":1763627064,
|
||||
"rx_iso":"2025-11-20T08:24:24Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!e38969e1",
|
||||
"neighbor_id":"!6aac99f2",
|
||||
"snr":-5.25,
|
||||
"rx_time":1763627064,
|
||||
"rx_iso":"2025-11-20T08:24:24Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!bcf10936",
|
||||
"snr":-13.25,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!f2867a08",
|
||||
"snr":-15.25,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":-1.0,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!9a0728b1",
|
||||
"snr":0.25,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!ea24e0b4",
|
||||
"snr":11.0,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":9.25,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!45edbd08",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":6.5,
|
||||
"rx_time":1763601426,
|
||||
"rx_iso":"2025-11-20T01:17:06Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da621dbc",
|
||||
"neighbor_id":"!43b6e530",
|
||||
"snr":-13.75,
|
||||
"rx_time":1763548274,
|
||||
"rx_iso":"2025-11-19T10:31:14Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da621dbc",
|
||||
"neighbor_id":"!18de8f57",
|
||||
"snr":6.75,
|
||||
"rx_time":1763548274,
|
||||
"rx_iso":"2025-11-19T10:31:14Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da621dbc",
|
||||
"neighbor_id":"!7c5b0920",
|
||||
"snr":-10.0,
|
||||
"rx_time":1763548274,
|
||||
"rx_iso":"2025-11-19T10:31:14Z"
|
||||
},
|
||||
{
|
||||
"node_id":"!da621dbc",
|
||||
"neighbor_id":"!fa6baed0",
|
||||
"snr":5.75,
|
||||
"rx_time":1763548274,
|
||||
"rx_iso":"2025-11-19T10:31:14Z"
|
||||
}
|
||||
]
|
||||
+17786
-4009
File diff suppressed because it is too large.
Load diff
+23717
File diff suppressed because it is too large.
Load diff
+20775
-125
File diff suppressed because it is too large.
Load diff
@@ -1,20 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
# Copyright © 2025-26 l5yth & contributors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
sqlite3 ../data/mesh.db ".backup './mesh.db'"
|
||||
curl http://127.0.0.1:41447/api/nodes |jq > ./nodes.json
|
||||
curl http://127.0.0.1:41447/api/messages |jq > ./messages.json
|
||||
+248
-78
@@ -238,6 +238,41 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
end
|
||||
end
|
||||
|
||||
# Retrieve a telemetry metric from nested or top-level payload keys.
|
||||
#
|
||||
# @param entry [Hash] telemetry payload.
|
||||
# @param keys [Array<String>] possible metric names, using snake_case.
|
||||
# @return [Object, nil] discovered metric value or nil when absent.
|
||||
def telemetry_metric(entry, *keys)
|
||||
sources = [
|
||||
entry,
|
||||
entry["device_metrics"],
|
||||
entry["deviceMetrics"],
|
||||
entry["environment_metrics"],
|
||||
entry["environmentMetrics"],
|
||||
].compact
|
||||
|
||||
candidates = keys.flat_map { |key| [key, camelize_key(key)] }.compact.uniq
|
||||
sources.each do |source|
|
||||
candidates.each do |candidate|
|
||||
return source[candidate] if source.key?(candidate)
|
||||
end
|
||||
end
|
||||
|
||||
nil
|
||||
end
|
||||
|
||||
# Convert a snake_case key to camelCase for fixture lookups.
|
||||
#
|
||||
# @param key [String] snake_case key.
|
||||
# @return [String, nil] camelCase variant or nil when not applicable.
|
||||
def camelize_key(key)
|
||||
return nil unless key.is_a?(String) && key.include?("_")
|
||||
|
||||
parts = key.split("_")
|
||||
[parts.first, *parts[1..].map(&:capitalize)].join
|
||||
end
|
||||
|
||||
# Import all nodes defined in the fixture file via the HTTP API.
|
||||
#
|
||||
# @return [void]
|
||||
@@ -262,6 +297,53 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
end
|
||||
end
|
||||
|
||||
# Import a subset of position packets from the fixture file.
|
||||
#
|
||||
# @param limit [Integer] number of fixture entries to submit.
|
||||
# @return [void]
|
||||
def import_positions_fixture(limit: positions_fixture.size)
|
||||
positions_fixture.first(limit).each do |position|
|
||||
post "/api/positions", position.to_json, auth_headers
|
||||
expect(last_response).to be_ok
|
||||
expect(JSON.parse(last_response.body)).to eq("status" => "ok")
|
||||
end
|
||||
end
|
||||
|
||||
# Import a subset of instance records from the fixture file.
|
||||
#
|
||||
# @param limit [Integer] number of fixture entries to submit.
|
||||
# @return [void]
|
||||
def import_instances_fixture(limit: instances_fixture.size)
|
||||
insert_sql = <<~SQL
|
||||
INSERT INTO instances (
|
||||
id, domain, pubkey, name, version, channel, frequency,
|
||||
latitude, longitude, last_update_time, is_private, signature
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
SQL
|
||||
|
||||
with_db do |db|
|
||||
instances_fixture.first(limit).each do |instance|
|
||||
db.execute(
|
||||
insert_sql,
|
||||
[
|
||||
instance["id"],
|
||||
instance["domain"],
|
||||
instance["pubkey"],
|
||||
instance["name"],
|
||||
instance["version"],
|
||||
instance["channel"],
|
||||
instance["frequency"],
|
||||
instance["latitude"],
|
||||
instance["longitude"],
|
||||
instance["lastUpdateTime"],
|
||||
instance["isPrivate"] ? 1 : 0,
|
||||
instance["signature"],
|
||||
],
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
let(:api_token) { "spec-token" }
|
||||
let(:auth_headers) do
|
||||
{
|
||||
@@ -272,6 +354,8 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
let(:nodes_fixture) { JSON.parse(File.read(fixture_path("nodes.json"))) }
|
||||
let(:messages_fixture) { JSON.parse(File.read(fixture_path("messages.json"))) }
|
||||
let(:telemetry_fixture) { JSON.parse(File.read(fixture_path("telemetry.json"))) }
|
||||
let(:positions_fixture) { JSON.parse(File.read(fixture_path("positions.json"))) }
|
||||
let(:instances_fixture) { JSON.parse(File.read(fixture_path("instances.json"))) }
|
||||
let(:trace_fixture) do
|
||||
[
|
||||
{
|
||||
@@ -2181,6 +2265,25 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
expect(self_entry["signature"]).not_to be_nil
|
||||
end
|
||||
|
||||
it "exposes validated instance records from fixture data" do
|
||||
clear_database
|
||||
sample_size = 3
|
||||
import_instances_fixture(limit: sample_size)
|
||||
|
||||
get "/api/instances"
|
||||
|
||||
expect(last_response).to be_ok
|
||||
payload = JSON.parse(last_response.body)
|
||||
non_self_entries = payload.reject { |entry| entry["id"] == SELF_INSTANCE_ID }
|
||||
expect(non_self_entries.size).to eq(sample_size)
|
||||
|
||||
sample = instances_fixture.first
|
||||
record = non_self_entries.find { |entry| entry["id"] == sample["id"] }
|
||||
expect(record).not_to be_nil
|
||||
expect(record["domain"]).to eq(sample["domain"])
|
||||
expect(record["name"]).to eq(sample["name"])
|
||||
end
|
||||
|
||||
it "includes previously stored remote registrations" do
|
||||
remote_attributes = {
|
||||
id: "remote-instance-1",
|
||||
@@ -2947,6 +3050,30 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
end
|
||||
end
|
||||
|
||||
it "stores position fixture samples with detailed metadata" do
|
||||
clear_database
|
||||
sample_count = 5
|
||||
import_positions_fixture(limit: sample_count)
|
||||
|
||||
with_db(readonly: true) do |db|
|
||||
db.results_as_hash = true
|
||||
rows = db.execute(
|
||||
"SELECT id, node_id, latitude, longitude, altitude, location_source FROM positions ORDER BY id",
|
||||
)
|
||||
expect(rows.size).to eq(sample_count)
|
||||
|
||||
positions_fixture.first(sample_count).each do |expected|
|
||||
row = rows.find { |entry| entry["id"] == expected["id"] }
|
||||
expect(row).not_to be_nil
|
||||
expect(row["node_id"]).to eq(expected["node_id"])
|
||||
expect_same_value(row["latitude"], expected["latitude"])
|
||||
expect_same_value(row["longitude"], expected["longitude"])
|
||||
expect_same_value(row["altitude"], expected["altitude"])
|
||||
expect(row["location_source"]).to eq(expected["location_source"])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "returns 400 when the payload is not valid JSON" do
|
||||
post "/api/positions", "{", auth_headers
|
||||
|
||||
@@ -3100,10 +3227,10 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
expect(first["node_id"]).to eq(payload[0]["node_id"])
|
||||
expect(first["rx_time"]).to eq(payload[0]["rx_time"])
|
||||
expect_same_value(first["battery_level"], payload[0]["battery_level"])
|
||||
expect_same_value(first["voltage"], payload[0].dig("device_metrics", "voltage"))
|
||||
expect_same_value(first["channel_utilization"], payload[0].dig("device_metrics", "channelUtilization"))
|
||||
expect_same_value(first["air_util_tx"], payload[0].dig("device_metrics", "airUtilTx"))
|
||||
expect(first["uptime_seconds"]).to eq(payload[0].dig("device_metrics", "uptimeSeconds"))
|
||||
expect_same_value(first["voltage"], telemetry_metric(payload[0], "voltage"))
|
||||
expect_same_value(first["channel_utilization"], telemetry_metric(payload[0], "channel_utilization"))
|
||||
expect_same_value(first["air_util_tx"], telemetry_metric(payload[0], "air_util_tx"))
|
||||
expect(first["uptime_seconds"]).to eq(telemetry_metric(payload[0], "uptime_seconds"))
|
||||
expect_same_value(first["current"], payload[0]["current"])
|
||||
expect_same_value(first["gas_resistance"], payload[0]["gas_resistance"])
|
||||
expect_same_value(first["iaq"], payload[0]["iaq"])
|
||||
@@ -3124,37 +3251,37 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
expect_same_value(first["soil_temperature"], payload[0]["soil_temperature"])
|
||||
|
||||
environment_row = rows.find { |row| row["id"] == payload[1]["id"] }
|
||||
expect(environment_row["temperature"]).to be_within(1e-6).of(payload[1].dig("environment_metrics", "temperature"))
|
||||
expect(environment_row["relative_humidity"]).to be_within(1e-6).of(payload[1].dig("environment_metrics", "relativeHumidity"))
|
||||
expect(environment_row["barometric_pressure"]).to be_within(1e-6).of(payload[1].dig("environment_metrics", "barometricPressure"))
|
||||
expect_same_value(environment_row["gas_resistance"], payload[1].dig("environment_metrics", "gasResistance"))
|
||||
expect_same_value(environment_row["iaq"], payload[1].dig("environment_metrics", "iaq"))
|
||||
expect_same_value(environment_row["distance"], payload[1].dig("environment_metrics", "distance"))
|
||||
expect_same_value(environment_row["lux"], payload[1].dig("environment_metrics", "lux"))
|
||||
expect_same_value(environment_row["white_lux"], payload[1].dig("environment_metrics", "whiteLux"))
|
||||
expect_same_value(environment_row["ir_lux"], payload[1].dig("environment_metrics", "irLux"))
|
||||
expect_same_value(environment_row["uv_lux"], payload[1].dig("environment_metrics", "uvLux"))
|
||||
expect_same_value(environment_row["wind_direction"], payload[1].dig("environment_metrics", "windDirection"))
|
||||
expect_same_value(environment_row["wind_speed"], payload[1].dig("environment_metrics", "windSpeed"))
|
||||
expect_same_value(environment_row["wind_gust"], payload[1].dig("environment_metrics", "windGust"))
|
||||
expect_same_value(environment_row["wind_lull"], payload[1].dig("environment_metrics", "windLull"))
|
||||
expect_same_value(environment_row["weight"], payload[1].dig("environment_metrics", "weight"))
|
||||
expect_same_value(environment_row["radiation"], payload[1].dig("environment_metrics", "radiation"))
|
||||
expect_same_value(environment_row["rainfall_1h"], payload[1].dig("environment_metrics", "rainfall1h"))
|
||||
expect_same_value(environment_row["rainfall_24h"], payload[1].dig("environment_metrics", "rainfall24h"))
|
||||
expect_same_value(environment_row["soil_moisture"], payload[1].dig("environment_metrics", "soilMoisture"))
|
||||
expect_same_value(environment_row["soil_temperature"], payload[1].dig("environment_metrics", "soilTemperature"))
|
||||
expect_same_value(environment_row["temperature"], telemetry_metric(payload[1], "temperature"))
|
||||
expect_same_value(environment_row["relative_humidity"], telemetry_metric(payload[1], "relative_humidity"))
|
||||
expect_same_value(environment_row["barometric_pressure"], telemetry_metric(payload[1], "barometric_pressure"))
|
||||
expect_same_value(environment_row["gas_resistance"], telemetry_metric(payload[1], "gas_resistance"))
|
||||
expect_same_value(environment_row["iaq"], telemetry_metric(payload[1], "iaq"))
|
||||
expect_same_value(environment_row["distance"], telemetry_metric(payload[1], "distance"))
|
||||
expect_same_value(environment_row["lux"], telemetry_metric(payload[1], "lux"))
|
||||
expect_same_value(environment_row["white_lux"], telemetry_metric(payload[1], "white_lux"))
|
||||
expect_same_value(environment_row["ir_lux"], telemetry_metric(payload[1], "ir_lux"))
|
||||
expect_same_value(environment_row["uv_lux"], telemetry_metric(payload[1], "uv_lux"))
|
||||
expect_same_value(environment_row["wind_direction"], telemetry_metric(payload[1], "wind_direction"))
|
||||
expect_same_value(environment_row["wind_speed"], telemetry_metric(payload[1], "wind_speed"))
|
||||
expect_same_value(environment_row["wind_gust"], telemetry_metric(payload[1], "wind_gust"))
|
||||
expect_same_value(environment_row["wind_lull"], telemetry_metric(payload[1], "wind_lull"))
|
||||
expect_same_value(environment_row["weight"], telemetry_metric(payload[1], "weight"))
|
||||
expect_same_value(environment_row["radiation"], telemetry_metric(payload[1], "radiation"))
|
||||
expect_same_value(environment_row["rainfall_1h"], telemetry_metric(payload[1], "rainfall_1h", "rainfall1h"))
|
||||
expect_same_value(environment_row["rainfall_24h"], telemetry_metric(payload[1], "rainfall_24h", "rainfall24h"))
|
||||
expect_same_value(environment_row["soil_moisture"], telemetry_metric(payload[1], "soil_moisture"))
|
||||
expect_same_value(environment_row["soil_temperature"], telemetry_metric(payload[1], "soil_temperature"))
|
||||
|
||||
third_row = rows.find { |row| row["id"] == payload[2]["id"] }
|
||||
expect_same_value(third_row["current"], payload[2].dig("device_metrics", "current"))
|
||||
expect_same_value(third_row["distance"], payload[2].dig("environment_metrics", "distance"))
|
||||
expect_same_value(third_row["lux"], payload[2].dig("environment_metrics", "lux"))
|
||||
expect_same_value(third_row["wind_direction"], payload[2].dig("environment_metrics", "windDirection"))
|
||||
expect_same_value(third_row["wind_speed"], payload[2].dig("environment_metrics", "windSpeed"))
|
||||
expect_same_value(third_row["weight"], payload[2].dig("environment_metrics", "weight"))
|
||||
expect_same_value(third_row["rainfall_24h"], payload[2].dig("environment_metrics", "rainfall24h"))
|
||||
expect_same_value(third_row["soil_moisture"], payload[2].dig("environment_metrics", "soilMoisture"))
|
||||
expect_same_value(third_row["soil_temperature"], payload[2].dig("environment_metrics", "soilTemperature"))
|
||||
expect_same_value(third_row["current"], telemetry_metric(payload[2], "current"))
|
||||
expect_same_value(third_row["distance"], telemetry_metric(payload[2], "distance"))
|
||||
expect_same_value(third_row["lux"], telemetry_metric(payload[2], "lux"))
|
||||
expect_same_value(third_row["wind_direction"], telemetry_metric(payload[2], "wind_direction"))
|
||||
expect_same_value(third_row["wind_speed"], telemetry_metric(payload[2], "wind_speed"))
|
||||
expect_same_value(third_row["weight"], telemetry_metric(payload[2], "weight"))
|
||||
expect_same_value(third_row["rainfall_24h"], telemetry_metric(payload[2], "rainfall_24h", "rainfall24h"))
|
||||
expect_same_value(third_row["soil_moisture"], telemetry_metric(payload[2], "soil_moisture"))
|
||||
expect_same_value(third_row["soil_temperature"], telemetry_metric(payload[2], "soil_temperature"))
|
||||
end
|
||||
|
||||
with_db(readonly: true) do |db|
|
||||
@@ -3164,11 +3291,29 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
"SELECT battery_level, voltage, channel_utilization, air_util_tx, uptime_seconds, last_heard, first_heard FROM nodes WHERE node_id = ?",
|
||||
[payload[0]["node_id"]],
|
||||
)
|
||||
expect_same_value(metrics_node["battery_level"], payload[0]["battery_level"])
|
||||
expect_same_value(metrics_node["voltage"], payload[0]["device_metrics"]["voltage"])
|
||||
expect_same_value(metrics_node["channel_utilization"], payload[0]["device_metrics"]["channelUtilization"])
|
||||
expect_same_value(metrics_node["air_util_tx"], payload[0]["device_metrics"]["airUtilTx"])
|
||||
expect(metrics_node["uptime_seconds"]).to eq(payload[0]["device_metrics"]["uptimeSeconds"])
|
||||
expect_same_value(metrics_node["battery_level"], telemetry_metric(payload[0], "battery_level"))
|
||||
expect_same_value(metrics_node["voltage"], telemetry_metric(payload[0], "voltage"))
|
||||
|
||||
telemetry_for_node = payload.select { |entry| entry["node_id"] == payload[0]["node_id"] }
|
||||
util_values = telemetry_for_node.filter_map { |entry| telemetry_metric(entry, "channel_utilization") }
|
||||
air_values = telemetry_for_node.filter_map { |entry| telemetry_metric(entry, "air_util_tx") }
|
||||
if util_values.any?
|
||||
expect(metrics_node["channel_utilization"]).to be_between(util_values.min, util_values.max)
|
||||
else
|
||||
expect(metrics_node["channel_utilization"]).to be_nil
|
||||
end
|
||||
if air_values.any?
|
||||
expect(metrics_node["air_util_tx"]).to be_between(air_values.min, air_values.max)
|
||||
else
|
||||
expect(metrics_node["air_util_tx"]).to be_nil
|
||||
end
|
||||
|
||||
uptime_values = telemetry_for_node.filter_map { |entry| telemetry_metric(entry, "uptime_seconds") }
|
||||
if uptime_values.any?
|
||||
expect(metrics_node["uptime_seconds"]).to be_between(uptime_values.min, uptime_values.max)
|
||||
else
|
||||
expect(metrics_node["uptime_seconds"]).to be_nil
|
||||
end
|
||||
expect(metrics_node["last_heard"]).to eq(payload[0]["rx_time"])
|
||||
expect(metrics_node["first_heard"]).to eq(payload[0]["rx_time"])
|
||||
|
||||
@@ -3176,17 +3321,35 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
"SELECT last_heard, battery_level, voltage FROM nodes WHERE node_id = ?",
|
||||
[payload[1]["node_id"]],
|
||||
)
|
||||
expect(env_node["last_heard"]).to eq(payload[1]["rx_time"])
|
||||
expect(env_node["battery_level"]).to be_nil
|
||||
expect(env_node["voltage"]).to be_nil
|
||||
env_rx_times = payload.select { |entry| entry["node_id"] == payload[1]["node_id"] }.filter_map do |entry|
|
||||
entry["rx_time"]
|
||||
end
|
||||
latest_rx = env_rx_times.max
|
||||
expect(env_node["last_heard"]).to eq(latest_rx)
|
||||
expect_same_value(env_node["battery_level"], telemetry_metric(payload[1], "battery_level"))
|
||||
expect_same_value(env_node["voltage"], telemetry_metric(payload[1], "voltage"))
|
||||
|
||||
local_node = db.get_first_row(
|
||||
"SELECT battery_level, uptime_seconds, last_heard FROM nodes WHERE node_id = ?",
|
||||
[payload[2]["node_id"]],
|
||||
)
|
||||
expect_same_value(local_node["battery_level"], payload[2]["device_metrics"]["battery_level"])
|
||||
expect(local_node["uptime_seconds"]).to eq(payload[2]["device_metrics"]["uptime_seconds"])
|
||||
expect(local_node["last_heard"]).to eq(payload[2]["rx_time"])
|
||||
expect_same_value(local_node["battery_level"], telemetry_metric(payload[2], "battery_level"))
|
||||
local_uptime_values = payload.select { |entry| entry["node_id"] == payload[2]["node_id"] }.filter_map do |entry|
|
||||
telemetry_metric(entry, "uptime_seconds")
|
||||
end
|
||||
if local_uptime_values.any?
|
||||
expect(local_node["uptime_seconds"]).to be_between(local_uptime_values.min, local_uptime_values.max)
|
||||
else
|
||||
expect(local_node["uptime_seconds"]).to be_nil
|
||||
end
|
||||
local_rx_times = payload.select { |entry| entry["node_id"] == payload[2]["node_id"] }.filter_map do |entry|
|
||||
entry["rx_time"]
|
||||
end
|
||||
if local_rx_times.any?
|
||||
expect(local_node["last_heard"]).to eq(local_rx_times.max)
|
||||
else
|
||||
expect(local_node["last_heard"]).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3650,7 +3813,7 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
it "returns the stored nodes with derived timestamps" do
|
||||
import_nodes_fixture
|
||||
|
||||
get "/api/nodes"
|
||||
get "/api/nodes?limit=#{nodes_fixture.size}"
|
||||
expect(last_response).to be_ok
|
||||
|
||||
actual = JSON.parse(last_response.body)
|
||||
@@ -3782,11 +3945,18 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
import_nodes_fixture
|
||||
import_messages_fixture
|
||||
|
||||
get "/api/messages?encrypted=1"
|
||||
filtered_messages = messages_fixture.select do |message|
|
||||
%w[text encrypted emoji reply_id].any? do |key|
|
||||
value = message[key]
|
||||
value.is_a?(String) ? !value.strip.empty? : !value.nil?
|
||||
end
|
||||
end
|
||||
|
||||
get "/api/messages?encrypted=1&limit=#{messages_fixture.size}"
|
||||
expect(last_response).to be_ok
|
||||
|
||||
actual = JSON.parse(last_response.body)
|
||||
expect(actual.size).to eq(messages_fixture.size)
|
||||
expect(actual.size).to eq(filtered_messages.size)
|
||||
|
||||
actual_by_id = actual.each_with_object({}) do |row, acc|
|
||||
acc[row["id"]] = row
|
||||
@@ -3800,7 +3970,7 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
end
|
||||
end
|
||||
|
||||
messages_fixture.each do |message|
|
||||
filtered_messages.each do |message|
|
||||
expected = message.reject { |key, _| key == "node" }
|
||||
actual_row = actual_by_id.fetch(message["id"])
|
||||
|
||||
@@ -4231,40 +4401,40 @@ RSpec.describe "Potato Mesh Sinatra app" do
|
||||
expect(first_entry["telemetry_time"]).to eq(latest["telemetry_time"])
|
||||
expect(first_entry["telemetry_time_iso"]).to eq(Time.at(latest["telemetry_time"]).utc.iso8601)
|
||||
expect(first_entry).not_to have_key("device_metrics")
|
||||
expect_same_value(first_entry["battery_level"], latest.dig("device_metrics", "battery_level") || latest.dig("device_metrics", "batteryLevel"))
|
||||
expect_same_value(first_entry["current"], latest.dig("device_metrics", "current"))
|
||||
expect_same_value(first_entry["distance"], latest.dig("environment_metrics", "distance"))
|
||||
expect_same_value(first_entry["lux"], latest.dig("environment_metrics", "lux"))
|
||||
expect_same_value(first_entry["wind_direction"], latest.dig("environment_metrics", "windDirection"))
|
||||
expect_same_value(first_entry["wind_speed"], latest.dig("environment_metrics", "windSpeed"))
|
||||
expect_same_value(first_entry["weight"], latest.dig("environment_metrics", "weight"))
|
||||
expect_same_value(first_entry["rainfall_24h"], latest.dig("environment_metrics", "rainfall24h"))
|
||||
expect_same_value(first_entry["soil_moisture"], latest.dig("environment_metrics", "soilMoisture"))
|
||||
expect_same_value(first_entry["soil_temperature"], latest.dig("environment_metrics", "soilTemperature"))
|
||||
expect_same_value(first_entry["battery_level"], telemetry_metric(latest, "battery_level"))
|
||||
expect_same_value(first_entry["current"], telemetry_metric(latest, "current"))
|
||||
expect_same_value(first_entry["distance"], telemetry_metric(latest, "distance"))
|
||||
expect_same_value(first_entry["lux"], telemetry_metric(latest, "lux"))
|
||||
expect_same_value(first_entry["wind_direction"], telemetry_metric(latest, "wind_direction"))
|
||||
expect_same_value(first_entry["wind_speed"], telemetry_metric(latest, "wind_speed"))
|
||||
expect_same_value(first_entry["weight"], telemetry_metric(latest, "weight"))
|
||||
expect_same_value(first_entry["rainfall_24h"], telemetry_metric(latest, "rainfall_24h", "rainfall24h"))
|
||||
expect_same_value(first_entry["soil_moisture"], telemetry_metric(latest, "soil_moisture"))
|
||||
expect_same_value(first_entry["soil_temperature"], telemetry_metric(latest, "soil_temperature"))
|
||||
|
||||
second_entry = data.last
|
||||
expect(second_entry["id"]).to eq(second_latest["id"])
|
||||
expect(second_entry).not_to have_key("environment_metrics")
|
||||
expect(second_entry["temperature"]).to be_within(1e-6).of(second_latest["environment_metrics"]["temperature"])
|
||||
expect(second_entry["relative_humidity"]).to be_within(1e-6).of(second_latest["environment_metrics"]["relativeHumidity"])
|
||||
expect(second_entry["barometric_pressure"]).to be_within(1e-6).of(second_latest["environment_metrics"]["barometricPressure"])
|
||||
expect_same_value(second_entry["gas_resistance"], second_latest.dig("environment_metrics", "gasResistance"))
|
||||
expect_same_value(second_entry["iaq"], second_latest.dig("environment_metrics", "iaq"))
|
||||
expect_same_value(second_entry["distance"], second_latest.dig("environment_metrics", "distance"))
|
||||
expect_same_value(second_entry["lux"], second_latest.dig("environment_metrics", "lux"))
|
||||
expect_same_value(second_entry["white_lux"], second_latest.dig("environment_metrics", "whiteLux"))
|
||||
expect_same_value(second_entry["ir_lux"], second_latest.dig("environment_metrics", "irLux"))
|
||||
expect_same_value(second_entry["uv_lux"], second_latest.dig("environment_metrics", "uvLux"))
|
||||
expect_same_value(second_entry["wind_direction"], second_latest.dig("environment_metrics", "windDirection"))
|
||||
expect_same_value(second_entry["wind_speed"], second_latest.dig("environment_metrics", "windSpeed"))
|
||||
expect_same_value(second_entry["wind_gust"], second_latest.dig("environment_metrics", "windGust"))
|
||||
expect_same_value(second_entry["wind_lull"], second_latest.dig("environment_metrics", "windLull"))
|
||||
expect_same_value(second_entry["weight"], second_latest.dig("environment_metrics", "weight"))
|
||||
expect_same_value(second_entry["radiation"], second_latest.dig("environment_metrics", "radiation"))
|
||||
expect_same_value(second_entry["rainfall_1h"], second_latest.dig("environment_metrics", "rainfall1h"))
|
||||
expect_same_value(second_entry["rainfall_24h"], second_latest.dig("environment_metrics", "rainfall24h"))
|
||||
expect_same_value(second_entry["soil_moisture"], second_latest.dig("environment_metrics", "soilMoisture"))
|
||||
expect_same_value(second_entry["soil_temperature"], second_latest.dig("environment_metrics", "soilTemperature"))
|
||||
expect_api_value(second_entry, "temperature", telemetry_metric(second_latest, "temperature"))
|
||||
expect_api_value(second_entry, "relative_humidity", telemetry_metric(second_latest, "relative_humidity"))
|
||||
expect_api_value(second_entry, "barometric_pressure", telemetry_metric(second_latest, "barometric_pressure"))
|
||||
expect_same_value(second_entry["gas_resistance"], telemetry_metric(second_latest, "gas_resistance"))
|
||||
expect_same_value(second_entry["iaq"], telemetry_metric(second_latest, "iaq"))
|
||||
expect_same_value(second_entry["distance"], telemetry_metric(second_latest, "distance"))
|
||||
expect_same_value(second_entry["lux"], telemetry_metric(second_latest, "lux"))
|
||||
expect_same_value(second_entry["white_lux"], telemetry_metric(second_latest, "white_lux"))
|
||||
expect_same_value(second_entry["ir_lux"], telemetry_metric(second_latest, "ir_lux"))
|
||||
expect_same_value(second_entry["uv_lux"], telemetry_metric(second_latest, "uv_lux"))
|
||||
expect_same_value(second_entry["wind_direction"], telemetry_metric(second_latest, "wind_direction"))
|
||||
expect_same_value(second_entry["wind_speed"], telemetry_metric(second_latest, "wind_speed"))
|
||||
expect_same_value(second_entry["wind_gust"], telemetry_metric(second_latest, "wind_gust"))
|
||||
expect_same_value(second_entry["wind_lull"], telemetry_metric(second_latest, "wind_lull"))
|
||||
expect_same_value(second_entry["weight"], telemetry_metric(second_latest, "weight"))
|
||||
expect_same_value(second_entry["radiation"], telemetry_metric(second_latest, "radiation"))
|
||||
expect_same_value(second_entry["rainfall_1h"], telemetry_metric(second_latest, "rainfall_1h", "rainfall1h"))
|
||||
expect_same_value(second_entry["rainfall_24h"], telemetry_metric(second_latest, "rainfall_24h", "rainfall24h"))
|
||||
expect_same_value(second_entry["soil_moisture"], telemetry_metric(second_latest, "soil_moisture"))
|
||||
expect_same_value(second_entry["soil_temperature"], telemetry_metric(second_latest, "soil_temperature"))
|
||||
end
|
||||
|
||||
it "excludes telemetry entries older than seven days" do
|
||||
|
||||
Reference in new issue
Block a user