CodeSys#RunTime中にPython Scriptを実行する

今回はCodeSysをインストールしたPi4のRunTimeでPython Scriptを実行する方法を書きたいと思います。

ライブラリインストール

Python ScriptをPi4で自動実行するにはシステムのライブラリをインストール必要があります。
https://help.codesys.com/webapp/idx-SysProcess%20Implementation-lib;product=SysProcess%20Implementation;version=3.5.16.0

SysFile

Fileを処理するライブラリ

SysTypes

File、コマンド実行するときに使われてる構造体

SysProcess

コマンド実行するライブラリ

チエック

ではCodeSysの中にそれらのライブラリがあるかどうかをCheckします。
Library Repositoryクリックし、Findを押します。
SearchのところにSysFileを入力します。もしあったらすでにインストールされている状態。
image.png

Openを押すと“Installed libraries”がの中にSysFileとそのバージョンも表示されています。
image.png

Import

インストールされたこと確認したら、次は自分のプロジェクトの中にImportすればOKです。Library Manager>Add Libraryをクリクします。
image.png
Advanced..をクリクします。
image.png
Add LibraryのPopupが出てきます。
Sysfileを入力し、SysFile,3.5.15.0を選んで、OKします。
image.png

そうすると、自分のプロジェクトにはこのライブラリを使えるようになります。
image.png
同じようにSysProcessを入れます。
image.png
SysTypesも。
image.png
たまにCodeSys再起動するとProject Environmentは最新じゃありませんよ~というメッセージが出てきますが、“Set All to Newest”でよいと思います。
image.png

External file

Python Scriptを追加するには“External file”というObjectを使うことになります。
Online Helpはこちらです:
https://help.codesys.com/webapp/_cds_obj_external_file;product=codesys;version=3.5.16.0

An External File is any file that you add to the project in the POUs view or Devices view. Click Project ‣ Add Object to open the Add External File dialog and define how the file belongs to the project.
An external file which was inserted in the POUs view is never downloaded to the controller.
An external file which was added in the Devices view is always downloaded to the controller when an online change or a download is performed due to an IEC code change.
When an external file is downloaded to the controller, it is not updated in the project

External FileはあなたがPOUs ViewかDevices Viewに任意のFileを追加するできるObjectです。Project>Add ObjectするとExternal fileのPop-upが出て、その中にFileがどこのものなのかを定義します。

  • もしExternal FileはPOUsの中に追加された場合は、Controllerにダウンロードさせません。
  • もしExternal FileはDevicesの中に追加された場合、Online Change・IEC code ChangeするとそのFileがControllerにダウンロードされます。

そしてExternal FileがControllerにダウンロードされても、ProjectにUpdateされることがありません。

Python Scriptを追加する

Add Object>External Fileをクリクします。
image.png

ここでFile Path・Nameを定義します。設定終わったら“Add”。
image.png

Edit Objectで先設定したFile Handling・更新タイミングなどもやり直しすることができます。
image.png

LoginしExternal Fileをダウンロードします。
一応ちゃんとControllerの中に入ってるかどうかを確認しましょう。
Deviceのところをダブルクリック。
Fileの先にクリック。
PathがPlcLogic/Applicationです。
うん、Hello.pyが入っていますね。

image.png

Script

単なる現在時間とってそのままLoggingするだけです。

import datetime
print('Hello,CodeSys')
d=datetime.datetime.now()

path='log.txt'

f=open(path,"a")
f.write(str(d)+'\n')
f.close()

PI4修正

まずViの使え方はこちらで:
https://prev.net-newbie.com/linux/commands/vi.html
https://jsapachehtml.hatenablog.com/entry/2014/11/23/124350

CODESYSControl.cfgに

[SysProcess]
Command=AllowAll

を追加します。
image.png

プログラム

初期化プログラム

ControllerがStop>Runになるとき走るプログラムを作ります。それは毎回もちゃんとScriptの実行権限・最新Fileなどを確実するためです。System Eventsが使うことになります。
Online Helpはこちらで:
https://help.codesys.com/api-content/2/codesys/3.5.13.0/en/_cds_obj_task_config_sys_event/#e5ddda49857aab52c0a8640e01f6cda7-id-8eb22e41857aab52c0a8640e009f5f0b

Task Configurationをクリクします。
System EventsのTabを開きます。
Add Event Handlerで新しいイベントを追加します。
image.png

