Advertisement
JachyHm

RDTC 1.1

Oct 2nd, 2017
148
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 12.23 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.  
  41. class Konfigurace:
  42.     def __init__(self):
  43.         self.config = configparser.ConfigParser()
  44.         self.config.read(os.path.abspath("konfigurace.ini"))
  45.         '''print("\n"+str(self.config))
  46.        for key in self.config:
  47.            print(key)
  48.        print("\n"+str(self.config["HLAVNI"]))
  49.        for key in self.config["HLAVNI"]:
  50.            print(key)
  51.        print("\n"+str(self.config["POSILEJ"]))
  52.        for key in self.config["POSILEJ"]:
  53.            print(key)
  54.        '''
  55. class Raildriver:
  56.     def __init__(self):
  57.         self.init = False
  58.  
  59.         print("Hledám konfigurační soubor v: "+str(os.path.abspath("konfigurace.ini")))
  60.  
  61.         try:
  62.             self.konf = Konfigurace()
  63.         except Exception:
  64.             input("\nKonfigurační soubor nebyl nalezen!!!")
  65.         else:
  66.             self.init = True
  67.             print("\nKonfigurační soubor nalezen, čtu")
  68.             self.start(
  69.                         dllPathVar = self.konf.config["HLAVNI"]['CestaDLL'],
  70.                         sleepTimeVar = 1/int(self.konf.config["HLAVNI"]['UpdateFrekvence']),
  71.                         comPort = self.konf.config["HLAVNI"]['COMport'],
  72.                         comBaud = int(self.konf.config["HLAVNI"]['Baudrate']),
  73.                         comParita = str.lower(self.konf.config["HLAVNI"]['Parita']),
  74.                         debugVar = self.konf.config["HLAVNI"]["Debug"],
  75.                         zmeneVar = self.konf.config["HLAVNI"]["PosilejJenZmeny"]
  76.                         )
  77.  
  78.     def start(self, dllPathVar, sleepTimeVar, comPort, comBaud, comParita, debugVar, zmeneVar):
  79.        
  80.         print("\n\nSTART APLIKACE...")
  81.  
  82.         self.sleepTime = sleepTimeVar
  83.         self.dllPath = dllPathVar
  84.         self.poleSignalek = []
  85.         self.pocetSignalek = 0
  86.         self.debug = debugVar
  87.         self.zmene = zmeneVar
  88.  
  89.         print("\nNačítám posílané názvy kontrolek z konfiguračního souboru.")
  90.  
  91.         for JmenoSignalky in self.konf.config['POSILEJ']:
  92.             self.pocetSignalek = self.pocetSignalek + 1
  93.             self.poleSignalek.append(JmenoSignalky)
  94.  
  95.         print("\nNačteno %d signálek z konfiguračního souboru."%(self.pocetSignalek))
  96.  
  97.         print("\nPřiřazuji hodnoty násobitelů.")
  98.         z = 0
  99.         self.poleNasobSignalek = self.konf.config['NASOB']
  100.         self.poleNasobHodnot = []
  101.  
  102.         while z < self.pocetSignalek:
  103.             try:
  104.                 self.poleNasobHodnot.append(self.poleNasobSignalek.index(self.poleSignalek[z]))
  105.             except:
  106.                 self.poleNasobHodnot.append(0)
  107.                 print("\nPro hodnotu: %s nebyl uveden násobitel, používám 0!"%(self.poleSignalek[z]))
  108.             z = z + 1
  109.  
  110.         print("\nPřiřazuji těmto kontrolkám jména ControlValues.")
  111.  
  112.         i = 0
  113.         self.NazvyCVSignalek = []
  114.  
  115.         while i < self.pocetSignalek:
  116.             self.NazvyCVSignalek.append(self.konf.config['POSILEJ'][self.poleSignalek[i]])
  117.             i = i + 1
  118.  
  119.         print("\nPřiřazeno %d názvů CV signálkám."%i)
  120.  
  121.         if self.pocetSignalek == i:
  122.             print("\nPočet pojmenovaných signálek je stejný jako přiřazených CV.")
  123.         else:
  124.             print("\nPočet pojmenovaných signálek není stejný jako přiřazených ID!!!\nKritická chyba při čtení souboru! Zkontroluj soubor!")
  125.  
  126.         i = 0
  127.  
  128.         print("\nPosílané názvy signálek a názvy CV jsou:")
  129.         while i < self.pocetSignalek:
  130.             print(str(self.poleSignalek[i])+"||"+str(self.NazvyCVSignalek[i]))
  131.             i = i + 1
  132.         print("\nInicializuji aplikaci!")
  133.        
  134.         paritaDict = {'suda':'E', 'licha':'O', 'zadna':'N'}
  135.  
  136.         self.ser = serial.Serial()
  137.         self.ser.port = comPort
  138.         self.ser.baudrate = comBaud
  139.         self.ser.parity = paritaDict[comParita]
  140.         self.ser.rtscts = False
  141.         self.comOK = False
  142.  
  143.         try:
  144.             self.ser.open()
  145.         except Exception as e:
  146.             if str(e).find("FileNotFoundError") != -1:
  147.                 input("\nNepovedlo se otevřít port %s, protože takový port nebyl v počítači nalezen! Nelze pokračovat!"%(comPort))
  148.             elif str(e).find("PermissionError") != -1:
  149.                 input("\nNepovedlo se otevřít port %s, přístup zamítnut! Nelze pokračovat!"%(comPort))
  150.             else:
  151.                 input("\nNepovedlo se otevřít port %s, z neznámého důvodu! Nelze pokračovat!\nChyba: %s"%(comPort,e))
  152.         else:
  153.             print("\nPort %s úspěšně otevřen."%(self.ser.name))
  154.             self.comOK = True
  155.  
  156.         signal.signal(signal.SIGINT, self.signal_handler)
  157.  
  158.     def zaokrouhli(self,cislo):
  159.         if cislo % 1 >= 0.5:
  160.             return(math.floor(cislo)+1)
  161.         else:
  162.             return(math.floor(cislo))
  163.  
  164.     def runRaildriver(self):
  165.         if self.init:
  166.             self.knihovnaOK = False
  167.             try:
  168.                 self.api = RaildriverAPI(self.dllPath)
  169.             except OSError:
  170.                 input("\nNebyla nalezena potřebná knihovna!!!")
  171.             else:
  172.                 self.knihovnaOK = True
  173.  
  174.             self.valueSignalek = []
  175.             self.valueSignalekStare = []
  176.  
  177.             a = 0
  178.             while a < self.pocetSignalek:
  179.                 a = a + 1
  180.                 self.valueSignalek.append(0)
  181.                 if self.zmene:
  182.                     self.valueSignalekStare.append(0)
  183.  
  184.             if (self.knihovnaOK):
  185.                 self.api.SetRailSimConnected(True)
  186.                 self.api.SetRailDriverConnected(True)
  187.                 print("\nNačtená knihovna: %s" % self.api.rdDll)
  188.  
  189.             self.idSignalek = []
  190.  
  191.             i = 0
  192.  
  193.             while self.api.GetLocoName() == None:
  194.                 if i > 1:
  195.                     print("\nČekám na nějakou mašinku")
  196.                     i = 0
  197.                 i = i + 1
  198.                 time.sleep(1)
  199.  
  200.             self.poleZeHry = self.api.GetControllerList()
  201.             z = 0
  202.             self.CVok = True
  203.  
  204.             print("\nPřiřazuji ID k názvům CV.")
  205.            
  206.             while z < self.pocetSignalek:
  207.                 try:
  208.                     self.idSignalek.append(self.poleZeHry.index(self.NazvyCVSignalek[z]))
  209.                 except Exception:
  210.                     input("\nPro signálku s názvem %s nebylo nalezeno odpovídající ID, program se ukončí!"%(self.NazvyCVSignalek[z]))
  211.                     self.CVok = False
  212.                     break
  213.                 z = z + 1
  214.             if (self.comOK and self.knihovnaOK and self.CVok):
  215.                 if self.debug:
  216.                     print("\n"+str(self.api.GetLocoName()))
  217.                     print("\n"+str(self.api.GetControllerList()))
  218.  
  219.                 i = 0
  220.  
  221.                 print("\nPosílané ID a názvy CV jsou:")
  222.                 while i < self.pocetSignalek:
  223.                     print(str(self.idSignalek[i])+"||"+str(self.NazvyCVSignalek[i]))
  224.                     i = i + 1
  225.  
  226.                 while True:
  227.                     a = 0
  228.                     while a < self.pocetSignalek:
  229.                         self.valueSignalek[a] = self.api.GetControllerValue(int(self.idSignalek[a]),0)
  230.                         if self.zmene:
  231.                             print(self.zmene)
  232.                             if self.valueSignalek[a] != self.valueSignalekStare[a]:
  233.                                 vystup = str(self.poleSignalek[a])+str(self.zaokrouhli(int(self.valueSignalek[a]+self.poleNasobHodnot[a])))
  234.                                 if self.debug:
  235.                                     print(vystup)
  236.                                 self.ser.write(vystup.encode())
  237.                             self.valueSignalekStare = self.valueSignalek[:]
  238.                         else:
  239.                             vystup = str(self.poleSignalek[a])+str(self.zaokrouhli(int(self.valueSignalek[a]+self.poleNasobHodnot[a])))
  240.                             if self.debug:
  241.                                 print(vystup)
  242.                             self.ser.write(vystup.encode())
  243.  
  244.                         a = a + 1
  245.                     time.sleep(self.sleepTime)
  246.  
  247.     def signal_handler(self, signal, frame):
  248.         sys.exit()
  249.         self.ser.close()
  250.  
  251. class RaildriverAPI:
  252.  
  253.     def __init__(self, libpath):
  254.         self.rdDll = ctypes.CDLL(libpath)
  255.  
  256.         self.SetRailSimConnected_c = self.rdDll.SetRailSimConnected
  257.         self.SetRailSimConnected_c.restype = None
  258.         self.SetRailSimConnected_c.argtypes = [ctypes.c_bool]
  259.  
  260.         self.SetRailDriverConnected_c = self.rdDll.SetRailDriverConnected
  261.         self.SetRailDriverConnected_c.restype = None
  262.         self.SetRailDriverConnected_c.argtypes = [ctypes.c_bool]
  263.        
  264.         self.GetRailSimLocoChanged_c = self.rdDll.GetRailSimLocoChanged
  265.         self.GetRailSimLocoChanged_c.restype = ctypes.c_bool
  266.         self.GetRailSimLocoChanged_c.argtypes = None
  267.  
  268.         self.GetLocoName_c = self.rdDll.GetLocoName
  269.         self.GetLocoName_c.restype = ctypes.c_char_p
  270.         self.GetLocoName_c.argtypes = None
  271.  
  272.         self.GetControllerList_c = self.rdDll.GetControllerList
  273.         self.GetControllerList_c.restype = ctypes.c_char_p
  274.         self.GetControllerList_c.argtypes = None
  275.  
  276.         self.GetControllerValue_c = self.rdDll.GetControllerValue
  277.         self.GetControllerValue_c.restype = ctypes.c_float
  278.         self.GetControllerValue_c.argtypes = [ctypes.c_int, ctypes.c_int]
  279.  
  280.     def SetRailSimConnected(self, connected):
  281.         """connect or disconnect to the API. Must be called first with True"""
  282.         self.SetRailSimConnected_c(connected)
  283.  
  284.     def SetRailDriverConnected(self, connected):
  285.         """connect or disconnect to Raildriver."""
  286.         self.SetRailDriverConnected_c(connected)
  287.        
  288.     def GetRailSimLocoChanged(self):
  289.         """returns if Loco has changed since last call"""
  290.         return self.GetRailSimLocoChanged_c()
  291.  
  292.     def GetLocoName(self):
  293.         """returns a tuple with 3 elements of the loko name [Producer, Product,Loco Name]"""
  294.         resp = self.GetLocoName_c().decode("utf-8")
  295.         if resp: return tuple(resp.split('.:.'))
  296.         else: return None
  297.  
  298.     def GetControllerList(self):
  299.         """returns a list of all controllers of the current loco"""
  300.         ctls = self.GetControllerList_c().decode("utf-8")
  301.         if ctls: return ctls.split("::")
  302.         else: return []
  303.  
  304.     def GetControllerValue(self, vid, t):
  305.         """get the next new/changed value, where
  306.           t=0 (value), t=1 (min), t=2 (max)
  307.         """
  308.         return self.GetControllerValue_c(vid, t)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement