11import bind from "bind-decorator" ;
22import stringify from "json-stable-stringify-without-jsonify" ;
3+ import type { Eui64 } from "zigbee-herdsman/dist/zspec/tstypes" ;
4+ import type { LQITableEntry , RoutingTableEntry } from "zigbee-herdsman/dist/zspec/zdo/definition/tstypes" ;
35import type { Zigbee2MQTTAPI , Zigbee2MQTTNetworkMap } from "../types/api" ;
4-
56import logger from "../util/logger" ;
67import * as settings from "../util/settings" ;
78import utils from "../util/utils" ;
@@ -185,8 +186,8 @@ export default class NetworkMap extends Extension {
185186
186187 async networkScan ( includeRoutes : boolean ) : Promise < Zigbee2MQTTNetworkMap > {
187188 logger . info ( `Starting network scan (includeRoutes '${ includeRoutes } ')` ) ;
188- const lqis = new Map < Device , zh . LQI > ( ) ;
189- const routingTables = new Map < Device , zh . RoutingTable > ( ) ;
189+ const lqis = new Map < Device , LQITableEntry [ ] > ( ) ;
190+ const routingTables = new Map < Device , RoutingTableEntry [ ] > ( ) ;
190191 const failed = new Map < Device , string [ ] > ( ) ;
191192 const requestWithRetry = async < T > ( request : ( ) => Promise < T > ) : Promise < T > => {
192193 try {
@@ -210,7 +211,7 @@ export default class NetworkMap extends Extension {
210211 await utils . sleep ( 1 ) ; // sleep 1 second between each scan to reduce stress on network.
211212
212213 try {
213- const result = await requestWithRetry < zh . LQI > ( async ( ) => await device . zh . lqi ( ) ) ;
214+ const result = await requestWithRetry < LQITableEntry [ ] > ( async ( ) => await device . zh . lqi ( ) ) ;
214215 lqis . set ( device , result ) ;
215216 logger . debug ( `LQI succeeded for '${ device . name } '` ) ;
216217 } catch ( error ) {
@@ -222,7 +223,7 @@ export default class NetworkMap extends Extension {
222223
223224 if ( includeRoutes ) {
224225 try {
225- const result = await requestWithRetry < zh . RoutingTable > ( async ( ) => await device . zh . routingTable ( ) ) ;
226+ const result = await requestWithRetry < RoutingTableEntry [ ] > ( async ( ) => await device . zh . routingTable ( ) ) ;
226227 routingTables . set ( device , result ) ;
227228 logger . debug ( `Routing table succeeded for '${ device . name } '` ) ;
228229 } catch ( error ) {
@@ -274,42 +275,47 @@ export default class NetworkMap extends Extension {
274275 }
275276
276277 // Add links
277- for ( const [ device , lqi ] of lqis ) {
278- for ( const neighbor of lqi . neighbors ) {
278+ for ( const [ device , table ] of lqis ) {
279+ for ( const neighbor of table ) {
279280 if ( neighbor . relationship > 3 ) {
280281 // Relationship is not active, skip it
281282 continue ;
282283 }
283284
285+ let neighborEui64 = neighbor . eui64 ;
286+
284287 // Some Xiaomi devices return 0x00 as the neighbor ieeeAddr (obviously not correct).
285288 // Determine the correct ieeeAddr based on the networkAddress.
286- if ( neighbor . ieeeAddr === "0x0000000000000000" ) {
287- const neighborDevice = this . zigbee . deviceByNetworkAddress ( neighbor . networkAddress ) ;
289+ if ( neighborEui64 === "0x0000000000000000" ) {
290+ const neighborDevice = this . zigbee . deviceByNetworkAddress ( neighbor . nwkAddress ) ;
288291
289292 if ( neighborDevice ) {
290- neighbor . ieeeAddr = neighborDevice . ieeeAddr ;
293+ neighborEui64 = neighborDevice . ieeeAddr as Eui64 ;
291294 }
292295 }
293296
294297 const link : Zigbee2MQTTNetworkMap [ "links" ] [ number ] = {
295- source : { ieeeAddr : neighbor . ieeeAddr , networkAddress : neighbor . networkAddress } ,
298+ source : { ieeeAddr : neighborEui64 , networkAddress : neighbor . nwkAddress } ,
296299 target : { ieeeAddr : device . ieeeAddr , networkAddress : device . zh . networkAddress } ,
297- linkquality : neighbor . linkquality ,
300+ deviceType : neighbor . deviceType ,
301+ rxOnWhenIdle : neighbor . rxOnWhenIdle ,
302+ relationship : neighbor . relationship ,
303+ permitJoining : neighbor . permitJoining ,
298304 depth : neighbor . depth ,
305+ lqi : neighbor . lqi ,
299306 routes : [ ] ,
300- // DEPRECATED:
301- sourceIeeeAddr : neighbor . ieeeAddr ,
307+ // below are @deprecated
308+ sourceIeeeAddr : neighborEui64 ,
302309 targetIeeeAddr : device . ieeeAddr ,
303- sourceNwkAddr : neighbor . networkAddress ,
304- lqi : neighbor . linkquality ,
305- relationship : neighbor . relationship ,
310+ sourceNwkAddr : neighbor . nwkAddress ,
311+ linkquality : neighbor . lqi ,
306312 } ;
307313
308314 const routingTable = routingTables . get ( device ) ;
309315
310316 if ( routingTable ) {
311- for ( const entry of routingTable . table ) {
312- if ( entry . status === "ACTIVE" && entry . nextHop === neighbor . networkAddress ) {
317+ for ( const entry of routingTable ) {
318+ if ( entry . nextHopAddress === neighbor . nwkAddress ) {
313319 link . routes . push ( entry ) ;
314320 }
315321 }
0 commit comments