Ignore:
Timestamp:
04/03/12 15:54:52 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

The CLI works now for most values

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/mlx/pyuipc_sim.py

    r54 r55  
    165165    def _writeBCD(value):
    166166        """Convert the given BCD value into a real value."""
    167         bcd = (value>>24) & 0xf
     167        bcd = (value>>12) & 0x0f
    168168        bcd *= 10
    169         bcd += (value>>16) & 0xf
     169        bcd += (value>>8) & 0x0f
    170170        bcd *= 10
    171         bcd += (value>>8) & 0xf
     171        bcd += (value>>4) & 0x0f
    172172        bcd *= 10
    173         bcd += (value>>0) & 0xf
     173        bcd += (value>>0) & 0x0f
    174174
    175175        return bcd
     
    391391        elif offset==0x2200:       # Engine #3 N1
    392392            return self.n1[self.ENGINE_3]
    393         elif offset==0x30c0:       # Grossweight
    394             return int((self.zfw + sum(self.fuelWeights)) * const.KGSTOLB)
     393        elif offset==0x30c0:       # Gross weight
     394            return (self.zfw + sum(self.fuelWeights)) * const.KGSTOLB
    395395        elif offset==0x31e4:       # Radio altitude
    396396            # FIXME: if self.radioAltitude is None, calculate from the
     
    560560        elif offset==0x2200:       # Engine #3 N1
    561561            self.n1[self.ENGINE_3] = value
    562         elif offset==0x30c0:       # Grossweight
     562        elif offset==0x30c0:       # Gross weight
    563563            raise FSUIPCException(ERR_DATA)
    564564        elif offset==0x31e4:       # Radio altitude
     
    757757
    758758# FIXME: implement proper completion and history
    759 class CLI(threading.Thread, cmd.Cmd):
     759class CLI(cmd.Cmd):
    760760    """The command-line interpreter."""
    761     def __init__(self, clientSocket):
     761    @staticmethod
     762    def str2bool(s):
     763        """Convert the given string to a PyUIPC boolean value (i.e. 0 or 1)."""
     764        return 1 if s in ["yes", "true", "on"] else 0
     765   
     766    @staticmethod
     767    def bool2str(value):
     768        """Convert the PyUIPC boolean value (i.e. 0 or 1) into a string."""
     769        return "no" if value==0 else "yes"
     770
     771    @staticmethod
     772    def degree2pyuipc(degree):
     773        """Convert the given degree (as a string) into a PyUIPC value."""
     774        return int(float(degree) * 65536.0 * 65536.0 / 360.0)
     775       
     776    @staticmethod
     777    def pyuipc2degree(value):
     778        """Convert the given PyUIPC value into a degree."""
     779        return valie * 360.0 / 65536.0 / 65536.0
     780       
     781    def __init__(self):
    762782        """Construct the CLI."""
    763         self._socket = clientSocket
    764         self._socketFile = clientSocket.makefile("rwb")
    765        
    766         threading.Thread.__init__(self)
    767         cmd.Cmd.__init__(self,
    768                          stdin = self._socketFile, stdout = self._socketFile)
    769        
    770         self.use_rawinput = False
     783        cmd.Cmd.__init__(self)
     784       
     785        self.use_rawinput = True
    771786        self.intro = "\nPyUIPC simulator command prompt\n"
    772787        self.prompt = "PyUIPC> "
     
    774789        self.daemon = True
    775790
    776     def run(self):
    777         """Execute the thread."""
     791        self._client = Client("localhost")
     792
     793        self._valueHandlers = {}
     794        self._valueHandlers["year"] = (0x0240, "H",  lambda value: value,
     795                                      lambda word: int(word))
     796        self._valueHandlers["yday"] = (0x023e, "H",  lambda value: value,
     797                                       lambda word: int(word))
     798        self._valueHandlers["hour"] = (0x023b, "b",  lambda value: value,
     799                                       lambda word: int(word))
     800        self._valueHandlers["min"] = (0x023c, "b",  lambda value: value,
     801                                      lambda word: int(word))
     802        self._valueHandlers["sec"] = (0x023a, "b",  lambda value: value,
     803                                      lambda word: int(word))
     804        self._valueHandlers["acftName"] = (0x3d00, -256,  lambda value: value,
     805                                           lambda word: word)
     806        self._valueHandlers["airPath"] = (0x3c00, -256,  lambda value: value,
     807                                          lambda word: word)
     808        self._valueHandlers["paused"] = (0x0264, "H", CLI.bool2str, CLI.str2bool)
     809        self._valueHandlers["frozen"] = (0x3364, "H", CLI.bool2str, CLI.str2bool)
     810        self._valueHandlers["replay"] = (0x0628, "d", CLI.bool2str, CLI.str2bool)
     811        self._valueHandlers["slew"] = (0x05dc, "H", CLI.bool2str, CLI.str2bool)
     812        self._valueHandlers["overspeed"] = (0x036d, "b", CLI.bool2str, CLI.str2bool)
     813        self._valueHandlers["stalled"] = (0x036c, "b", CLI.bool2str, CLI.str2bool)
     814        self._valueHandlers["onTheGround"] = (0x0366, "H", CLI.bool2str, CLI.str2bool)
     815        self._valueHandlers["zfw"] = (0x3bfc, "d",
     816                                      lambda value: value * const.LBSTOKG / 256.0,
     817                                      lambda word: int(float(word) * 256.0 *
     818                                                       const.KGSTOLB))
     819        self._valueHandlers["grossWeight"] = (0x30c0, "f",
     820                                              lambda value: value * const.LBSTOKG,
     821                                              lambda word: None)
     822        self._valueHandlers["heading"] = (0x0580, "d",
     823                                          CLI.pyuipc2degree, CLI.degree2pyuipc)
     824        self._valueHandlers["pitch"] = (0x0578, "d",
     825                                        CLI.pyuipc2degree, CLI.degree2pyuipc)
     826        self._valueHandlers["bank"] = (0x057c, "d",
     827                                       CLI.pyuipc2degree, CLI.degree2pyuipc)
     828        self._valueHandlers["ias"] = (0x02bc, "d",
     829                                      lambda value: value / 128.0,
     830                                      lambda word: int(float(word) * 128.0))
     831        self._valueHandlers["mach"] = (0x11c6, "H",
     832                                       lambda value: value / 20480.0,
     833                                       lambda word: int(float(word) * 20480.0))
     834        self._valueHandlers["gs"] = (0x02b4, "d",
     835                                     lambda value: value * 3600.0 / 65536.0 / 1852.0,
     836                                     lambda word: int(float(word) * 65536.0 *
     837                                                      1852.0 / 3600))
     838        self._valueHandlers["vs"] = (0x02c8, "d",
     839                                     lambda value: value * 60 /                                     
     840                                     const.FEETTOMETRES / 256.0,
     841                                     lambda word: int(float(word) *
     842                                                      const.FEETTOMETRES *
     843                                                      256.0 / 60.0))
     844        self._valueHandlers["radioAltitude"] = (0x31e4, "d",
     845                                                lambda value: value /
     846                                                const.FEETTOMETRES /
     847                                                65536.0,
     848                                                lambda word: int(float(word) *
     849                                                                 const.FEETTOMETRES *
     850                                                                 65536.0))
     851        self._valueHandlers["altitude"] = (0x0570, "l",
     852                                           lambda value: value /
     853                                           const.FEETTOMETRES / 65536.0 /
     854                                           65536.0,
     855                                           lambda word: long(float(word) *
     856                                                             const.FEETTOMETRES *
     857                                                             65536.0 * 65536.0))
     858        self._valueHandlers["gLoad"] = (0x11ba, "H",
     859                                        lambda value: value / 625.0,
     860                                        lambda word: int(float(word) * 625.0))
     861
     862        self._valueHandlers["flapsControl"] = (0x0bdc, "d",
     863                                               lambda value: value * 100.0 / 16383.0,
     864                                               lambda word: int(float(word) *
     865                                                                16383.0 / 100.0))
     866        self._valueHandlers["flaps"] = (0x0be0, "d",
     867                                        lambda value: value * 100.0 / 16383.0,
     868                                        lambda word: int(float(word) *
     869                                                         16383.0 / 100.0))
     870        self._valueHandlers["lights"] = (0x0d0c, "H",
     871                                        lambda value: value,
     872                                        lambda word: int(word))
     873        self._valueHandlers["pitot"] = (0x029c, "b", CLI.bool2str, CLI.str2bool)
     874        self._valueHandlers["parking"] = (0x0bc8, "H", CLI.bool2str, CLI.str2bool)
     875        self._valueHandlers["noseGear"] = (0x0bec, "d",
     876                                           lambda value: value * 100.0 / 16383.0,
     877                                           lambda word: int(float(word) *
     878                                                            16383.0 / 100.0))
     879        self._valueHandlers["spoilersArmed"] = (0x0bcc, "d",
     880                                                CLI.bool2str, CLI.str2bool)
     881        self._valueHandlers["spoilers"] = (0x0bd0, "d",
     882                                           lambda value: value,
     883                                           lambda word: int(word))
     884        self._valueHandlers["qnh"] = (0x0330, "H",
     885                                      lambda value: value / 16.0,
     886                                      lambda word: int(float(word)*16.0))
     887        self._valueHandlers["nav1"] = (0x0350, "H",
     888                                       Values._writeFrequency,
     889                                       lambda word: Values._readFrequency(float(word)))
     890        self._valueHandlers["nav2"] = (0x0352, "H",
     891                                       Values._writeFrequency,
     892                                       lambda word: Values._readFrequency(float(word)))
     893        self._valueHandlers["squawk"] = (0x0354, "H",
     894                                       Values._writeBCD,
     895                                       lambda word: Values._readBCD(int(word)))
     896        self._valueHandlers["windSpeed"] = (0x0e90, "H",
     897                                            lambda value: value,
     898                                            lambda word: int(word))
     899        self._valueHandlers["windDirection"] = (0x0e92, "H",
     900                                                lambda value: value * 360.0 / 65536.0,
     901                                                lambda word: int(int(word) *
     902                                                                 65536.0 / 360.0))
     903                                                           
     904    def default(self, line):
     905        """Handle unhandle commands."""
     906        if line=="EOF":
     907            print
     908            return True
     909        else:
     910            return super(CLI, self).default(line)
     911
     912    def do_get(self, args):
     913        """Handle the get command."""
     914        names = args.split()
     915        data = []       
     916        for name in names:
     917            if name not in self._valueHandlers:
     918                print >> sys.stderr, "Unknown variable: " + name
     919                return False
     920            valueHandler = self._valueHandlers[name]
     921            data.append((valueHandler[0], valueHandler[1]))
     922
    778923        try:
    779             self.cmdloop()
     924            result = self._client.read(data)
     925            for i in range(0, len(result)):
     926                name = names[i]
     927                valueHandler = self._valueHandlers[name]
     928                print name + "=" + str(valueHandler[2](result[i]))
    780929        except Exception, e:
    781             print "pyuipc_sim.CLI.run: command loop terminated abnormally: " + str(e)
    782            
    783         try:
    784             self._socketFile.close()
    785         except:
    786             pass
    787        
    788         self._socket.close()
     930            print >> sys.stderr, "Failed to read data: " + str(e)                       
     931
     932        return False
     933
     934    def help_get(self):
     935        """Print help for the get command."""
     936        print "get <variable> [<variable>...]"
     937
     938    def complete_get(self, text, line, begidx, endidx):
     939        """Try to complete the get command."""
     940        return [key for key in self._valueHandlers if key.startswith(text)]
    789941
    790942    def do_set(self, args):
    791943        """Handle the set command."""
    792         words = args.split()
    793         if len(words)==2:
    794             variable = words[0]
    795             if variable in ["zfw"]:
    796                 values.__setattr__(variable, float(words[1]))
    797             else:
    798                 print >> self._socketFile, "Unhandled variable: " + variable
     944        arguments = args.split()
     945        names = []
     946        data = []
     947        for argument in arguments:
     948            words = argument.split("=")
     949            if len(words)!=2:
     950                print >> sys.stderr, "Invalid argument: " + argument
     951                return False
     952
     953            (name, value) = words
     954            if name not in self._valueHandlers:
     955                print >> sys.stderr, "Unknown variable: " + name
     956                return False
     957
     958            valueHandler = self._valueHandlers[name]
     959            try:
     960                value = valueHandler[3](value)
     961                data.append((valueHandler[0], valueHandler[1], value))
     962            except Exception, e:
     963                print >> sys.stderr, "Invalid value '%s' for variable %s: %s" % \
     964                      (value, name, str(e))
     965                return False
     966               
     967        try:
     968            self._client.write(data)
     969            print "Data written"
     970        except Exception, e:
     971            print >> sys.stderr, "Failed to write data: " + str(e)
     972
    799973        return False
    800974
    801975    def help_set(self):
    802976        """Print help for the set command."""
    803         print >> self._socketFile, "set <variable> <value>"
     977        print "set <variable>=<value> [<variable>=<value>...]"
     978
     979    def complete_set(self, text, line, begidx, endidx):
     980        """Try to complete the set command."""
     981        if not text and begidx>0 and line[begidx-1]=="=":
     982            return []
     983        else:
     984            return [key + "=" for key in self._valueHandlers if key.startswith(text)]
    804985
    805986    def do_quit(self, args):
     
    810991
    811992if __name__ == "__main__":
    812     client = Client("127.0.0.1")
    813     # print client.write([(0x3bfc, "d", 1000 * 256.0 * const.KGSTOLB)])
    814     # print client.read([(0x3bfc, "d")])
    815     print client.write([(0x023c, "d", 30)])
    816     print client.read([(0x023c, "d")])
     993    CLI().cmdloop()
    817994else:
    818995    server = Server()
Note: See TracChangeset for help on using the changeset viewer.