2121import os
2222import socket
2323import struct
24+ import xml .etree .ElementTree as ET
25+
26+ from logging import getLogger
27+ from typing import Set
2428
2529# region same code as other examples
2630from examples_settings import Settings
31+ from openlcb .convert import Convert
2732from openlcb .localnode import LocalNode
2833from openlcb .memoryspace import MemorySpace
29- from openlcb .memorymanager import Segment # do 1st to fix path if no pip install
34+ from openlcb .memorymanager import Segment
3035settings = Settings ()
3136
3237if __name__ == "__main__" :
3338 settings .load_cli_args (docstring = __doc__ )
3439# endregion same code as other examples
3540
36- from openlcb import emit_cast , get_config_dir , precise_sleep # noqa: E402
41+ from openlcb import assert_xml , emit_cast , formatted_ex , get_config_dir , prDim , precise_sleep # noqa: E402, E501
3742from openlcb .tcplink .tcpsocket import TcpSocket # noqa: E402
3843
3944from openlcb .canbus .canphysicallayergridconnect import ( # noqa: E402
4045 CanPhysicalLayerGridConnect ,
4146)
4247from openlcb .canbus .canlink import CanLink # noqa: E402
4348from openlcb .nodeid import NodeID # noqa: E402
44- from openlcb .datagramservice import DatagramService # noqa: E402
49+ from openlcb .datagramservice import DatagramReadMemo , DatagramService # noqa: E402, E501
4550from openlcb .memoryservice import MemoryService # noqa: E402
4651from openlcb .message import Message # noqa: E402
4752from openlcb .mti import MTI # noqa: E402
7176print ("RR, SR are raw socket interface receive and send;"
7277 " RL, SL are link interface; RM, SM are message interface" )
7378
79+ me = os .path .basename (__file__ )
80+ logger = getLogger (__name__ )
7481
7582# def sendToSocket(frame: CanFrame):
7683# string = frame.encodeAsString()
7784# print(" SR: {}".format(string.strip()))
7885# sock.sendString(string)
7986# physicalLayer.onFrameSent(frame)
8087
81- def prDim (s : str ):
82- """Show extra debugging information in darker text so special cases
83- are readable (resets to 00 [default colors] for text after prDim).
84- Note: 0;30;40 is non-bold dim, but that's invisible in cmd.exe.
85- """
86- print ("\033 [1;30;40m {}\033 [00m" .format (s ))
87- # - `\033` starts ansi escape sequence
88- # - 30 for gray
89- # - 00 to reset to white
90-
9188
9289def printFrame (frame ):
9390 prDim (" RL: {}" .format (frame ))
@@ -98,7 +95,11 @@ def printFrame(frame):
9895
9996
10097def printMessage (message : Message ):
101- prDim ("RM: {} from {}" .format (message .mti , message .source ))
98+ prDim (f"RM: { message .mti } from { message .source } " )
99+ # state = canLink.pollState()
100+ # if state is not CanLink.State.Permitted:
101+ # print(f"RM: - SKIPPED (state={state})")
102+ # return
102103
103104
104105localNodeID = NodeID (settings ['localNodeID' ])
@@ -159,7 +160,10 @@ def printMessage(message: Message):
159160""" # noqa: E501
160161
161162
162- def handleDatagram (memo ):
163+ assert_xml (cdi )
164+
165+
166+ def handleDatagram (memo : DatagramReadMemo ):
163167 """create a call-back to print datagram contents when received
164168
165169 Args:
@@ -169,7 +173,7 @@ def handleDatagram(memo):
169173 bool: Always False (True would mean we sent a reply to the datagram,
170174 but let the MemoryService do that).
171175 """
172- print (f"Datagram receive call back: { emit_cast (memo )} " )
176+ print (f"Datagram receive call back: { Convert . toHex (memo . data )} " )
173177 return False
174178
175179
@@ -189,24 +193,24 @@ def memoryReadFail(memo):
189193
190194
191195# create a node and connect it update
192- # This is a very minimal node, which just takes part in the low-level common
193- # protocols
194- localNodeID = NodeID (settings ['localNodeID' ])
196+ # This node takes part in high level protocols.
197+ # See docstring.
195198localNode = LocalNode (
196199 localNodeID ,
197- SNIP ("python-openlcb example authors" ,
198- "example_node_memory_implementation" ,
199- "1.0" , "1.0" , "example_node_memory_implementation" ,
200- "python-openlcb example node with memory" ),
201- set ([
200+ canLink ,
201+ snip = SNIP ("python-openlcb example authors" ,
202+ "example_node_memory_implementation" ,
203+ "1.0" , "1.0" , "example_node_memory_implementation" ,
204+ "python-openlcb example node with memory" ),
205+ pipSet = set ([
202206 PIP .SIMPLE_NODE_IDENTIFICATION_PROTOCOL ,
203207 PIP .DATAGRAM_PROTOCOL ,
204208 PIP .CONFIGURATION_DESCRIPTION_INFORMATION ,
205209 PIP .ADCDI_PROTOCOL ,
206210 PIP .MEMORY_CONFIGURATION_PROTOCOL ,
207211 ]),
208- canLink
209212)
213+
210214memoryService .memory = localNode
211215my_conf_dir = os .path .join (get_config_dir ("python-openlcb" ))
212216backup_name = "example_node_memory_implementation.cdi.xml"
@@ -218,6 +222,10 @@ def memoryReadFail(memo):
218222segment = localNode .getSegment (MemorySpace .CDI .value )
219223assert isinstance (segment , Segment )
220224assert isinstance (segment ._data , (bytearray , bytes ))
225+ last = localNode .getLast (0xFF )
226+ assert last is not None
227+ last = localNode .getLast (MemorySpace .CDI )
228+ assert last is not None
221229# localNodeProcessor = LocalNodeProcessor(canLink, localNode)
222230# canLink.registerMessageReceivedListener(localNodeProcessor.process)
223231localNodeProcessor = localNode .localNodeProcessor
@@ -231,8 +239,7 @@ def displayOtherNodeIds(message: Message) :
231239 """
232240 if message .mti == MTI .Verified_NodeID :
233241 print (f"[displayOtherNodeIds] Detected farNodeID { message .source } " )
234- else :
235- print (f"[displayOtherNodeIds] { message .mti } from { message .source } " )
242+ # For others, see printMessage
236243
237244
238245canLink .registerMessageReceivedListener (displayOtherNodeIds )
@@ -252,19 +259,22 @@ def displayOtherNodeIds(message: Message) :
252259 precise_sleep (.02 )
253260print (" SL : link up" )
254261# request that nodes identify themselves so that we can print their node IDs
255- message = Message (MTI .Verify_NodeID_Number_Global ,
256- NodeID (settings ['localNodeID' ]), None )
262+ message = Message (MTI .Verify_NodeID_Number_Global , localNodeID , None )
257263canLink .sendMessage (message )
258264
259265# process resulting activity
260266while True :
261267 count = 0
262- count += physicalLayer .sendAll (sock , verbose = True ,
263- verbose_fn = prDim )
264- count += physicalLayer .receiveAll (sock , verbose = settings ['trace' ],
265- verbose_fn = prDim )
266- if count < 1 :
267- precise_sleep (.01 )
268- # else skip sleep to avoid latency (port already delayed)
268+ try :
269+ count += physicalLayer .sendAll (sock , verbose = True ,
270+ verbose_fn = prDim )
271+ count += physicalLayer .receiveAll (sock , verbose = settings ['trace' ],
272+ verbose_fn = prDim )
273+ if count < 1 :
274+ precise_sleep (.01 )
275+ # else skip sleep to avoid latency (port already delayed)
276+ except Exception :
277+ print (f"localNodeID={ localNodeID } " )
278+ raise
269279
270280physicalLayer .physicalLayerDown ()
0 commit comments