<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"><channel><title>Ticket search results</title><link>https://forge.codesys.com/tol/scripting/snippets/</link><description>You searched for status:Unlicense</description><language>en</language><lastBuildDate>Wed, 09 Aug 2023 17:04:52 -0000</lastBuildDate><item><title>CreateProperties from variable declaration in FB</title><link>https://forge.codesys.com/tol/scripting/snippets/23/</link><description>See original posting at: https://forge.codesys.com/forge/talk/Engineering/thread/678b24f53f/#d16e
By CODESYS and Ben Newman


def CreateAllProperties(fbname):
    # get current project
    project = projects.primary 
    # find the function block
    fb = project.find(fbname, True)[0]

    # get the declaration text
    declaration = fb.textual_declaration
    # iterate all lines in the declaration
    for i in range(declaration.linecount):
        line = declaration.get_line(i)  # get this declaration line
        stripped = line.strip() # strip out white space in this line
        endofline = stripped.find(";")
        stripped = stripped[0:endofline] # discards anything past the ";" (comments, etc)
        if stripped.startswith("_"):
            var = stripped.split(":")   #NOTE: this also removes initial value declarations, or puts them into the [2] index of var, which we can discard
            membername = var[0].strip(" ")
            propname = membername.lstrip("_");
            proptype = var[1].strip(" ");
            print("Creating property \"" + propname + "\" with type " + proptype)
            fb.create_property(propname, return_type=proptype, language=None)
            print("property " + propname + " with type " + proptype + "was created!")

            newprop = fb.find(propname)[0]
            getter = newprop.find("Get")[0]
            setter = newprop.find("Set")[0]            
            #newprop.textual_declaration.insert(0,0,"{attribute 'monitoring':='call'}\r\n")
            print("Inserting to getter")
            getter.textual_implementation.replace(propname + ":= " + membername + ";")
            print("Inserting to setter")
            setter.textual_implementation.replace(membername + ":= " + propname + ";")

CreateAllProperties("*NameOfFunctionBlock*")</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">hermsen</dc:creator><pubDate>Wed, 09 Aug 2023 17:04:52 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/23/</guid></item><item><title>Print all libraries and their dependencies</title><link>https://forge.codesys.com/tol/scripting/snippets/22/</link><description>~~~Python
# search for libman object
proj = projects.primary
objects = proj.get_children(recursive=True)
for object in objects:
    if object.is_libman:
        #and print all its libraries
        for libref in iter(object):
            if libref.is_placeholder and isinstance(libref.effective_resolution,str):
                print(libref.name + " " + libref.effective_resolution)
            else:
                print(libref.name)
            #and print all its libraries' dependencies
            dependencies = libref.get_dependencies()
            for dependency in dependencies:
                if dependency.is_placeholder and isinstance(dependency.effective_resolution,str):
                    print("+" + dependency.name + " " + dependency.effective_resolution)
                else:
                    print("+" + dependency.name) 
~~~
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">i-campbell</dc:creator><pubDate>Tue, 17 May 2022 12:23:49 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/22/</guid></item><item><title>update project information</title><link>https://forge.codesys.com/tol/scripting/snippets/21/</link><description>~~~
proj = projects.load("D:\Some.library")

project_info = proj.get_project_info()

# Set some values
project_info.company = "Test Library Ltd"
project_info.title = "Script Test Project"
project_info.version = (0, 8, 15, 4711)
project_info.default_namespace = "testlibrary"
project_info.author = "Python von Scriptinger"

# some values recommended in the library toolchain
project_info.values["DefaultNamespace"] = "testlibrary"
project_info.values["Placeholder"] = "testlibrary"
project_info.values["DocFormat"] = "reStructuredText"

# now we set a custom / vendor specific value.
project_info.values["SpecialDeviceId"] = "PLC0815_4711"

# Enable generation of Accessor functions, so the IEC
# application can display the version in an info screen.
project_info.change_accessor_generation(True)

# And set the library to released
project_info.released = False;

proj.save()
~~~
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">aliazzz</dc:creator><pubDate>Fri, 30 Jun 2023 09:59:53 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/21/</guid></item><item><title>Update Device</title><link>https://forge.codesys.com/tol/scripting/snippets/20/</link><description>To be able to compile a project, you usually need to update the devices in the device tree to match your currently installed versions. The following python script should do exactly this in an automated way for all devices, which it finds:

