55import  ubinascii 
66import  pycom 
77
8- __version__  =  '1 ' 
8+ __version__  =  '2 ' 
99
1010class  Loramesh :
1111    """ Class for using Lora Mesh - openThread """ 
1212
13-     STATE_NOT_CONNECTED  =  const (0 )
14-     STATE_CHILD  =  const (1 )
15-     STATE_ROUTER  =  const (2 )
16-     STATE_LEADER  =  const (3 )
17-     #STATE_CHILD_SINGLE  = const(4)
18-     STATE_LEADER_SINGLE  =  const (4 )
13+     STATE_DISABLED  =  const (0 )
14+     STATE_DETACHED  =  const (1 )
15+     STATE_CHILD  =  const (2 )
16+     STATE_ROUTER  =  const (3 )
17+     STATE_LEADER  =  const (4 )
18+     STATE_LEADER_SINGLE  =  const (5 )
1919
20-     # rgb LED color for each state: not connected , child, router, leader and single leader 
21-     RGBLED  =  [0x0A0000 , 0x0A0A0A , 0x000A00 , 0x00000A ,  0x07070A ]
20+     # rgb LED color for each state: disabled, detached , child, router, leader and single leader 
21+     RGBLED  =  [0x0A0000 , 0x0A0000 ,  0x0A0A0A , 0x000A00 , 0x0A000A ,  0x000A0A ]
2222
2323    # address to be used for multicasting 
2424    MULTICAST_MESH_ALL  =  'ff03::1' 
@@ -33,25 +33,37 @@ def __init__(self, lora=None):
3333            self .lora  =  LoRa (mode = LoRa .LORA , region = LoRa .EU868 , bandwidth = LoRa .BW_125KHZ , sf = 7 )
3434        else :
3535            self .lora  =  lora 
36-         self .lora .mesh ()
36+         self .mesh   =   self . lora .Mesh ()
3737        self .rloc  =  '' 
3838        self .ip_eid  =  '' 
3939        self .ip_link  =  '' 
4040        self .single  =  True 
41-         self .state_id  =  STATE_NOT_CONNECTED 
41+         self .state  =  STATE_DISABLED 
42+ 
43+     def  _state_update (self ):
44+         """ Returns the Thread role """ 
45+         self .state  =  self .mesh .state ()
46+         if  self .state  <  0 :
47+             self .state  =  self .STATE_DISABLED 
48+         return  self .state 
49+ 
50+     def  _rloc_ip_net_addr (self ):
51+         """ returns the family part of RLOC IPv6, without last word (2B) """ 
52+         self .net_addr  =  ':' .join (self .rloc .split (':' )[:- 1 ]) +  ':' 
53+         return  self .net_addr 
4254
4355    def  _update_ips (self ):
4456        """ Updates all the unicast IPv6 of the Thread interface """ 
45-         ip_all  =  self .lora .cli ('ipaddr' )
46-         ips  =  ip_all .split ('\r \n ' )
47-         try :
48-             rloc16  =  int (self .lora .cli ('rloc16' ), 16 )
49-         except  Exception :
50-             rloc16  =  0xFFFF 
57+         ips  =  self .mesh .ipaddr ()
58+         self .rloc16  =  self .mesh .rloc ()
5159        for  line  in  ips :
5260            if  line .startswith ('fd' ):
5361                # Mesh-Local unicast IPv6 
54-                 if  int (line .split (':' )[- 1 ], 16 ) ==  rloc16 :
62+                 try :
63+                     addr  =  int (line .split (':' )[- 1 ], 16 )
64+                 except  Exception :
65+                     continue 
66+                 if  addr  ==  self .rloc16 :
5567                    # found RLOC 
5668                    # RLOC IPv6 has x:x:x:x:0:ff:fe00:RLOC16 
5769                    self .rloc  =  line 
@@ -63,87 +75,47 @@ def _update_ips(self):
6375                self .ip_link  =  line 
6476
6577    def  is_connected (self ):
66-         """ Returns true if it is connected if its  Child, Router or Leader """ 
78+         """ Returns true if it is connected as either  Child, Router or Leader """ 
6779        connected  =  False 
68-         state  =  self .state ()
69-         if  state  ==   STATE_CHILD   or   state   ==   STATE_ROUTER   or   state   ==   STATE_LEADER :
80+         self . state  =  self . mesh .state ()
81+         if  self . state  in  ( STATE_CHILD ,  STATE_ROUTER ,  STATE_LEADER ,  STATE_LEADER_SINGLE ) :
7082            connected  =  True 
7183        return  connected 
7284
73-     def  state (self ):
74-         """ Returns the Thread role """ 
75-         state_code  =  STATE_NOT_CONNECTED 
76-         try :
77-             state  =  self .lora .cli ('state' )
78- 
79-             if  state .startswith ('child' ):
80-                 state_code  =  STATE_CHILD 
81-             elif  state .startswith ('router' ):
82-                 state_code  =  STATE_ROUTER 
83-             elif  state .startswith ('leader' ):
84-                 state_code  =  STATE_LEADER 
85-                 self .single  =  False 
86-                 single_str  =  self .lora .cli ('singleton' )
87-                 if  single_str .startswith ('true' ):
88-                     self .single  =  True 
89-                     state_code  =  STATE_LEADER_SINGLE 
90- 
91-             self .state_id  =  state_code 
92-         except  Exception :
93-                 pass 
94-         return  state_code 
95- 
9685    def  led_state (self ):
9786        """ Sets the LED according to the Thread role """ 
98-         pycom .rgbled (self .RGBLED [self .state ()])
87+         if  self .state  ==  STATE_LEADER  and  self .mesh .single ():
88+             pycom .rgbled (self .RGBLED [self .STATE_LEADER_SINGLE ])
89+         else :
90+             pycom .rgbled (self .RGBLED [self .state ])
9991
10092    def  ip (self ):
10193        """ Returns the IPv6 RLOC """ 
10294        self ._update_ips ()
10395        return  self .rloc 
10496
105-     def  parent_ip (self ):
106-         """ Returns the IP of the parent, if it's child node """ 
107-         ip  =  None 
108-         state  =  self .state ()
109-         if  state  ==  STATE_CHILD  or  state  ==  STATE_ROUTER :
110-             try :
111-                 ip_words  =  self .ip ().split (':' )
112-                 parent_rloc  =  int (self .lora .cli ('parent' ).split ('\r \n ' )[1 ].split (' ' )[1 ], 16 )
113-                 ip_words [- 1 ] =  hex (parent_rloc )[2 :]
114-                 ip  =  ':' .join (ip_words )
115-             except  Exception :
116-                 pass 
117-         return  ip 
97+     def  neighbors (self ):
98+         """ Returns a list with all properties of the neighbors """ 
99+         return  self .mesh .neighbors ()
118100
119101    def  neighbors_ip (self ):
120-         """ Returns a list with IP of the neighbors (children, parent, other routers) """ 
121-         state  =  self .state ()
122-         neigh  =  []
123-         if  state  ==  STATE_ROUTER  or  state  ==  STATE_LEADER :
124-             ip_words  =  self .ip ().split (':' )
125-             # obtain RLOC16 neighbors 
126-             neighbors  =  self .lora .cli ('neighbor list' ).split (' ' )
127-             for  rloc  in  neighbors :
128-                 if  len (rloc ) ==  0 :
129-                     continue 
130-                 try :
131-                     ip_words [- 1 ] =  str (rloc [2 :])
132-                     nei_ip  =  ':' .join (ip_words )
133-                     neigh .append (nei_ip )
134-                 except  Exception :
135-                         pass 
136-         elif  state  ==  STATE_CHILD :
137-             neigh .append (self .parent_ip ())
138-         return  neigh 
102+         """ Returns a list with IPv6 (as strings) of the neighbors """ 
103+         neighbors  =  self .neighbors ()
104+         nei_list  =  []
105+         net_ip  =  self ._rloc_ip_net_addr ()
106+         if  neighbors  is  not   None :
107+             for  nei_rec  in  neighbors :
108+                 nei_ip  =  net_ip  +  hex (nei_rec .rloc16 )[2 :]
109+                 nei_list .append (nei_ip )
110+         return  nei_list 
139111
140112    def  ipaddr (self ):
141113        """ Returns a list with all unicast IPv6 """ 
142-         return  self .lora . cli ( ' ipaddr' ). split ( ' \r \n '  )
114+         return  self .mesh . ipaddr ( )
143115
144116    def  cli (self , command ):
145117        """ Simple wrapper for OpenThread CLI """ 
146-         return  self .lora .cli (command )
118+         return  self .mesh .cli (command )
147119
148120    def  ping (self , ip ):
149121        """ Returns ping return time, to an IP """ 
@@ -161,7 +133,7 @@ def ping(self, ip):
161133    def  blink (self , num  =  3 , period  =  .5 , color  =  None ):
162134        """ LED blink """ 
163135        if  color  is  None :
164-             color  =  self .RGBLED [self .state () ]
136+             color  =  self .RGBLED [self .state ]
165137        for  i  in  range (0 , num ):
166138            pycom .rgbled (0 )
167139            time .sleep (period )
0 commit comments