Board index FlightGear Support Interfacing

Python3 class for telnet

Connecting two computers, using generic protocol, connecting with Matlab?

Python3 class for telnet

Postby jam007 » Sun Mar 19, 2017 10:39 am

I wrote the class below to help with telnet communication with Python3.
It uses "data" mode for communication. This saves a lot of reply parsing but I found two important gotchas:
* The subscribe command does return an echo reply even in data mode. The other non retrieving does not, including unsubscribe(!).
* The ls command replies with one line per item but nothing that signals that all items are listed. If you want to use ls in data mode you have to set a timeout to the reader. :!:

The code:
Code: Select all
import telnetlib

# FlightGear Telnet class in Python3
class FGTelnet:

    eol="\r\n".encode('ascii')

    def __init__(self,host="localhost",port=5401):
        """
        Instantiates a FGTelnet object,
        opens connection and switche to data mode.
        Default to localhost at port 5401
        """
        self.host=host
        self.port=port
        self.tn=telnetlib.Telnet()
        self.tn.set_debuglevel(0) #Debug
        self.tn.open(host, port)
        self.tn.write("data".encode('ascii')+FGTelnet.eol)

    def __message(self, text):
        """Creates ASCII coded message with EOL"""
        return text.encode('ascii')+FGTelnet.eol

    def getprop(self, prop):
        """
        Gets property
        prop -- path
        """
        self.tn.write(self.__message("get "+prop))
        return self.tn.read_until(FGTelnet.eol).decode('ascii').strip()
       

    def setprop(self, prop, value, type="s"):
        """
        Sets property
        prop --  path
        value -- property value
        type --  type: s=string, b=bool, i=int, d=double
        """
        if type=="b":
            self.tn.write(self.__message("setb "+prop+" "+str(value)))
        elif type=="i":
            self.tn.write(self.__message("seti "+prop+" "+str(value)))
        elif type=="d":
            self.tn.write(self.__message("setd "+prop+" "+str(value)))
        else:
            self.tn.write(self.__message("set "+prop+" "+str(value)))

    def sendcmd(self, text, reply=False):
        """
        Sends a command to the server
        text --  the command string
        reply -- If true the reply is read directly.
        Note: In data mode cd, set, run and unsubscribe does not create
        an echo reply but subscribe does. The listing command ls
        cannot be used with this method as it returns EOL after
        every item but no end of list marker in data mode.
        """
        self.tn.write(self.__message(text))
        if reply :
            return self.tn.read_until(FGTelnet.eol).decode('ascii').strip()
        else:
            return ""

    def readreply(self):
        """Reads a reply from the server """
        return self.tn.read_until(FGTelnet.eol).decode('ascii').strip()

    def close(self):
        print(self.tn.read_eager()) #Debug
        self.tn.close()

    def __del__(self):
        self.tn.close()

if __name__ == "__main__" :
    """Some test operations"""
    fgtn=FGTelnet()
    print(fgtn.host)
    fgtn.setprop("/tmp/teststring", "test")
    fgtn.setprop("/tmp/testbool", "true","b")
    fgtn.setprop("/tmp/testint", "256","i")
    fgtn.setprop("/tmp/testdouble", "3.1415","d")
    print(fgtn.getprop("/controls/engines/engine/cutoff"))
    print(fgtn.getprop("/controls/engines/engine/throttle"))
    fgtn.sendcmd("dump /position")
    print(fgtn.readreply()+"\n\n")
    #Subscribe echoes command so it has to be read and discarded
    fgtn.sendcmd("subscribe /tmp/teststring", True)
    print("Quit session and program by setting /tmp/teststring to end in FG")
    r=""
    while r != "/tmp/teststring=end":
        r=fgtn.readreply()
        print(r)
    fgtn.close()
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04

Re: Python3 class for telnet

Postby Hooray » Sun Mar 19, 2017 12:29 pm

I originally came up with subscribe/unsubscribe in response to the j661 project needing listener-like semantics to emulate pub/sub (well, poorly so).
So if you think something is broken or missing, feel free to post feature requests (or ideally patches) and file a corresponding merge request.
I certainly won't expose any improvements to that code, it's accessible enough to be improved accordingly.

For some background info, refer to my recent posting at: Why not use Erlang instead of NASAL?

In a perfect world, we would use Torsten's AJAX/mongoose approach instead - or at least come up with an asynchronous telnet-like equivalent, e.g. mapping the property tree to UDP. The Multiplayer protocol already uses XDR for encoding purposes - as things are standing we're facing the usual problem of great ideas and concepts all over the place in SG/FG that are, and often remain, poorly integrated ... ThorstenB once mentioned how the flight recorder/replay system and the multiplayer system could greatly benefit from each other if properly integrated - and that also applies to multi-instance use-cases like FSWeekend/Linux or multi-crew (dual pilot) uses.


Feel free to create a coresponding wiki tutorial to share your code, my suggestion would also to add it to the upcoming newsletter. By the way, the contrib directory already contains similar examples, so you may want to get your's committed, too ?
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Python3 class for telnet

Postby jam007 » Sun Mar 19, 2017 2:56 pm

