Advertisement
JachyHm

Railworks to COM

Sep 29th, 2017
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.71 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:
  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.                         )
  76.  
  77.     def start(self,dllPathVar,sleepTimeVar,comPort,comBaud,comParita,debugVar):
  78.        
  79.         print("\n\nSTART APLIKACE...")
  80.  
  81.         self.sleepTime = sleepTimeVar
  82.         self.dllPath = dllPathVar
  83.         self.poleSignalek = []
  84.         self.pocetSignalek = 0
  85.         self.debug = debugVar
  86.  
  87.         print("\nNacitam nazvy kontrolek z konfiguracniho souboru.")
  88.  
  89.         for JmenoSignalky in self.konf.config['POSILEJ']:
  90.             self.pocetSignalek = self.pocetSignalek + 1
  91.             self.poleSignalek.append(JmenoSignalky)
  92.  
  93.         print("\nNacteno %d signalek z konfiguracniho souboru."%(self.pocetSignalek))
  94.         print("\nPrirazuji ID k nazvum kontrolek.")
  95.  
  96.         i = 0
  97.         self.idSignalek = []
  98.  
  99.         while i < self.pocetSignalek:
  100.             self.idSignalek.append(self.konf.config['POSILEJ'][self.poleSignalek[i]])
  101.             i = i + 1
  102.  
  103.         print("\nPrirazeno %d ID signalek."%i)
  104.  
  105.         if self.pocetSignalek == i:
  106.             print("\nPocet pojmenovanych signalek je stejny jako prirazenych ID.")
  107.         else:
  108.             print("\nPocet pojmenovanych signalek neni stejny jako prirazenych ID!!!\nKriticka chyba pri cteni souboru! Zkontroluj soubor!")
  109.  
  110.         i = 0
  111.  
  112.         print("\nNazvy signalek a ID jsou:")
  113.         while i < self.pocetSignalek:
  114.             print(str(self.poleSignalek[i])+"||"+str(self.idSignalek[i]))
  115.             i = i + 1
  116.         print("\nInicializuji aplikaci!")
  117.        
  118.         paritaDict = {'suda':'E', 'licha':'O', 'zadna':'N'}
  119.  
  120.         self.ser = serial.Serial()
  121.         self.ser.port = comPort
  122.         self.ser.baudrate = comBaud
  123.         self.ser.parity = paritaDict[comParita]
  124.         self.ser.rtscts = False
  125.         self.comOK = False
  126.  
  127.         try:
  128.             self.ser.open()
  129.         except Exception as e:
  130.             if str(e).find("FileNotFoundError") != -1:
  131.                 input("\nNepovedlo se otevřít port %s, protože takový port nebyl v počítači nalezen! Nelze pokračovat!"%(comPort))
  132.             elif str(e).find("PermissionError") != -1:
  133.                 input("\nNepovedlo se otevřít port %s, přístup zamítnut! Nelze pokračovat!"%(comPort))
  134.             else:
  135.                 input("\nNepovedlo se otevřít port %s, z neznámého důvodu! Nelze pokračovat!\nChyba: %s"%(comPort,e))
  136.         else:
  137.             print("\nPort %s úspěšně otevřen."%(self.ser.name))
  138.             self.comOK = True
  139.  
  140.         signal.signal(signal.SIGINT, self.signal_handler)
  141.  
  142.     def zaokrouhli(self,cislo):
  143.         if cislo % 1 >= 0.5:
  144.             return(math.floor(cislo)+1)
  145.         else:
  146.             return(math.floor(cislo))
  147.  
  148.     def runRaildriver(self):
  149.         if self.init:
  150.             self.knihovnaOK = False
  151.             try:
  152.                 self.api = RaildriverAPI(self.dllPath)
  153.             except OSError:
  154.                 input("\nNebyla nalezena potřebná knihovna!!!")
  155.             else:
  156.                 self.knihovnaOK = True
  157.  
  158.             self.valueSignalek = []
  159.             self.valueSignalekStare = []
  160.  
  161.             a = 0
  162.             while a < self.pocetSignalek:
  163.                 a = a + 1
  164.                 self.valueSignalek.append(0)
  165.                 self.valueSignalekStare.append(0)
  166.             if self.knihovnaOK:
  167.                 self.api.SetRailSimConnected(True)
  168.                 self.api.SetRailDriverConnected(True)
  169.                 print("\nNačtená knihovna: %s" % self.api.rdDll)
  170.                 print(self.api.GetLocoName())
  171.                 print(self.api.GetControllerList())
  172.  
  173.             while (self.comOK and self.knihovnaOK):
  174.                 a = 0
  175.                 while a < self.pocetSignalek:
  176.                     self.valueSignalek[a] = self.api.GetControllerValue(int(self.idSignalek[a]),0)
  177.                     #if self.valueSignalek[a] != self.valueSignalekStare[a]:
  178.                     vystup = str(self.poleSignalek[a])+str(self.zaokrouhli(int(self.valueSignalek[a])))
  179.                     if self.debug:
  180.                         print(vystup)
  181.                     self.ser.write(vystup.encode())
  182.                     a = a + 1
  183.                 #self.valueSignalekStare = self.valueSignalek[:]
  184.                 time.sleep(self.sleepTime)
  185.  
  186.     def signal_handler(self, signal, frame):
  187.         sys.exit()
  188.         self.ser.close()
  189.  
  190. class RaildriverAPI:
  191.  
  192.     def __init__(self, libpath):
  193.         self.rdDll = ctypes.CDLL(libpath)
  194.  
  195.         self.SetRailSimConnected_c = self.rdDll.SetRailSimConnected
  196.         self.SetRailSimConnected_c.restype = None
  197.         self.SetRailSimConnected_c.argtypes = [ctypes.c_bool]
  198.  
  199.         self.SetRailDriverConnected_c = self.rdDll.SetRailDriverConnected
  200.         self.SetRailDriverConnected_c.restype = None
  201.         self.SetRailDriverConnected_c.argtypes = [ctypes.c_bool]
  202.        
  203.         self.GetRailSimLocoChanged_c = self.rdDll.GetRailSimLocoChanged
  204.         self.GetRailSimLocoChanged_c.restype = ctypes.c_bool
  205.         self.GetRailSimLocoChanged_c.argtypes = None
  206.  
  207.         self.GetLocoName_c = self.rdDll.GetLocoName
  208.         self.GetLocoName_c.restype = ctypes.c_char_p
  209.         self.GetLocoName_c.argtypes = None
  210.  
  211.         self.GetControllerList_c = self.rdDll.GetControllerList
  212.         self.GetControllerList_c.restype = ctypes.c_char_p
  213.         self.GetControllerList_c.argtypes = None
  214.  
  215.         self.GetControllerValue_c = self.rdDll.GetControllerValue
  216.         self.GetControllerValue_c.restype = ctypes.c_float
  217.         self.GetControllerValue_c.argtypes = [ctypes.c_int, ctypes.c_int]
  218.  
  219.     def SetRailSimConnected(self, connected):
  220.         """connect or disconnect to the API. Must be called first with True"""
  221.         self.SetRailSimConnected_c(connected)
  222.  
  223.     def SetRailDriverConnected(self, connected):
  224.         """connect or disconnect to Raildriver."""
  225.         self.SetRailDriverConnected_c(connected)
  226.        
  227.     def GetRailSimLocoChanged(self):
  228.         """returns if Loco has changed since last call"""
  229.         return self.GetRailSimLocoChanged_c()
  230.  
  231.     def GetLocoName(self):
  232.         """returns a tuple with 3 elements of the loko name [Producer, Product,Loco Name]"""
  233.         resp = self.GetLocoName_c().decode("utf-8")
  234.         if resp: return tuple(resp.split('.:.'))
  235.         else: return None
  236.  
  237.     def GetControllerList(self):
  238.         """returns a list of all controllers of the current loco"""
  239.         ctls = self.GetControllerList_c().decode("utf-8")
  240.         if ctls: return ctls.split("::")
  241.         else: return []
  242.  
  243.     def GetControllerValue(self, vid, t):
  244.         """get the next new/changed value, where
  245.           t=0 (value), t=1 (min), t=2 (max)
  246.         """
  247.         return self.GetControllerValue_c(vid, t)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement