Pass an executable created in Python to another PC

Good morning everyone,
My name is Donato and I am a PLC programmer with zero experience with Python :py:. For a project I had to write a Python code to pass the position of a filter wheel (HID device) to a Siemens 1200 series PLC. Working on the development PC (Windows 11 x64) on PyCharm Community Edition (2023.1.4) IDE with Python interpreter 3.10.7 I wrote, tested and converted the code to.exe format using “pyinstaller --onefile”.
So far so good, but when I run the exe on the client’s PC (Windows 11 x64, IDE PyCharm Community Edition (2023.1.4), Python 3.10.7) I find the code runs fine in the IDE but the executable doesn’t work , can anyone tell me why?

I use the snap7.dll and HID libraries in the code below:

# Ruota_PY_PLC

import hid
import snap7
import struct
import logging

# Configura il logger
logging.basicConfig(filename='log.txt', level=logging.DEBUG)

plc = snap7.client.Client(lib_location="C:\SIF\Smoke_Analysis\TEMP\FilterWheel\Sorgenti\dll\snap7.dll")
plc.connect('192.168.0.1', 0, 1)
state = plc.get_cpu_state()
logging.debug(f'Stato PLC: {state}')

#vendor_id = 0x1278
#product_id = 0x0920

Device = hid.Device(vid=0x1278, pid=0x0920)

start_address = 100
length = 1

try:
    if Device:
        logging.debug("Ruota Filtri Connessa.")
    else:
        logging.warning("Ruota Filtri Disconnessa.")

    previous_data = None

    while True:
        data = Device.read(1)
        if data:
            if data[0] != previous_data:
                logging.info("Filtro Selezionato: %s", data[0])
                previous_data = data[0]

                def writeMemory(start_address, length, data):
                    try:
                        plc.mb_write(start_address, length, bytearray(struct.pack('B', data[0])))
                        logging.debug("MB100: %s", data[0])
                    except Exception as e:
                        logging.error(f"Errore durante la scrittura in memoria: {str(e)}")

                writeMemory(start_address, length, data)

except Exception as e:
    logging.error(f"Si è verificato un errore generale: {str(e)}")


finally:
    Device.close()

Thanks.

Two questions:

  • what is the error message?
  • you have mentioned running in IDE, does it mean Python is installed on the client’s machine?

Yes, I have installed the same version of Python and PyCharm on the client’s PC.
I have no error messages when using with IDE because the code works correctly and the operating data of the code are reported to me in the ‘log.txt’ file, but when I try to start ‘Ruota_PY_PLC.exe’ apparently nothing happens and not even compiled ‘log.txt’ and I can’t know what’s wrong. Is there another method to view error messages?

If Python is installed on client’s machine, then there is no point of creating an EXE. You can just run it using that Python installation :smiley:

Is there any reason you wanted to make it EXE in the first place?

1 Like

I need it because I have to call it in SCADA Movicon 11.6 which necessarily requires an EXE.
I understand this is a strange ride but that’s what I found when I started this new job :stuck_out_tongue:

Um, could You explain what it is? First time I’ve meet with this term :confused:

I think there may be a problem: if the file is in any other location, then you have got trouble.

Have you checked that file? Maybe it may sound strange, but what if you didn’t do logging at all (temporary of course :wink: )?

Well done for making considerable efforts to ensure the development env is the same as your client’s.

Double check the permissions required on the client’s machine to run an external executable (e.g. run it in as admin). Your code is trying to write to an arbitrary location in memory on the plc afterall. Windows may well not like that.

If pyinstaller is the issue, do you have access to the client’s machine? I think you have to trouble shoot it from there - either top down, turning things off gradually from where you are now until it works, or building things up from a pyinstaller Hello World example. Pyinstaller’s useful, but it’s certainly not guaranteed to successfully cross compile. What PyInstaller Does and How It Does It — PyInstaller 6.5.0 documentation

The string "C:\SIF\Smoke_Analysis\TEMP\FilterWheel\Sorgenti\dll\snap7.dll" needs to be a raw string r"C:\SIF\Smoke_Analysis\TEMP\FilterWheel\Sorgenti\dll\snap7.dll" because of the backslashes.

You’ve been lucky in that it doesn’t contain, say, \n, which would be interpreted as a linefeed (newline) character, or \t, which would be interpreted as a tab character.

I’m very glad you also think so, and are advocating for the belt and braces best practise approach, over something as easy to add as an r before a string literal.

Exactly what steps do you take to “try to start” the program? If you are double-clicking it then of course you will not see anything when a problem occurs on startup. Instead, you should use a cmd window, and check for a Python stack trace showing up there. Most likely it will give some information about some missing file or resource (which might just not be in the right place).