Hooray wrote in Sun Mar 19, 2017 12:29 pm:So if you think something is broken or missing, feel free to post feature requests (or ideally patches) and file a corresponding merge request.

Ok.
By the way, the contrib directory already contains similar examples, so you may want to get your's committed, too ?

Could you point me to that directory? I have managed to miss it.
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04

Re: Python3 class for telnet

Postby Hooray » Sun Mar 19, 2017 3:05 pm

See: https://sourceforge.net/p/flightgear/fl ... e/scripts/
And more specifically: https://sourceforge.net/p/flightgear/fl ... ghtGear.py

Regarding any potential additions/changes to the way telnet works currently, my suggestion would be to introduce a new command for switching compatibility mode "off", i.e. so that you can make changes that may no longer need to be backward compatible - e.g. something like "compat-mode off/on" or "set version" - this may need to be discussed on the devel list, but it would be a good way to make useful changes without any chance to break existing use-cases/tools

If in doubt, tell us exactly what you have in mind - I may also be able to work you through all the steps of changing the C++ code accordingly, even though I think the tutorial I once added should still cover most things. But it may take me a few weeks to revisit this topic and provide feedback - if in doubt, you are better off using the devel list and finding a reviewer/mentor there.

Obviously that is assuming that you are able build/patch fg from source and have some basic C++ knowledge - even though a solid background in Nasal coding should suffice to make heads and tails of the C++ patch implementing subscribe/unsubscribe, so that you could use that as the foundation for making similar changes - for instance, anything involving primarily changes in terms of output/formatting would be trivial to do.

Concerning the telnet/python class, you may also want to look up Curt's and bugman's comments on coming up with a Python-enabled property tree implementation - I would suggest searching for:

search.php?st=0&sk=t&sd=d&sr=posts&keywords=python+property+tree&author=curt
search.php?st=0&sk=t&sd=d&sr=posts&keywords=python+property+tree&author=bugman

These are roughly ~15 postings, but should/could be pretty relevant given your efforts - if in doubt, get in touch with them.

In addition, it may be worthwhile to look up Torsten's mongoose/AJAX work: search.php?st=0&sk=t&sd=d&sr=posts&keywords=mongoose+ajax
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Python3 class for telnet

Postby jam007 » Sun Mar 19, 2017 3:54 pm


Ah. That was the script I referenced here. It is in Python 2.? and was the inspiration to mine.
If in doubt, tell us exactly what you have in mind

Basically two small changes in props.cxx.
1) Adding a if (mode == PROMPT) { around line 164-166
2) Add a end of list marker to data mode. Eg. inserting a if (mode == DATA) { send an empty line } on line 299.

Looking at the code I notice that unsubscribe don't echo in PROMT mode. Maybe this could be changed too so all commands behaves in the same way.

I'm a bit reluctant to start (again) with git. Last time I only managed to mess things up and become frustrated with all the commands...
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04

Re: Python3 class for telnet

Postby Hooray » Sun Mar 19, 2017 4:05 pm

You don't necessarily need to use git to make these modifications and test them - either way, feel free to make a corresponding feature request, your changes sound sane to me, they were probably simply missed originally.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Python3 class for telnet

Postby jam007 » Sun Mar 19, 2017 4:10 pm

Will do
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04

Re: Python3 class for telnet

Postby jonititan » Mon Nov 27, 2017 8:13 am

I found this much better than the FG example python class for telnet and used in a research project.

How should I cite your work?

Is it on github somewhere?
Joni P
Flight Data guy.
Ask me about artificial immune systems for health management of unmanned aircraft...
jonititan
 
Posts: 14
Joined: Fri Sep 29, 2017 1:04 pm

Re: Python3 class for telnet

Postby jam007 » Wed Nov 29, 2017 3:26 pm

jonititan wrote in Mon Nov 27, 2017 8:13 am:I found this much better than the FG example python class for telnet and used in a research project.
:)
jonititan wrote in Mon Nov 27, 2017 8:13 am:How should I cite your work?
Is it on github somewhere?

No idea! It's not on github, I just posted it here as I thought that others might be interested in a Python3 version.
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04

Re: Python3 class for telnet

Postby Hooray » Wed Nov 29, 2017 4:22 pm

He's is asking if you'd like to see your nickname/real name attributed in the corresponding work - if so, you should get in touch via PM.
Otherwise, I'd suggest to just release it into the public domain - you can still add a corresponding header/disclaimer to your code.
Please don't send support requests by PM, instead post your questions on the forum so that all users can contribute and benefit
Thanks & all the best,
Hooray
Help write next month's newsletter !
pui2canvas | MapStructure | Canvas Development | Programming resources
Hooray
 
Posts: 11100
Joined: Tue Mar 25, 2008 8:40 am

Re: Python3 class for telnet

Postby jam007 » Wed Nov 29, 2017 6:57 pm

Ok
jam007
 
Posts: 477
Joined: Sun Dec 16, 2012 10:04 am
Location: Uppsala, Sweden
Version: 2017.3.1
OS: Ubuntu 16.04


Return to Interfacing

Who is online

Users browsing this forum: No registered users and 1 guest