Advertisement
JachyHm

RDTC 2.0

Jan 19th, 2018
814
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 20.78 KB | None | 0 0
  1. # Copyright (c) 2016, Markus Barenhoff and Copyright (c) 2017, Jáchym Hurtík
  2. #
  3. # All rights reserved.
  4. #
  5. # Redistribution and use in source and binary forms, with or without
  6. # modification, are permitted provided that the following conditions are met:
  7. #
  8. #     * Redistributions of source code must retain the above copyright
  9. #       notice, this list of conditions and the following disclaimer.
  10. #
  11. #     * Redistributions in binary form must reproduce the above
  12. #       copyright notice, this list of conditions and the following
  13. #       disclaimer in the documentation and/or other materials provided
  14. #       with the distribution.
  15. #
  16. #     * Neither the name of Markus Barenhoff nor the names of other
  17. #       contributors may be used to endorse or promote products derived
  18. #       from this software without specific prior written permission.
  19. #
  20. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31.  
  32. import os
  33. import time
  34. import ctypes
  35. import signal
  36. import sys
  37. import configparser
  38. import math
  39. import serial
  40. from threading import Thread
  41.  
  42. class Konfigurace:
  43.     """
  44.    Objekt Konfigurace.\n
  45.    Ma objekt config - objekt config parseru.\n
  46.    Parametry Fce: Konfigurace.config[<nazev kategorie>][<nazev hodnoty>] vraci hodnotu uvedenou v ini
  47.    """
  48.     def __init__(self):
  49.         """
  50.        Funkce spustena pri vytvoreni objektu Konfigurace.
  51.        Vytvori objekt Konfigurace.config.
  52.        Otevre soubor konfigurace.ini pro cteni konfigurace.
  53.        """
  54.         self.config = configparser.ConfigParser()
  55.         self.config.read(os.path.abspath("konfigurace.ini"))
  56.         '''print(str(self.config))
  57.        for key in self.config:
  58.            print(key)
  59.        print(str(self.config["HLAVNI"]))
  60.        for key in self.config["HLAVNI"]:
  61.            print(key)
  62.        print(str(self.config["POSILEJ"]))
  63.        for key in self.config["POSILEJ"]:
  64.            print(key)
  65.        '''
  66. class Raildriver:
  67.     """Hlavni objekt aplikace
  68.    """
  69.     def nastavVypis(self,level):
  70.         self.level = level
  71.     def vypis(self,zprava,level,konec=False):
  72.         if level <= self.level:
  73.             levelSlovnik = {1:"INFO: ",2:"DEBUG: "}
  74.             if not konec:
  75.                 print(time.strftime("%H:%M:%S ")+levelSlovnik[level]+str(zprava))
  76.             else:
  77.                 input(time.strftime("%H:%M:%S ")+levelSlovnik[level]+str(zprava))
  78.  
  79.     def __init__(self):
  80.         self.init = False
  81.         self.nastavVypis(1)
  82.         self.vypis("Hledám konfigurační soubor v: "+str(os.path.abspath("konfigurace.ini")), 2)
  83.  
  84.         try:
  85.             self.konf = Konfigurace()
  86.         except Exception:
  87.             input("Konfigurační soubor nebyl nalezen!!!")
  88.         else:
  89.             self.init = True
  90.             self.vypis("Konfigurační soubor nalezen, čtu",2)
  91.             self.start(
  92.                         dllPathVar = self.konf.config["HLAVNI"]['CestaDLL'],
  93.                         sleepTimeVar = 1/int(self.konf.config["HLAVNI"]['UpdateFrekvence']),
  94.                         comPort = self.konf.config["HLAVNI"]['COMport'],
  95.                         comBaud = int(self.konf.config["HLAVNI"]['Baudrate']),
  96.                         comParita = str.lower(self.konf.config["HLAVNI"]['Parita']),
  97.                         debugVar = self.konf.config["HLAVNI"]["Debug"],
  98.                         zmeneVar = self.konf.config["HLAVNI"]["PosilejJenZmeny"]
  99.                         )
  100.  
  101.     def str_to_bool(self, s):
  102.         """
  103.        Converts boolean formated as string to bol type;
  104.        Parameters:\n
  105.        string\n
  106.        Returns:\n
  107.        bol; or raise Exception if string is not bol
  108.        """
  109.         if s == 'True':
  110.             return True
  111.         elif s == 'False':
  112.             return False
  113.         else:
  114.             raise ValueError
  115.  
  116.     def start(self, dllPathVar, sleepTimeVar, comPort, comBaud, comParita, debugVar, zmeneVar):
  117.         """
  118.        Inicializace aplikace. Nastaveni vsech potrebnych veci pred odpovedi hry.
  119.        """
  120.  
  121.         self.sleepTime = sleepTimeVar
  122.         self.dllPath = dllPathVar
  123.         self.poleSignalek = []
  124.         self.polePrijimanychSignalek = []
  125.         self.pocetSignalek = 0
  126.         self.pocetPrijimanychSignalek = 0
  127.         self.debug = self.str_to_bool(debugVar)
  128.         self.zmene = self.str_to_bool(zmeneVar)
  129.  
  130.         if self.debug == True:
  131.             self.nastavVypis(2)
  132.         self.vypis("START APLIKACE...",1)
  133.  
  134.         self.vypis("Načítám posílané názvy kontrolek z konfiguračního souboru.",2)
  135.  
  136.         #jmena signalek
  137.         for JmenoSignalky in self.konf.config['POSILEJ']:
  138.             self.pocetSignalek += 1
  139.             self.poleSignalek.append(JmenoSignalky)
  140.  
  141.         #prijate
  142.         for JmenoPrijimaneSignalky in self.konf.config['PRIJIMEJ']:
  143.             self.pocetPrijimanychSignalek += 1
  144.             self.polePrijimanychSignalek.append(JmenoPrijimaneSignalky)
  145.  
  146.         self.vypis("Načteno %d signálek z konfiguračního souboru."%(self.pocetSignalek),2)
  147.         self.vypis("Načteno %d přijímaných hodnot z konfiguračního souboru."%(self.pocetPrijimanychSignalek),2)
  148.  
  149.  
  150.         self.vypis("Přiřazuji hodnoty násobitelů.",2)
  151.  
  152.         #nasobitele
  153.         self.poleNasobSignalek = []
  154.         self.poleRawNasobitele = []
  155.         for NasobitelSignalky in self.konf.config['NASOB']:
  156.             self.poleNasobSignalek.append(NasobitelSignalky)
  157.             self.poleRawNasobitele.append(self.konf.config['NASOB'][NasobitelSignalky])
  158.        
  159.         self.poleNasobHodnot = []
  160.         z = 0
  161.         while z < self.pocetSignalek:
  162.             try:
  163.                 self.poleNasobHodnot.append(int(self.poleRawNasobitele[self.poleNasobSignalek.index(self.poleSignalek[z])]))
  164.             except:
  165.                 self.poleNasobHodnot.append(1)
  166.                 self.vypis("Pro hodnotu: %s nebyl uveden násobitel, používám 1!"%(self.poleSignalek[z]),1)
  167.             else:
  168.                 self.vypis("Pro hodnotu: %s byl uveden násobitel, používám %d!"%(self.poleSignalek[z],int(self.poleRawNasobitele[self.poleNasobSignalek.index(self.poleSignalek[z])])),2)
  169.             z = z + 1
  170.  
  171.         #prijate
  172.         self.poleNasobPrijatychSignalek = []
  173.         self.poleRawNasobitelePrijate = []
  174.         for NasobitelPrijateSignalky in self.konf.config['NASOB_PRIJATE']:
  175.             self.poleNasobPrijatychSignalek.append(NasobitelPrijateSignalky)
  176.             self.poleRawNasobitelePrijate.append(self.konf.config['NASOB_PRIJATE'][NasobitelPrijateSignalky])
  177.  
  178.         self.poleNasobHodnotPrijate = []
  179.         z = 0
  180.         while z < self.pocetPrijimanychSignalek:
  181.             try:
  182.                 self.poleNasobHodnotPrijate.append(int(self.poleRawNasobitelePrijate[self.poleNasobPrijatychSignalek.index(self.polePrijimanychSignalek[z])]))
  183.             except:
  184.                 self.poleNasobHodnotPrijate.append(1)
  185.                 self.vypis("Pro přijímanou hodnotu: %s nebyl uveden násobitel, používám 1!"%(self.polePrijimanychSignalek[z]),1)
  186.             else:
  187.                 self.vypis("Pro hodnotu: %s byl uveden násobitel, používám %d!"%(self.polePrijimanychSignalek[z],int(self.poleRawNasobitelePrijate[self.poleNasobPrijatychSignalek.index(self.polePrijimanychSignalek[z])])),2)
  188.             z = z + 1
  189.  
  190.  
  191.         self.vypis("Přiřazuji těmto kontrolkám jména ControlValues.",2)
  192.  
  193.         #prirazovani jmen
  194.         i = 0
  195.         self.NazvyCVSignalek = []
  196.  
  197.         while i < self.pocetSignalek:
  198.             self.NazvyCVSignalek.append(self.konf.config['POSILEJ'][self.poleSignalek[i]])
  199.             i = i + 1
  200.  
  201.         self.vypis("Přiřazeno %d názvů CV signálkám."%i,2)
  202.  
  203.         if self.pocetSignalek == i:
  204.             self.vypis("Počet pojmenovaných signálek je stejný jako přiřazených CV.",2)
  205.         else:
  206.             self.vypis("Počet pojmenovaných signálek není stejný jako přiřazených CV!!!\nKritická chyba při čtení souboru! Zkontroluj soubor!",2)
  207.  
  208.         i = 0
  209.  
  210.         self.vypis("Posílané názvy signálek a názvy CV jsou:",2)
  211.         while i < self.pocetSignalek:
  212.             self.vypis(str(self.poleSignalek[i])+"||"+str(self.NazvyCVSignalek[i]),2)
  213.             i = i + 1
  214.  
  215.         #prijimane
  216.         i = 0
  217.         self.NazvyCVPrijimanychSignalek = []
  218.  
  219.         while i < self.pocetPrijimanychSignalek:
  220.             self.NazvyCVPrijimanychSignalek.append(self.konf.config['PRIJIMEJ'][self.polePrijimanychSignalek[i]])
  221.             i = i + 1
  222.  
  223.         self.vypis("Přiřazeno %d názvů CV přijímaným signálkám."%i,2)
  224.  
  225.         if self.pocetPrijimanychSignalek == i:
  226.             self.vypis("Počet pojmenovaných přijímaných signálek je stejný jako přiřazených CV.",2)
  227.         else:
  228.             self.vypis("Počet pojmenovaných přijímaných signálek není stejný jako přiřazených CV!!!\nKritická chyba při čtení souboru! Zkontroluj soubor!",2)
  229.  
  230.         i = 0
  231.         self.vypis("Přijímané názvy signálek a názvy CV jsou:",2)
  232.         while i < self.pocetPrijimanychSignalek:
  233.             self.vypis(str(self.polePrijimanychSignalek[i])+"||"+str(self.NazvyCVPrijimanychSignalek[i]),2)
  234.             i = i + 1
  235.  
  236.        
  237.         paritaDict = {'suda':'E', 'licha':'O', 'zadna':'N'}
  238.  
  239.         self.ser = serial.Serial()
  240.         self.ser.port = comPort
  241.         self.ser.baudrate = comBaud
  242.         #self.ser.parity = paritaDict[comParita]
  243.         self.ser.rtscts = False
  244.         self.comOK = False
  245.  
  246.         try:
  247.             self.ser.open()
  248.         except Exception as e:
  249.             if str(e).find("FileNotFoundError") != -1:
  250.                 self.vypis("Nepovedlo se otevřít port %s, protože takový port nebyl v počítači nalezen! Nelze pokračovat!"%(comPort),1,True)
  251.             elif str(e).find("PermissionError") != -1:
  252.                 self.vypis("Nepovedlo se otevřít port %s, přístup zamítnut! Nelze pokračovat!"%(comPort),1,True)
  253.             else:
  254.                 self.vypis("Nepovedlo se otevřít port %s, z neznámého důvodu! Nelze pokračovat!\nChyba: %s"%(comPort,e),1,True)
  255.         else:
  256.             self.vypis("Port %s úspěšně otevřen."%(self.ser.name),1)
  257.             self.comOK = True
  258.  
  259.         self.vypis("Soubory načtené v pořádku, čekám na odpověď hry!",1)
  260.         signal.signal(signal.SIGINT, self.signal_handler)
  261.    
  262.     def signal_handler(self, signal, frame):
  263.         sys.exit()
  264.         self.ser.close()
  265.  
  266.     def zaokrouhli(self,cislo):
  267.         """
  268.        Parametry:\n
  269.        cislo k zaokrouhleni\n
  270.        Return:\n
  271.        zaokrouhlene cislo"""
  272.         if cislo % 1 >= 0.5:
  273.             return(math.floor(cislo)+1)
  274.         else:
  275.             return(math.floor(cislo))
  276.  
  277.     def runRaildriver(self):
  278.         """Hlavni vlakno aplikace - procedura; nic nevraci, nema zadne arg"""
  279.         if self.init:
  280.             self.knihovnaOK = False
  281.             try:
  282.                 self.api = RaildriverAPI(self.dllPath)
  283.             except OSError:
  284.                 self.vypis("Nebyla nalezena potřebná knihovna!!!",1,True)
  285.             else:
  286.                 self.knihovnaOK = True
  287.  
  288.             self.valueSignalek = []
  289.             self.valueSignalekStare = []
  290.  
  291.             a = 0
  292.             while a < self.pocetSignalek:
  293.                 a = a + 1
  294.                 self.valueSignalek.append(0)
  295.                 if self.zmene:
  296.                     self.valueSignalekStare.append(0)
  297.  
  298.             if (self.knihovnaOK):
  299.                 self.api.SetRailSimConnected(True)
  300.                 self.api.SetRailDriverConnected(True)
  301.                 self.vypis("Načtená knihovna: %s" % self.api.rdDll,2)
  302.  
  303.             self.idSignalek = []
  304.  
  305.             i = 0
  306.  
  307.             while self.api.GetLocoName() == None:
  308.                 self.vypis("Čekám na nějakou mašinku",2)
  309.                 time.sleep(1)
  310.  
  311.             self.poleZeHry = self.api.GetControllerList()
  312.             z = 0
  313.             self.CVok = True
  314.  
  315.             self.vypis("Přiřazuji ID k názvům CV.",2)
  316.            
  317.             #prirazeni ID hry kontrolkam
  318.             while z < self.pocetSignalek:
  319.                 try:
  320.                     self.idSignalek.append(self.poleZeHry.index(self.NazvyCVSignalek[z]))
  321.                 except Exception:
  322.                     self.vypis("Pro signálku s názvem %s nebylo nalezeno odpovídající ID, program se ukončí!"%(self.NazvyCVSignalek[z]),1,True)
  323.                     self.CVok = False
  324.                     break
  325.                 z = z + 1
  326.  
  327.             #prijimane
  328.             self.idPrijimanychSignalek = []
  329.             z = 0
  330.             while z < self.pocetPrijimanychSignalek:
  331.                 try:
  332.                     self.idPrijimanychSignalek.append(self.poleZeHry.index(self.NazvyCVPrijimanychSignalek[z]))
  333.                 except Exception:
  334.                     self.vypis("Pro přijímanou signálku s názvem %s nebylo nalezeno odpovídající ID, program se ukončí!"%(self.NazvyCVPrijimanychSignalek[z]),1,True)
  335.                     self.CVok = False
  336.                     break
  337.                 z = z + 1
  338.  
  339.             if (self.comOK and self.knihovnaOK and self.CVok):
  340.                 if self.debug:
  341.                     self.vypis(str(self.api.GetLocoName()),2)
  342.                     self.vypis(str(self.api.GetControllerList()),2)
  343.  
  344.                 i = 0
  345.  
  346.                 self.vypis("Posílané ID a názvy CV jsou:",2)
  347.                 while i < self.pocetSignalek:
  348.                     self.vypis(str(self.idSignalek[i])+"||"+str(self.NazvyCVSignalek[i]),2)
  349.                     i = i + 1
  350.  
  351.                 self.vypis("Přijímané ID a názvy CV jsou:",2)
  352.                 while i < self.pocetPrijimanychSignalek:
  353.                     self.vypis(str(self.idPrijimanychSignalek[i])+"||"+str(self.NazvyCVPrijimanychSignalek[i]),2)
  354.                     i = i + 1
  355.  
  356.                 self.vypis("Odpověď v pořádku, aplikace běží!",1)
  357.  
  358.                 v = VlaknoPrijmi(self)
  359.  
  360.                 while True:
  361.                     casZacatekCyklu = time.time()
  362.  
  363.                     a = 0
  364.                     while a < self.pocetSignalek:
  365.                         self.valueSignalek[a] = self.api.GetControllerValue(int(self.idSignalek[a]),0)
  366.                         if self.zmene:
  367.                             if self.valueSignalek[a] != self.valueSignalekStare[a]:
  368.                                 vystup = str(self.poleSignalek[a])+str(self.zaokrouhli(int(self.valueSignalek[a]*self.poleNasobHodnot[a])))
  369.                                 self.vypis(vystup,2)
  370.                                 self.ser.write(vystup.encode())
  371.                             self.valueSignalekStare = self.valueSignalek[:]
  372.                         else:
  373.                             vystup = str(self.poleSignalek[a])+str(self.zaokrouhli(int(self.valueSignalek[a]*self.poleNasobHodnot[a])))
  374.                             self.vypis(vystup,2)
  375.                             self.ser.write(vystup.encode())
  376.  
  377.                         a = a + 1
  378.  
  379.                    
  380.                     ubehlyCas = time.time() - casZacatekCyklu
  381.                     spi = self.sleepTime-ubehlyCas
  382.                     if spi > 0:
  383.                         time.sleep(spi)
  384.                     else:
  385.                         self.vypis("Cyklus je příliš dlouhý! Nestíhám dodržovat obnovovací frekvenci!",1)
  386. class VlaknoPrijmi:
  387.     def __init__(self,Raildriver):
  388.         self.r = Thread(target=self.ctiCOM(Raildriver))
  389.         self.r.start()
  390.     def ctiCOM(self,Raildriver):
  391.         self.init = False
  392.         while True:
  393.             if self.init == False:
  394.                 buff = ""
  395.                 lastLomeno = False
  396.                 while True:
  397.                     buff = buff+Raildriver.ser.read().decode(sys.getfilesystemencoding())
  398.                     if buff.find("\n") != -1:
  399.                         break
  400.                 self.init = True
  401.             else:
  402.                 serialPrichozi = Raildriver.ser.readline().decode(sys.getfilesystemencoding())
  403.                 Raildriver.vypis("RAW vstup serialu: %s"%(serialPrichozi),2)
  404.                 prijateCV = "".join(filter(str.isalpha, serialPrichozi))
  405.                 prijataHodnota = int(serialPrichozi[len(prijateCV):])
  406.                
  407.                 Raildriver.vypis("Přijaté CV: %s"%(prijateCV),2)
  408.                 Raildriver.vypis("Přijatá hodnota: %d"%(prijataHodnota),2)
  409.                
  410.                 try:
  411.                     idPrijateHodnoty = Raildriver.idPrijimanychSignalek[Raildriver.polePrijimanychSignalek.index(prijateCV)]
  412.                 except Exception as e:
  413.                     Raildriver.vypis("Přijatá hodnota: %s není definovaná! Chyba: %s"%(prijataHodnota,e),1)
  414.                 else:
  415.                     nasobitelPrijateHodnoty = Raildriver.poleNasobHodnotPrijate[Raildriver.polePrijimanychSignalek.index(prijateCV)]
  416.                     Raildriver.api.SetControllerValue(idPrijateHodnoty,prijataHodnota/nasobitelPrijateHodnoty)
  417.                     Raildriver.vypis("ID CV přijaté hodnoty: %d"%(idPrijateHodnoty),2)
  418.  
  419.  
  420. class RaildriverAPI:
  421.     """
  422.    API aplikace pro praci s knihovnou RailDriver.dll\n
  423.    Pri prvni definici musi byt zadana cesta k DLL jako parametr.\n
  424.    Funkce:\n
  425.    SetRailSimConnected(connected) - connect or disconnect to api;
  426.    SetRailDriverConnected(connected) - connect or disconnect to Raildriver;
  427.    GetRailSimLocoChanged()- returns True if loco has changed from last call;
  428.    GetLocoName() - returns tuple [Producer, Product,Loco Name];
  429.    GetControllerList() - returns tuple of all control values;
  430.    GetControllerValue(valueID, t) - t=0 (value), t=1 (min), t=2 (max); returns value as int;
  431.    """
  432.     def __init__(self, libpath):
  433.         self.rdDll = ctypes.CDLL(libpath)
  434.  
  435.         self.SetRailSimConnected_c = self.rdDll.SetRailSimConnected
  436.         self.SetRailSimConnected_c.restype = None
  437.         self.SetRailSimConnected_c.argtypes = [ctypes.c_bool]
  438.  
  439.         self.SetRailDriverConnected_c = self.rdDll.SetRailDriverConnected
  440.         self.SetRailDriverConnected_c.restype = None
  441.         self.SetRailDriverConnected_c.argtypes = [ctypes.c_bool]
  442.        
  443.         self.GetRailSimLocoChanged_c = self.rdDll.GetRailSimLocoChanged
  444.         self.GetRailSimLocoChanged_c.restype = ctypes.c_bool
  445.         self.GetRailSimLocoChanged_c.argtypes = None
  446.  
  447.         self.GetLocoName_c = self.rdDll.GetLocoName
  448.         self.GetLocoName_c.restype = ctypes.c_char_p
  449.         self.GetLocoName_c.argtypes = None
  450.  
  451.         self.GetControllerList_c = self.rdDll.GetControllerList
  452.         self.GetControllerList_c.restype = ctypes.c_char_p
  453.         self.GetControllerList_c.argtypes = None
  454.  
  455.         self.GetControllerValue_c = self.rdDll.GetControllerValue
  456.         self.GetControllerValue_c.restype = ctypes.c_float
  457.         self.GetControllerValue_c.argtypes = [ctypes.c_int, ctypes.c_int]
  458.  
  459.         self.SetControllerValue_c = self.rdDll.SetControllerValue
  460.         self.SetControllerValue_c.restype = ctypes.c_byte
  461.         self.SetControllerValue_c.argtypes = [ctypes.c_int, ctypes.c_float]
  462.  
  463.     def SetRailSimConnected(self, connected):
  464.         """connect or disconnect to the API. Must be called first with True"""
  465.         self.SetRailSimConnected_c(connected)
  466.  
  467.     def SetRailDriverConnected(self, connected):
  468.         """connect or disconnect to Raildriver."""
  469.         self.SetRailDriverConnected_c(connected)
  470.        
  471.     def GetRailSimLocoChanged(self):
  472.         """returns if Loco has changed since last call"""
  473.         return self.GetRailSimLocoChanged_c()
  474.  
  475.     def GetLocoName(self):
  476.         """returns a tuple with 3 elements of the loko name [Producer, Product,Loco Name]"""
  477.         resp = self.GetLocoName_c().decode("utf-8")
  478.         if resp: return tuple(resp.split('.:.'))
  479.         else: return None
  480.  
  481.     def GetControllerList(self):
  482.         """returns a list of all controllers of the current loco"""
  483.         ctls = self.GetControllerList_c().decode("utf-8")
  484.         if ctls: return ctls.split("::")
  485.         else: return []
  486.  
  487.     def GetControllerValue(self, vid, t):
  488.         """get the next new/changed value, where
  489.           t=0 (value), t=1 (min), t=2 (max)
  490.         """
  491.         return self.GetControllerValue_c(vid, t)
  492.  
  493.     def SetControllerValue(self, vid, value):
  494.         """set the new value"""
  495.         self.SetControllerValue_c(vid, value)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement