Tuesday, November 6, 2018

[Python 3] Install Dlib library

1. dlib
http://dlib.net/
https://pypi.org/project/dlib/

2. cmake
https://pypi.org/project/cmake/

Before installing dlib library on Windows OS, it is required to install Visual Studio for use of C++ library and CMake.

For installing CMake, pip install cmake

[Python 3] Notepad++ setting for Python

To run python code on notepad++, we need a Menu : PlugIns > NppExec > Excecute setting



After selecting Execute... (F6) on the popup menu, set up the commands as one of below.




Tuesday, October 16, 2018

[Python 3] Pyinstaller and PyQt5 : Failed to execute script 'file name'

If we have this error 'Failed to execute script' when executing an exe file, then try below and recompile it .
It is necessary to add the path of required dlls file to the system path.


1. Install Windows SDK(or visual studio 2015), and add the path to the system 'Envrionment Variables'
Windows SDK (Korean) download

For example,

     C:\Program Files (x86)\Windows Kits\10\Redist\ucrt\DLLs\x86



2. Add the path of PyQt5 bin folder to the system 'Envrionment Variables'
For example,

       C:\Program Files\Python36\Lib\site-packages\PyQt5\Qt\bin




or directly modify xxxxx.spec file which was created after compiling, and re-compile with xxxxx.spec file.


After this, compile python code with pyinstaller, and put ui file( GUI code created by PyQt5) in the same folder as exe file. 
: pyinstaller -F --noconsole 'filename.py'

[Python 3] IPG CarMaker Automation w/ Vector CANoe and Powersupply for HIL

# Main function
  • Automate IPG CarMaker execution
  • Switch on/Off powersupply output
  • Start/Stop data logging of CANoe 
  • Open/Close EyeQClient
1. GUI by PyQt5
automation.ui and TestAutomation_pyqt.py

2. GUI by tkinter
TestAutomation_sw.py


Sunday, September 9, 2018

[Python 3] CANoe via COM API

Example code


# coding: utf-8
#"""API for setup/usage of Canoe COM Client interface.
#"""
# --------------------------------------------------------------------------
# Standard library imports
import os
import sys
import subprocess
# import win32com.client
import time
import threading
from win32com.client import *
from win32com.client.connect import *