~~~
#
# update all devices in project
#
def update_device(proj):
    print("*** update device")
    
    # search for devices to update
    objects = proj.get_children(recursive=True)
    for object in objects:
        if object.is_device:
            print("*** found device")
            DeviceId = object.get_device_identification()
            devices = device_repository.get_all_devices()
            for device in devices:
                if device.device_id.type == DeviceId.type and device.device_id.id == DeviceId.id:
                    deviceToUpdate = device
            if deviceToUpdate != None:
                print ("*** found device to update %s" % deviceToUpdate.device_id)
                object.update(device=deviceToUpdate.device_id)



~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Mon, 21 Sep 2020 21:09:55 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/20/</guid></item><item><title>Install missing libraries</title><link>https://forge.codesys.com/tol/scripting/snippets/19/</link><description>Thanks @jelle for the ideas I got from snippet [#18]. But as the snippet from @jelle was not complete, yet, a lot of transfer knowledge was necessary to use it. So after I implemented it by myself, I thought, that I should add my version here also.

It acts on the primary project. So you should open the project before calling this function.
And it uses WebClient from DotNet, because the "request" module, which was referenced in [#18] was not available.

~~~
import os, re
from System.Net import WebClient


#
# Install a library from a URL (starting with http(s))
#
def install_library(url, librarymanager):
    if not url.startswith("http"):
        return
    
    downloaddir = os.path.join(os.environ["USERPROFILE"], "downloads")
    if not os.path.exists(downloaddir):
        os.makedirs(downloaddir)
    basename, extension = os.path.splitext(url)
    localname = os.path.join(downloaddir, "dl" + extension)
    print("*** download %s to %s\n" % (url, localname))

    web_client = WebClient()
    web_client.DownloadFile(url, localname)
    repo = librarymanager.repositories[0]
    print("*** installing %s\n" % url)
    librarymanager.install_library (localname, repo, True)

#
# search for missing libraries in current primary project
#
def install_missing_libraries(librarymanager):
    proj = projects.primary
    # compile a regular expression to match lib placeholders
    p = re.compile('[^,]+, [^(]+\([^)]+\)')
    
    # search for libman
    objects = proj.get_children(recursive=True)
    for object in objects:
        if object.is_libman:
            for libref in iter(object):
                if libref.is_placeholder:
                    if libref.effective_resolution is None and libref.default_resolution is not None:
                        libInfo = str(libref.default_resolution)
                        m = re.findall('([^,]+), ([^(]+) \(([^)]+)\)', libInfo)
                        if len(m) &gt; 0:
                            libname, libversion, libvendor = m[0]
                            indexurl = "https://store.codesys.com/CODESYSLibs/%s/%s/%s/index" % (libvendor, libname, libversion)
                            web_client = WebClient()
                            try:
                                filename = web_client.DownloadString(indexurl).rstrip()
                            except:
                                filename = None

                            if filename != None:
                                liburl = "https://store.codesys.com/CODESYSLibs/%s/%s/%s/%s" % (libvendor, libname, libversion, filename)
                                install_library(liburl, librarymanager)

~~~

The function can be called like this:

~~~
install_missing_libraries(librarymanager)
~~~

The variable "librarymanager" is implicitly available in python scripts, running in CODESYS.</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sun, 20 Sep 2020 19:27:40 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/19/</guid></item><item><title>Installation of missing libraries</title><link>https://forge.codesys.com/tol/scripting/snippets/18/</link><description>Script that lists all the library dependencies:
~~~
proj = projects.open(projectPath)
objects = proj.get_children(recursive=True)
    for candidate in objects:
        if candidate.is_libman:
            for libref in iter(candidate):
                if libref.is_placeholder:
                    if libref.effective_resolution is not None:
                        libInfo = str(libref.effective_resolution)
                        libMissing = False
                    elif libref.default_resolution is not None:
                        libInfo = str(libref.default_resolution)
                        libMissing = True
                elif libref.is_managed:   
                    libInfo = str(libref.managed_library)
                else:               
                    libInfo = str(libref.name)   
~~~
         
Script that downloads the libraries:
~~~
libraryServers  = ["https://store.codesys.com/CODESYSLibs/"]
            for server in libraryServers:
                libraryFileName = None
                url = str("%s%s/%s/%s/" % (server, data['supplier'], data['name'], data['version']))
                response = requests.get(url + "index")
            fileUrl = str("%s%s" % (url, libraryFileName)).rstrip()
            response = requests.get(fileUrl)
            f.write(response.content)
~~~

Script that installs the downloaded libraries:
~~~
repo = librarymanager.repositories[0]
librarymanager.install_library(absLibPath, repo, overwrite=True)
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">jelle</dc:creator><pubDate>Tue, 14 Jul 2020 11:16:24 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/18/</guid></item><item><title>Handle Answers of Dialogs</title><link>https://forge.codesys.com/tol/scripting/snippets/17/</link><description>Log Message Keys:
~~~
system.prompt_handling |= PromptHandling.LogMessageKeys
~~~

Define Reaction for specific messages:
~~~
system.prompt_answers["EnterDebugMode_Prompt"]=PromptResult.OK
~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Tue, 21 Apr 2020 07:31:44 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/17/</guid></item><item><title>Disable System Prompts and Dialogs</title><link>https://forge.codesys.com/tol/scripting/snippets/16/</link><description>Disable prompts, as those are enabled in UI mode by default:
~~~
system.prompt_handling = PromptHandling.None
~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Tue, 21 Apr 2020 07:28:02 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/16/</guid></item><item><title>Searching for an object example</title><link>https://forge.codesys.com/tol/scripting/snippets/15/</link><description>~~~
# Search recursivly for 'TheObjectIWantToSearchFor'
Recursive = True
result_list = projects.primary.find('TheObjectIWantToSearchFor', Recursive)
 
for result in result_list:
    print("Object " + result.get_name() + " found with Guid " + str(result.guid))
~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">aliazzz</dc:creator><pubDate>Mon, 24 Feb 2020 20:59:08 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/15/</guid></item><item><title>Login and monitor variable</title><link>https://forge.codesys.com/tol/scripting/snippets/14/</link><description>~~~python
# login
    onlineapp = online.create_online_application(app)
    try:
        onlineapp.login(OnlineChangeOption.Try, True)
    except:
        print("Error: compile error")
        return False

    # run program
    onlineapp.start()

    # wait until project finishes
    for timeout in range(10):
        system.delay(1000)
        xready = onlineapp.read_value("PRG_RUNTEST.xReady")
        if str(xready) == "TRUE":
            break
    # check for error
    xerror = onlineapp.read_value("PRG_RUNTEST.xError")
~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 16:04:51 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/14/</guid></item><item><title>Add device to project</title><link>https://forge.codesys.com/tol/scripting/snippets/13/</link><description>~~~python
devId = None
    devices = device_repository.get_all_devices("CODESYS Control Win V3")
    for device in devices:
        devId = device.device_id
    proj = projects.primary
    
    # delete existing testdev device
    existing = proj.find('testdev')
    if len(existing) &gt; 0:
        existing[0].remove()
        
    # add device
    proj.add('testdev', devId)
    apps = proj.find('Application', True)
    if len(apps) &gt; 0:
        app = apps[0]
        tc = app.create_task_configuration()
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 16:01:54 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/13/</guid></item><item><title>Switch device to simulation mode</title><link>https://forge.codesys.com/tol/scripting/snippets/12/</link><description>~~~python
# set device to simulation mode
    devs = proj.find('testdev')
    if len(devs) &gt; 0:
        devs[0].set_simulation_mode(True)
~~~
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Tue, 28 Dec 2021 23:37:48 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/12/</guid></item><item><title>Check compile errors of libraries</title><link>https://forge.codesys.com/tol/scripting/snippets/11/</link><description>~~~python
CompileCategory = Guid("{97F48D64-A2A3-4856-B640-75C046E37EA9}")

# Clear messages from Build category
system.clear_messages(CompileCategory)

projects.primary.check_all_pool_objects()

# Get message objects which contain all the data
severities = {
   Severity.FatalError : "Fatal error", Severity.Error : "Error",
   Severity.Warning : "Warning", Severity.Information : "Information",
   Severity.Text : "Text"
   }

msgs = system.get_message_objects(CompileCategory, Severity.FatalError|Severity.Error)
for msg in msgs:
   sev = severities[msg.severity]
   print("{} {}{}: {}".format(sev, msg.prefix, msg.number, msg.text)
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/11/</guid></item><item><title>Add Device with Task Configuration</title><link>https://forge.codesys.com/tol/scripting/snippets/10/</link><description>~~~python
# add device
proj.add('PLC', devId)
apps = proj.find('Application', True)
if len(apps) &gt; 0:
    tc = apps[0].create_task_configuration()

# add task
task = tc.create_task('Task')
task.pous.add('PLC_PRG')
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/10/</guid></item><item><title>SVN update</title><link>https://forge.codesys.com/tol/scripting/snippets/9/</link><description>~~~python
def set_username(req):
    req.username = username
    req.password = password
    req.save = True # Optional

svn.auth_username_password += set_username
svn.update()
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/9/</guid></item><item><title>SVN commit</title><link>https://forge.codesys.com/tol/scripting/snippets/8/</link><description>~~~python
def set_username(req):
    req.username = username
    req.password = password
    req.save = True # Optional

svn.auth_username_password += set_username
svn.commit(message)
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/8/</guid></item><item><title>SVN checkout</title><link>https://forge.codesys.com/tol/scripting/snippets/7/</link><description>~~~python
def set_username(req):
    req.username = username
    req.password = password
    req.save = True # Optional

svn.auth_username_password += set_username
svn.checkout(url, dir, filename)
proj = projects.primary
proj.save_as(filename)
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/7/</guid></item><item><title>Modify Properties / Compiler defines</title><link>https://forge.codesys.com/tol/scripting/snippets/6/</link><description>~~~python
# Find Object VICTIM in projecttree
victim = projects.primary.find("VICTIM", True)[0]
props = victim.build_properties

props.external = not props.external
props.enable_system_call = not props.enable_system_call
props.link_always = not props.link_always
props.exclude_from_build = not props.exclude_from_build
if ";FOOBAR" in props.compiler_defines:
        props.compiler_defines = props.compiler_defines.replace(";FOOBAR","")
else:
        props.compiler_defines = props.compiler_defines + ";FOOBAR"
~~~
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/6/</guid></item><item><title>Export as PLCOpen XML</title><link>https://forge.codesys.com/tol/scripting/snippets/5/</link><description>~~~python
class ER(ExportReporter):
    def error(self, object, message):   
        system.write_message(Severity.Error, "Error exporting %s: %s" % (object, message))
    def warning(self, object, message):   
        system.write_message(Severity.Warning, "Warning exporting %s: %s" % (object, message))
    def nonexportable(self, object):   
        system.write_message(Severity.Information, "Object not exportable: %s" % object)
    @property
    def aborting(self):
        return False;

reporter = ER()
proj = projects.open(filename)
proj.export_xml(reporter, proj.get_children(False), tempname, recursive = True)
proj.close()
~~~

</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/5/</guid></item><item><title>Create an FB</title><link>https://forge.codesys.com/tol/scripting/snippets/3/</link><description>**Only Structured Text can be edited directly! **
For the graphical languages you have to import the POU from PLCopenXML or the codesys native format. 
See `IScriptTextualObjectMarker`, `IScriptObjectWithTextualDeclaration`, `IScriptObjectWithTextualImplementation` and `IScriptTextDocument` for the textual language and the methods `importxml()` and `importnative()` from `IScriptObject2` and `IScriptProject2` for the import.  Find the Scripting object, for example `withfind()`, and use the method `remove()` to delete an object.

~~~python
proj = projects.primary

found = proj.find("Application", True)
app = found[0]

# Create FB
mypou = app.create_pou("MyPou")

# Change declaration of the FB
implementation = mypou.textual_declaration.replace("""FUNCTION_BLOCK MyPou
VAR_INPUT
   iValue : INT;
END_VAR
VAR_OUTPUT
END_VAR
VAR
END_VAR""")

# Change implementation of the FB
mypou.textual_implementation.replace("""iValue := iValue + 1;""")

# Add method to FB
dosomething = mypou.create_method("DoSomething", "INT")

# Change declaration of the method
dosomething.textual_declaration.replace("""METHOD DoSomething : INT
VAR_INPUT
   iVal1 : INT;
   iVal2 : INT;
END_VAR""")

# Change implementation of the method
dosomething.textual_implementation.replace("""DoSomething := iVal1 + iVal2;""")

# Find the pou and delete it
found = app.find("MyPou")
if found and len(found) == 1:
   found[0].remove()
else:
   print("POU 'MyPou' was not found")
~~~
</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/3/</guid></item><item><title>Open and close a project</title><link>https://forge.codesys.com/tol/scripting/snippets/1/</link><description>~~~python
proj = projects.open(filepath)
...
Proj.close()
~~~</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Ingo</dc:creator><pubDate>Sat, 08 Feb 2020 02:18:39 -0000</pubDate><guid isPermaLink="false">https://forge.codesys.com/tol/scripting/snippets/1/</guid></item></channel></rss>