Online HelpのScreenShotですが、使うのはそのPrepareStartです。
Call before starting the applicationってつまりControllerがStop>Runになるときです。
image.png
Add Event Handlerを押すと、以下のPopupが出てきます。
ここでどんなEventでどんなプログラムを走るのかを決めます。
image.png
EventのところにPrepareStartを選びます。
image.png
Function CallでそのEventがトリガーしたとき走るプログラムを設定します。
ここで名前入れるだけOKを押すと勝手にFunctionが作成されます。
image.png
GVLでGlobal変数を作ります。
image.png
そして初期値をFalseします。
image.png

実行プログラム

_PythonExecuteのPOUを作ります。
image.png

使うFunction

最初にライブラリをImportすることが覚えていますか?そのライブラリの中に2つのFunctionを使うことになります。
Library Manager>Libraryを選び>Functionを選び>4番の所にそのFunctionの説明が書いています。

image.png

SysProcessExecuteCommand2

https://help.codesys.com/webapp/SysProcessExecuteCommand2;product=SysProcess%20Implementation;version=3.5.16.0
  • Return:DINT
  • Input:
    • pszcommand:実行するコマンド
    • udisStdOutLen:コマンド実行した後Terminal出力された文字列
    • pReseult:実行結果。0=エラーなし、だと思います。

システムコマンド実行するためにFunctionです。注意するのはコマンドの出力はOSに依存します。

SysFileCopy

https://help.codesys.com/webapp/SysFileCopy;product=SysFile;version=3.5.9.0
  • Return:RTS_IEC_RESULT、Runtimeシステムのエラーコード
  • szDestFileName:Copy先のPath
  • szSourceFileName:Copy元のPath
  • pulCopied:CopyしたByte数

実装

Interface

PROGRAM _PythonExecute
VAR
    dwCopySize: DWORD;
    dutResult : RTS_IEC_RESULT;
    szCommand : STRING(200);
    fbTimer : TON;
    szStdOout : STRING(1000);
    fbTimer1 : TON;
    Command : STRING(200);
END_VAR

Program

(*
   /etc/CODESYSControl.cfg:
   [SysProcess]
   Command=AllowAll 
*)

IF NOT GVL.init THEN

    //Copy the scripts to local
    SysFile.SysFileCopy('/var/opt/codesys/hello.py'
                        ,'/var/opt/codesys/PlcLogic/Application/hello.py'
                        ,ADR(dwCopySize));


    //Change the permission that can execute
    SysProcess_Implementation.SysProcessExecuteCommand2(pszCommand:='chmod +x *.py'
                                                        , pszStdOut:=szStdOout
                                                        , udiStdOutLen:= SIZEOF(szStdOout)
                                                        , pResult := ADR(dutResult));

    //Init is finished
    GVL.init:=TRUE;

END_IF

//Flash Timer
fbTimer1(IN:= TRUE, PT:=T#1S); 

//Command 
Command:= 'sudo python hello.py';

//Timer is ON
IF fbTimer1.Q  THEN
        //Reset it and flash again
        fbTimer1(IN:= FALSE);
        //Execute
        SysProcess.SysProcessExecuteCommand2(pszCommand:=Command
                                            , pszStdOut:=szStdOout
                                            , udiStdOutLen:= SIZEOF(szStdOout)
                                            , pResult := ADR(dutResult));
END_IF

実行すると、まずScriptが/var/opt/codesys/hello.pyにCopyされるとわかります。
image.png

そしてlog.txtが作成されます。
image.png

Logの中時間が記録されてます。
image.png

はーい、お疲れ様です。

Footer_Basic

Please Support some devices for my blog

Amazon Gift List

Find ME

Twitter:@3threes2
Email:soup01threes*gmail.com (* to @)
YoutubeChannel:https://www.youtube.com/channel/UCQ3CHGAIXZAbeOC_9mjQiWQ

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

コメント

  1. Carriecar より:

    お世話になっております。突然の問い合わせメール失礼いたします。

    当該記事「CodeSys#RunTime中にPython Scriptを実行する」を参考にし、同じことが出来ております。ありがとうございます。
     更にProjectで検討しており、CODESYSからROSのコア(roscore)を実行出来るようにPythonを作り、CODESYSから「SysProcessExecuteCommand2」を使って呼び出すのですが、Result=1が返り、roscoreも起動しません。(Pythonファイル単体ではroscoreが起動出来ます)
    環境のCODESYSControl.cfgには以下の2つは既に追加しており問題なさそうです。
    [SysProcess]
    BasePriority=Realtime
    Command=AllowAll
    SysProcessExecuteCommand2のResult=1の理由がOnline Helpでも見つからず、何かヒントがあればと思いコメント欄に記載致しました。
    Result=1の意味、あと、考えられる箇所があればご教授いただければ幸いです。
    ※プロジェクトのメールで必要な画面Bitmapが送れます。お声掛け頂ければ幸いです。