1
0
mirror of https://github.com/JoelBender/bacpypes synced 2025-09-28 22:15:23 +08:00
bacpypes/samples/TCPClient25.py

149 lines
4.0 KiB
Python
Executable File

#!/usr/bin/env python2.5
"""
This simple TCP client application connects to a server and sends the text
entered in the console. There is no conversion from incoming streams of
content into a line or any other higher-layer concept of a packet.
"""
import os
import sys
from bacpypes.debugging import bacpypes_debugging, ModuleLogger
from bacpypes.core import run, stop
from bacpypes.task import TaskManager
from bacpypes.comm import PDU, Client, Server, bind, ApplicationServiceElement
from bacpypes.consolelogging import ArgumentParser
from bacpypes.console import ConsoleClient
from bacpypes.tcp import TCPClientDirector
# some debugging
_debug = 0
_log = ModuleLogger(globals())
# settings
SERVER_HOST = os.getenv('SERVER_HOST', '127.0.0.1')
SERVER_PORT = int(os.getenv('SERVER_PORT', 9000))
# globals
server_address = None
#
# MiddleMan
#
class MiddleMan(Client, Server):
"""
An instance of this class sits between the TCPClientDirector and the
console client. Downstream packets from a console have no concept of a
destination, so this is added to the PDUs before being sent to the
director. The source information in upstream packets is ignored by the
console client.
"""
def indication(self, pdu):
if _debug: MiddleMan._debug("indication %r", pdu)
global server_address
# no data means EOF, stop
if not pdu.pduData:
stop()
return
# pass it along
self.request(PDU(pdu.pduData, destination=server_address))
def confirmation(self, pdu):
if _debug: MiddleMan._debug("confirmation %r", pdu)
# pass it along
self.response(pdu)
bacpypes_debugging(MiddleMan)
#
# MiddleManASE
#
class MiddleManASE(ApplicationServiceElement):
def indication(self, add_actor=None, del_actor=None, actor_error=None, error=None):
if add_actor:
if _debug: MiddleManASE._debug("indication add_actor=%r", add_actor)
if del_actor:
if _debug: MiddleManASE._debug("indication del_actor=%r", del_actor)
if actor_error:
if _debug: MiddleManASE._debug("indication actor_error=%r error=%r", actor_error, error)
# if there are no clients, quit
if not self.elementService.clients:
if _debug: MiddleManASE._debug(" - quitting")
stop()
bacpypes_debugging(MiddleManASE)
def main():
"""
Main function, called when run as an application.
"""
global server_address
# check the version
if (sys.version_info[:2] != (2, 5)):
sys.stderr.write("Python 2.5 only\n")
sys.exit(1)
# parse the command line arguments
parser = ArgumentParser(description=__doc__)
parser.add_argument(
"host", nargs='?',
help="address of host (default %r)" % (SERVER_HOST,),
default=SERVER_HOST,
)
parser.add_argument(
"port", nargs='?', type=int,
help="server port (default %r)" % (SERVER_PORT,),
default=SERVER_PORT,
)
args = parser.parse_args()
if _debug: _log.debug("initialization")
if _debug: _log.debug(" - args: %r", args)
# extract the server address and port
host = args.host
port = args.port
server_address = (host, port)
if _debug: _log.debug(" - server_address: %r", server_address)
# build the stack
this_console = ConsoleClient()
if _debug: _log.debug(" - this_console: %r", this_console)
this_middle_man = MiddleMan()
if _debug: _log.debug(" - this_middle_man: %r", this_middle_man)
this_director = TCPClientDirector()
if _debug: _log.debug(" - this_director: %r", this_director)
bind(this_console, this_middle_man, this_director)
bind(MiddleManASE(), this_director)
# create a task manager for scheduled functions
task_manager = TaskManager()
if _debug: _log.debug(" - task_manager: %r", task_manager)
# don't wait to connect
this_director.connect(server_address)
if _debug: _log.debug("running")
run()
if __name__ == "__main__":
main()