# Vector Canoe Class
class CANoe:
    def __init__(self):
        self.application = None
        # check if there is any instance of CANoe process
        # output = subprocess.check_output('tasklist', shell=True)
        # if CANoe process is still available, kill the process
        # if "CANoe32.exe" in str(output):
        #     os.system("taskkill /im CANoe32.exe /f 2>nul >nul")

        # re-dispatch object for CANoe Application
        self.application = win32com.client.DispatchEx("CANoe.Application")
        self.ver = self.application.Version
        print('Loaded CANoe version ',
            self.ver.major, '.',
            self.ver.minor, '.',
            self.ver.Build, '...')#, sep,''

        self.Measurement = self.application.Measurement.Running
        print(self.Measurement)


    def open_simulation(self, cfgname):
        # open CANoe simulation
        if (self.application != None):
            # check for valid file and it is *.cfg file
            if os.path.isfile(cfgname) and (os.path.splitext(cfgname)[1] == ".cfg"):
                self.application.Open(cfgname)
            else:
                raise RuntimeError("Can't find CANoe cfg file")
        else:
            raise RuntimeError("CANoe Application is missing,unable to open simulation")

    def close_simulation(self):
        # close CANoe simulation
        if (self.application != None):
            self.stop_Measurement()
            self.application.Quit()

        # make sure the CANoe is close properly, otherwise enforce taskkill
        output = subprocess.check_output('tasklist', shell=True)

        if "CANoe32.exe" in str(output):
            os.system("taskkill /im CANoe32.exe /f 2>nul >nul")

        self.application = None

    def start_Measurement(self):
        retry = 0
        retry_counter = 5
        # try to establish measurement within 20s timeout
        while not self.application.Measurement.Running and (retry < retry_counter):
            self.application.Measurement.Start()
            time.sleep(1)
            retry += 1
        if (retry == retry_counter):
            raise RuntimeWarning("CANoe start measuremet failed, Please Check Connection!")

    def stop_Measurement(self):
        if self.application.Measurement.Running:
            self.application.Measurement.Stop()
        else:
            pass

    def get_EnvVar(self, var):

        if (self.application != None):
            result = self.application.Environment.GetVariable(var)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def set_EnvVar(self, var, value):
        result = None

        if (self.application != None):
            # set the environment varible
            result = self.application.Environment.GetVariable(var)
            result.Value = value

            checker = self.get_EnvVar(var)
            # check the environment varible is set properly?
            while (checker != value):
                checker = self.get_EnvVar(var)
        else:
            raise RuntimeError("CANoe is not open,unable to SetVariable")

    def get_SigVal(self, channel_num, msg_name, sig_name, bus_type="CAN"):
        # """
        # @summary Get the value of a raw CAN signal on the CAN simulation bus
        # @param channel_num - Integer value to indicate from which channel we will read the signal, usually start from 1,
                             # Check with CANoe can channel setup.
        # @param msg_name - String value that indicate the message name to which the signal belong. Check DBC setup.
        # @param sig_name - String value of the signal to be read
        # @param bus_type - String value of the bus type - e.g. "CAN", "LIN" and etc.
        # @return The CAN signal value in floating point value.
                # Even if the signal is of integer type, we will still return by
                # floating point value.
        # @exception None
        # """
        if (self.application != None):
            result = self.application.GetBus(bus_type).GetSignal(channel_num, msg_name, sig_name)
            return result.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def get_SysVar(self, ns_name, sysvar_name):

        if (self.application != None):
            systemCAN = self.application.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sysvar_name)
            return sys_value.Value
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def set_SysVar(self, ns_name, sysvar_name, var):

        if (self.application != None):
            systemCAN = self.application.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables(sysvar_name)
            sys_value.Value = var
            # print(sys_value)
            # result = sys_value(sys_name)
            #
            # result = var
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

    def get_all_SysVar(self, ns_name):

        if (self.application != None):
            sysvars=[]
            systemCAN = self.application.System.Namespaces
            sys_namespace = systemCAN(ns_name)
            sys_value = sys_namespace.Variables
            for sys in sys_value:
                sysvars.append(sys.Name)
                sysvars.append(sys.Value)
            return sysvars
        else:
            raise RuntimeError("CANoe is not open,unable to GetVariable")

#On Event Thread
class Event_Job(threading.Thread):

    def __init__(self, name,var,event):#*args, **kwargs
        super(Event_Job, self).__init__()#*args, **kwargs
        self.__flag = threading.Event()     #
        self.__flag.set()       # 设置为True
        self.__running = threading.Event()      #
        self.__running.set()      #

        self.name = name
        self.var = var
        self.event = event

    def run(self):
        pythoncom.CoInitialize()
        self.app = DispatchEx('CANoe.Application')
        self.systemCAN = self.app.System.Namespaces
        self.sys_namespace = self.systemCAN(self.name)
        self.sys_value = self.sys_namespace.Variables
        self.result = self.sys_value(self.var)
        WithEvents(self.result, self.event)

        while self.__running.isSet():
            self.__flag.wait()      #
            # self.func(self.txt)
            # print time.time()
            # pythoncom.CoInitialize()
            pythoncom.PumpWaitingMessages()
            time.sleep(0.01)
            # pythoncom.CoUninitialize()

    def pause(self):
        self.__flag.clear()     #

    def resume(self):
        self.__flag.set()    #

    def stop(self):
        self.__flag.set()       #
        self.__running.clear()        #
        pythoncom.CoUninitialize()

class MFL_volplus_Events(object):
    def __init__(self):
        pass

    #"""Handler for CANoe var events"""
    def OnChange(self,value):
        # self.Changed = True
        print("< MFL_volplus_Events var change>")
        # print(self.Name)
        print(value)

