Skip to content

Commit

Permalink
Merge pull request bobjacobsen#32 from Hierosoft/examples-gui
Browse files Browse the repository at this point in the history
Add shared Settings and Examples GUI
  • Loading branch information
bobjacobsen authored Apr 10, 2024
2 parents 035112e + d2c6822 commit 91b28bd
Show file tree
Hide file tree
Showing 46 changed files with 1,737 additions and 857 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@
*localoverrides.py

*tempCDI.xml
/*.bad_json.txt
/settings.json
/.vscode/settings.json
# ^ /.vscode/settings.json is ignored since it may have python.defaultInterpreterPath with differs depending on the specific machine. Recommended: place that setting in there ("PythonOlcbNode Folder" tab in VSCode settings)
130 changes: 62 additions & 68 deletions example_cdi_access.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
'''
Demo of using the memory service to read the CDI from memory, then an example of parsing
Demo of using the memory service to read the CDI from memory, then an
example of parsing
Usage:
python3 example_memory_transfer.py [host|host:port]
Expand All @@ -13,7 +14,9 @@

from openlcb.canbus.tcpsocket import TcpSocket

from openlcb.canbus.canphysicallayergridconnect import CanPhysicalLayerGridConnect
from openlcb.canbus.canphysicallayergridconnect import (
CanPhysicalLayerGridConnect,
)
from openlcb.canbus.canlink import CanLink
from openlcb.nodeid import NodeID
from openlcb.datagramservice import (
Expand All @@ -25,83 +28,63 @@
)

# specify connection information
host = "192.168.16.212"
port = 12021
localNodeID = "05.01.01.01.03.01"
#farNodeID = "09.00.99.03.00.35"
farNodeID = "02.01.57.00.04.9C"
# region moved to settings
# host = "192.168.16.212"
# port = 12021
# localNodeID = "05.01.01.01.03.01"
# # farNodeID = "09.00.99.03.00.35"
# farNodeID = "02.01.57.00.04.9C"
# endregion moved to settings

# region same code as other examples


def usage():
print(__doc__, file=sys.stderr)

from examples_settings import Settings
settings = Settings()

if __name__ == "__main__":
# global host # only necessary if this is moved to a main/other function
import sys
if len(sys.argv) == 2:
host = sys.argv[1]
parts = host.split(":")
if len(parts) == 2:
host = parts[0]
try:
port = int(parts[1])
except ValueError:
usage()
print("Error: Port {} is not an integer.".format(parts[1]),
file=sys.stderr)
sys.exit(1)
elif len(parts) > 2:
usage()
print("Error: blank, address or address:port format was expected.")
sys.exit(1)
elif len(sys.argv) > 2:
usage()
print("Error: blank, address or address:port format was expected.")
sys.exit(1)

settings.load_cli_args(docstring=__doc__)
# endregion same code as other examples

s = TcpSocket()
s.connect(host, port)
s.connect(settings['host'], settings['port'])


#print("RR, SR are raw socket interface receive and send;"
# print("RR, SR are raw socket interface receive and send;"
# " RL, SL are link interface; RM, SM are message interface")


def sendToSocket(string):
#print(" SR: {}".format(string.strip()))
# print(" SR: {}".format(string.strip()))
s.send(string)


def printFrame(frame):
# print(" RL: {}".format(frame))
pass


def printMessage(message):
#print("RM: {} from {}".format(message, message.source))
# print("RM: {} from {}".format(message, message.source))
pass


def printDatagram(memo):
"""create a call-back to print datagram contents when received
"""A call-back for when datagrams received
Args:
memo (_type_): _description_
DatagramReadMemo: The datagram object
Returns:
bool: Always False (True would mean we sent a reply to this datagram,
but let MemoryService do that).
bool: Always False (True would mean we sent a reply to the datagram,
but let the MemoryService do that).
"""
#print("Datagram receive call back: {}".format(memo.data))
# print("Datagram receive call back: {}".format(memo.data))
return False


canPhysicalLayerGridConnect = CanPhysicalLayerGridConnect(sendToSocket)
canPhysicalLayerGridConnect.registerFrameReceivedListener(printFrame)

canLink = CanLink(NodeID(localNodeID))
canLink = CanLink(NodeID(settings['localNodeID']))
canLink.linkPhysicalLayer(canPhysicalLayerGridConnect)
canLink.registerMessageReceivedListener(printMessage)

Expand All @@ -113,25 +96,26 @@ def printDatagram(memo):
memoryService = MemoryService(datagramService)



# accumulate the CDI information
resultingCDI = []

# Invoked when the memory read successfully returns,
# this queues a new read until the entire CDI has been
# returned. At that point, it invokes the XML processing below.

def memoryReadSuccess(memo):
"""createcallbacks to get results of memory read
Invoked when the memory read successfully returns,
this queues a new read until the entire CDI has been
returned. At that point, it invokes the XML processing below.
Args:
memo (_type_): _description_
"""
#print("successful memory read: {}".format(memo.data))
# print("successful memory read: {}".format(memo.data))

global resultingCDI

# is this done?
if len(memo.data) == 64 and not 0 in memo.data:
if len(memo.data) == 64 and 0 not in memo.data:
# save content
resultingCDI += memo.data
# update the address
Expand All @@ -140,7 +124,7 @@ def memoryReadSuccess(memo):
memoryService.requestMemoryRead(memo)
else :
# and we're done!
# save content
# save content
resultingCDI += memo.data
# concert resultingCDI to a string up to 1st zero
cdiString = ""
Expand All @@ -151,37 +135,40 @@ def memoryReadSuccess(memo):

# and process that
processXML(cdiString)

# done



def memoryReadFail(memo):
print("memory read failed: {}".format(memo.data))


#######################
# The XML parsing section.
#
#
# This creates a handler object that just prints
# information as it's presented.
# information as it's presented.
#
# Since `characters` can be called multiple times
# in a row, we buffer up the characters until the `endElement`
# call is invoked to indicate the text is complete

import xml.sax
import xml.sax # noqa: E402


# define XML SAX callbacks in a handler object
class MyHandler(xml.sax.handler.ContentHandler):
"""XML SAX callbacks in a handler object"""
def __init__(self):
self._charBuffer = []

def startElement(self, name, attrs):
print ("Start: ", name)
print("Start: ", name)
if attrs is not None and attrs :
print (" Atributes: ", attrs.getNames())
print(" Atributes: ", attrs.getNames())

def endElement(self, name):
print (name, "cpntent:", self._flushCharBuffer())
print ("End: ", name)
print(name, "cpntent:", self._flushCharBuffer())
print("End: ", name)
pass

def _flushCharBuffer(self):
Expand All @@ -192,17 +179,24 @@ def _flushCharBuffer(self):
def characters(self, data):
self._charBuffer.append(data)


handler = MyHandler()

# process the XML and invoke callbacks

def processXML(content) :
"""process the XML and invoke callbacks
Args:
content (_type_): _description_
"""
xml.sax.parseString(content, handler)
print("\nParser done")


#######################

# have the socket layer report up to bring the link layer up and get an alias
#print(" SL : link up")
# print(" SL : link up")
canPhysicalLayerGridConnect.physicalLayerUp()


Expand All @@ -216,8 +210,8 @@ def memoryRead():
time.sleep(1)

# read 64 bytes from the CDI space starting at address zero
memMemo = MemoryReadMemo(NodeID(farNodeID), 64, 0xFF, 0, memoryReadFail,
memoryReadSuccess)
memMemo = MemoryReadMemo(NodeID(settings['farNodeID']), 64, 0xFF, 0,
memoryReadFail, memoryReadSuccess)
memoryService.requestMemoryRead(memMemo)


Expand All @@ -228,6 +222,6 @@ def memoryRead():
# process resulting activity
while True:
received = s.receive()
#print(" RR: {}".format(received.strip()))
# print(" RR: {}".format(received.strip()))
# pass to link processor
canPhysicalLayerGridConnect.receiveString(received)
45 changes: 12 additions & 33 deletions example_datagram_transfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
import threading

from openlcb.canbus.tcpsocket import TcpSocket
from openlcb.canbus.canphysicallayergridconnect import CanPhysicalLayerGridConnect
from openlcb.canbus.canphysicallayergridconnect import (
CanPhysicalLayerGridConnect,
)
from openlcb.canbus.canlink import CanLink
from openlcb.nodeid import NodeID
from openlcb.datagramservice import (
Expand All @@ -21,47 +23,24 @@
)

# specify connection information
host = "192.168.16.212"
port = 12021
# region replaced by settings
# host = "192.168.16.212"
# port = 12021
# endregion replaced by settings

# region same code as other examples


def usage():
print(__doc__, file=sys.stderr)

from examples_settings import Settings
settings = Settings()

if __name__ == "__main__":
# global host # only necessary if this is moved to a main/other function
import sys
if len(sys.argv) == 2:
host = sys.argv[1]
parts = host.split(":")
if len(parts) == 2:
host = parts[0]
try:
port = int(parts[1])
except ValueError:
usage()
print("Error: Port {} is not an integer.".format(parts[1]),
file=sys.stderr)
sys.exit(1)
elif len(parts) > 2:
usage()
print("Error: blank, address or address:port format was expected.")
sys.exit(1)
elif len(sys.argv) > 2:
usage()
print("Error: blank, address or address:port format was expected.")
sys.exit(1)

settings.load_cli_args(docstring=__doc__)
# endregion same code as other examples


localNodeID = "05.01.01.01.03.01"
farNodeID = "09.00.99.03.00.35"
s = TcpSocket()
s.connect(host, port)
s.connect(settings['host'], settings['port'])

print("RR, SR are raw socket interface receive and send;"
" RL, SL are link interface; RM, SM are message interface")
Expand Down Expand Up @@ -101,7 +80,7 @@ def datagramReceiver(memo):
"""A call-back for when datagrams received
Args:
_type_: _description_
DatagramReadMemo: The datagram object
Returns:
bool: Always True (means we sent the reply to this datagram)
Expand Down
Loading

0 comments on commit 91b28bd

Please sign in to comment.