Pemantauan suhu di perusahaan


Tugas datang dengan "sesuatu" untuk melihat dan mengendalikan suhu di pabrik. Kontroler PLC 160 telah dipasang dan sensor suhu terhubung melalui antarmuka RS-485 ( Wikipedia ).

Kontroler dan sensor dipasang sebelum saya.

Ada contoh diagram koneksi:


Digunakan CoDeSys ( Wikipedia ) untuk melihat.

Tidak ada riwayat suhu dan tidak diketahui kapan kecelakaan itu terjadi.

Mulai


Idenya datang dengan cara ini - untuk membuat situs WEB dalam hubungannya dengan database MySQL dan menyimpan informasi tentang suhu dan kecelakaan di sana.

Tugas Awal:

  • Lihat data dari komputer mana saja di perusahaan
  • Lihat crash dan insiden saat ini
  • Tampilan nilai saat ini secara online
  • Ubah nilai maksimum dan minimum untuk perekaman alarm

Kemudian ternyata yang berikut:

Minimum dan maksimum tidak cukup untuk mengendalikan kecelakaan.

Maksimum kritis dan minimum kritis ditambahkan, serta waktu selama suhu bisa kembali normal.

  1. Jika suhu telah melampaui minimum atau maksimum, tetapi kembali normal selama waktu T , maka ini adalah kecelakaan kecil (tetapi kecelakaan ini dicatat sebagai tidak signifikan).

    gambar
  2. Jika suhu melampaui minimum kritis atau maksimum kritis, maka ini adalah kecelakaan kritis segera.

    gambar

Itu diperlukan untuk membedakan akses:

  • Administrator - hanya untukku)))
  • Teknolog - ubah 5 parameter untuk setiap sensor

    gambar
    Saya harus menambahkan perubahan pada parameter kecelakaan pada waktunya. Ini agar, misalnya, dari pukul 00:00 hingga 09:00, kecelakaan tidak dicatat.

    gambar
  • Insinyur - Kalibrasi

    Dengan benar, Anda perlu menggunakan laptop dengan port COM untuk melekat pada modul untuk kalibrasi. Saya memutuskan untuk menerapkan hal yang sama melalui WEB, mis. orang yang terlibat dalam kalibrasi datang ke sensor dengan termometernya dan menampilkan nilai aktual di situs.

    gambar
  • Semua orang - lihat

Bagian perangkat lunak


Mesin virtual dibuat dengan sekelompok PLC 160 melalui jaringan lokal.
CoDeSys Terpasang.

Alamat IP dikonfigurasikan sehingga komputer melihat pengontrol.

gambar

Proyek ini terletak di jalur c: \ project \ pro \ dan disebut my_work.pro .

Proyek itu sendiri diluncurkan melalui file run.cmd

"C:\Program Files\3S Software\CoDeSys V2.3\Codesys.exe" "C:\project\pro\my_work.pro" /userlevel 0 /password 157999 /online 

Aplikasi meluncurkan file run.cmd

 WinExec(Pchar(“c:\run.cmd”), SW_HIDE); 

Saya menggunakan DDE untuk mendapatkan nilai suhu ( Wikipedia )

config.ini

 [CoDeSys] service=CoDeSys topic=C:\project\pro\my_work.pro item=C:\Program Files\3S Software\CoDeSys V2.3\ cmd=C:\run.cmd [db] host=127.0.0.1 port=3306 user=root key=keypassword db=workdb 