class MFL_volminus_Events(object):
    def __init__(self):
        pass

    #"""Handler for CANoe var events"""
    def OnChange(self,value):
        # self.Changed = True
        print("< MFL_volminus_Events var change>")
        # print(self.Name)
        print(value)


if __name__ == '__main__':
os.chdir("C:\Program Files\Vector CANoe 10.0\Exec64")
os.popen("canoe64 -regserver").readlines()

app = CANoe()
time.sleep(5)
app.start_Measurement()


# #Regserver COM API
# os.chdir("C:\Program Files (x86)\Vector CANoe 9.0\Exec32")
# os.popen("canoe32 -regserver").readlines()
# #or
# os.chdir("C:\Program Files\Vector CANoe 10.0\Exec64")
# os.popen("canoe64 -regserver").readlines()

# app = CANoe()
# time.sleep(5111)
# app.start_Measurement()
# time.sleep(5)
# app.stop_Measurement()
# time.sleep(1111)
# varnames = app.get_all_SysVar("mfl")
#
# time.sleep(1)
# vol_plus = Event_Job("mfl","vol_plus",MFL_volplus_Events)
# vol_plus.start()
#
# vol_minus = Event_Job("mfl","vol_minus",MFL_volminus_Events)
# vol_minus.start()
#
# time.sleep(31)
# app.set_SysVar("mfl","vol_plus",1)
#
# print(app.get_SysVar("mfl","vol_plus"))
#
# vol_plus.stop()
# vol_minus.stop()


Python code download

[Python 3] PyQt5 and Qt Designer

1. Install PyQt
  >> pip install PyQt5

2. Install Qt Designer
  >> pip install PyQt5-tools
 : It is very similar with Matlab GUIDE.
   - Drag and drop components on a layout
   - Modify the attribute of each component
   - Add a function to a corresponding component name

3. Convert *.ui (Qt Designer code) to *.py(Python code)
  >> pyuic5 filename.ui > filename.py -x
   or pyuic5 filename.ui -o filename.py -x
 where, with -x
if __name__ = "__main__"
are included.

Without converting ui to py, ui can be directly loaded to python code as below.

     form_class = uic.loadUiType("automation.ui")[0]



Sunday, July 8, 2018

[Python 3] Licensing : Mac address, Current date, and Change in system date


import re, uuid, datetime

class cm_license():
    def __init__(self,master):
  self.master = master

# Mac address
    def macAddress():
  ma = uuid.getnode()
temp_mac = re.findall('..','%012x' % uuid.getnode())
mac = ':'.join(temp_mac)
return mac
# Check the expiry date of the license
  def checkDate():
edate = datetime.date(2018,12,30)
current = datetime.datetime.now()
cdate = datetime.date(current.year, current.month, current.day)
date_diff = edate > cdate
return date_diff


if __name__ == '__main__':
# License
license_address = '00:e1:8c:eb:87:04' # Specifiy the mac address of pc
mac_name = cm_license.macAddress()
check_date = cm_license.checkDate()
# Run the code
if (mac_name == license_address) and (check_date == True):
main()
else:
messagebox.showinfo('License','Wrong physical address')



Thursday, July 5, 2018

[Python 3] Power supply control (KIKUSUI, Regulated DC Power Supply, PMX35-3A) via USB

1. Python library used
 1) pyvisa
    Frontend library
 2) pyvisa-py
    : Compatible library able to be used instead of the proprietary library NI-VISA
     Backend library
 3) pyusb (or libsub1)
   If you cannot detect usb drive with pyusb, then install the dependencies " libusb1 "
   - pip install pyusb for pyusb,
   - pip install libusb1 for libusb1
   : I did it after installing 'libusb1'
 4)  pyserial
 
For access to USB, both pyusb and pyserial are necessary to be installed.

2. KI-VISA ( for USB driver)
 It is compliant with IVI VISA specification 5.0, and the device driver for usb compatible products is installed automatically.
 After installing this, I had a power supply with python.

 file name : kivisa_5_5_0_275(x64).exe

3. Python 3 code

import visa

rm = visa.ResourceManager()
sl = rm.list_resources()
print(sl)

inst = rm.open_resource(sl[0]) # sl[0] is KIKUSUI power supply
# To automatically find a instrument
# serialno = '0x5555555'
# for sn in sl:
#     i = sn.find(serialno)
#     if i == 0:
#        inst = rm.open_resource(i)
inst.query('*IDN?')
inst.write('*IDN?')

# Preset, can avoid the initial error when connected to power supply 
inst.write("rst; status:preset; *cls")

# inst.write('SOUR:POW:MODE ON')

# inst.write("INST P6V") # Select +6V output
inst.write('VOLT 6.0') # Set output voltage to 6.0 V
inst.write('CURR 1.0') # Set output current to 1.0 A

# Most straightforward method
# to program the power supply over the remote interface
#  inst.write("APPL P6V, 6.0, 1.0")

# Output on/off
inst.write("OUTP OFF")
inst.write("OUTP ON")


Wednesday, July 4, 2018

[Python 3] String and Unicode

If any kind of text string is to be sent across the network, it needs to be encoded. This is why the server is using the " encode('ascii') " method on the data it transmits. Likewise, when a client receives network data, that data is first received as raw unencoded bytes. If you print it out or try to process it as text, we're unlikely to get what we expect. Instead, we need to decode it first. This is why the client code is using " decode('ascii') " on the result.

[Python 3] Python version management with virtual environment

1. virtualenv (On windows)
  • Install
    : pip install virtualenv
  • Create a folder
    : virtualenv venv
  • Activate a virtualenv
    : .\venv\Scripts\activate
  • Deactivate
    : Deactivate
  • Previous version
    : virtualenv venv --python=python3.5

2. pyvenv (manage multiple python 3.3 or later version)

3. autoenv
 automatically execute virtual environment

[Python 3] Python library

# In order to install python libraries, type
>> pip install

# Check the libraries installed
>> pip freeze

# Get the dependency libraries installed
>> pip freeze > reg.txt
# Install the same dependency libraries
>> pip install -r reg.txt

[Data science]
1. matplotlib
2. numpy
3. pandas
4. scipy

[Machine learning]
1. scikit-learn (pip install sklearn)

[Excel]
1. openpyxl
2. xlrd
3. xlwt
4. xlsxwriter

[Image processing]
1. OpenCV
2. OpenCV-contrib
3. Pillow
4. dlib (w/ cmake)

[CAN]
1. python-can : pip install python-can

[Database]
1. SQLite (default)

[GUI]
https://insights.dice.com/2017/08/07/7-top-python-gui-frameworks-for-2017-2/
1. tkinter (default)
2. wxpython (wxGlase, wxformbuilder)
3. PyQt : free license for not commercial use (w/ Qt designer)

[Standalone application]
1. Pyinstaller (recommend)
2. cx_Freeze
3. py2exe (for python 2.x)

[Python 3] Create CarMaker TestRun files with tkinter GUI

We can automate creating TestRun files of CarMaker.

GUI tool looks like below.



We need two files; one is an Excel where parameters are specified, and the other is a TestRun template file.

1. Read all parameters specified in Excel sheet
2. Find the same parameters in TestRun template file
3. Change values in TestRun template file into new values specified in Excel sheet
4. Create a new TestRun file
5. Repeat 1-4

carmaker_testrun

[Python 3] Using Pandas with Pyinstaller

When compiling python code including pandas library, if we have errors on pandas library,
we should do the following:

1. Go to the directory below
  c:/~/Python3.6/Lib/site-package/PyInstaller/hooks

2. Make a file named 'hook-pandas.py' in case that there is no such file.
  The contents should be as below.

 hiddenimports = ['pandas._libs.tslibs.timedeltas',
                             'pandas._libs.tslibs.nattype',
                             'pandas._libs.tslibs.np_datetime',
                             'pandas._libs.skiplist']

3. Then, type the following command on the cmd to make a standalone application
  > pyinstaller -F --noconsole [filename]