Program dimulai:

  1. Unduh parameter konfigurasi CoDeSys dari "config.ini"

    Memuat parameter konfigurasi MySQL dari "config.ini"

    Oleh Timer (Diputuskan bahwa itu akan cukup untuk membaca data satu menit):

    • Dapatkan jumlah sensor dengan MySQL
    • Untuk setiap sensor, buat komponen DDE.DDEConv :

       DDE.DDEConv[…]:= TDdeClientConv.Create(Self) DDE.DDEConv[…].ServiceApplication:=”patchcodesys” DDE.DDEConv[…].SetLink(“name”,”patchdde”) 

      Kami membuat komponen DDE.DDEItem dan mengikatnya ke komponen DDE.DDEConv :

       DDE.DDEItem[…]:=TDdeClientItem.Create(Self) DDE.DDEItem[…].DdeConv:=DDE.DDEConv[…] 

      Kami memberikan nama sensor dengan MySQL :

       DDE.DDEItem[…].DdeItem:=MySQL.GetSensorName(…) 

      Akibatnya, kami memperoleh nilai suhu:

       DDE.DDEItem[…].Text 

      Kami menyimpan nilai suhu saat ini dan parameternya untuk setiap sensor.

       MySQL.InsertTemp(MySQL.GetSensorName(...),””,INSQL(UMin[...]),INSQL(UMax[...]),INSQL(CRMin[...]),INSQL(CRMax[...])) 

    • Kami dapatkan dari MySQL pada tanggal dan waktu saat ini:

      Minimum

       UMin[I…]:=OUTSQL(MySQL.GetMin(MySQL.GetSensorName(…))) 

      Maksimum

       UMax[…]:=OUTSQL(MySQL.GetMax(MySQL.GetSensorName(...))) 

      Minimum kritis

       CRMin[…]:=OUTSQL(MySQL.GetCriticalMin(MySQL.GetSensorName(…))) 

      Maksimum kritis

       CRMax[…]:=OUTSQL(MySQL.GetCriticalMax(MySQL.GetSensorName(…))) 

      Waktu

       CRTime[…]:=MySQL.GetCriticalTime(MySQL.GetSensorName(…)) 

      Catatan: "Perlindungan dari orang bodoh " - jika minimum lebih besar dari maksimum atau sebaliknya - maka kami mengubah nilai-nilai ini di tempat.

       if (UMin[…]>=UMax[…]) then begin UM[…]:=UMin[…]; UMin[…]:=UMax[…]; UMax[…]:=UM[…]; end; 

    • Kecelakaan itu:

      Jika tidak ada kecelakaan, buat catatan

       MySQL.InsertCrash(FormatDateTime('yyyy-mm-dd hh:nn:ss', dt),FormatDateTime('yyyy-mm-dd hh:nn:ss', dt),MySQL.GetSensorName(...),…) 

      Jika ada kecelakaan, kami memperbarui

       MySQL.UpdateCrash(MySQL.GetCrashID(MySQL.GetSensorName(...)),FormatDateTime('yyyy-mm-dd hh:nn:ss', dt),…) 

      Kecelakaan berakhir, atur bendera pelengkap.

    Situs web


    Menulis halaman dalam PHP .

    Halaman utama (sepotong kode, jangan banyak ditendang):

     <?php require 'config.php'; session_start(); $page = isset( $_GET['page'] ) ? $_GET['page'] : ""; switch ( $page ) { case 'login': login(); break; case 'logout': logout(); break; case 'list': listpage(); break; ………………….. ?> 

    Halaman yang tersisa adalah tentang jenis yang sama. Setiap halaman memproses datanya.

    Apa yang telah dilakukan:

    • Daftar sensor. Nama, nama Sensor untuk program, tipe Sensor.

      gambar
    • Sensor dikelompokkan berdasarkan tujuan.

      gambar
    • Ditambahkan "status kecelakaan": Dalam proses kecelakaan, Kecelakaan selesai, Kecelakaan kritis.
    • Diimplementasikan menambahkan pengguna dan peran mereka.
    • Penebangan siapa yang melakukan apa.
    • Arsip semua kecelakaan.
    • Bagan.

    Kruk


    1. Ketika program CoDeSys dimulai, sebuah jendela muncul:

      gambar
      Kami menutupnya secara terprogram.

       W_WND_Button_Run: HWND: W_WND_RUN: HWND; C_Button_Message='Button'; C_CoDeSys_Message='CoDeSys'; W_WND_RUN := FindWindow(nil,C_CoDeSys_Message); if W_WND_RUN<>0 then begin W_WND_Button_Run:=FindWindowEx(W_WND_RUN, 0,C_Button_Message, nil); if W_WND_Button_Run<>0 then begin SendMessage(W_WND_Button_Run, WM_LBUTTONDOWN, 10, 10); SendMessage(W_WND_Button_Run, WM_LBUTTONUP, 10, 10); SendMessage(W_WND_Button_Run, WM_LBUTTONDOWN, 10, 10); SendMessage(W_WND_Button_Run, WM_LBUTTONUP, 10, 10); end; end; 

    2. Tiba-tiba controller dimatikan.

      gambar

       W_WND_Error:=FindWindow(nil,''); if W_WND_Error<>0 then begin W_WND_Button_Error:=FindWindowEx(W_WND_Error,0,'Button', nil); if W_WND_Button_Error<>0 then begin SendMessage(W_WND_Button_Error, WM_LBUTTONDOWN, 10, 10); SendMessage(W_WND_Button_Error, WM_LBUTTONUP, 10, 10); SendMessage(W_WND_Button_Error, WM_LBUTTONDOWN, 10, 10); SendMessage(W_WND_Button_Error, WM_LBUTTONUP, 10, 10); PostMessage(FindWindow(PChar(C_CoDeSys),nil), WM_QUIT, 0, 0); end; end; 

    3. Gantung yang tidak bisa dipahami.

      gambar

      Kami me-restart aplikasi.

       C_CLOSE_DEBUG='CoDeSys for Automation Alliance (debug)'; W_WND_CLOSE:=FindWindow(nil,C_CLOSE_DEBUG); if W_WND_CLOSE<>0 then begin KillProcess('Codesys.exe'); KillProcess('WerFault.exe'); PostMessage(FindWindow(PChar(C_Close_DEBUG),nil), WM_QUIT, 0, 0); PostMessage(FindWindow(PChar(C_CoDeSys),nil), WM_QUIT, 0, 0); MySQL.InsertLog('Error debug.. Kill process - codesys.exe and WerFault.exe'); MySQL.InsertLog('Restart programm'); RestartThisApp; end; //  function KillProcess(ExeName: string): LongBool; var B: BOOL; ProcList: THandle; PE: TProcessEntry32; begin Result := False; ProcList := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0); PE.dwSize := SizeOf(PE); B := Process32First(ProcList, PE); while B do begin if (UpperCase(PE.szExeFile) = UpperCase(ExtractFileName(ExeName))) then Result := TerminateProcess(OpenProcess($0001, False, PE.th32ProcessID), 0); B:= Process32Next(ProcList, PE); end; CloseHandle(ProcList); end; //  procedure TForm1.RestartThisApp; begin ShellExecute(Handle, nil, PChar(Application.ExeName), nil, nil, SW_SHOWNORMAL); Application.Terminate; // or, if this is the main form, simply Close; end; 

    Zabbix


    Membuat host dengan alamat 127.0.0.1 .

    Ini memiliki aturan deteksi bernama "Sensor".

    gambar

    gambar

    Prototipe elemen data.

    gambar

    Pemicu prototipe.

    gambar

    Tambahkan ke zabbix_agentd.conf

     UserParameter=sensors[*],/usr/lib/zabbix/alertscripts/sensors.sh UserParameter=crash[*],/usr/lib/zabbix/alertscripts/crash.sh $1 

    Skrip itu sendiri:

    sensor.sh

     #!/bin/sh unset id unset res id=(`echo "select id FROM sensor WHERE type='1'" | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) echo '{ "data": [' for (( count=1; count<${#id[@]}; count++ )) do res=(`echo "select name FROM sensor WHERE (type='1' and id='${id[$count]}') " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null `) r={${res[@]} l=${#r} res1=(`echo "select param FROM sensor WHERE (type='1' and id='${id[$count]}') " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null `) r1={${res1[@]} l1=${#r1} res2=(`echo "select ddename FROM sensor WHERE (type='1' and id='${id[$count]}') " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null `) r2={${res2[@]} l2=${#r2} res3=(`echo "select min FROM temp_${r2:17:l2} ORDER BY id DESC LIMIT 1 " | mysql -uroot -ps -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) r3={${res3[@]} l3=${#r3} res4=(`echo "select max FROM temp_${r2:17:l2} ORDER BY id DESC LIMIT 1 " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) r4={${res4[@]} l4=${#r4} res5=(`echo "select cmin FROM temp_${r2:17:l2} ORDER BY id DESC LIMIT 1 " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) r5={${res5[@]} l5=${#r5}2>/dev/null res6=(`echo "select cmax FROM temp_${r2:17:l2} ORDER BY id DESC LIMIT 1 " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) r6={${res6[@]} l6=${#r6} res7=(`echo "select param FROM temp_${r2:17:l2} ORDER BY id DESC LIMIT 1 " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null`) r7={${res7[@]} l7=${#r7} s=$s'{ "{#SID}": "'${id[$count]}'", "{#SNAME}": "'${r:5:l}'", "{#SDDENAME}": "'${r2:17:l2}'" , "{#SPARAM}": "'${r7:7:l7}'", "{#SMIN}": "'${r3:5:l3}'", "{#SMAX}": "'${r4:5:l4}'", "{#SCMIN}": "'${r5:6:l5}'", "{#SCMAX}": "'${r6:6:l6}'" },' done a=${#s} b=${s: 0: $a-1} c=${#b} d=$b echo $d']}' 

    crash.sh

     #!/bin/sh a=$1 unset res res=(`echo "select flag, id_status FROM crash WHERE id_sensor='$a' ORDER BY id DESC LIMIT 1 " | mysql -uroot -p -D workdb -h 0.0.0.0 --default-character-set=utf8 2>/dev/null `) for (( count=2; count<${#res[@]}; count++ )) do s=$s' '${res[$count]} done b=${s:0:2} c=${s:3:4} if [ $b = 0 -a $c = 1 ] then echo 0 else echo 1 fi 

    Dan kemudian melalui zabbix Anda dapat mengirim surat dan SMS dan banyak lagi.

    Hasil


    Hasilnya adalah sistem pemantauan suhu di perusahaan dengan tinjauan kecelakaan saat ini dan masa lalu.

    gambar

    Baca lebih lanjut tentang kecelakaan itu.

    gambar

    Saat ini, sensor untuk membuka / menutup pintu ditambahkan.

    Pro:

    • Biaya minimum ( relatif ).
    • Ditambah dengan karma (?).
    • Pemantauan telah berjalan selama 3 tahun.

    Cons:

    • Banyak poin kegagalan: pengontrol, jaringan, program CoDeSys , mesin virtual, MySQL , IIS .

    PS

    Jangan banyak menendang. Ini artikel pertama saya.

Source: https://habr.com/ru/post/id470822/


All Articles