From 56f8735fb39c8bad77aa453d859df9a1aaf03d8a Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli" Date: Sat, 16 Sep 2017 09:56:41 +0200 Subject: [PATCH] novi file in area CONF-IOB con files log ripuliti --- CONF-IOB/Donati/1000_Pi1/IOB.cfg | 23 + CONF-IOB/Donati/1000_Pi1/IOB.cfg.donati | 24 + CONF-IOB/Donati/1000_Pi1/IOB.cfg.steamware | 23 + CONF-IOB/Donati/1000_Pi1/MapoIOB | 41 ++ CONF-IOB/Donati/1000_Pi1/cleanPython.sh | 14 + CONF-IOB/Donati/1000_Pi1/crontab | 1 + CONF-IOB/Donati/1000_Pi1/logReboot.txt | 1 + CONF-IOB/Donati/1000_Pi1/logfile.txt | 0 CONF-IOB/Donati/1000_Pi1/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1000_Pi1/sendReboot.py | 130 ++++ CONF-IOB/Donati/1000_Pi1/sendRebootIOB | 33 + CONF-IOB/Donati/1000_Pi1/unix.py | 31 + CONF-IOB/Donati/1000_Pi3/IOB.cfg | 35 + CONF-IOB/Donati/1000_Pi3/IOB.cfg.donati | 35 + CONF-IOB/Donati/1000_Pi3/IOB.cfg.steamware | 35 + CONF-IOB/Donati/1000_Pi3/MapoIOB | 41 ++ CONF-IOB/Donati/1000_Pi3/MapoIOB_logrot | 28 + CONF-IOB/Donati/1000_Pi3/checkAlive.sh | 20 + CONF-IOB/Donati/1000_Pi3/cleanPython.sh | 14 + CONF-IOB/Donati/1000_Pi3/convertLogFile.py | 46 ++ CONF-IOB/Donati/1000_Pi3/crontab | 1 + CONF-IOB/Donati/1000_Pi3/install-RPI-IOB.sh | 51 ++ CONF-IOB/Donati/1000_Pi3/logReboot.txt | 0 CONF-IOB/Donati/1000_Pi3/logfile.txt | 0 CONF-IOB/Donati/1000_Pi3/mppar | 2 + CONF-IOB/Donati/1000_Pi3/mpser | 2 + CONF-IOB/Donati/1000_Pi3/readFile.py | 152 +++++ CONF-IOB/Donati/1000_Pi3/readParallela.py | 641 ++++++++++++++++++ CONF-IOB/Donati/1000_Pi3/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1000_Pi3/saveTemp.sh | 17 + CONF-IOB/Donati/1000_Pi3/sendReboot.py | 130 ++++ CONF-IOB/Donati/1000_Pi3/sendRebootIOB | 33 + .../Donati/1000_Pi3/sendRebootIOB.service | 22 + CONF-IOB/Donati/1000_Pi3/setIobConf.sh | 26 + CONF-IOB/Donati/1000_Pi3/unix.py | 31 + CONF-IOB/Donati/1000_Pi3/unix.pyc | Bin 0 -> 692 bytes CONF-IOB/Donati/1000_Pi3/win.py | 32 + CONF-IOB/Donati/1000_Pi3/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/1005_149/IOB.cfg | 23 + CONF-IOB/Donati/1005_149/MapoIOB | 41 ++ CONF-IOB/Donati/1005_149/MapoIOB_par | 40 ++ CONF-IOB/Donati/1005_149/MapoIOB_ser | 40 ++ CONF-IOB/Donati/1005_149/checkAlive.sh | 20 + CONF-IOB/Donati/1005_149/cleanPython.sh | 14 + CONF-IOB/Donati/1005_149/logfile.txt | 0 CONF-IOB/Donati/1005_149/mppar | 2 + CONF-IOB/Donati/1005_149/mpser | 2 + .../1005_149/python-serial_2.5-2.1_all.deb | Bin 0 -> 79040 bytes CONF-IOB/Donati/1005_149/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1005_149/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1005_149/sendReboot.py | 96 +++ CONF-IOB/Donati/1005_149/unix.py | 30 + CONF-IOB/Donati/1006_151/IOB.cfg | 23 + CONF-IOB/Donati/1006_151/MapoIOB | 41 ++ CONF-IOB/Donati/1006_151/MapoIOB.bak | 40 ++ CONF-IOB/Donati/1006_151/checkAlive.sh | 20 + CONF-IOB/Donati/1006_151/cleanPython.sh | 14 + CONF-IOB/Donati/1006_151/old/IOB.cfg | 19 + CONF-IOB/Donati/1006_151/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1006_151/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1006_151/sendReboot.py | 96 +++ CONF-IOB/Donati/1006_151/unix.py | 31 + CONF-IOB/Donati/1007_152/IOB.cfg | 23 + CONF-IOB/Donati/1007_152/MapoIOB | 41 ++ CONF-IOB/Donati/1007_152/checkAlive.sh | 20 + CONF-IOB/Donati/1007_152/cleanPython.sh | 14 + CONF-IOB/Donati/1007_152/logfile.txt | 0 CONF-IOB/Donati/1007_152/old/IOB.cfg | 19 + CONF-IOB/Donati/1007_152/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1007_152/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1007_152/sendReboot.py | 96 +++ CONF-IOB/Donati/1007_152/unix.py | 31 + CONF-IOB/Donati/1008_153/IOB.cfg | 23 + CONF-IOB/Donati/1008_153/MapoIOB | 41 ++ CONF-IOB/Donati/1008_153/checkAlive.sh | 20 + CONF-IOB/Donati/1008_153/cleanPython.sh | 14 + CONF-IOB/Donati/1008_153/logfile.txt | 0 CONF-IOB/Donati/1008_153/old/IOB.cfg | 19 + CONF-IOB/Donati/1008_153/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1008_153/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1008_153/sendReboot.py | 96 +++ CONF-IOB/Donati/1008_153/unix.py | 31 + CONF-IOB/Donati/1009_154/IOB.cfg | 23 + CONF-IOB/Donati/1009_154/MapoIOB | 41 ++ CONF-IOB/Donati/1009_154/checkAlive.sh | 20 + CONF-IOB/Donati/1009_154/cleanPython.sh | 14 + CONF-IOB/Donati/1009_154/logfile.txt | 0 CONF-IOB/Donati/1009_154/old/IOB.cfg | 19 + CONF-IOB/Donati/1009_154/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1009_154/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1009_154/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1009_154/sendReboot.py | 96 +++ CONF-IOB/Donati/1009_154/unix.py | 31 + CONF-IOB/Donati/1010_155/IOB.cfg | 23 + CONF-IOB/Donati/1010_155/MapoIOB | 41 ++ CONF-IOB/Donati/1010_155/checkAlive.sh | 20 + CONF-IOB/Donati/1010_155/cleanPython.sh | 14 + CONF-IOB/Donati/1010_155/logfile.txt | 0 CONF-IOB/Donati/1010_155/old/IOB.cfg | 19 + CONF-IOB/Donati/1010_155/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1010_155/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1010_155/sendReboot.py | 96 +++ CONF-IOB/Donati/1010_155/unix.py | 31 + CONF-IOB/Donati/1011_156/IOB.cfg | 23 + CONF-IOB/Donati/1011_156/MapoIOB | 41 ++ CONF-IOB/Donati/1011_156/checkAlive.sh | 20 + CONF-IOB/Donati/1011_156/logfile.txt | 0 CONF-IOB/Donati/1011_156/old/IOB.cfg | 19 + CONF-IOB/Donati/1011_156/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1011_156/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1011_156/sendReboot.py | 130 ++++ CONF-IOB/Donati/1011_156/unix.py | 31 + CONF-IOB/Donati/1011_170/IOB.cfg | 23 + CONF-IOB/Donati/1011_170/MapoIOB | 41 ++ CONF-IOB/Donati/1011_170/checkAlive.sh | 20 + CONF-IOB/Donati/1011_170/cleanPython.sh | 14 + CONF-IOB/Donati/1011_170/logfile.txt | 0 CONF-IOB/Donati/1011_170/old/IOB.cfg | 19 + CONF-IOB/Donati/1011_170/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1011_170/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1011_170/sendReboot.py | 96 +++ CONF-IOB/Donati/1011_170/unix.py | 31 + CONF-IOB/Donati/1012_157/IOB.cfg | 23 + CONF-IOB/Donati/1012_157/MapoIOB | 41 ++ CONF-IOB/Donati/1012_157/checkAlive.sh | 20 + CONF-IOB/Donati/1012_157/cleanPython.sh | 14 + CONF-IOB/Donati/1012_157/logfile.txt | 0 CONF-IOB/Donati/1012_157/old/IOB.cfg | 19 + CONF-IOB/Donati/1012_157/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1012_157/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1012_157/sendReboot.py | 96 +++ CONF-IOB/Donati/1012_157/sendRebootIOB | 29 + CONF-IOB/Donati/1012_157/unix.py | 31 + CONF-IOB/Donati/1013_158/IOB.cfg | 23 + CONF-IOB/Donati/1013_158/MapoIOB | 41 ++ CONF-IOB/Donati/1013_158/checkAlive.sh | 20 + CONF-IOB/Donati/1013_158/cleanPython.sh | 14 + CONF-IOB/Donati/1013_158/logfile.txt | 0 CONF-IOB/Donati/1013_158/old/IOB.cfg | 19 + CONF-IOB/Donati/1013_158/old/readParallela.py | 337 +++++++++ CONF-IOB/Donati/1013_158/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1013_158/sendReboot.py | 96 +++ CONF-IOB/Donati/1013_158/unix.py | 31 + CONF-IOB/Donati/1014_159/IOB.cfg | 23 + CONF-IOB/Donati/1014_159/MapoIOB | 41 ++ CONF-IOB/Donati/1014_159/checkAlive.sh | 20 + CONF-IOB/Donati/1014_159/cleanPython.sh | 14 + CONF-IOB/Donati/1014_159/logfile.txt | 0 CONF-IOB/Donati/1014_159/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1014_159/sendReboot.py | 96 +++ CONF-IOB/Donati/1014_159/unix.py | 31 + CONF-IOB/Donati/1015_162/IOB.cfg | 23 + CONF-IOB/Donati/1015_162/MapoIOB | 41 ++ CONF-IOB/Donati/1015_162/checkAlive.sh | 20 + CONF-IOB/Donati/1015_162/cleanPython.sh | 14 + CONF-IOB/Donati/1015_162/logfile.txt | 0 CONF-IOB/Donati/1015_162/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1015_162/sendReboot.py | 96 +++ CONF-IOB/Donati/1015_162/sendRebootIOB | 29 + CONF-IOB/Donati/1015_162/unix.py | 31 + CONF-IOB/Donati/1016_163/IOB.cfg | 23 + CONF-IOB/Donati/1016_163/MapoIOB | 41 ++ CONF-IOB/Donati/1016_163/checkAlive.sh | 20 + CONF-IOB/Donati/1016_163/cleanPython.sh | 14 + CONF-IOB/Donati/1016_163/logfile.txt | 0 CONF-IOB/Donati/1016_163/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1016_163/sendReboot.py | 96 +++ CONF-IOB/Donati/1016_163/unix.py | 31 + CONF-IOB/Donati/1017_164/IOB.cfg | 23 + CONF-IOB/Donati/1017_164/MapoIOB | 41 ++ CONF-IOB/Donati/1017_164/checkAlive.sh | 20 + CONF-IOB/Donati/1017_164/cleanPython.sh | 14 + CONF-IOB/Donati/1017_164/logfile.txt | 0 CONF-IOB/Donati/1017_164/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1017_164/sendReboot.py | 96 +++ CONF-IOB/Donati/1017_164/unix.py | 31 + CONF-IOB/Donati/1018_168/IOB.cfg | 23 + CONF-IOB/Donati/1018_168/MapoIOB | 41 ++ CONF-IOB/Donati/1018_168/checkAlive.sh | 20 + CONF-IOB/Donati/1018_168/cleanPython.sh | 14 + CONF-IOB/Donati/1018_168/logfile.txt | 0 CONF-IOB/Donati/1018_168/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1018_168/sendReboot.py | 96 +++ CONF-IOB/Donati/1018_168/unix.py | 30 + CONF-IOB/Donati/1019_169/IOB.cfg | 23 + CONF-IOB/Donati/1019_169/MapoIOB | 41 ++ CONF-IOB/Donati/1019_169/checkAlive.sh | 20 + CONF-IOB/Donati/1019_169/cleanPython.sh | 14 + CONF-IOB/Donati/1019_169/logfile.txt | 0 CONF-IOB/Donati/1019_169/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1019_169/sendReboot.py | 96 +++ CONF-IOB/Donati/1019_169/unix.py | 31 + CONF-IOB/Donati/1020_165/IOB.cfg | 23 + CONF-IOB/Donati/1020_165/MapoIOB | 41 ++ CONF-IOB/Donati/1020_165/checkAlive.sh | 20 + CONF-IOB/Donati/1020_165/cleanPython.sh | 14 + CONF-IOB/Donati/1020_165/logfile.txt | 0 CONF-IOB/Donati/1020_165/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1020_165/sendReboot.py | 96 +++ CONF-IOB/Donati/1020_165/unix.py | 31 + CONF-IOB/Donati/1021_167/IOB.cfg | 23 + CONF-IOB/Donati/1021_167/MapoIOB | 41 ++ CONF-IOB/Donati/1021_167/checkAlive.sh | 20 + CONF-IOB/Donati/1021_167/cleanPython.sh | 14 + CONF-IOB/Donati/1021_167/logfile.txt | 0 CONF-IOB/Donati/1021_167/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1021_167/sendReboot.py | 96 +++ CONF-IOB/Donati/1021_167/unix.py | 31 + CONF-IOB/Donati/1022_166/IOB.cfg | 23 + CONF-IOB/Donati/1022_166/MapoIOB | 41 ++ CONF-IOB/Donati/1022_166/checkAlive.sh | 20 + CONF-IOB/Donati/1022_166/cleanPython.sh | 14 + CONF-IOB/Donati/1022_166/logfile.txt | 0 CONF-IOB/Donati/1022_166/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1022_166/sendReboot.py | 96 +++ CONF-IOB/Donati/1022_166/unix.py | 31 + CONF-IOB/Donati/1024_177/IOB.cfg | 23 + CONF-IOB/Donati/1024_177/IOB.cfg.donati | 23 + CONF-IOB/Donati/1024_177/IOB.cfg.steamware | 23 + CONF-IOB/Donati/1024_177/MapoIOB | 41 ++ CONF-IOB/Donati/1024_177/checkAlive.sh | 20 + CONF-IOB/Donati/1024_177/cleanPython.sh | 14 + CONF-IOB/Donati/1024_177/crontab | 1 + CONF-IOB/Donati/1024_177/install-RPI-IOB.sh | 47 ++ CONF-IOB/Donati/1024_177/mppar | 2 + CONF-IOB/Donati/1024_177/mpser | 2 + CONF-IOB/Donati/1024_177/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1024_177/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1024_177/saveTemp.sh | 17 + CONF-IOB/Donati/1024_177/sendReboot.py | 130 ++++ CONF-IOB/Donati/1024_177/sendRebootIOB | 33 + .../Donati/1024_177/sendRebootIOB.service | 22 + CONF-IOB/Donati/1024_177/setIobConf.sh | 26 + CONF-IOB/Donati/1024_177/test.py | 31 + CONF-IOB/Donati/1024_177/unix.py | 31 + CONF-IOB/Donati/1024_177/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/1024_177/win.py | 32 + CONF-IOB/Donati/1024_177/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/1025_178/IOB.cfg | 23 + CONF-IOB/Donati/1025_178/IOB.cfg.donati | 23 + CONF-IOB/Donati/1025_178/IOB.cfg.steamware | 23 + CONF-IOB/Donati/1025_178/MapoIOB | 41 ++ CONF-IOB/Donati/1025_178/checkAlive.sh | 20 + CONF-IOB/Donati/1025_178/cleanPython.sh | 14 + CONF-IOB/Donati/1025_178/crontab | 1 + CONF-IOB/Donati/1025_178/install-RPI-IOB.sh | 47 ++ CONF-IOB/Donati/1025_178/mppar | 2 + CONF-IOB/Donati/1025_178/mpser | 2 + CONF-IOB/Donati/1025_178/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1025_178/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1025_178/saveTemp.sh | 17 + CONF-IOB/Donati/1025_178/sendReboot.py | 130 ++++ CONF-IOB/Donati/1025_178/sendRebootIOB | 33 + .../Donati/1025_178/sendRebootIOB.service | 22 + CONF-IOB/Donati/1025_178/setIobConf.sh | 26 + CONF-IOB/Donati/1025_178/test.py | 31 + CONF-IOB/Donati/1025_178/unix.py | 31 + CONF-IOB/Donati/1025_178/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/1025_178/win.py | 32 + CONF-IOB/Donati/1025_178/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/1026_180/IOB.cfg | 23 + CONF-IOB/Donati/1026_180/IOB.cfg.donati | 23 + CONF-IOB/Donati/1026_180/IOB.cfg.steamware | 23 + CONF-IOB/Donati/1026_180/MapoIOB | 41 ++ CONF-IOB/Donati/1026_180/checkAlive.sh | 20 + CONF-IOB/Donati/1026_180/cleanPython.sh | 14 + CONF-IOB/Donati/1026_180/crontab | 1 + CONF-IOB/Donati/1026_180/install-RPI-IOB.sh | 47 ++ CONF-IOB/Donati/1026_180/mppar | 2 + CONF-IOB/Donati/1026_180/mpser | 2 + CONF-IOB/Donati/1026_180/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1026_180/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1026_180/saveTemp.sh | 17 + CONF-IOB/Donati/1026_180/sendReboot.py | 130 ++++ CONF-IOB/Donati/1026_180/sendRebootIOB | 33 + .../Donati/1026_180/sendRebootIOB.service | 22 + CONF-IOB/Donati/1026_180/setIobConf.sh | 26 + CONF-IOB/Donati/1026_180/test.py | 31 + CONF-IOB/Donati/1026_180/unix.py | 31 + CONF-IOB/Donati/1026_180/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/1026_180/win.py | 32 + CONF-IOB/Donati/1026_180/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/1027 - 185/IOB.cfg | 23 + CONF-IOB/Donati/1027 - 185/IOB.cfg.donati | 23 + CONF-IOB/Donati/1027 - 185/IOB.cfg.steamware | 23 + CONF-IOB/Donati/1027 - 185/MapoIOB | 41 ++ CONF-IOB/Donati/1027 - 185/checkAlive.sh | 20 + CONF-IOB/Donati/1027 - 185/cleanPython.sh | 14 + CONF-IOB/Donati/1027 - 185/crontab | 1 + CONF-IOB/Donati/1027 - 185/install-RPI-IOB.sh | 47 ++ CONF-IOB/Donati/1027 - 185/mppar | 2 + CONF-IOB/Donati/1027 - 185/mpser | 2 + CONF-IOB/Donati/1027 - 185/readParallela.py | 530 +++++++++++++++ CONF-IOB/Donati/1027 - 185/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/1027 - 185/saveTemp.sh | 17 + CONF-IOB/Donati/1027 - 185/sendReboot.py | 130 ++++ CONF-IOB/Donati/1027 - 185/sendRebootIOB | 33 + .../Donati/1027 - 185/sendRebootIOB.service | 22 + CONF-IOB/Donati/1027 - 185/setIobConf.sh | 26 + CONF-IOB/Donati/1027 - 185/test.py | 31 + CONF-IOB/Donati/1027 - 185/unix.py | 31 + CONF-IOB/Donati/1027 - 185/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/1027 - 185/win.py | 32 + CONF-IOB/Donati/1027 - 185/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/1501_172/IOB.cfg | 10 + CONF-IOB/Donati/1501_172/LogoHighResWhite.png | Bin 0 -> 18907 bytes CONF-IOB/Donati/1501_172/MP-MON-DEMO.html | 540 +++++++++++++++ CONF-IOB/Donati/1501_172/MP-MON-DEMO_b.html | 540 +++++++++++++++ .../1501_172/MP-MON-DEMO_files/OpenSans.woff | Bin 0 -> 21956 bytes .../MP-MON-DEMO_files/OpenSansCondensed.woff | Bin 0 -> 22432 bytes .../1501_172/MP-MON-DEMO_files/bootstrap | 1 + .../Donati/1501_172/MP-MON-DEMO_files/css | 21 + .../Donati/1501_172/MP-MON-DEMO_files/jquery | 1 + .../1501_172/MP-MON-DEMO_files/jqueryval | 1 + .../MP-MON-DEMO_files/logoSteamware.png | Bin 0 -> 22301 bytes .../1501_172/MP-MON-DEMO_files/modernizr | 1 + CONF-IOB/Donati/1501_172/install-RPI-MON.sh | 25 + CONF-IOB/Donati/1501_172/logBrowser.txt | 0 CONF-IOB/Donati/1501_172/logReboot.txt | 0 CONF-IOB/Donati/1501_172/logTemp.txt | 1 + CONF-IOB/Donati/1501_172/restartBrowser.sh | 67 ++ CONF-IOB/Donati/1501_172/saveTemp.sh | 17 + CONF-IOB/Donati/1501_172/sendReboot.py | 115 ++++ CONF-IOB/Donati/1501_172/sendRebootIOB | 31 + .../Donati/1501_172/sendRebootIOB.service | Bin 0 -> 555 bytes CONF-IOB/Donati/1501_172/startBrowser.sh | 66 ++ CONF-IOB/Donati/1501_172/testNet.sh | 20 + CONF-IOB/Donati/1502_173/IOB.cfg | 9 + CONF-IOB/Donati/1502_173/LogoHighResWhite.png | Bin 0 -> 18907 bytes CONF-IOB/Donati/1502_173/MP-MON-DEMO.html | 547 +++++++++++++++ CONF-IOB/Donati/1502_173/MP-MON-DEMO_b.html | 547 +++++++++++++++ .../1502_173/MP-MON-DEMO_files/OpenSans.woff | Bin 0 -> 21956 bytes .../MP-MON-DEMO_files/OpenSansCondensed.woff | Bin 0 -> 22432 bytes .../1502_173/MP-MON-DEMO_files/bootstrap | 1 + .../Donati/1502_173/MP-MON-DEMO_files/css | 21 + .../Donati/1502_173/MP-MON-DEMO_files/jquery | 1 + .../1502_173/MP-MON-DEMO_files/jqueryval | 1 + .../MP-MON-DEMO_files/logoSteamware.png | Bin 0 -> 22301 bytes .../1502_173/MP-MON-DEMO_files/modernizr | 1 + CONF-IOB/Donati/1502_173/READ.me | 10 + CONF-IOB/Donati/1502_173/install-RPI-MON.sh | 43 ++ CONF-IOB/Donati/1502_173/logBrowser.txt | 0 CONF-IOB/Donati/1502_173/logReboot.txt | 0 CONF-IOB/Donati/1502_173/logTemp.txt | 1 + CONF-IOB/Donati/1502_173/saveTemp.sh | 17 + CONF-IOB/Donati/1502_173/sendReboot.py | 115 ++++ CONF-IOB/Donati/1502_173/sendRebootIOB | 31 + .../Donati/1502_173/sendRebootIOB.service | 22 + CONF-IOB/Donati/1502_173/startBrowser.sh | 66 ++ CONF-IOB/Donati/1502_173/testNet.sh | 20 + CONF-IOB/Donati/1503_174/IOB.cfg | 9 + CONF-IOB/Donati/1503_174/LogoHighResWhite.png | Bin 0 -> 18907 bytes CONF-IOB/Donati/1503_174/MP-MON-DEMO.html | 547 +++++++++++++++ CONF-IOB/Donati/1503_174/MP-MON-DEMO_b.html | 547 +++++++++++++++ .../1503_174/MP-MON-DEMO_files/OpenSans.woff | Bin 0 -> 21956 bytes .../MP-MON-DEMO_files/OpenSansCondensed.woff | Bin 0 -> 22432 bytes .../1503_174/MP-MON-DEMO_files/bootstrap | 1 + .../Donati/1503_174/MP-MON-DEMO_files/css | 21 + .../Donati/1503_174/MP-MON-DEMO_files/jquery | 1 + .../1503_174/MP-MON-DEMO_files/jqueryval | 1 + .../MP-MON-DEMO_files/logoSteamware.png | Bin 0 -> 22301 bytes .../1503_174/MP-MON-DEMO_files/modernizr | 1 + CONF-IOB/Donati/1503_174/READ.me | 10 + CONF-IOB/Donati/1503_174/install-RPI-MON.sh | 43 ++ CONF-IOB/Donati/1503_174/logBrowser.txt | 0 CONF-IOB/Donati/1503_174/logReboot.txt | 0 CONF-IOB/Donati/1503_174/logTemp.txt | 1 + CONF-IOB/Donati/1503_174/saveTemp.sh | 17 + CONF-IOB/Donati/1503_174/sendReboot.py | 115 ++++ CONF-IOB/Donati/1503_174/sendRebootIOB | 31 + .../Donati/1503_174/sendRebootIOB.service | 22 + CONF-IOB/Donati/1503_174/startBrowser.sh | 66 ++ CONF-IOB/Donati/1503_174/testNet.sh | 20 + CONF-IOB/Donati/1504_175/IOB.cfg | 10 + CONF-IOB/Donati/1504_175/LogoHighResWhite.png | Bin 0 -> 18907 bytes CONF-IOB/Donati/1504_175/MP-MON-DEMO.html | 547 +++++++++++++++ CONF-IOB/Donati/1504_175/MP-MON-DEMO_b.html | 547 +++++++++++++++ .../1504_175/MP-MON-DEMO_files/OpenSans.woff | Bin 0 -> 21956 bytes .../MP-MON-DEMO_files/OpenSansCondensed.woff | Bin 0 -> 22432 bytes .../1504_175/MP-MON-DEMO_files/bootstrap | 1 + .../Donati/1504_175/MP-MON-DEMO_files/css | 21 + .../Donati/1504_175/MP-MON-DEMO_files/jquery | 1 + .../1504_175/MP-MON-DEMO_files/jqueryval | 1 + .../MP-MON-DEMO_files/logoSteamware.png | Bin 0 -> 22301 bytes .../1504_175/MP-MON-DEMO_files/modernizr | 1 + CONF-IOB/Donati/1504_175/READ.me | 10 + CONF-IOB/Donati/1504_175/install-RPI-MON.sh | 43 ++ CONF-IOB/Donati/1504_175/logBrowser.txt | 0 CONF-IOB/Donati/1504_175/logReboot.txt | 0 CONF-IOB/Donati/1504_175/logTemp.txt | 1 + CONF-IOB/Donati/1504_175/saveTemp.sh | 17 + CONF-IOB/Donati/1504_175/sendReboot.py | 115 ++++ CONF-IOB/Donati/1504_175/sendRebootIOB | 31 + .../Donati/1504_175/sendRebootIOB.service | 22 + CONF-IOB/Donati/1504_175/startBrowser.sh | 66 ++ CONF-IOB/Donati/1504_175/testNet.sh | 20 + CONF-IOB/Donati/2001_184/IOB.cfg | 35 + CONF-IOB/Donati/2001_184/IOB.cfg.donati | 35 + CONF-IOB/Donati/2001_184/IOB.cfg.steamware | 35 + CONF-IOB/Donati/2001_184/MapoIOB | 41 ++ CONF-IOB/Donati/2001_184/MapoIOB_logrot | 28 + CONF-IOB/Donati/2001_184/checkAlive.sh | 20 + CONF-IOB/Donati/2001_184/cleanPython.sh | 14 + CONF-IOB/Donati/2001_184/convertLogFile.py | 46 ++ CONF-IOB/Donati/2001_184/crontab | 1 + CONF-IOB/Donati/2001_184/install-RPI-IOB.sh | 51 ++ CONF-IOB/Donati/2001_184/mppar | 2 + CONF-IOB/Donati/2001_184/mpser | 2 + CONF-IOB/Donati/2001_184/readFile.py | 152 +++++ CONF-IOB/Donati/2001_184/readParallela.py | 608 +++++++++++++++++ CONF-IOB/Donati/2001_184/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/2001_184/saveTemp.sh | 17 + CONF-IOB/Donati/2001_184/sendReboot.py | 130 ++++ CONF-IOB/Donati/2001_184/sendRebootIOB | 33 + .../Donati/2001_184/sendRebootIOB.service | 22 + CONF-IOB/Donati/2001_184/setIobConf.sh | 26 + CONF-IOB/Donati/2001_184/unix.py | 31 + CONF-IOB/Donati/2001_184/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/2001_184/win.py | 32 + CONF-IOB/Donati/2001_184/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/2002_183/IOB.cfg | 35 + CONF-IOB/Donati/2002_183/IOB.cfg.donati | 35 + CONF-IOB/Donati/2002_183/IOB.cfg.steamware | 35 + CONF-IOB/Donati/2002_183/MapoIOB | 41 ++ CONF-IOB/Donati/2002_183/MapoIOB_logrot | 28 + CONF-IOB/Donati/2002_183/checkAlive.sh | 20 + CONF-IOB/Donati/2002_183/cleanPython.sh | 14 + CONF-IOB/Donati/2002_183/convertLogFile.py | 46 ++ CONF-IOB/Donati/2002_183/crontab | 1 + CONF-IOB/Donati/2002_183/install-RPI-IOB.sh | 51 ++ CONF-IOB/Donati/2002_183/mppar | 2 + CONF-IOB/Donati/2002_183/mpser | 2 + CONF-IOB/Donati/2002_183/readFile.py | 152 +++++ CONF-IOB/Donati/2002_183/readParallela.py | 608 +++++++++++++++++ CONF-IOB/Donati/2002_183/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/2002_183/saveTemp.sh | 17 + CONF-IOB/Donati/2002_183/sendReboot.py | 130 ++++ CONF-IOB/Donati/2002_183/sendRebootIOB | 33 + .../Donati/2002_183/sendRebootIOB.service | 22 + CONF-IOB/Donati/2002_183/setIobConf.sh | 26 + CONF-IOB/Donati/2002_183/unix.py | 31 + CONF-IOB/Donati/2002_183/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/2002_183/win.py | 32 + CONF-IOB/Donati/2002_183/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/2003_187/IOB.cfg | 35 + CONF-IOB/Donati/2003_187/IOB.cfg.donati | 35 + CONF-IOB/Donati/2003_187/IOB.cfg.steamware | 35 + CONF-IOB/Donati/2003_187/MapoIOB | 41 ++ CONF-IOB/Donati/2003_187/MapoIOB_logrot | 28 + CONF-IOB/Donati/2003_187/checkAlive.sh | 20 + CONF-IOB/Donati/2003_187/cleanPython.sh | 14 + CONF-IOB/Donati/2003_187/convertLogFile.py | 46 ++ CONF-IOB/Donati/2003_187/crontab | 1 + CONF-IOB/Donati/2003_187/install-RPI-IOB.sh | 51 ++ CONF-IOB/Donati/2003_187/mppar | 2 + CONF-IOB/Donati/2003_187/mpser | 2 + CONF-IOB/Donati/2003_187/readFile.py | 152 +++++ CONF-IOB/Donati/2003_187/readParallela.py | 608 +++++++++++++++++ CONF-IOB/Donati/2003_187/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/2003_187/saveTemp.sh | 17 + CONF-IOB/Donati/2003_187/sendReboot.py | 130 ++++ CONF-IOB/Donati/2003_187/sendRebootIOB | 33 + .../Donati/2003_187/sendRebootIOB.service | 22 + CONF-IOB/Donati/2003_187/setIobConf.sh | 26 + CONF-IOB/Donati/2003_187/unix.py | 31 + CONF-IOB/Donati/2003_187/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/2003_187/win.py | 32 + CONF-IOB/Donati/2003_187/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/2004_186/IOB.cfg | 35 + CONF-IOB/Donati/2004_186/IOB.cfg.donati | 35 + CONF-IOB/Donati/2004_186/IOB.cfg.steamware | 35 + CONF-IOB/Donati/2004_186/MapoIOB | 41 ++ CONF-IOB/Donati/2004_186/MapoIOB_logrot | 28 + CONF-IOB/Donati/2004_186/checkAlive.sh | 20 + CONF-IOB/Donati/2004_186/cleanPython.sh | 14 + CONF-IOB/Donati/2004_186/convertLogFile.py | 46 ++ CONF-IOB/Donati/2004_186/crontab | 1 + CONF-IOB/Donati/2004_186/install-RPI-IOB.sh | 51 ++ CONF-IOB/Donati/2004_186/mppar | 2 + CONF-IOB/Donati/2004_186/mpser | 2 + CONF-IOB/Donati/2004_186/readFile.py | 152 +++++ CONF-IOB/Donati/2004_186/readParallela.py | 608 +++++++++++++++++ CONF-IOB/Donati/2004_186/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/2004_186/saveTemp.sh | 17 + CONF-IOB/Donati/2004_186/sendReboot.py | 130 ++++ CONF-IOB/Donati/2004_186/sendRebootIOB | 33 + .../Donati/2004_186/sendRebootIOB.service | 22 + CONF-IOB/Donati/2004_186/setIobConf.sh | 26 + CONF-IOB/Donati/2004_186/unix.py | 31 + CONF-IOB/Donati/2004_186/unix.pyc | Bin 0 -> 669 bytes CONF-IOB/Donati/2004_186/win.py | 32 + CONF-IOB/Donati/2004_186/win.pyc | Bin 0 -> 883 bytes CONF-IOB/Donati/old-FILE/IOB.cfg | 23 + CONF-IOB/Donati/old-FILE/MapoIOB | 40 ++ CONF-IOB/Donati/old-FILE/checkAlive.sh | 20 + CONF-IOB/Donati/old-FILE/crontab | 1 + CONF-IOB/Donati/old-FILE/readParallela.py | 488 +++++++++++++ CONF-IOB/Donati/old-FILE/readSeriale.py | 363 ++++++++++ CONF-IOB/Donati/old-FILE/sendReboot.py | 115 ++++ CONF-IOB/Donati/old-FILE/sendRebootIOB | 31 + CONF-IOB/Donati/old-FILE/unix.py | 31 + CONF-IOB/Donati/old-FILE/win.py | 32 + 502 files changed, 40584 insertions(+) create mode 100644 CONF-IOB/Donati/1000_Pi1/IOB.cfg create mode 100644 CONF-IOB/Donati/1000_Pi1/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1000_Pi1/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1000_Pi1/MapoIOB create mode 100644 CONF-IOB/Donati/1000_Pi1/cleanPython.sh create mode 100644 CONF-IOB/Donati/1000_Pi1/crontab create mode 100644 CONF-IOB/Donati/1000_Pi1/logReboot.txt create mode 100644 CONF-IOB/Donati/1000_Pi1/logfile.txt create mode 100644 CONF-IOB/Donati/1000_Pi1/readParallela.py create mode 100644 CONF-IOB/Donati/1000_Pi1/sendReboot.py create mode 100644 CONF-IOB/Donati/1000_Pi1/sendRebootIOB create mode 100644 CONF-IOB/Donati/1000_Pi1/unix.py create mode 100644 CONF-IOB/Donati/1000_Pi3/IOB.cfg create mode 100644 CONF-IOB/Donati/1000_Pi3/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1000_Pi3/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1000_Pi3/MapoIOB create mode 100644 CONF-IOB/Donati/1000_Pi3/MapoIOB_logrot create mode 100644 CONF-IOB/Donati/1000_Pi3/checkAlive.sh create mode 100644 CONF-IOB/Donati/1000_Pi3/cleanPython.sh create mode 100644 CONF-IOB/Donati/1000_Pi3/convertLogFile.py create mode 100644 CONF-IOB/Donati/1000_Pi3/crontab create mode 100644 CONF-IOB/Donati/1000_Pi3/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/1000_Pi3/logReboot.txt create mode 100644 CONF-IOB/Donati/1000_Pi3/logfile.txt create mode 100644 CONF-IOB/Donati/1000_Pi3/mppar create mode 100644 CONF-IOB/Donati/1000_Pi3/mpser create mode 100644 CONF-IOB/Donati/1000_Pi3/readFile.py create mode 100644 CONF-IOB/Donati/1000_Pi3/readParallela.py create mode 100644 CONF-IOB/Donati/1000_Pi3/readSeriale.py create mode 100644 CONF-IOB/Donati/1000_Pi3/saveTemp.sh create mode 100644 CONF-IOB/Donati/1000_Pi3/sendReboot.py create mode 100644 CONF-IOB/Donati/1000_Pi3/sendRebootIOB create mode 100644 CONF-IOB/Donati/1000_Pi3/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1000_Pi3/setIobConf.sh create mode 100644 CONF-IOB/Donati/1000_Pi3/unix.py create mode 100644 CONF-IOB/Donati/1000_Pi3/unix.pyc create mode 100644 CONF-IOB/Donati/1000_Pi3/win.py create mode 100644 CONF-IOB/Donati/1000_Pi3/win.pyc create mode 100644 CONF-IOB/Donati/1005_149/IOB.cfg create mode 100644 CONF-IOB/Donati/1005_149/MapoIOB create mode 100644 CONF-IOB/Donati/1005_149/MapoIOB_par create mode 100644 CONF-IOB/Donati/1005_149/MapoIOB_ser create mode 100644 CONF-IOB/Donati/1005_149/checkAlive.sh create mode 100644 CONF-IOB/Donati/1005_149/cleanPython.sh create mode 100644 CONF-IOB/Donati/1005_149/logfile.txt create mode 100644 CONF-IOB/Donati/1005_149/mppar create mode 100644 CONF-IOB/Donati/1005_149/mpser create mode 100644 CONF-IOB/Donati/1005_149/python-serial_2.5-2.1_all.deb create mode 100644 CONF-IOB/Donati/1005_149/readParallela.py create mode 100644 CONF-IOB/Donati/1005_149/readSeriale.py create mode 100644 CONF-IOB/Donati/1005_149/sendReboot.py create mode 100644 CONF-IOB/Donati/1005_149/unix.py create mode 100644 CONF-IOB/Donati/1006_151/IOB.cfg create mode 100644 CONF-IOB/Donati/1006_151/MapoIOB create mode 100644 CONF-IOB/Donati/1006_151/MapoIOB.bak create mode 100644 CONF-IOB/Donati/1006_151/checkAlive.sh create mode 100644 CONF-IOB/Donati/1006_151/cleanPython.sh create mode 100644 CONF-IOB/Donati/1006_151/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1006_151/old/readParallela.py create mode 100644 CONF-IOB/Donati/1006_151/readParallela.py create mode 100644 CONF-IOB/Donati/1006_151/sendReboot.py create mode 100644 CONF-IOB/Donati/1006_151/unix.py create mode 100644 CONF-IOB/Donati/1007_152/IOB.cfg create mode 100644 CONF-IOB/Donati/1007_152/MapoIOB create mode 100644 CONF-IOB/Donati/1007_152/checkAlive.sh create mode 100644 CONF-IOB/Donati/1007_152/cleanPython.sh create mode 100644 CONF-IOB/Donati/1007_152/logfile.txt create mode 100644 CONF-IOB/Donati/1007_152/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1007_152/old/readParallela.py create mode 100644 CONF-IOB/Donati/1007_152/readParallela.py create mode 100644 CONF-IOB/Donati/1007_152/sendReboot.py create mode 100644 CONF-IOB/Donati/1007_152/unix.py create mode 100644 CONF-IOB/Donati/1008_153/IOB.cfg create mode 100644 CONF-IOB/Donati/1008_153/MapoIOB create mode 100644 CONF-IOB/Donati/1008_153/checkAlive.sh create mode 100644 CONF-IOB/Donati/1008_153/cleanPython.sh create mode 100644 CONF-IOB/Donati/1008_153/logfile.txt create mode 100644 CONF-IOB/Donati/1008_153/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1008_153/old/readParallela.py create mode 100644 CONF-IOB/Donati/1008_153/readParallela.py create mode 100644 CONF-IOB/Donati/1008_153/sendReboot.py create mode 100644 CONF-IOB/Donati/1008_153/unix.py create mode 100644 CONF-IOB/Donati/1009_154/IOB.cfg create mode 100644 CONF-IOB/Donati/1009_154/MapoIOB create mode 100644 CONF-IOB/Donati/1009_154/checkAlive.sh create mode 100644 CONF-IOB/Donati/1009_154/cleanPython.sh create mode 100644 CONF-IOB/Donati/1009_154/logfile.txt create mode 100644 CONF-IOB/Donati/1009_154/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1009_154/old/readParallela.py create mode 100644 CONF-IOB/Donati/1009_154/readParallela.py create mode 100644 CONF-IOB/Donati/1009_154/readSeriale.py create mode 100644 CONF-IOB/Donati/1009_154/sendReboot.py create mode 100644 CONF-IOB/Donati/1009_154/unix.py create mode 100644 CONF-IOB/Donati/1010_155/IOB.cfg create mode 100644 CONF-IOB/Donati/1010_155/MapoIOB create mode 100644 CONF-IOB/Donati/1010_155/checkAlive.sh create mode 100644 CONF-IOB/Donati/1010_155/cleanPython.sh create mode 100644 CONF-IOB/Donati/1010_155/logfile.txt create mode 100644 CONF-IOB/Donati/1010_155/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1010_155/old/readParallela.py create mode 100644 CONF-IOB/Donati/1010_155/readParallela.py create mode 100644 CONF-IOB/Donati/1010_155/sendReboot.py create mode 100644 CONF-IOB/Donati/1010_155/unix.py create mode 100644 CONF-IOB/Donati/1011_156/IOB.cfg create mode 100644 CONF-IOB/Donati/1011_156/MapoIOB create mode 100644 CONF-IOB/Donati/1011_156/checkAlive.sh create mode 100644 CONF-IOB/Donati/1011_156/logfile.txt create mode 100644 CONF-IOB/Donati/1011_156/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1011_156/old/readParallela.py create mode 100644 CONF-IOB/Donati/1011_156/readParallela.py create mode 100644 CONF-IOB/Donati/1011_156/sendReboot.py create mode 100644 CONF-IOB/Donati/1011_156/unix.py create mode 100644 CONF-IOB/Donati/1011_170/IOB.cfg create mode 100644 CONF-IOB/Donati/1011_170/MapoIOB create mode 100644 CONF-IOB/Donati/1011_170/checkAlive.sh create mode 100644 CONF-IOB/Donati/1011_170/cleanPython.sh create mode 100644 CONF-IOB/Donati/1011_170/logfile.txt create mode 100644 CONF-IOB/Donati/1011_170/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1011_170/old/readParallela.py create mode 100644 CONF-IOB/Donati/1011_170/readParallela.py create mode 100644 CONF-IOB/Donati/1011_170/sendReboot.py create mode 100644 CONF-IOB/Donati/1011_170/unix.py create mode 100644 CONF-IOB/Donati/1012_157/IOB.cfg create mode 100644 CONF-IOB/Donati/1012_157/MapoIOB create mode 100644 CONF-IOB/Donati/1012_157/checkAlive.sh create mode 100644 CONF-IOB/Donati/1012_157/cleanPython.sh create mode 100644 CONF-IOB/Donati/1012_157/logfile.txt create mode 100644 CONF-IOB/Donati/1012_157/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1012_157/old/readParallela.py create mode 100644 CONF-IOB/Donati/1012_157/readParallela.py create mode 100644 CONF-IOB/Donati/1012_157/sendReboot.py create mode 100644 CONF-IOB/Donati/1012_157/sendRebootIOB create mode 100644 CONF-IOB/Donati/1012_157/unix.py create mode 100644 CONF-IOB/Donati/1013_158/IOB.cfg create mode 100644 CONF-IOB/Donati/1013_158/MapoIOB create mode 100644 CONF-IOB/Donati/1013_158/checkAlive.sh create mode 100644 CONF-IOB/Donati/1013_158/cleanPython.sh create mode 100644 CONF-IOB/Donati/1013_158/logfile.txt create mode 100644 CONF-IOB/Donati/1013_158/old/IOB.cfg create mode 100644 CONF-IOB/Donati/1013_158/old/readParallela.py create mode 100644 CONF-IOB/Donati/1013_158/readParallela.py create mode 100644 CONF-IOB/Donati/1013_158/sendReboot.py create mode 100644 CONF-IOB/Donati/1013_158/unix.py create mode 100644 CONF-IOB/Donati/1014_159/IOB.cfg create mode 100644 CONF-IOB/Donati/1014_159/MapoIOB create mode 100644 CONF-IOB/Donati/1014_159/checkAlive.sh create mode 100644 CONF-IOB/Donati/1014_159/cleanPython.sh create mode 100644 CONF-IOB/Donati/1014_159/logfile.txt create mode 100644 CONF-IOB/Donati/1014_159/readParallela.py create mode 100644 CONF-IOB/Donati/1014_159/sendReboot.py create mode 100644 CONF-IOB/Donati/1014_159/unix.py create mode 100644 CONF-IOB/Donati/1015_162/IOB.cfg create mode 100644 CONF-IOB/Donati/1015_162/MapoIOB create mode 100644 CONF-IOB/Donati/1015_162/checkAlive.sh create mode 100644 CONF-IOB/Donati/1015_162/cleanPython.sh create mode 100644 CONF-IOB/Donati/1015_162/logfile.txt create mode 100644 CONF-IOB/Donati/1015_162/readParallela.py create mode 100644 CONF-IOB/Donati/1015_162/sendReboot.py create mode 100644 CONF-IOB/Donati/1015_162/sendRebootIOB create mode 100644 CONF-IOB/Donati/1015_162/unix.py create mode 100644 CONF-IOB/Donati/1016_163/IOB.cfg create mode 100644 CONF-IOB/Donati/1016_163/MapoIOB create mode 100644 CONF-IOB/Donati/1016_163/checkAlive.sh create mode 100644 CONF-IOB/Donati/1016_163/cleanPython.sh create mode 100644 CONF-IOB/Donati/1016_163/logfile.txt create mode 100644 CONF-IOB/Donati/1016_163/readParallela.py create mode 100644 CONF-IOB/Donati/1016_163/sendReboot.py create mode 100644 CONF-IOB/Donati/1016_163/unix.py create mode 100644 CONF-IOB/Donati/1017_164/IOB.cfg create mode 100644 CONF-IOB/Donati/1017_164/MapoIOB create mode 100644 CONF-IOB/Donati/1017_164/checkAlive.sh create mode 100644 CONF-IOB/Donati/1017_164/cleanPython.sh create mode 100644 CONF-IOB/Donati/1017_164/logfile.txt create mode 100644 CONF-IOB/Donati/1017_164/readParallela.py create mode 100644 CONF-IOB/Donati/1017_164/sendReboot.py create mode 100644 CONF-IOB/Donati/1017_164/unix.py create mode 100644 CONF-IOB/Donati/1018_168/IOB.cfg create mode 100644 CONF-IOB/Donati/1018_168/MapoIOB create mode 100644 CONF-IOB/Donati/1018_168/checkAlive.sh create mode 100644 CONF-IOB/Donati/1018_168/cleanPython.sh create mode 100644 CONF-IOB/Donati/1018_168/logfile.txt create mode 100644 CONF-IOB/Donati/1018_168/readParallela.py create mode 100644 CONF-IOB/Donati/1018_168/sendReboot.py create mode 100644 CONF-IOB/Donati/1018_168/unix.py create mode 100644 CONF-IOB/Donati/1019_169/IOB.cfg create mode 100644 CONF-IOB/Donati/1019_169/MapoIOB create mode 100644 CONF-IOB/Donati/1019_169/checkAlive.sh create mode 100644 CONF-IOB/Donati/1019_169/cleanPython.sh create mode 100644 CONF-IOB/Donati/1019_169/logfile.txt create mode 100644 CONF-IOB/Donati/1019_169/readParallela.py create mode 100644 CONF-IOB/Donati/1019_169/sendReboot.py create mode 100644 CONF-IOB/Donati/1019_169/unix.py create mode 100644 CONF-IOB/Donati/1020_165/IOB.cfg create mode 100644 CONF-IOB/Donati/1020_165/MapoIOB create mode 100644 CONF-IOB/Donati/1020_165/checkAlive.sh create mode 100644 CONF-IOB/Donati/1020_165/cleanPython.sh create mode 100644 CONF-IOB/Donati/1020_165/logfile.txt create mode 100644 CONF-IOB/Donati/1020_165/readParallela.py create mode 100644 CONF-IOB/Donati/1020_165/sendReboot.py create mode 100644 CONF-IOB/Donati/1020_165/unix.py create mode 100644 CONF-IOB/Donati/1021_167/IOB.cfg create mode 100644 CONF-IOB/Donati/1021_167/MapoIOB create mode 100644 CONF-IOB/Donati/1021_167/checkAlive.sh create mode 100644 CONF-IOB/Donati/1021_167/cleanPython.sh create mode 100644 CONF-IOB/Donati/1021_167/logfile.txt create mode 100644 CONF-IOB/Donati/1021_167/readParallela.py create mode 100644 CONF-IOB/Donati/1021_167/sendReboot.py create mode 100644 CONF-IOB/Donati/1021_167/unix.py create mode 100644 CONF-IOB/Donati/1022_166/IOB.cfg create mode 100644 CONF-IOB/Donati/1022_166/MapoIOB create mode 100644 CONF-IOB/Donati/1022_166/checkAlive.sh create mode 100644 CONF-IOB/Donati/1022_166/cleanPython.sh create mode 100644 CONF-IOB/Donati/1022_166/logfile.txt create mode 100644 CONF-IOB/Donati/1022_166/readParallela.py create mode 100644 CONF-IOB/Donati/1022_166/sendReboot.py create mode 100644 CONF-IOB/Donati/1022_166/unix.py create mode 100644 CONF-IOB/Donati/1024_177/IOB.cfg create mode 100644 CONF-IOB/Donati/1024_177/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1024_177/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1024_177/MapoIOB create mode 100644 CONF-IOB/Donati/1024_177/checkAlive.sh create mode 100644 CONF-IOB/Donati/1024_177/cleanPython.sh create mode 100644 CONF-IOB/Donati/1024_177/crontab create mode 100644 CONF-IOB/Donati/1024_177/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/1024_177/mppar create mode 100644 CONF-IOB/Donati/1024_177/mpser create mode 100644 CONF-IOB/Donati/1024_177/readParallela.py create mode 100644 CONF-IOB/Donati/1024_177/readSeriale.py create mode 100644 CONF-IOB/Donati/1024_177/saveTemp.sh create mode 100644 CONF-IOB/Donati/1024_177/sendReboot.py create mode 100644 CONF-IOB/Donati/1024_177/sendRebootIOB create mode 100644 CONF-IOB/Donati/1024_177/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1024_177/setIobConf.sh create mode 100644 CONF-IOB/Donati/1024_177/test.py create mode 100644 CONF-IOB/Donati/1024_177/unix.py create mode 100644 CONF-IOB/Donati/1024_177/unix.pyc create mode 100644 CONF-IOB/Donati/1024_177/win.py create mode 100644 CONF-IOB/Donati/1024_177/win.pyc create mode 100644 CONF-IOB/Donati/1025_178/IOB.cfg create mode 100644 CONF-IOB/Donati/1025_178/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1025_178/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1025_178/MapoIOB create mode 100644 CONF-IOB/Donati/1025_178/checkAlive.sh create mode 100644 CONF-IOB/Donati/1025_178/cleanPython.sh create mode 100644 CONF-IOB/Donati/1025_178/crontab create mode 100644 CONF-IOB/Donati/1025_178/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/1025_178/mppar create mode 100644 CONF-IOB/Donati/1025_178/mpser create mode 100644 CONF-IOB/Donati/1025_178/readParallela.py create mode 100644 CONF-IOB/Donati/1025_178/readSeriale.py create mode 100644 CONF-IOB/Donati/1025_178/saveTemp.sh create mode 100644 CONF-IOB/Donati/1025_178/sendReboot.py create mode 100644 CONF-IOB/Donati/1025_178/sendRebootIOB create mode 100644 CONF-IOB/Donati/1025_178/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1025_178/setIobConf.sh create mode 100644 CONF-IOB/Donati/1025_178/test.py create mode 100644 CONF-IOB/Donati/1025_178/unix.py create mode 100644 CONF-IOB/Donati/1025_178/unix.pyc create mode 100644 CONF-IOB/Donati/1025_178/win.py create mode 100644 CONF-IOB/Donati/1025_178/win.pyc create mode 100644 CONF-IOB/Donati/1026_180/IOB.cfg create mode 100644 CONF-IOB/Donati/1026_180/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1026_180/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1026_180/MapoIOB create mode 100644 CONF-IOB/Donati/1026_180/checkAlive.sh create mode 100644 CONF-IOB/Donati/1026_180/cleanPython.sh create mode 100644 CONF-IOB/Donati/1026_180/crontab create mode 100644 CONF-IOB/Donati/1026_180/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/1026_180/mppar create mode 100644 CONF-IOB/Donati/1026_180/mpser create mode 100644 CONF-IOB/Donati/1026_180/readParallela.py create mode 100644 CONF-IOB/Donati/1026_180/readSeriale.py create mode 100644 CONF-IOB/Donati/1026_180/saveTemp.sh create mode 100644 CONF-IOB/Donati/1026_180/sendReboot.py create mode 100644 CONF-IOB/Donati/1026_180/sendRebootIOB create mode 100644 CONF-IOB/Donati/1026_180/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1026_180/setIobConf.sh create mode 100644 CONF-IOB/Donati/1026_180/test.py create mode 100644 CONF-IOB/Donati/1026_180/unix.py create mode 100644 CONF-IOB/Donati/1026_180/unix.pyc create mode 100644 CONF-IOB/Donati/1026_180/win.py create mode 100644 CONF-IOB/Donati/1026_180/win.pyc create mode 100644 CONF-IOB/Donati/1027 - 185/IOB.cfg create mode 100644 CONF-IOB/Donati/1027 - 185/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/1027 - 185/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/1027 - 185/MapoIOB create mode 100644 CONF-IOB/Donati/1027 - 185/checkAlive.sh create mode 100644 CONF-IOB/Donati/1027 - 185/cleanPython.sh create mode 100644 CONF-IOB/Donati/1027 - 185/crontab create mode 100644 CONF-IOB/Donati/1027 - 185/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/1027 - 185/mppar create mode 100644 CONF-IOB/Donati/1027 - 185/mpser create mode 100644 CONF-IOB/Donati/1027 - 185/readParallela.py create mode 100644 CONF-IOB/Donati/1027 - 185/readSeriale.py create mode 100644 CONF-IOB/Donati/1027 - 185/saveTemp.sh create mode 100644 CONF-IOB/Donati/1027 - 185/sendReboot.py create mode 100644 CONF-IOB/Donati/1027 - 185/sendRebootIOB create mode 100644 CONF-IOB/Donati/1027 - 185/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1027 - 185/setIobConf.sh create mode 100644 CONF-IOB/Donati/1027 - 185/test.py create mode 100644 CONF-IOB/Donati/1027 - 185/unix.py create mode 100644 CONF-IOB/Donati/1027 - 185/unix.pyc create mode 100644 CONF-IOB/Donati/1027 - 185/win.py create mode 100644 CONF-IOB/Donati/1027 - 185/win.pyc create mode 100644 CONF-IOB/Donati/1501_172/IOB.cfg create mode 100644 CONF-IOB/Donati/1501_172/LogoHighResWhite.png create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO.html create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_b.html create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSans.woff create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSansCondensed.woff create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/bootstrap create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/css create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/jquery create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/jqueryval create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/logoSteamware.png create mode 100644 CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/modernizr create mode 100644 CONF-IOB/Donati/1501_172/install-RPI-MON.sh create mode 100644 CONF-IOB/Donati/1501_172/logBrowser.txt create mode 100644 CONF-IOB/Donati/1501_172/logReboot.txt create mode 100644 CONF-IOB/Donati/1501_172/logTemp.txt create mode 100644 CONF-IOB/Donati/1501_172/restartBrowser.sh create mode 100644 CONF-IOB/Donati/1501_172/saveTemp.sh create mode 100644 CONF-IOB/Donati/1501_172/sendReboot.py create mode 100644 CONF-IOB/Donati/1501_172/sendRebootIOB create mode 100644 CONF-IOB/Donati/1501_172/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1501_172/startBrowser.sh create mode 100644 CONF-IOB/Donati/1501_172/testNet.sh create mode 100644 CONF-IOB/Donati/1502_173/IOB.cfg create mode 100644 CONF-IOB/Donati/1502_173/LogoHighResWhite.png create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO.html create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_b.html create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/OpenSans.woff create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/OpenSansCondensed.woff create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/bootstrap create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/css create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/jquery create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/jqueryval create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/logoSteamware.png create mode 100644 CONF-IOB/Donati/1502_173/MP-MON-DEMO_files/modernizr create mode 100644 CONF-IOB/Donati/1502_173/READ.me create mode 100644 CONF-IOB/Donati/1502_173/install-RPI-MON.sh create mode 100644 CONF-IOB/Donati/1502_173/logBrowser.txt create mode 100644 CONF-IOB/Donati/1502_173/logReboot.txt create mode 100644 CONF-IOB/Donati/1502_173/logTemp.txt create mode 100644 CONF-IOB/Donati/1502_173/saveTemp.sh create mode 100644 CONF-IOB/Donati/1502_173/sendReboot.py create mode 100644 CONF-IOB/Donati/1502_173/sendRebootIOB create mode 100644 CONF-IOB/Donati/1502_173/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1502_173/startBrowser.sh create mode 100644 CONF-IOB/Donati/1502_173/testNet.sh create mode 100644 CONF-IOB/Donati/1503_174/IOB.cfg create mode 100644 CONF-IOB/Donati/1503_174/LogoHighResWhite.png create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO.html create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_b.html create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/OpenSans.woff create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/OpenSansCondensed.woff create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/bootstrap create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/css create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/jquery create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/jqueryval create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/logoSteamware.png create mode 100644 CONF-IOB/Donati/1503_174/MP-MON-DEMO_files/modernizr create mode 100644 CONF-IOB/Donati/1503_174/READ.me create mode 100644 CONF-IOB/Donati/1503_174/install-RPI-MON.sh create mode 100644 CONF-IOB/Donati/1503_174/logBrowser.txt create mode 100644 CONF-IOB/Donati/1503_174/logReboot.txt create mode 100644 CONF-IOB/Donati/1503_174/logTemp.txt create mode 100644 CONF-IOB/Donati/1503_174/saveTemp.sh create mode 100644 CONF-IOB/Donati/1503_174/sendReboot.py create mode 100644 CONF-IOB/Donati/1503_174/sendRebootIOB create mode 100644 CONF-IOB/Donati/1503_174/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1503_174/startBrowser.sh create mode 100644 CONF-IOB/Donati/1503_174/testNet.sh create mode 100644 CONF-IOB/Donati/1504_175/IOB.cfg create mode 100644 CONF-IOB/Donati/1504_175/LogoHighResWhite.png create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO.html create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_b.html create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/OpenSans.woff create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/OpenSansCondensed.woff create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/bootstrap create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/css create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/jquery create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/jqueryval create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/logoSteamware.png create mode 100644 CONF-IOB/Donati/1504_175/MP-MON-DEMO_files/modernizr create mode 100644 CONF-IOB/Donati/1504_175/READ.me create mode 100644 CONF-IOB/Donati/1504_175/install-RPI-MON.sh create mode 100644 CONF-IOB/Donati/1504_175/logBrowser.txt create mode 100644 CONF-IOB/Donati/1504_175/logReboot.txt create mode 100644 CONF-IOB/Donati/1504_175/logTemp.txt create mode 100644 CONF-IOB/Donati/1504_175/saveTemp.sh create mode 100644 CONF-IOB/Donati/1504_175/sendReboot.py create mode 100644 CONF-IOB/Donati/1504_175/sendRebootIOB create mode 100644 CONF-IOB/Donati/1504_175/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/1504_175/startBrowser.sh create mode 100644 CONF-IOB/Donati/1504_175/testNet.sh create mode 100644 CONF-IOB/Donati/2001_184/IOB.cfg create mode 100644 CONF-IOB/Donati/2001_184/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/2001_184/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/2001_184/MapoIOB create mode 100644 CONF-IOB/Donati/2001_184/MapoIOB_logrot create mode 100644 CONF-IOB/Donati/2001_184/checkAlive.sh create mode 100644 CONF-IOB/Donati/2001_184/cleanPython.sh create mode 100644 CONF-IOB/Donati/2001_184/convertLogFile.py create mode 100644 CONF-IOB/Donati/2001_184/crontab create mode 100644 CONF-IOB/Donati/2001_184/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/2001_184/mppar create mode 100644 CONF-IOB/Donati/2001_184/mpser create mode 100644 CONF-IOB/Donati/2001_184/readFile.py create mode 100644 CONF-IOB/Donati/2001_184/readParallela.py create mode 100644 CONF-IOB/Donati/2001_184/readSeriale.py create mode 100644 CONF-IOB/Donati/2001_184/saveTemp.sh create mode 100644 CONF-IOB/Donati/2001_184/sendReboot.py create mode 100644 CONF-IOB/Donati/2001_184/sendRebootIOB create mode 100644 CONF-IOB/Donati/2001_184/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/2001_184/setIobConf.sh create mode 100644 CONF-IOB/Donati/2001_184/unix.py create mode 100644 CONF-IOB/Donati/2001_184/unix.pyc create mode 100644 CONF-IOB/Donati/2001_184/win.py create mode 100644 CONF-IOB/Donati/2001_184/win.pyc create mode 100644 CONF-IOB/Donati/2002_183/IOB.cfg create mode 100644 CONF-IOB/Donati/2002_183/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/2002_183/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/2002_183/MapoIOB create mode 100644 CONF-IOB/Donati/2002_183/MapoIOB_logrot create mode 100644 CONF-IOB/Donati/2002_183/checkAlive.sh create mode 100644 CONF-IOB/Donati/2002_183/cleanPython.sh create mode 100644 CONF-IOB/Donati/2002_183/convertLogFile.py create mode 100644 CONF-IOB/Donati/2002_183/crontab create mode 100644 CONF-IOB/Donati/2002_183/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/2002_183/mppar create mode 100644 CONF-IOB/Donati/2002_183/mpser create mode 100644 CONF-IOB/Donati/2002_183/readFile.py create mode 100644 CONF-IOB/Donati/2002_183/readParallela.py create mode 100644 CONF-IOB/Donati/2002_183/readSeriale.py create mode 100644 CONF-IOB/Donati/2002_183/saveTemp.sh create mode 100644 CONF-IOB/Donati/2002_183/sendReboot.py create mode 100644 CONF-IOB/Donati/2002_183/sendRebootIOB create mode 100644 CONF-IOB/Donati/2002_183/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/2002_183/setIobConf.sh create mode 100644 CONF-IOB/Donati/2002_183/unix.py create mode 100644 CONF-IOB/Donati/2002_183/unix.pyc create mode 100644 CONF-IOB/Donati/2002_183/win.py create mode 100644 CONF-IOB/Donati/2002_183/win.pyc create mode 100644 CONF-IOB/Donati/2003_187/IOB.cfg create mode 100644 CONF-IOB/Donati/2003_187/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/2003_187/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/2003_187/MapoIOB create mode 100644 CONF-IOB/Donati/2003_187/MapoIOB_logrot create mode 100644 CONF-IOB/Donati/2003_187/checkAlive.sh create mode 100644 CONF-IOB/Donati/2003_187/cleanPython.sh create mode 100644 CONF-IOB/Donati/2003_187/convertLogFile.py create mode 100644 CONF-IOB/Donati/2003_187/crontab create mode 100644 CONF-IOB/Donati/2003_187/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/2003_187/mppar create mode 100644 CONF-IOB/Donati/2003_187/mpser create mode 100644 CONF-IOB/Donati/2003_187/readFile.py create mode 100644 CONF-IOB/Donati/2003_187/readParallela.py create mode 100644 CONF-IOB/Donati/2003_187/readSeriale.py create mode 100644 CONF-IOB/Donati/2003_187/saveTemp.sh create mode 100644 CONF-IOB/Donati/2003_187/sendReboot.py create mode 100644 CONF-IOB/Donati/2003_187/sendRebootIOB create mode 100644 CONF-IOB/Donati/2003_187/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/2003_187/setIobConf.sh create mode 100644 CONF-IOB/Donati/2003_187/unix.py create mode 100644 CONF-IOB/Donati/2003_187/unix.pyc create mode 100644 CONF-IOB/Donati/2003_187/win.py create mode 100644 CONF-IOB/Donati/2003_187/win.pyc create mode 100644 CONF-IOB/Donati/2004_186/IOB.cfg create mode 100644 CONF-IOB/Donati/2004_186/IOB.cfg.donati create mode 100644 CONF-IOB/Donati/2004_186/IOB.cfg.steamware create mode 100644 CONF-IOB/Donati/2004_186/MapoIOB create mode 100644 CONF-IOB/Donati/2004_186/MapoIOB_logrot create mode 100644 CONF-IOB/Donati/2004_186/checkAlive.sh create mode 100644 CONF-IOB/Donati/2004_186/cleanPython.sh create mode 100644 CONF-IOB/Donati/2004_186/convertLogFile.py create mode 100644 CONF-IOB/Donati/2004_186/crontab create mode 100644 CONF-IOB/Donati/2004_186/install-RPI-IOB.sh create mode 100644 CONF-IOB/Donati/2004_186/mppar create mode 100644 CONF-IOB/Donati/2004_186/mpser create mode 100644 CONF-IOB/Donati/2004_186/readFile.py create mode 100644 CONF-IOB/Donati/2004_186/readParallela.py create mode 100644 CONF-IOB/Donati/2004_186/readSeriale.py create mode 100644 CONF-IOB/Donati/2004_186/saveTemp.sh create mode 100644 CONF-IOB/Donati/2004_186/sendReboot.py create mode 100644 CONF-IOB/Donati/2004_186/sendRebootIOB create mode 100644 CONF-IOB/Donati/2004_186/sendRebootIOB.service create mode 100644 CONF-IOB/Donati/2004_186/setIobConf.sh create mode 100644 CONF-IOB/Donati/2004_186/unix.py create mode 100644 CONF-IOB/Donati/2004_186/unix.pyc create mode 100644 CONF-IOB/Donati/2004_186/win.py create mode 100644 CONF-IOB/Donati/2004_186/win.pyc create mode 100644 CONF-IOB/Donati/old-FILE/IOB.cfg create mode 100644 CONF-IOB/Donati/old-FILE/MapoIOB create mode 100644 CONF-IOB/Donati/old-FILE/checkAlive.sh create mode 100644 CONF-IOB/Donati/old-FILE/crontab create mode 100644 CONF-IOB/Donati/old-FILE/readParallela.py create mode 100644 CONF-IOB/Donati/old-FILE/readSeriale.py create mode 100644 CONF-IOB/Donati/old-FILE/sendReboot.py create mode 100644 CONF-IOB/Donati/old-FILE/sendRebootIOB create mode 100644 CONF-IOB/Donati/old-FILE/unix.py create mode 100644 CONF-IOB/Donati/old-FILE/win.py diff --git a/CONF-IOB/Donati/1000_Pi1/IOB.cfg b/CONF-IOB/Donati/1000_Pi1/IOB.cfg new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1000_Pi1/IOB.cfg.donati b/CONF-IOB/Donati/1000_Pi1/IOB.cfg.donati new file mode 100644 index 0000000..ee07860 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/IOB.cfg.donati @@ -0,0 +1,24 @@ +[id] +idxMacchina = 1002 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 + diff --git a/CONF-IOB/Donati/1000_Pi1/IOB.cfg.steamware b/CONF-IOB/Donati/1000_Pi1/IOB.cfg.steamware new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/IOB.cfg.steamware @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1000_Pi1/MapoIOB b/CONF-IOB/Donati/1000_Pi1/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1000_Pi1/cleanPython.sh b/CONF-IOB/Donati/1000_Pi1/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1000_Pi1/crontab b/CONF-IOB/Donati/1000_Pi1/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1000_Pi1/logReboot.txt b/CONF-IOB/Donati/1000_Pi1/logReboot.txt new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/logReboot.txt @@ -0,0 +1 @@ + diff --git a/CONF-IOB/Donati/1000_Pi1/logfile.txt b/CONF-IOB/Donati/1000_Pi1/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1000_Pi1/readParallela.py b/CONF-IOB/Donati/1000_Pi1/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1000_Pi1/sendReboot.py b/CONF-IOB/Donati/1000_Pi1/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1000_Pi1/sendRebootIOB b/CONF-IOB/Donati/1000_Pi1/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1000_Pi1/unix.py b/CONF-IOB/Donati/1000_Pi1/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi1/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1000_Pi3/IOB.cfg b/CONF-IOB/Donati/1000_Pi3/IOB.cfg new file mode 100644 index 0000000..ac044d0 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/IOB.cfg @@ -0,0 +1,35 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MP/IO/IOB/input/ +URLALIVE = http://10.74.82.219/MP/IO/IOB +URLENABLED = http://10.74.82.219/MP/IO/IOB/enabled/ +URLADV1 = ?valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.05 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.15 +NMAXSEND = 5 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 + +[blink] +MAX_COUNTER_BLINK = 30 +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 1 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 diff --git a/CONF-IOB/Donati/1000_Pi3/IOB.cfg.donati b/CONF-IOB/Donati/1000_Pi3/IOB.cfg.donati new file mode 100644 index 0000000..a6408ee --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/IOB.cfg.donati @@ -0,0 +1,35 @@ +[id] +idxMacchina = 0 + +[web] +URLBASE = http://192.168.51.77/MP/IO/IOB/input/ +URLALIVE = http://192.168.51.77/MP/IO/IOB +URLENABLED = http://192.168.51.77/MP/IO/IOB/enabled/ +URLADV1 = ?valore= +URLREBO = http://192.168.51.77/MP/IO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.05 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.15 +NMAXSEND = 5 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 + +[blink] +MAX_COUNTER_BLINK = 30 +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 1 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 diff --git a/CONF-IOB/Donati/1000_Pi3/IOB.cfg.steamware b/CONF-IOB/Donati/1000_Pi3/IOB.cfg.steamware new file mode 100644 index 0000000..ac044d0 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/IOB.cfg.steamware @@ -0,0 +1,35 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MP/IO/IOB/input/ +URLALIVE = http://10.74.82.219/MP/IO/IOB +URLENABLED = http://10.74.82.219/MP/IO/IOB/enabled/ +URLADV1 = ?valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.05 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.15 +NMAXSEND = 5 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 + +[blink] +MAX_COUNTER_BLINK = 30 +bit0 = 0 +bit1 = 0 +bit2 = 0 +bit3 = 1 +bit4 = 0 +bit5 = 0 +bit6 = 0 +bit7 = 0 diff --git a/CONF-IOB/Donati/1000_Pi3/MapoIOB b/CONF-IOB/Donati/1000_Pi3/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1000_Pi3/MapoIOB_logrot b/CONF-IOB/Donati/1000_Pi3/MapoIOB_logrot new file mode 100644 index 0000000..13410b9 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/MapoIOB_logrot @@ -0,0 +1,28 @@ +/var/log/MapoIOB.log { + size 8M + copytruncate + create 700 pi pi + dateext + rotate 100 + compress + maxage 366 + missingok +} +/var/log/logReboot.txt { + size 1M + copytruncate + create 700 pi pi + dateext + rotate 30 + compress + missingok +} +/var/log/logTemp.txt { + size 1M + copytruncate + create 700 pi pi + dateext + rotate 30 + compress + missingok +} diff --git a/CONF-IOB/Donati/1000_Pi3/checkAlive.sh b/CONF-IOB/Donati/1000_Pi3/checkAlive.sh new file mode 100644 index 0000000..aace73d --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB.log ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB.log' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1000_Pi3/cleanPython.sh b/CONF-IOB/Donati/1000_Pi3/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1000_Pi3/convertLogFile.py b/CONF-IOB/Donati/1000_Pi3/convertLogFile.py new file mode 100644 index 0000000..760c2a9 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/convertLogFile.py @@ -0,0 +1,46 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readFile v. 0.1 +# - single instance timer +# - invio multiplo x send eventi accodati +#--------------------------------------------------------------- +import os, sys +import argparse +#-------------------------------------------------------------- + +# gestione parser argomenti in input +parser = argparse.ArgumentParser() +parser.add_argument("inFile") +parser.add_argument("outFile") +args = parser.parse_args() + +#with open('logfile.txt', 'r') as inf, open('persMem.dat',"w") as outf: +with open(args.inFile, 'r') as inf, open(args.outFile,"w") as outf: + data = inf.readlines() + + lastDt = "" + lastMs = 0 + stepMs = 200 + + for line in data: + words = line.split() + if words[2] == 'queue': + # recupero dataOra + newDt = words[0].replace("-","") + words[1].replace(":","") + + # verifico se data/ora identica... + if (lastDt == newDt): + # --> aggiungo stepMs + lastMs += stepMs + else: + lastMs = 0 + + lastDt = newDt + + newDt = newDt + '{:03d}'.format(lastMs) #str(lastMs) + #print words[0].replace("-","") + words[1].replace(":","") + " | " + newDt + "\n" + + # print words + # outf.write(words[0].replace("-","") + words[1].replace(":","") + '#' + words[4].replace(">","") + '#' + words[5].replace("[","").replace("]","") +'\n') + outf.write(newDt + '#' + words[4].replace(">","") + '#' + words[5].replace("[","").replace("]","") +'\n') \ No newline at end of file diff --git a/CONF-IOB/Donati/1000_Pi3/crontab b/CONF-IOB/Donati/1000_Pi3/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1000_Pi3/install-RPI-IOB.sh b/CONF-IOB/Donati/1000_Pi3/install-RPI-IOB.sh new file mode 100644 index 0000000..7de1dc1 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/install-RPI-IOB.sh @@ -0,0 +1,51 @@ +#|/bin/bash + +#installa il necessario per RPI-3-IOB partendo dal contenuto della folder /home/pi/steamware + +#step 1: creo file di log nuovi +rm /var/log/log*.txt +rm /var/log/MapoIOB* +rm /home/pi/steamware/log*.txt + +touch /var/log/logReboot.txt +touch /var/log/logTemp.txt +touch /var/log/MapoIOB.log + +ln -sf /var/log/logReboot.txt /home/pi/steamware/logReboot.txt +ln -sf /var/log/logTemp.txt /home/pi/steamware/logTemp.txt +ln -sf /var/log/MapoIOB.log /home/pi/steamware/logfile.txt + +chown pi:pi /home/pi -R +chmod 666 /var/log/log*.txt +chmod 666 /var/log/MapoIOB.log + +#step 2: copio files in /usr/local/bin +cd /home/pi/steamware +chmod +x *.sh +cp *.sh /usr/local/bin/ + +#step 3: copio files x logrotate... +cd /home/pi/steamware +cp MapoIOB_logrot /etc/logrotate.d/ + +# step 4: copio target systemd in avvio... +cp -f sendRebootIOB /etc/init.d/sendRebootIOB +cp -f sendRebootIOB.service /etc/systemd/system/sendRebootIOB.service +echo "" +echo "-----------------------------------------------" +echo "Completare registrazione servizio avvio: digitare i seguenti comandi" +echo "systemctl enable sendRebootIOB" +echo "systemctl daemon-reload" +echo "systemctl status sendRebootIOB" +echo "-----------------------------------------------" +echo "" +echo "" +echo "" +echo "-----------------------------------------------" +echo "Infine creare voce crontab che salvi temperatura CPU/GPU ogni 20 minuti..." +echo "crontab -e" +echo "*/20 * * * * /usr/local/bin/saveTemp.sh" +echo "-----------------------------------------------" + + + diff --git a/CONF-IOB/Donati/1000_Pi3/logReboot.txt b/CONF-IOB/Donati/1000_Pi3/logReboot.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1000_Pi3/logfile.txt b/CONF-IOB/Donati/1000_Pi3/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1000_Pi3/mppar b/CONF-IOB/Donati/1000_Pi3/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1000_Pi3/mpser b/CONF-IOB/Donati/1000_Pi3/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1000_Pi3/readFile.py b/CONF-IOB/Donati/1000_Pi3/readFile.py new file mode 100644 index 0000000..887118d --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/readFile.py @@ -0,0 +1,152 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readFile v. 0.1 +# - single instance timer +# - invio multiplo x send eventi accodati + +#--------------------------------------------------------------- + +import time + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import Queue + +import argparse +#-------------------------------------------------------------- + +# gestione parser argomenti in input +parser = argparse.ArgumentParser() +parser.add_argument("memFile") +parser.add_argument("logFile") +args = parser.parse_args() + +#definizione variabili BASE +stepQueuePut=25000 +stepQueueGet=250 +NMAXSEND=500000 # limite invio file x fare prove... +idxMacchina = "2003" + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda illimitata" +Coda = Queue.Queue(0) + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(valore): + + try: + Coda.put(valore) + except Queue.Full: + logPro.error( "Queue full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#-------------------------------------------------------------- +# svuotaCoda x invio dati al server +def svuota_coda(): + + global NMAXSEND + + try: + if not Coda.empty(): + # invio SOLO i primi NMAXSEND eventi... SE minore del num eventi... + if NMAXSEND > Coda.qsize(): + NMAXSEND = Coda.qsize() + + + i = 0 + + with open(args.logFile,"w") as outf: + while i <= NMAXSEND: + if not Coda.empty(): + + # formatto dataOra corrente + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + + #prendo primo elemento dalla coda + resp = Coda.get() + + # recupero valori da elemento coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + + # registro chiamata + risposta + # outf.write(url + " --> " + answ3 + "\n") + + # incremento e controllo se mostrare output + i += 1 + if (i % stepQueueGet) == 0: + print "Inviati %d valori..." % i + + print "Inviati %d valori..." % i + except: + print "Errore in svuotamento coda!" + + +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + # NMAXSEND = config.getint ( 'time' , 'NMAXSEND' ) + # idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#--------------------------------------------------------------- + +dtCurr = datetime.utcnow().strftime('%H:%M:%S.%f')[:-3] +print "Inizio elaborazione: %s" % dtCurr + +# Leggo il file! +i = 0 +with open(args.memFile, 'r') as inf, open(args.logFile,"w") as outf: + data = inf.readlines() + + print "Trovate %d da processare..." % len(data) + +# leggo e metto in QUEUE... + for line in data: + accoda(line) + i += 1 + if (i % stepQueuePut) == 0: + print "Accodati %d valori..." % i + +print "Completata lettura file! %d righe accodate da trasmettere" % Coda.qsize() + +dtCurr = datetime.utcnow().strftime('%H:%M:%S.%f')[:-3] +print "Inizio invio: %s" % dtCurr + + +# chiamo procedura x svuotare coda... +svuota_coda() + +dtCurr = datetime.utcnow().strftime('%H:%M:%S.%f')[:-3] +print "Completato invio: %s" % dtCurr \ No newline at end of file diff --git a/CONF-IOB/Donati/1000_Pi3/readParallela.py b/CONF-IOB/Donati/1000_Pi3/readParallela.py new file mode 100644 index 0000000..a1e5489 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/readParallela.py @@ -0,0 +1,641 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 2.0 +# - single instance timer +# - invio multiplo x send eventi accodati +# - gestione segnali BLINKING + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue + +from array import * + +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# numero campioni filtraggio segnale ballerino +MAX_COUNTER_BLINK = 10 + +PROGRAM_NAME ="ReadPar IOB-pi v.2.0" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 +NMAXSEND = 5 # numero massimo di invii per singolo ciclo di svuotamento + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 9999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +# +# array per ingressi filtrati + +i_counters = array ( 'i',[0,0,0,0,0,0,0,0]) +B_blinking = array ( 'B',[0,0,0,0,0,0,0,0]) +B_previous = array ( 'B',[0,0,0,0,0,0,0,0]) +B_input = array ( 'B',[0,0,0,0,0,0,0,0]) +B_output = array ( 'B',[0,0,0,0,0,0,0,0]) + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda illimitata" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallelaFiltrata(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + + + try: + + if GPIO.input(in_0): + B_input[0] = 0 + else: + B_input[0] = 1 + + if GPIO.input(in_1): + B_input[1] = 0 + else: + B_input[1] = 1 + + if GPIO.input(in_2): + B_input[2] = 0 + else: + B_input[2] = 1 + + if GPIO.input(in_3): + B_input[3] = 0 + else: + B_input[3] = 1 + + if GPIO.input(in_4): + B_input[4] = 0 + else: + B_input[4] = 1 + + if GPIO.input(in_5): + B_input[5] = 0 + else: + B_input[5] = 1 + + if GPIO.input(in_6): + B_input[6] = 0 + else: + B_input[6] = 1 + + if GPIO.input(in_7): + B_input[7] = 0 + else: + B_input[7] = 1 + + + + #ciclo per ogni segnale + for i in xrange(8) : + + # print (i) + # se non blinking, copia ingresso + if ( B_blinking[i] == 0 ) : + B_output[i] = B_input[i] + else: + + # gestione segnale blinking + + # se fronte del segnale + if ( B_previous[i] != B_input[i] ) : + + B_previous[i] = B_input[i] + + # se fronte di salita + if ( B_input[i] == 1 ) : + # subito uscita = 1 + B_output[i] = 1 + i_counters[i] = MAX_COUNTER_BLINK + else : + # loggo che ho rilevato un blink... + if (LOGLEVEL > 5) : + logPro.info("Blink down on bit " + `i`) + else: + # no , segnale eguale a prima + # se input a 0 + if ( B_input[i] == 0 ) : + + # E CONTEGGIO IN CORSO + if ( i_counters[i] > 0 ) : + + i_counters[i] = i_counters[i] -1 + if ( i_counters[i] == 0 ) : + + B_output[i] = 0 + # loggo che ho CONFERMATO un cambio fronte... + if (LOGLEVEL > 5) : + logPro.info("END Blink on bit " + `i` ) + + #Rimettiamo insieme i bit + new_value = 0 + + if ( B_output[0] == 1 ) : + new_value = new_value + 1 + + if ( B_output[1] == 1 ) : + new_value = new_value + 2 + + if ( B_output[2] == 1 ) : + new_value = new_value + 4 + + if ( B_output[3] == 1 ) : + new_value = new_value + 8 + + if ( B_output[4] == 1 ) : + new_value = new_value + 16 + + if ( B_output[5] == 1 ) : + new_value = new_value + 32 + + if ( B_output[6] == 1 ) : + new_value = new_value + 64 + + if ( B_output[7] == 1 ) : + new_value = new_value + 128 + + current = hex( new_value ).replace ( "0x" , "" ).upper() + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Queue full" + `dtEve` + '#' + `value` + '#' + `cont` ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# svuotaCoda x invio dati al server +def svuota_coda(): + + global onLine + global sending + global timer_busy + global NMAXSEND + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # SAM 2016.12.23: modifica x invio FINO A nMaxSend ELEMENTI ad ogni ciclo di svuotamento + i = NMAXSEND + + while i >= 0: + if not Coda.empty(): + + # formatto dataOra corrente + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + + #prendo primo elemento dalla coda + resp = Coda.get() + + # recupero valori da elemento coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # tolgo 1 al contatore + i -= 1 + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 10000 # round robin 10000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + NMAXSEND = config.getint ( 'time' , 'NMAXSEND' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) + + B_blinking[0] = config.getint ( 'blink' , 'bit0' ) + B_blinking[1] = config.getint ( 'blink' , 'bit1' ) + B_blinking[2] = config.getint ( 'blink' , 'bit2' ) + B_blinking[3] = config.getint ( 'blink' , 'bit3' ) + B_blinking[4] = config.getint ( 'blink' , 'bit4' ) + B_blinking[5] = config.getint ( 'blink' , 'bit5' ) + B_blinking[6] = config.getint ( 'blink' , 'bit6' ) + B_blinking[7] = config.getint ( 'blink' , 'bit7' ) + + MAX_COUNTER_BLINK = config.getint ( 'blink' , 'MAX_COUNTER_BLINK' ) + + +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallelaFiltrata() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG diff --git a/CONF-IOB/Donati/1000_Pi3/readSeriale.py b/CONF-IOB/Donati/1000_Pi3/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1000_Pi3/saveTemp.sh b/CONF-IOB/Donati/1000_Pi3/saveTemp.sh new file mode 100644 index 0000000..a2cd2be --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/saveTemp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#salva la temperatura CPU e GPU su chiamata... + +# imposto logfile... +logFile="/var/log/logTemp.txt" + +cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp) +cpuTemp1=$(($cpuTemp0/1000)) +cpuTemp2=$(($cpuTemp0/100)) +cpuTempM=$(($cpuTemp2 % $cpuTemp1)) + +gpuTemp=`vcgencmd measure_temp` + +loadAvg=`cat /proc/loadavg` + +echo "$(date) | CPU: temp=$cpuTemp1.$cpuTempM ºC | GPU: $gpuTemp | LoadAvg: $loadAvg" >> $logFile diff --git a/CONF-IOB/Donati/1000_Pi3/sendReboot.py b/CONF-IOB/Donati/1000_Pi3/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1000_Pi3/sendRebootIOB b/CONF-IOB/Donati/1000_Pi3/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1000_Pi3/sendRebootIOB.service b/CONF-IOB/Donati/1000_Pi3/sendRebootIOB.service new file mode 100644 index 0000000..48e3690 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/sendRebootIOB.service @@ -0,0 +1,22 @@ +[Unit] +SourcePath=/etc/init.d/sendRebootIOB +Description=LSB: Steamware's IOB reboot signal +Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target +Wants=network-online.target +After=network.target network-online.target auditd.service +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=no +TimeoutSec=5min +IgnoreSIGPIPE=no +KillMode=process +GuessMainPID=no +RemainAfterExit=yes +SysVStartPriority=2 +ExecStart=/etc/init.d/sendRebootIOB start +ExecStop=/etc/init.d/sendRebootIOB stop + +[Install] +WantedBy=multi-user.target diff --git a/CONF-IOB/Donati/1000_Pi3/setIobConf.sh b/CONF-IOB/Donati/1000_Pi3/setIobConf.sh new file mode 100644 index 0000000..30b4781 --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/setIobConf.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# verifico se sia rete donati o rete steamware o offline... +netStatus=`cat /sys/class/net/eth0/operstate` +iaddr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` + +cd /home/pi/steamware + +if [[ $netStatus != "up" ]] +then + echo "Siamo Offline, pagina demo!" +elif [[ $iaddr == "10.74.82"* ]] +then + cp IOB.cfg.steamware IOB.cfg -f + echo "Siamo in Steamware!" +elif [[ $iaddr == "192.168.51"* ]] +then + cp IOB.cfg.donati IOB.cfg -f + echo "Siamo a Passirano!" +else + echo "Siamo altrove, pagina demo!" +fi + +echo "$iaddr" + +chown pi:pi * \ No newline at end of file diff --git a/CONF-IOB/Donati/1000_Pi3/unix.py b/CONF-IOB/Donati/1000_Pi3/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1000_Pi3/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1000_Pi3/unix.pyc b/CONF-IOB/Donati/1000_Pi3/unix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e2189ce424fdac5d31114de18ed11f77664526ee GIT binary patch literal 692 zcma)3L2uJA6#nca+nRM8I01(#5|^CPJ345V#7}|kAsn~96%2OS?{Qh2ndb;y4_7g|QwSkkjLEs%$0YT9dD{0Rp0>3v^vhZq z=WkV9j>_?e=>wjYr}@b3asI3<@{_N`3Cw54HH?~eb~WeCC&lRV<@o#w=R?MyigDMq z9q&G>8mpLZ+HF+o`MEiF(T(C8&Fhr%U}s+u8hme8YOvM=>r}P+QFUstG5R`NZyygI z(P1yidI$Mh1oBWEh)CKV#o539_9aDeVp>gR6056Ko7lF|NtR`?eL+<(<4y8KZxU@? zWo}ebtySlgrW*L)O8)|-56frdSY*>K7TPRWq++=NmF)KZan-eUPn!N)*xOZGZyNQ^ R{}>DFi+>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + try: + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + except: + logga("Errore nel file WIN.PY per FD") + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + #fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + print " Dummy Method! Completa Lockfile\n" + except IOError: + return False + + return True +try: + if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) +except: + logga("if not lockfile NON RIUSCITO in file WIN.PY") + sys.exit(1) diff --git a/CONF-IOB/Donati/1000_Pi3/win.pyc b/CONF-IOB/Donati/1000_Pi3/win.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9a11e6dca5bd435d4e6baf0fb24c05441229bd GIT binary patch literal 883 zcmbVJO>fgc5S_Kte3%vqR1h3M+XHGOq)3HZg%H$fA)>V-Cso=iQf0;4vc%c7ycM=3KTtxF`MC&Tz z2u%m=00iV8e34m)%9FWLQk`?H_^20kXQ-ecExC z8tq(o^p(*_-Ek}|sIlwDi`M0wBehO7Tc-~J>81-~wm}1SWSb!7qeo;O0e8z%mx3#i z^D~(X$E(vn=7lKvUe|0Of_LY$*@7Pk`(9@oJk+xy7dGYldNOq>LA!-0>t@i#*4$AD zg=R$YX_)N39xnA^au|hZ@9d)_j`okioG91l=V=wviz_yjbuZ10sHzRixoErURcgNM zTJ<~2+OSgv<_WZLdwgg_X~v?QrAp~>SD2~Q#rU8<5asxzRGngRU1tyMSCM7zx+=_P zn~>Yg_glcaXWU$!tA^$wZUI+XLKHVLooQ}#E_tWZ3Csg{_v7&0Ht)+hm&T^*v*0QA zXoZB2%u|3oL$c*pHF*?AJn0<{!rn0EQr&z4JU%9?11i3t{`^^5$OHyTZaHwvv+gC$ r;&SieleGU9@;_U7G1J*R7cX6Jb04tER@iE*wdS)mXaT#24F&8ksVTb- literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1005_149/IOB.cfg b/CONF-IOB/Donati/1005_149/IOB.cfg new file mode 100644 index 0000000..c99d105 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1005_149/MapoIOB b/CONF-IOB/Donati/1005_149/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1005_149/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1005_149/MapoIOB_par b/CONF-IOB/Donati/1005_149/MapoIOB_par new file mode 100644 index 0000000..73410e5 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/MapoIOB_par @@ -0,0 +1,40 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1005_149/MapoIOB_ser b/CONF-IOB/Donati/1005_149/MapoIOB_ser new file mode 100644 index 0000000..514e7a4 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/MapoIOB_ser @@ -0,0 +1,40 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readSeriale" + cd /home/pi/steamware + /usr/bin/python ./readSeriale.py 2>&1 & + ;; + stop) + echo "Stopping readSeriale" + RS_PID=`ps auxwww | grep readSeriale.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1005_149/checkAlive.sh b/CONF-IOB/Donati/1005_149/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1005_149/cleanPython.sh b/CONF-IOB/Donati/1005_149/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1005_149/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1005_149/logfile.txt b/CONF-IOB/Donati/1005_149/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1005_149/mppar b/CONF-IOB/Donati/1005_149/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1005_149/mpser b/CONF-IOB/Donati/1005_149/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1005_149/python-serial_2.5-2.1_all.deb b/CONF-IOB/Donati/1005_149/python-serial_2.5-2.1_all.deb new file mode 100644 index 0000000000000000000000000000000000000000..c52896ce458cd87eaa92c68b8a3d01e875c6c594 GIT binary patch literal 79040 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 X!v9~F`qLv2+=>mK9%K>{1n&O;wGe7` literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1005_149/readParallela.py b/CONF-IOB/Donati/1005_149/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1005_149/readSeriale.py b/CONF-IOB/Donati/1005_149/readSeriale.py new file mode 100644 index 0000000..909de6d --- /dev/null +++ b/CONF-IOB/Donati/1005_149/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1005_149/sendReboot.py b/CONF-IOB/Donati/1005_149/sendReboot.py new file mode 100644 index 0000000..814157a --- /dev/null +++ b/CONF-IOB/Donati/1005_149/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.6 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.6" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1005_149/unix.py b/CONF-IOB/Donati/1005_149/unix.py new file mode 100644 index 0000000..8167be6 --- /dev/null +++ b/CONF-IOB/Donati/1005_149/unix.py @@ -0,0 +1,30 @@ +import fcntl +import os + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1006_151/IOB.cfg b/CONF-IOB/Donati/1006_151/IOB.cfg new file mode 100644 index 0000000..3d03ee7 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1006 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1006_151/MapoIOB b/CONF-IOB/Donati/1006_151/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1006_151/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1006_151/MapoIOB.bak b/CONF-IOB/Donati/1006_151/MapoIOB.bak new file mode 100644 index 0000000..f3a37c4 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/MapoIOB.bak @@ -0,0 +1,40 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: +# Required-Stop: +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1006_151/checkAlive.sh b/CONF-IOB/Donati/1006_151/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1006_151/cleanPython.sh b/CONF-IOB/Donati/1006_151/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1006_151/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1006_151/old/IOB.cfg b/CONF-IOB/Donati/1006_151/old/IOB.cfg new file mode 100644 index 0000000..ba3ef61 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1006 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1006_151/old/readParallela.py b/CONF-IOB/Donati/1006_151/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1006_151/readParallela.py b/CONF-IOB/Donati/1006_151/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1006_151/sendReboot.py b/CONF-IOB/Donati/1006_151/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1006_151/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1006_151/unix.py b/CONF-IOB/Donati/1006_151/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1006_151/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1007_152/IOB.cfg b/CONF-IOB/Donati/1007_152/IOB.cfg new file mode 100644 index 0000000..0a79446 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1007 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1007_152/MapoIOB b/CONF-IOB/Donati/1007_152/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1007_152/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1007_152/checkAlive.sh b/CONF-IOB/Donati/1007_152/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1007_152/cleanPython.sh b/CONF-IOB/Donati/1007_152/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1007_152/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1007_152/logfile.txt b/CONF-IOB/Donati/1007_152/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1007_152/old/IOB.cfg b/CONF-IOB/Donati/1007_152/old/IOB.cfg new file mode 100644 index 0000000..39a8d52 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1007 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1007_152/old/readParallela.py b/CONF-IOB/Donati/1007_152/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1007_152/readParallela.py b/CONF-IOB/Donati/1007_152/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1007_152/sendReboot.py b/CONF-IOB/Donati/1007_152/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1007_152/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1007_152/unix.py b/CONF-IOB/Donati/1007_152/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1007_152/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1008_153/IOB.cfg b/CONF-IOB/Donati/1008_153/IOB.cfg new file mode 100644 index 0000000..421003b --- /dev/null +++ b/CONF-IOB/Donati/1008_153/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1008 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1008_153/MapoIOB b/CONF-IOB/Donati/1008_153/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1008_153/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1008_153/checkAlive.sh b/CONF-IOB/Donati/1008_153/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1008_153/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1008_153/cleanPython.sh b/CONF-IOB/Donati/1008_153/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1008_153/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1008_153/logfile.txt b/CONF-IOB/Donati/1008_153/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1008_153/old/IOB.cfg b/CONF-IOB/Donati/1008_153/old/IOB.cfg new file mode 100644 index 0000000..fd55446 --- /dev/null +++ b/CONF-IOB/Donati/1008_153/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1008 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1008_153/old/readParallela.py b/CONF-IOB/Donati/1008_153/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1008_153/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1008_153/readParallela.py b/CONF-IOB/Donati/1008_153/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1008_153/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1008_153/sendReboot.py b/CONF-IOB/Donati/1008_153/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1008_153/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1008_153/unix.py b/CONF-IOB/Donati/1008_153/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1008_153/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1009_154/IOB.cfg b/CONF-IOB/Donati/1009_154/IOB.cfg new file mode 100644 index 0000000..54b5db1 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1009 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1009_154/MapoIOB b/CONF-IOB/Donati/1009_154/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1009_154/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1009_154/checkAlive.sh b/CONF-IOB/Donati/1009_154/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1009_154/cleanPython.sh b/CONF-IOB/Donati/1009_154/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1009_154/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1009_154/logfile.txt b/CONF-IOB/Donati/1009_154/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1009_154/old/IOB.cfg b/CONF-IOB/Donati/1009_154/old/IOB.cfg new file mode 100644 index 0000000..072fa86 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1009 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1009_154/old/readParallela.py b/CONF-IOB/Donati/1009_154/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1009_154/readParallela.py b/CONF-IOB/Donati/1009_154/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1009_154/readSeriale.py b/CONF-IOB/Donati/1009_154/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1009_154/sendReboot.py b/CONF-IOB/Donati/1009_154/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1009_154/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1009_154/unix.py b/CONF-IOB/Donati/1009_154/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1009_154/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1010_155/IOB.cfg b/CONF-IOB/Donati/1010_155/IOB.cfg new file mode 100644 index 0000000..9e76f31 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1010 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1010_155/MapoIOB b/CONF-IOB/Donati/1010_155/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1010_155/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1010_155/checkAlive.sh b/CONF-IOB/Donati/1010_155/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1010_155/cleanPython.sh b/CONF-IOB/Donati/1010_155/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1010_155/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1010_155/logfile.txt b/CONF-IOB/Donati/1010_155/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1010_155/old/IOB.cfg b/CONF-IOB/Donati/1010_155/old/IOB.cfg new file mode 100644 index 0000000..9dc38c5 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1010 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1010_155/old/readParallela.py b/CONF-IOB/Donati/1010_155/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1010_155/readParallela.py b/CONF-IOB/Donati/1010_155/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1010_155/sendReboot.py b/CONF-IOB/Donati/1010_155/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1010_155/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1010_155/unix.py b/CONF-IOB/Donati/1010_155/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1010_155/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1011_156/IOB.cfg b/CONF-IOB/Donati/1011_156/IOB.cfg new file mode 100644 index 0000000..0851fb2 --- /dev/null +++ b/CONF-IOB/Donati/1011_156/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1011 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1011_156/MapoIOB b/CONF-IOB/Donati/1011_156/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1011_156/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1011_156/checkAlive.sh b/CONF-IOB/Donati/1011_156/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1011_156/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1011_156/logfile.txt b/CONF-IOB/Donati/1011_156/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1011_156/old/IOB.cfg b/CONF-IOB/Donati/1011_156/old/IOB.cfg new file mode 100644 index 0000000..e19a30e --- /dev/null +++ b/CONF-IOB/Donati/1011_156/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1011 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1011_156/old/readParallela.py b/CONF-IOB/Donati/1011_156/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1011_156/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1011_156/readParallela.py b/CONF-IOB/Donati/1011_156/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1011_156/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1011_156/sendReboot.py b/CONF-IOB/Donati/1011_156/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1011_156/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1011_156/unix.py b/CONF-IOB/Donati/1011_156/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1011_156/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1011_170/IOB.cfg b/CONF-IOB/Donati/1011_170/IOB.cfg new file mode 100644 index 0000000..aeab237 --- /dev/null +++ b/CONF-IOB/Donati/1011_170/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1011 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1011_170/MapoIOB b/CONF-IOB/Donati/1011_170/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1011_170/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1011_170/checkAlive.sh b/CONF-IOB/Donati/1011_170/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1011_170/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1011_170/cleanPython.sh b/CONF-IOB/Donati/1011_170/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1011_170/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1011_170/logfile.txt b/CONF-IOB/Donati/1011_170/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1011_170/old/IOB.cfg b/CONF-IOB/Donati/1011_170/old/IOB.cfg new file mode 100644 index 0000000..e19a30e --- /dev/null +++ b/CONF-IOB/Donati/1011_170/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1011 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1011_170/old/readParallela.py b/CONF-IOB/Donati/1011_170/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1011_170/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1011_170/readParallela.py b/CONF-IOB/Donati/1011_170/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1011_170/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1011_170/sendReboot.py b/CONF-IOB/Donati/1011_170/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1011_170/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1011_170/unix.py b/CONF-IOB/Donati/1011_170/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1011_170/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1012_157/IOB.cfg b/CONF-IOB/Donati/1012_157/IOB.cfg new file mode 100644 index 0000000..25071c7 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1012 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1012_157/MapoIOB b/CONF-IOB/Donati/1012_157/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1012_157/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1012_157/checkAlive.sh b/CONF-IOB/Donati/1012_157/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1012_157/cleanPython.sh b/CONF-IOB/Donati/1012_157/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1012_157/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1012_157/logfile.txt b/CONF-IOB/Donati/1012_157/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1012_157/old/IOB.cfg b/CONF-IOB/Donati/1012_157/old/IOB.cfg new file mode 100644 index 0000000..183aace --- /dev/null +++ b/CONF-IOB/Donati/1012_157/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1012 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1012_157/old/readParallela.py b/CONF-IOB/Donati/1012_157/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1012_157/readParallela.py b/CONF-IOB/Donati/1012_157/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1012_157/sendReboot.py b/CONF-IOB/Donati/1012_157/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1012_157/sendRebootIOB b/CONF-IOB/Donati/1012_157/sendRebootIOB new file mode 100644 index 0000000..fa28624 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/sendRebootIOB @@ -0,0 +1,29 @@ +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + echo "Starting sendReboot" + cd /home/pi/steamware + /usr/bin/python ./sendReboot.py 2>&1 & + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1012_157/unix.py b/CONF-IOB/Donati/1012_157/unix.py new file mode 100644 index 0000000..44cec83 --- /dev/null +++ b/CONF-IOB/Donati/1012_157/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os + + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1013_158/IOB.cfg b/CONF-IOB/Donati/1013_158/IOB.cfg new file mode 100644 index 0000000..ad18453 --- /dev/null +++ b/CONF-IOB/Donati/1013_158/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1013 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1013_158/MapoIOB b/CONF-IOB/Donati/1013_158/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1013_158/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1013_158/checkAlive.sh b/CONF-IOB/Donati/1013_158/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1013_158/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1013_158/cleanPython.sh b/CONF-IOB/Donati/1013_158/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1013_158/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1013_158/logfile.txt b/CONF-IOB/Donati/1013_158/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1013_158/old/IOB.cfg b/CONF-IOB/Donati/1013_158/old/IOB.cfg new file mode 100644 index 0000000..53061fb --- /dev/null +++ b/CONF-IOB/Donati/1013_158/old/IOB.cfg @@ -0,0 +1,19 @@ +[id] +idxMacchina = 1013 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.5 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 60 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1013_158/old/readParallela.py b/CONF-IOB/Donati/1013_158/old/readParallela.py new file mode 100644 index 0000000..7520b36 --- /dev/null +++ b/CONF-IOB/Donati/1013_158/old/readParallela.py @@ -0,0 +1,337 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.1" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + ##### convertire in HEX !!!! + + except: + pass + + return current + + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- +def avviaParallela(): + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logga("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1013_158/readParallela.py b/CONF-IOB/Donati/1013_158/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1013_158/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1013_158/sendReboot.py b/CONF-IOB/Donati/1013_158/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1013_158/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1013_158/unix.py b/CONF-IOB/Donati/1013_158/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1013_158/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1014_159/IOB.cfg b/CONF-IOB/Donati/1014_159/IOB.cfg new file mode 100644 index 0000000..6cc9f3e --- /dev/null +++ b/CONF-IOB/Donati/1014_159/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1014 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1014_159/MapoIOB b/CONF-IOB/Donati/1014_159/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1014_159/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1014_159/checkAlive.sh b/CONF-IOB/Donati/1014_159/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1014_159/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1014_159/cleanPython.sh b/CONF-IOB/Donati/1014_159/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1014_159/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1014_159/logfile.txt b/CONF-IOB/Donati/1014_159/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1014_159/readParallela.py b/CONF-IOB/Donati/1014_159/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1014_159/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1014_159/sendReboot.py b/CONF-IOB/Donati/1014_159/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1014_159/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1014_159/unix.py b/CONF-IOB/Donati/1014_159/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1014_159/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1015_162/IOB.cfg b/CONF-IOB/Donati/1015_162/IOB.cfg new file mode 100644 index 0000000..81cd593 --- /dev/null +++ b/CONF-IOB/Donati/1015_162/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1015 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1015_162/MapoIOB b/CONF-IOB/Donati/1015_162/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1015_162/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1015_162/checkAlive.sh b/CONF-IOB/Donati/1015_162/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1015_162/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1015_162/cleanPython.sh b/CONF-IOB/Donati/1015_162/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1015_162/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1015_162/logfile.txt b/CONF-IOB/Donati/1015_162/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1015_162/readParallela.py b/CONF-IOB/Donati/1015_162/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1015_162/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1015_162/sendReboot.py b/CONF-IOB/Donati/1015_162/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1015_162/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1015_162/sendRebootIOB b/CONF-IOB/Donati/1015_162/sendRebootIOB new file mode 100644 index 0000000..fa28624 --- /dev/null +++ b/CONF-IOB/Donati/1015_162/sendRebootIOB @@ -0,0 +1,29 @@ +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + echo "Starting sendReboot" + cd /home/pi/steamware + /usr/bin/python ./sendReboot.py 2>&1 & + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1015_162/unix.py b/CONF-IOB/Donati/1015_162/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1015_162/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1016_163/IOB.cfg b/CONF-IOB/Donati/1016_163/IOB.cfg new file mode 100644 index 0000000..4c98374 --- /dev/null +++ b/CONF-IOB/Donati/1016_163/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1016 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1016_163/MapoIOB b/CONF-IOB/Donati/1016_163/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1016_163/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1016_163/checkAlive.sh b/CONF-IOB/Donati/1016_163/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1016_163/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1016_163/cleanPython.sh b/CONF-IOB/Donati/1016_163/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1016_163/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1016_163/logfile.txt b/CONF-IOB/Donati/1016_163/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1016_163/readParallela.py b/CONF-IOB/Donati/1016_163/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1016_163/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1016_163/sendReboot.py b/CONF-IOB/Donati/1016_163/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1016_163/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1016_163/unix.py b/CONF-IOB/Donati/1016_163/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1016_163/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1017_164/IOB.cfg b/CONF-IOB/Donati/1017_164/IOB.cfg new file mode 100644 index 0000000..5407642 --- /dev/null +++ b/CONF-IOB/Donati/1017_164/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1017 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1017_164/MapoIOB b/CONF-IOB/Donati/1017_164/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1017_164/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1017_164/checkAlive.sh b/CONF-IOB/Donati/1017_164/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1017_164/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1017_164/cleanPython.sh b/CONF-IOB/Donati/1017_164/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1017_164/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1017_164/logfile.txt b/CONF-IOB/Donati/1017_164/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1017_164/readParallela.py b/CONF-IOB/Donati/1017_164/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1017_164/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1017_164/sendReboot.py b/CONF-IOB/Donati/1017_164/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1017_164/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1017_164/unix.py b/CONF-IOB/Donati/1017_164/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1017_164/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1018_168/IOB.cfg b/CONF-IOB/Donati/1018_168/IOB.cfg new file mode 100644 index 0000000..a86e699 --- /dev/null +++ b/CONF-IOB/Donati/1018_168/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1018 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1018_168/MapoIOB b/CONF-IOB/Donati/1018_168/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1018_168/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1018_168/checkAlive.sh b/CONF-IOB/Donati/1018_168/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1018_168/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1018_168/cleanPython.sh b/CONF-IOB/Donati/1018_168/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1018_168/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1018_168/logfile.txt b/CONF-IOB/Donati/1018_168/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1018_168/readParallela.py b/CONF-IOB/Donati/1018_168/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1018_168/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1018_168/sendReboot.py b/CONF-IOB/Donati/1018_168/sendReboot.py new file mode 100644 index 0000000..814157a --- /dev/null +++ b/CONF-IOB/Donati/1018_168/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.6 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.6" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1018_168/unix.py b/CONF-IOB/Donati/1018_168/unix.py new file mode 100644 index 0000000..8167be6 --- /dev/null +++ b/CONF-IOB/Donati/1018_168/unix.py @@ -0,0 +1,30 @@ +import fcntl +import os + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1019_169/IOB.cfg b/CONF-IOB/Donati/1019_169/IOB.cfg new file mode 100644 index 0000000..b6e5e45 --- /dev/null +++ b/CONF-IOB/Donati/1019_169/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1019 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1019_169/MapoIOB b/CONF-IOB/Donati/1019_169/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1019_169/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1019_169/checkAlive.sh b/CONF-IOB/Donati/1019_169/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1019_169/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1019_169/cleanPython.sh b/CONF-IOB/Donati/1019_169/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1019_169/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1019_169/logfile.txt b/CONF-IOB/Donati/1019_169/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1019_169/readParallela.py b/CONF-IOB/Donati/1019_169/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1019_169/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1019_169/sendReboot.py b/CONF-IOB/Donati/1019_169/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1019_169/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1019_169/unix.py b/CONF-IOB/Donati/1019_169/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1019_169/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1020_165/IOB.cfg b/CONF-IOB/Donati/1020_165/IOB.cfg new file mode 100644 index 0000000..77fbcfd --- /dev/null +++ b/CONF-IOB/Donati/1020_165/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1020 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1020_165/MapoIOB b/CONF-IOB/Donati/1020_165/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1020_165/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1020_165/checkAlive.sh b/CONF-IOB/Donati/1020_165/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1020_165/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1020_165/cleanPython.sh b/CONF-IOB/Donati/1020_165/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1020_165/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1020_165/logfile.txt b/CONF-IOB/Donati/1020_165/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1020_165/readParallela.py b/CONF-IOB/Donati/1020_165/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1020_165/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1020_165/sendReboot.py b/CONF-IOB/Donati/1020_165/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1020_165/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1020_165/unix.py b/CONF-IOB/Donati/1020_165/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1020_165/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1021_167/IOB.cfg b/CONF-IOB/Donati/1021_167/IOB.cfg new file mode 100644 index 0000000..d1e0658 --- /dev/null +++ b/CONF-IOB/Donati/1021_167/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1021 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1021_167/MapoIOB b/CONF-IOB/Donati/1021_167/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1021_167/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1021_167/checkAlive.sh b/CONF-IOB/Donati/1021_167/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1021_167/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1021_167/cleanPython.sh b/CONF-IOB/Donati/1021_167/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1021_167/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1021_167/logfile.txt b/CONF-IOB/Donati/1021_167/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1021_167/readParallela.py b/CONF-IOB/Donati/1021_167/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1021_167/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1021_167/sendReboot.py b/CONF-IOB/Donati/1021_167/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1021_167/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1021_167/unix.py b/CONF-IOB/Donati/1021_167/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1021_167/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1022_166/IOB.cfg b/CONF-IOB/Donati/1022_166/IOB.cfg new file mode 100644 index 0000000..8833201 --- /dev/null +++ b/CONF-IOB/Donati/1022_166/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1022 + +[web] +URLBASE = http://192.168.51.71/MPIO2/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO2/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO2/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO2/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1022_166/MapoIOB b/CONF-IOB/Donati/1022_166/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1022_166/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1022_166/checkAlive.sh b/CONF-IOB/Donati/1022_166/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1022_166/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1022_166/cleanPython.sh b/CONF-IOB/Donati/1022_166/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1022_166/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1022_166/logfile.txt b/CONF-IOB/Donati/1022_166/logfile.txt new file mode 100644 index 0000000..e69de29 diff --git a/CONF-IOB/Donati/1022_166/readParallela.py b/CONF-IOB/Donati/1022_166/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1022_166/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1022_166/sendReboot.py b/CONF-IOB/Donati/1022_166/sendReboot.py new file mode 100644 index 0000000..36dd316 --- /dev/null +++ b/CONF-IOB/Donati/1022_166/sendReboot.py @@ -0,0 +1,96 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.1 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME ="SendReboot IOB-pi v.1.3" + +# DA FILE CONF +idxMacchina = "99" + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + + try: + url = URLREBO + idxMacchina + urllib.urlopen ( url ) + except: + logging.info ( "NETWORK:Errore http-no com rete-timeout per url: " + url ) + print "Url aforte" , url + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma" + PROGRAM_NAME) + + +# lettura file configurazione + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + + +chiamaUrl() + diff --git a/CONF-IOB/Donati/1022_166/unix.py b/CONF-IOB/Donati/1022_166/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1022_166/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1024_177/IOB.cfg b/CONF-IOB/Donati/1024_177/IOB.cfg new file mode 100644 index 0000000..1c88599 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1024 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1024_177/IOB.cfg.donati b/CONF-IOB/Donati/1024_177/IOB.cfg.donati new file mode 100644 index 0000000..1c88599 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/IOB.cfg.donati @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1024 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1024_177/IOB.cfg.steamware b/CONF-IOB/Donati/1024_177/IOB.cfg.steamware new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1024_177/IOB.cfg.steamware @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1024_177/MapoIOB b/CONF-IOB/Donati/1024_177/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1024_177/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1024_177/checkAlive.sh b/CONF-IOB/Donati/1024_177/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1024_177/cleanPython.sh b/CONF-IOB/Donati/1024_177/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1024_177/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1024_177/crontab b/CONF-IOB/Donati/1024_177/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1024_177/install-RPI-IOB.sh b/CONF-IOB/Donati/1024_177/install-RPI-IOB.sh new file mode 100644 index 0000000..19491e1 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/install-RPI-IOB.sh @@ -0,0 +1,47 @@ +#|/bin/bash + +#installa il necessario per RPI-3-IOB partendo dal contenuto della folder /home/pi/steamware + +#step 1: creo file di log nuovi +rm /var/log/log*.txt +rm /var/log/MapoIOB +rm /home/pi/steamware/log*.txt + +touch /var/log/logReboot.txt +touch /var/log/logTemp.txt +touch /var/log/MapoIOB + +ln -sf /var/log/logReboot.txt /home/pi/steamware/logReboot.txt +ln -sf /var/log/logTemp.txt /home/pi/steamware/logTemp.txt +ln -sf /var/log/MapoIOB /home/pi/steamware/logfile.txt + +chown pi:pi /home/pi -R +chmod 666 /var/log/log*.txt +chmod 666 /var/log/MapoIOB + +#step 2: copio files in /usr/local/bin +cd /home/pi/steamware +chmod +x *.sh +cp *.sh /usr/local/bin/ + +# step 3: copio target systemd in avvio... +cp -f sendRebootIOB /etc/init.d/sendRebootIOB +cp -f sendRebootIOB.service /etc/systemd/system/sendRebootIOB.service +echo "" +echo "-----------------------------------------------" +echo "Completare registrazione servizio avvio: digitare i seguenti comandi" +echo "systemctl enable sendRebootIOB" +echo "systemctl daemon-reload" +echo "systemctl status sendRebootIOB" +echo "-----------------------------------------------" +echo "" +echo "" +echo "" +echo "-----------------------------------------------" +echo "Infine creare voce crontab che salvi temperatura CPU/GPU ogni 20 minuti..." +echo "crontab -e" +echo "*/20 * * * * /usr/local/bin/saveTemp.sh" +echo "-----------------------------------------------" + + + diff --git a/CONF-IOB/Donati/1024_177/mppar b/CONF-IOB/Donati/1024_177/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1024_177/mpser b/CONF-IOB/Donati/1024_177/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1024_177/readParallela.py b/CONF-IOB/Donati/1024_177/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1024_177/readSeriale.py b/CONF-IOB/Donati/1024_177/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1024_177/saveTemp.sh b/CONF-IOB/Donati/1024_177/saveTemp.sh new file mode 100644 index 0000000..a2cd2be --- /dev/null +++ b/CONF-IOB/Donati/1024_177/saveTemp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#salva la temperatura CPU e GPU su chiamata... + +# imposto logfile... +logFile="/var/log/logTemp.txt" + +cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp) +cpuTemp1=$(($cpuTemp0/1000)) +cpuTemp2=$(($cpuTemp0/100)) +cpuTempM=$(($cpuTemp2 % $cpuTemp1)) + +gpuTemp=`vcgencmd measure_temp` + +loadAvg=`cat /proc/loadavg` + +echo "$(date) | CPU: temp=$cpuTemp1.$cpuTempM ºC | GPU: $gpuTemp | LoadAvg: $loadAvg" >> $logFile diff --git a/CONF-IOB/Donati/1024_177/sendReboot.py b/CONF-IOB/Donati/1024_177/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1024_177/sendRebootIOB b/CONF-IOB/Donati/1024_177/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1024_177/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1024_177/sendRebootIOB.service b/CONF-IOB/Donati/1024_177/sendRebootIOB.service new file mode 100644 index 0000000..48e3690 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/sendRebootIOB.service @@ -0,0 +1,22 @@ +[Unit] +SourcePath=/etc/init.d/sendRebootIOB +Description=LSB: Steamware's IOB reboot signal +Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target +Wants=network-online.target +After=network.target network-online.target auditd.service +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=no +TimeoutSec=5min +IgnoreSIGPIPE=no +KillMode=process +GuessMainPID=no +RemainAfterExit=yes +SysVStartPriority=2 +ExecStart=/etc/init.d/sendRebootIOB start +ExecStop=/etc/init.d/sendRebootIOB stop + +[Install] +WantedBy=multi-user.target diff --git a/CONF-IOB/Donati/1024_177/setIobConf.sh b/CONF-IOB/Donati/1024_177/setIobConf.sh new file mode 100644 index 0000000..30b4781 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/setIobConf.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# verifico se sia rete donati o rete steamware o offline... +netStatus=`cat /sys/class/net/eth0/operstate` +iaddr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` + +cd /home/pi/steamware + +if [[ $netStatus != "up" ]] +then + echo "Siamo Offline, pagina demo!" +elif [[ $iaddr == "10.74.82"* ]] +then + cp IOB.cfg.steamware IOB.cfg -f + echo "Siamo in Steamware!" +elif [[ $iaddr == "192.168.51"* ]] +then + cp IOB.cfg.donati IOB.cfg -f + echo "Siamo a Passirano!" +else + echo "Siamo altrove, pagina demo!" +fi + +echo "$iaddr" + +chown pi:pi * \ No newline at end of file diff --git a/CONF-IOB/Donati/1024_177/test.py b/CONF-IOB/Donati/1024_177/test.py new file mode 100644 index 0000000..3145cbe --- /dev/null +++ b/CONF-IOB/Donati/1024_177/test.py @@ -0,0 +1,31 @@ +import logging + +# set up logging to file - see previous section for more details +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + datefmt='%m-%d %H:%M', + filename='test.log', + filemode='w') +# define a Handler which writes INFO messages or higher to the sys.stderr +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# set a format which is simpler for console use +formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') +# tell the handler to use this format +console.setFormatter(formatter) +# add the handler to the root logger +logging.getLogger('').addHandler(console) + +# Now, we can log to the root logger, or any other logger. First the root... +logging.info('Jackdaws love my big sphinx of quartz.') + +# Now, define a couple of other loggers which might represent areas in your +# application: + +logger1 = logging.getLogger('myapp.area1') +logger2 = logging.getLogger('myapp.area2') + +logger1.debug('Quick zephyrs blow, vexing daft Jim.') +logger1.info('How quickly daft jumping zebras vex.') +logger2.warning('Jail zesty vixen who grabbed pay from quack.') +logger2.error('The five boxing wizards jump quickly.') diff --git a/CONF-IOB/Donati/1024_177/unix.py b/CONF-IOB/Donati/1024_177/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1024_177/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1024_177/unix.pyc b/CONF-IOB/Donati/1024_177/unix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a42c57dccb546762ac8321fadd75696744be6872 GIT binary patch literal 669 zcma)3O>fgc5Ph?@o5oF$-~=2hOI&<%?g$}Blmeo1kdvw*m&%GaVN=H&c{hThaw@-( zKf(`y*`*&>)}GlnA3JZKHu&9-JHH;!m$+Sm_cv^&U{~=^sDZ^jCM@VKFR&1(1b%Wu z02!bPa6>RTsu1tqOMy*@Dsnk${HSSqz+=@PUip$3I=YB$#AcWU7T6H3{{i8{07I7z zF}xA@LAW}Gjj%buHF?nS{?M1{ym^Aqc5xY_Jp&Qh7}L2u!ZdY!dD?R%j#e8Rx@{*L z+hH)d7!~8Uvs*kX&hn8x^!f8*lAnHNPGGfcZ0%94mzOKwd^#C@yco|Pa6a_-!(`mH zy7k>BWo@MAo3(qHI(|RgPf@k>H(FIG=i!}s&S>yOZ{=X82FA*A`?YN4VBe^3+3xE8 z@ChI8bE|Q>AYM=)j;T+PFkOzbyZPoBM{&|<#nvQ7m0O({U8^L^ve-Q3s*~|D`K0!V zGPZ2K%cR`N*2>iBF1%v^FRj+=wQAPIBbRU`>6AX){=X%>+Ujaw%h&F0yo4U{7k7_( G6wzNWP=h!C literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1024_177/win.py b/CONF-IOB/Donati/1024_177/win.py new file mode 100644 index 0000000..f679f60 --- /dev/null +++ b/CONF-IOB/Donati/1024_177/win.py @@ -0,0 +1,32 @@ +import win32api +print " Running on WINDOWS\n" +import os +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + try: + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + except: + logga("Errore nel file WIN.PY per FD") + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + #fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + print " Dummy Method! Completa Lockfile\n" + except IOError: + return False + + return True +try: + if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) +except: + logga("if not lockfile NON RIUSCITO in file WIN.PY") + sys.exit(1) diff --git a/CONF-IOB/Donati/1024_177/win.pyc b/CONF-IOB/Donati/1024_177/win.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9a11e6dca5bd435d4e6baf0fb24c05441229bd GIT binary patch literal 883 zcmbVJO>fgc5S_Kte3%vqR1h3M+XHGOq)3HZg%H$fA)>V-Cso=iQf0;4vc%c7ycM=3KTtxF`MC&Tz z2u%m=00iV8e34m)%9FWLQk`?H_^20kXQ-ecExC z8tq(o^p(*_-Ek}|sIlwDi`M0wBehO7Tc-~J>81-~wm}1SWSb!7qeo;O0e8z%mx3#i z^D~(X$E(vn=7lKvUe|0Of_LY$*@7Pk`(9@oJk+xy7dGYldNOq>LA!-0>t@i#*4$AD zg=R$YX_)N39xnA^au|hZ@9d)_j`okioG91l=V=wviz_yjbuZ10sHzRixoErURcgNM zTJ<~2+OSgv<_WZLdwgg_X~v?QrAp~>SD2~Q#rU8<5asxzRGngRU1tyMSCM7zx+=_P zn~>Yg_glcaXWU$!tA^$wZUI+XLKHVLooQ}#E_tWZ3Csg{_v7&0Ht)+hm&T^*v*0QA zXoZB2%u|3oL$c*pHF*?AJn0<{!rn0EQr&z4JU%9?11i3t{`^^5$OHyTZaHwvv+gC$ r;&SieleGU9@;_U7G1J*R7cX6Jb04tER@iE*wdS)mXaT#24F&8ksVTb- literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1025_178/IOB.cfg b/CONF-IOB/Donati/1025_178/IOB.cfg new file mode 100644 index 0000000..cc79c66 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1025 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1025_178/IOB.cfg.donati b/CONF-IOB/Donati/1025_178/IOB.cfg.donati new file mode 100644 index 0000000..cc79c66 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/IOB.cfg.donati @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1025 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1025_178/IOB.cfg.steamware b/CONF-IOB/Donati/1025_178/IOB.cfg.steamware new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1025_178/IOB.cfg.steamware @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1025_178/MapoIOB b/CONF-IOB/Donati/1025_178/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1025_178/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1025_178/checkAlive.sh b/CONF-IOB/Donati/1025_178/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1025_178/cleanPython.sh b/CONF-IOB/Donati/1025_178/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1025_178/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1025_178/crontab b/CONF-IOB/Donati/1025_178/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1025_178/install-RPI-IOB.sh b/CONF-IOB/Donati/1025_178/install-RPI-IOB.sh new file mode 100644 index 0000000..19491e1 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/install-RPI-IOB.sh @@ -0,0 +1,47 @@ +#|/bin/bash + +#installa il necessario per RPI-3-IOB partendo dal contenuto della folder /home/pi/steamware + +#step 1: creo file di log nuovi +rm /var/log/log*.txt +rm /var/log/MapoIOB +rm /home/pi/steamware/log*.txt + +touch /var/log/logReboot.txt +touch /var/log/logTemp.txt +touch /var/log/MapoIOB + +ln -sf /var/log/logReboot.txt /home/pi/steamware/logReboot.txt +ln -sf /var/log/logTemp.txt /home/pi/steamware/logTemp.txt +ln -sf /var/log/MapoIOB /home/pi/steamware/logfile.txt + +chown pi:pi /home/pi -R +chmod 666 /var/log/log*.txt +chmod 666 /var/log/MapoIOB + +#step 2: copio files in /usr/local/bin +cd /home/pi/steamware +chmod +x *.sh +cp *.sh /usr/local/bin/ + +# step 3: copio target systemd in avvio... +cp -f sendRebootIOB /etc/init.d/sendRebootIOB +cp -f sendRebootIOB.service /etc/systemd/system/sendRebootIOB.service +echo "" +echo "-----------------------------------------------" +echo "Completare registrazione servizio avvio: digitare i seguenti comandi" +echo "systemctl enable sendRebootIOB" +echo "systemctl daemon-reload" +echo "systemctl status sendRebootIOB" +echo "-----------------------------------------------" +echo "" +echo "" +echo "" +echo "-----------------------------------------------" +echo "Infine creare voce crontab che salvi temperatura CPU/GPU ogni 20 minuti..." +echo "crontab -e" +echo "*/20 * * * * /usr/local/bin/saveTemp.sh" +echo "-----------------------------------------------" + + + diff --git a/CONF-IOB/Donati/1025_178/mppar b/CONF-IOB/Donati/1025_178/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1025_178/mpser b/CONF-IOB/Donati/1025_178/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1025_178/readParallela.py b/CONF-IOB/Donati/1025_178/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1025_178/readSeriale.py b/CONF-IOB/Donati/1025_178/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1025_178/saveTemp.sh b/CONF-IOB/Donati/1025_178/saveTemp.sh new file mode 100644 index 0000000..a2cd2be --- /dev/null +++ b/CONF-IOB/Donati/1025_178/saveTemp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#salva la temperatura CPU e GPU su chiamata... + +# imposto logfile... +logFile="/var/log/logTemp.txt" + +cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp) +cpuTemp1=$(($cpuTemp0/1000)) +cpuTemp2=$(($cpuTemp0/100)) +cpuTempM=$(($cpuTemp2 % $cpuTemp1)) + +gpuTemp=`vcgencmd measure_temp` + +loadAvg=`cat /proc/loadavg` + +echo "$(date) | CPU: temp=$cpuTemp1.$cpuTempM ºC | GPU: $gpuTemp | LoadAvg: $loadAvg" >> $logFile diff --git a/CONF-IOB/Donati/1025_178/sendReboot.py b/CONF-IOB/Donati/1025_178/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1025_178/sendRebootIOB b/CONF-IOB/Donati/1025_178/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1025_178/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1025_178/sendRebootIOB.service b/CONF-IOB/Donati/1025_178/sendRebootIOB.service new file mode 100644 index 0000000..48e3690 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/sendRebootIOB.service @@ -0,0 +1,22 @@ +[Unit] +SourcePath=/etc/init.d/sendRebootIOB +Description=LSB: Steamware's IOB reboot signal +Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target +Wants=network-online.target +After=network.target network-online.target auditd.service +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=no +TimeoutSec=5min +IgnoreSIGPIPE=no +KillMode=process +GuessMainPID=no +RemainAfterExit=yes +SysVStartPriority=2 +ExecStart=/etc/init.d/sendRebootIOB start +ExecStop=/etc/init.d/sendRebootIOB stop + +[Install] +WantedBy=multi-user.target diff --git a/CONF-IOB/Donati/1025_178/setIobConf.sh b/CONF-IOB/Donati/1025_178/setIobConf.sh new file mode 100644 index 0000000..30b4781 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/setIobConf.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# verifico se sia rete donati o rete steamware o offline... +netStatus=`cat /sys/class/net/eth0/operstate` +iaddr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` + +cd /home/pi/steamware + +if [[ $netStatus != "up" ]] +then + echo "Siamo Offline, pagina demo!" +elif [[ $iaddr == "10.74.82"* ]] +then + cp IOB.cfg.steamware IOB.cfg -f + echo "Siamo in Steamware!" +elif [[ $iaddr == "192.168.51"* ]] +then + cp IOB.cfg.donati IOB.cfg -f + echo "Siamo a Passirano!" +else + echo "Siamo altrove, pagina demo!" +fi + +echo "$iaddr" + +chown pi:pi * \ No newline at end of file diff --git a/CONF-IOB/Donati/1025_178/test.py b/CONF-IOB/Donati/1025_178/test.py new file mode 100644 index 0000000..3145cbe --- /dev/null +++ b/CONF-IOB/Donati/1025_178/test.py @@ -0,0 +1,31 @@ +import logging + +# set up logging to file - see previous section for more details +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + datefmt='%m-%d %H:%M', + filename='test.log', + filemode='w') +# define a Handler which writes INFO messages or higher to the sys.stderr +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# set a format which is simpler for console use +formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') +# tell the handler to use this format +console.setFormatter(formatter) +# add the handler to the root logger +logging.getLogger('').addHandler(console) + +# Now, we can log to the root logger, or any other logger. First the root... +logging.info('Jackdaws love my big sphinx of quartz.') + +# Now, define a couple of other loggers which might represent areas in your +# application: + +logger1 = logging.getLogger('myapp.area1') +logger2 = logging.getLogger('myapp.area2') + +logger1.debug('Quick zephyrs blow, vexing daft Jim.') +logger1.info('How quickly daft jumping zebras vex.') +logger2.warning('Jail zesty vixen who grabbed pay from quack.') +logger2.error('The five boxing wizards jump quickly.') diff --git a/CONF-IOB/Donati/1025_178/unix.py b/CONF-IOB/Donati/1025_178/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1025_178/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1025_178/unix.pyc b/CONF-IOB/Donati/1025_178/unix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a42c57dccb546762ac8321fadd75696744be6872 GIT binary patch literal 669 zcma)3O>fgc5Ph?@o5oF$-~=2hOI&<%?g$}Blmeo1kdvw*m&%GaVN=H&c{hThaw@-( zKf(`y*`*&>)}GlnA3JZKHu&9-JHH;!m$+Sm_cv^&U{~=^sDZ^jCM@VKFR&1(1b%Wu z02!bPa6>RTsu1tqOMy*@Dsnk${HSSqz+=@PUip$3I=YB$#AcWU7T6H3{{i8{07I7z zF}xA@LAW}Gjj%buHF?nS{?M1{ym^Aqc5xY_Jp&Qh7}L2u!ZdY!dD?R%j#e8Rx@{*L z+hH)d7!~8Uvs*kX&hn8x^!f8*lAnHNPGGfcZ0%94mzOKwd^#C@yco|Pa6a_-!(`mH zy7k>BWo@MAo3(qHI(|RgPf@k>H(FIG=i!}s&S>yOZ{=X82FA*A`?YN4VBe^3+3xE8 z@ChI8bE|Q>AYM=)j;T+PFkOzbyZPoBM{&|<#nvQ7m0O({U8^L^ve-Q3s*~|D`K0!V zGPZ2K%cR`N*2>iBF1%v^FRj+=wQAPIBbRU`>6AX){=X%>+Ujaw%h&F0yo4U{7k7_( G6wzNWP=h!C literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1025_178/win.py b/CONF-IOB/Donati/1025_178/win.py new file mode 100644 index 0000000..f679f60 --- /dev/null +++ b/CONF-IOB/Donati/1025_178/win.py @@ -0,0 +1,32 @@ +import win32api +print " Running on WINDOWS\n" +import os +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + try: + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + except: + logga("Errore nel file WIN.PY per FD") + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + #fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + print " Dummy Method! Completa Lockfile\n" + except IOError: + return False + + return True +try: + if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) +except: + logga("if not lockfile NON RIUSCITO in file WIN.PY") + sys.exit(1) diff --git a/CONF-IOB/Donati/1025_178/win.pyc b/CONF-IOB/Donati/1025_178/win.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9a11e6dca5bd435d4e6baf0fb24c05441229bd GIT binary patch literal 883 zcmbVJO>fgc5S_Kte3%vqR1h3M+XHGOq)3HZg%H$fA)>V-Cso=iQf0;4vc%c7ycM=3KTtxF`MC&Tz z2u%m=00iV8e34m)%9FWLQk`?H_^20kXQ-ecExC z8tq(o^p(*_-Ek}|sIlwDi`M0wBehO7Tc-~J>81-~wm}1SWSb!7qeo;O0e8z%mx3#i z^D~(X$E(vn=7lKvUe|0Of_LY$*@7Pk`(9@oJk+xy7dGYldNOq>LA!-0>t@i#*4$AD zg=R$YX_)N39xnA^au|hZ@9d)_j`okioG91l=V=wviz_yjbuZ10sHzRixoErURcgNM zTJ<~2+OSgv<_WZLdwgg_X~v?QrAp~>SD2~Q#rU8<5asxzRGngRU1tyMSCM7zx+=_P zn~>Yg_glcaXWU$!tA^$wZUI+XLKHVLooQ}#E_tWZ3Csg{_v7&0Ht)+hm&T^*v*0QA zXoZB2%u|3oL$c*pHF*?AJn0<{!rn0EQr&z4JU%9?11i3t{`^^5$OHyTZaHwvv+gC$ r;&SieleGU9@;_U7G1J*R7cX6Jb04tER@iE*wdS)mXaT#24F&8ksVTb- literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1026_180/IOB.cfg b/CONF-IOB/Donati/1026_180/IOB.cfg new file mode 100644 index 0000000..18a11f3 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1026 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1026_180/IOB.cfg.donati b/CONF-IOB/Donati/1026_180/IOB.cfg.donati new file mode 100644 index 0000000..18a11f3 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/IOB.cfg.donati @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1026 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1026_180/IOB.cfg.steamware b/CONF-IOB/Donati/1026_180/IOB.cfg.steamware new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1026_180/IOB.cfg.steamware @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1026_180/MapoIOB b/CONF-IOB/Donati/1026_180/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1026_180/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1026_180/checkAlive.sh b/CONF-IOB/Donati/1026_180/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1026_180/cleanPython.sh b/CONF-IOB/Donati/1026_180/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1026_180/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1026_180/crontab b/CONF-IOB/Donati/1026_180/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1026_180/install-RPI-IOB.sh b/CONF-IOB/Donati/1026_180/install-RPI-IOB.sh new file mode 100644 index 0000000..19491e1 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/install-RPI-IOB.sh @@ -0,0 +1,47 @@ +#|/bin/bash + +#installa il necessario per RPI-3-IOB partendo dal contenuto della folder /home/pi/steamware + +#step 1: creo file di log nuovi +rm /var/log/log*.txt +rm /var/log/MapoIOB +rm /home/pi/steamware/log*.txt + +touch /var/log/logReboot.txt +touch /var/log/logTemp.txt +touch /var/log/MapoIOB + +ln -sf /var/log/logReboot.txt /home/pi/steamware/logReboot.txt +ln -sf /var/log/logTemp.txt /home/pi/steamware/logTemp.txt +ln -sf /var/log/MapoIOB /home/pi/steamware/logfile.txt + +chown pi:pi /home/pi -R +chmod 666 /var/log/log*.txt +chmod 666 /var/log/MapoIOB + +#step 2: copio files in /usr/local/bin +cd /home/pi/steamware +chmod +x *.sh +cp *.sh /usr/local/bin/ + +# step 3: copio target systemd in avvio... +cp -f sendRebootIOB /etc/init.d/sendRebootIOB +cp -f sendRebootIOB.service /etc/systemd/system/sendRebootIOB.service +echo "" +echo "-----------------------------------------------" +echo "Completare registrazione servizio avvio: digitare i seguenti comandi" +echo "systemctl enable sendRebootIOB" +echo "systemctl daemon-reload" +echo "systemctl status sendRebootIOB" +echo "-----------------------------------------------" +echo "" +echo "" +echo "" +echo "-----------------------------------------------" +echo "Infine creare voce crontab che salvi temperatura CPU/GPU ogni 20 minuti..." +echo "crontab -e" +echo "*/20 * * * * /usr/local/bin/saveTemp.sh" +echo "-----------------------------------------------" + + + diff --git a/CONF-IOB/Donati/1026_180/mppar b/CONF-IOB/Donati/1026_180/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1026_180/mpser b/CONF-IOB/Donati/1026_180/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1026_180/readParallela.py b/CONF-IOB/Donati/1026_180/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1026_180/readSeriale.py b/CONF-IOB/Donati/1026_180/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1026_180/saveTemp.sh b/CONF-IOB/Donati/1026_180/saveTemp.sh new file mode 100644 index 0000000..a2cd2be --- /dev/null +++ b/CONF-IOB/Donati/1026_180/saveTemp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#salva la temperatura CPU e GPU su chiamata... + +# imposto logfile... +logFile="/var/log/logTemp.txt" + +cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp) +cpuTemp1=$(($cpuTemp0/1000)) +cpuTemp2=$(($cpuTemp0/100)) +cpuTempM=$(($cpuTemp2 % $cpuTemp1)) + +gpuTemp=`vcgencmd measure_temp` + +loadAvg=`cat /proc/loadavg` + +echo "$(date) | CPU: temp=$cpuTemp1.$cpuTempM ºC | GPU: $gpuTemp | LoadAvg: $loadAvg" >> $logFile diff --git a/CONF-IOB/Donati/1026_180/sendReboot.py b/CONF-IOB/Donati/1026_180/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1026_180/sendRebootIOB b/CONF-IOB/Donati/1026_180/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1026_180/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1026_180/sendRebootIOB.service b/CONF-IOB/Donati/1026_180/sendRebootIOB.service new file mode 100644 index 0000000..48e3690 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/sendRebootIOB.service @@ -0,0 +1,22 @@ +[Unit] +SourcePath=/etc/init.d/sendRebootIOB +Description=LSB: Steamware's IOB reboot signal +Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target +Wants=network-online.target +After=network.target network-online.target auditd.service +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=no +TimeoutSec=5min +IgnoreSIGPIPE=no +KillMode=process +GuessMainPID=no +RemainAfterExit=yes +SysVStartPriority=2 +ExecStart=/etc/init.d/sendRebootIOB start +ExecStop=/etc/init.d/sendRebootIOB stop + +[Install] +WantedBy=multi-user.target diff --git a/CONF-IOB/Donati/1026_180/setIobConf.sh b/CONF-IOB/Donati/1026_180/setIobConf.sh new file mode 100644 index 0000000..30b4781 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/setIobConf.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# verifico se sia rete donati o rete steamware o offline... +netStatus=`cat /sys/class/net/eth0/operstate` +iaddr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` + +cd /home/pi/steamware + +if [[ $netStatus != "up" ]] +then + echo "Siamo Offline, pagina demo!" +elif [[ $iaddr == "10.74.82"* ]] +then + cp IOB.cfg.steamware IOB.cfg -f + echo "Siamo in Steamware!" +elif [[ $iaddr == "192.168.51"* ]] +then + cp IOB.cfg.donati IOB.cfg -f + echo "Siamo a Passirano!" +else + echo "Siamo altrove, pagina demo!" +fi + +echo "$iaddr" + +chown pi:pi * \ No newline at end of file diff --git a/CONF-IOB/Donati/1026_180/test.py b/CONF-IOB/Donati/1026_180/test.py new file mode 100644 index 0000000..3145cbe --- /dev/null +++ b/CONF-IOB/Donati/1026_180/test.py @@ -0,0 +1,31 @@ +import logging + +# set up logging to file - see previous section for more details +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + datefmt='%m-%d %H:%M', + filename='test.log', + filemode='w') +# define a Handler which writes INFO messages or higher to the sys.stderr +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# set a format which is simpler for console use +formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') +# tell the handler to use this format +console.setFormatter(formatter) +# add the handler to the root logger +logging.getLogger('').addHandler(console) + +# Now, we can log to the root logger, or any other logger. First the root... +logging.info('Jackdaws love my big sphinx of quartz.') + +# Now, define a couple of other loggers which might represent areas in your +# application: + +logger1 = logging.getLogger('myapp.area1') +logger2 = logging.getLogger('myapp.area2') + +logger1.debug('Quick zephyrs blow, vexing daft Jim.') +logger1.info('How quickly daft jumping zebras vex.') +logger2.warning('Jail zesty vixen who grabbed pay from quack.') +logger2.error('The five boxing wizards jump quickly.') diff --git a/CONF-IOB/Donati/1026_180/unix.py b/CONF-IOB/Donati/1026_180/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1026_180/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1026_180/unix.pyc b/CONF-IOB/Donati/1026_180/unix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a42c57dccb546762ac8321fadd75696744be6872 GIT binary patch literal 669 zcma)3O>fgc5Ph?@o5oF$-~=2hOI&<%?g$}Blmeo1kdvw*m&%GaVN=H&c{hThaw@-( zKf(`y*`*&>)}GlnA3JZKHu&9-JHH;!m$+Sm_cv^&U{~=^sDZ^jCM@VKFR&1(1b%Wu z02!bPa6>RTsu1tqOMy*@Dsnk${HSSqz+=@PUip$3I=YB$#AcWU7T6H3{{i8{07I7z zF}xA@LAW}Gjj%buHF?nS{?M1{ym^Aqc5xY_Jp&Qh7}L2u!ZdY!dD?R%j#e8Rx@{*L z+hH)d7!~8Uvs*kX&hn8x^!f8*lAnHNPGGfcZ0%94mzOKwd^#C@yco|Pa6a_-!(`mH zy7k>BWo@MAo3(qHI(|RgPf@k>H(FIG=i!}s&S>yOZ{=X82FA*A`?YN4VBe^3+3xE8 z@ChI8bE|Q>AYM=)j;T+PFkOzbyZPoBM{&|<#nvQ7m0O({U8^L^ve-Q3s*~|D`K0!V zGPZ2K%cR`N*2>iBF1%v^FRj+=wQAPIBbRU`>6AX){=X%>+Ujaw%h&F0yo4U{7k7_( G6wzNWP=h!C literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1026_180/win.py b/CONF-IOB/Donati/1026_180/win.py new file mode 100644 index 0000000..f679f60 --- /dev/null +++ b/CONF-IOB/Donati/1026_180/win.py @@ -0,0 +1,32 @@ +import win32api +print " Running on WINDOWS\n" +import os +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + try: + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + except: + logga("Errore nel file WIN.PY per FD") + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + #fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + print " Dummy Method! Completa Lockfile\n" + except IOError: + return False + + return True +try: + if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) +except: + logga("if not lockfile NON RIUSCITO in file WIN.PY") + sys.exit(1) diff --git a/CONF-IOB/Donati/1026_180/win.pyc b/CONF-IOB/Donati/1026_180/win.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9a11e6dca5bd435d4e6baf0fb24c05441229bd GIT binary patch literal 883 zcmbVJO>fgc5S_Kte3%vqR1h3M+XHGOq)3HZg%H$fA)>V-Cso=iQf0;4vc%c7ycM=3KTtxF`MC&Tz z2u%m=00iV8e34m)%9FWLQk`?H_^20kXQ-ecExC z8tq(o^p(*_-Ek}|sIlwDi`M0wBehO7Tc-~J>81-~wm}1SWSb!7qeo;O0e8z%mx3#i z^D~(X$E(vn=7lKvUe|0Of_LY$*@7Pk`(9@oJk+xy7dGYldNOq>LA!-0>t@i#*4$AD zg=R$YX_)N39xnA^au|hZ@9d)_j`okioG91l=V=wviz_yjbuZ10sHzRixoErURcgNM zTJ<~2+OSgv<_WZLdwgg_X~v?QrAp~>SD2~Q#rU8<5asxzRGngRU1tyMSCM7zx+=_P zn~>Yg_glcaXWU$!tA^$wZUI+XLKHVLooQ}#E_tWZ3Csg{_v7&0Ht)+hm&T^*v*0QA zXoZB2%u|3oL$c*pHF*?AJn0<{!rn0EQr&z4JU%9?11i3t{`^^5$OHyTZaHwvv+gC$ r;&SieleGU9@;_U7G1J*R7cX6Jb04tER@iE*wdS)mXaT#24F&8ksVTb- literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1027 - 185/IOB.cfg b/CONF-IOB/Donati/1027 - 185/IOB.cfg new file mode 100644 index 0000000..18a11f3 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/IOB.cfg @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1026 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1027 - 185/IOB.cfg.donati b/CONF-IOB/Donati/1027 - 185/IOB.cfg.donati new file mode 100644 index 0000000..18a11f3 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/IOB.cfg.donati @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1026 + +[web] +URLBASE = http://192.168.51.71/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://192.168.51.71/MPIO/Alive.aspx +URLENABLED = http://192.168.51.71/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.25 +TIMEOUTSHORT = 2 +TIMEOUTLONG = 50 +SENDURLTIME = 0.2 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = /var/log/logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1027 - 185/IOB.cfg.steamware b/CONF-IOB/Donati/1027 - 185/IOB.cfg.steamware new file mode 100644 index 0000000..6246b6a --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/IOB.cfg.steamware @@ -0,0 +1,23 @@ +[id] +idxMacchina = 1005 + +[web] +URLBASE = http://10.74.82.219/MPIO/inputIOB.aspx?idxMacchina= +URLALIVE = http://10.74.82.219/MPIO/Alive.aspx +URLENABLED = http://10.74.82.219/MPIO/Enabled.aspx?idxMacchina= +URLADV1 = &valore= +URLREBO = http://10.74.82.219/MPIO/sendReboot.aspx?idxMacchina= + +[time] +SAMPLETIME = 0.20 +TIMEOUTSHORT = 0.30 +TIMEOUTLONG = 50 +SENDURLTIME = 0.50 + +[log] +LOGLEVEL = 10 +LOGFILE = logfile.txt +LOGREBO = logReboot.txt + +[comm] +port = /dev/ttyAMA0 diff --git a/CONF-IOB/Donati/1027 - 185/MapoIOB b/CONF-IOB/Donati/1027 - 185/MapoIOB new file mode 100644 index 0000000..c49ec0a --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/MapoIOB @@ -0,0 +1,41 @@ +### BEGIN INIT INFO +# Provides: MapoIOB: script Steamware per avvio driver IOB +# Required-Start: $remote_fs $syslog ramlog +# Required-Stop: $remote_fs $syslog ramlog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's MapoIOB driver +# Description: Steamware's MapoIOB driver, versione lettura porta parallela +### END INIT INFO + +#! /bin/sh +# /etc/init.d/MapoIOB + +export HOME +case "$1" in + start) + echo "Starting readParallela" + cd /home/pi/steamware + /usr/bin/python ./readParallela.py 2>&1 & + ;; + stop) + echo "Stopping readParallela" + RS_PID=`ps auxwww | grep readParallela.py | head -1 | awk '{print $2}'` + kill -9 $RS_PID + cd /home/pi/steamware + rm .lockfile + ;; + restart) + ## Stop the service and regardless of whether it was + ## running or not, start it again. + $0 stop + killall python + $0 start + ;; + *) + echo "Usage: /etc/init.d/MapoIOB {start|stop|restart}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1027 - 185/checkAlive.sh b/CONF-IOB/Donati/1027 - 185/checkAlive.sh new file mode 100644 index 0000000..92bc816 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/checkAlive.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# controlla se il logfile è correntemente scritto (quindi MapoIOB è alive) altrimenti riavvia! + +DATE=`date +%Y-%m-%d` +cd /var/log +if [ -f MapoIOB ] + then + # controllo SE sia stato acceduto da meno di 2 minuti (=alive da log...) + trovato=`find . -name 'MapoIOB*' -cmin -1` + if [[ $trovato != './MapoIOB' ]] + then + /etc/init.d/MapoIOB restart + echo $date + "riavvio!" + fi +else + # in questo caso AVVIO il processo MapoIOB + /etc/init.d/MapoIOB start + echo $date + "file non trovato, avvio!" +fi diff --git a/CONF-IOB/Donati/1027 - 185/cleanPython.sh b/CONF-IOB/Donati/1027 - 185/cleanPython.sh new file mode 100644 index 0000000..c4f616a --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/cleanPython.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +DATE=`date +%Y-%m-%d_%T` +# log inizio pulizia +echo $DATE " - INIZIO pulizia processi python" >> clean.log +# effettua pulizia processi: killa tutti i processi python +killall python + +# avvia MapoIob +/etc/init.d/MapoIOB start + +# log fatto! +DATE=`date +%Y-%m-%d_%T` +echo $DATE " - FINE pulizia processi python + riavvio MapoIOB" >> clean.log diff --git a/CONF-IOB/Donati/1027 - 185/crontab b/CONF-IOB/Donati/1027 - 185/crontab new file mode 100644 index 0000000..74fe381 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/crontab @@ -0,0 +1 @@ +* * * * * /bin/bash /home/pi/steamware/checkAlive.sh >> /home/pi/stdout 2>> /home/pi/stderr diff --git a/CONF-IOB/Donati/1027 - 185/install-RPI-IOB.sh b/CONF-IOB/Donati/1027 - 185/install-RPI-IOB.sh new file mode 100644 index 0000000..19491e1 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/install-RPI-IOB.sh @@ -0,0 +1,47 @@ +#|/bin/bash + +#installa il necessario per RPI-3-IOB partendo dal contenuto della folder /home/pi/steamware + +#step 1: creo file di log nuovi +rm /var/log/log*.txt +rm /var/log/MapoIOB +rm /home/pi/steamware/log*.txt + +touch /var/log/logReboot.txt +touch /var/log/logTemp.txt +touch /var/log/MapoIOB + +ln -sf /var/log/logReboot.txt /home/pi/steamware/logReboot.txt +ln -sf /var/log/logTemp.txt /home/pi/steamware/logTemp.txt +ln -sf /var/log/MapoIOB /home/pi/steamware/logfile.txt + +chown pi:pi /home/pi -R +chmod 666 /var/log/log*.txt +chmod 666 /var/log/MapoIOB + +#step 2: copio files in /usr/local/bin +cd /home/pi/steamware +chmod +x *.sh +cp *.sh /usr/local/bin/ + +# step 3: copio target systemd in avvio... +cp -f sendRebootIOB /etc/init.d/sendRebootIOB +cp -f sendRebootIOB.service /etc/systemd/system/sendRebootIOB.service +echo "" +echo "-----------------------------------------------" +echo "Completare registrazione servizio avvio: digitare i seguenti comandi" +echo "systemctl enable sendRebootIOB" +echo "systemctl daemon-reload" +echo "systemctl status sendRebootIOB" +echo "-----------------------------------------------" +echo "" +echo "" +echo "" +echo "-----------------------------------------------" +echo "Infine creare voce crontab che salvi temperatura CPU/GPU ogni 20 minuti..." +echo "crontab -e" +echo "*/20 * * * * /usr/local/bin/saveTemp.sh" +echo "-----------------------------------------------" + + + diff --git a/CONF-IOB/Donati/1027 - 185/mppar b/CONF-IOB/Donati/1027 - 185/mppar new file mode 100644 index 0000000..b433a73 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/mppar @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/pi/steamware/readParallela.py diff --git a/CONF-IOB/Donati/1027 - 185/mpser b/CONF-IOB/Donati/1027 - 185/mpser new file mode 100644 index 0000000..444b459 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/mpser @@ -0,0 +1,2 @@ +#!/bin/bash +/usr/bin/python /home/steamware/readSeriale.py diff --git a/CONF-IOB/Donati/1027 - 185/readParallela.py b/CONF-IOB/Donati/1027 - 185/readParallela.py new file mode 100644 index 0000000..5a38f21 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/readParallela.py @@ -0,0 +1,530 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# readParallela v. 1.8 +# versione estetica di Carlo + single instance timer + +#--------------------------------------------------------------- +# levare locking +# timer semplificata +# GPIO global + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging +import logging.handlers +import threading +import Queue +#-------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +PROGRAM_NAME ="ReadPar IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "1001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) +SENDURLTIME = 0.08 + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +# VAR + +out_0 = 24 +out_1 = 26 + +in_0 = 11 +in_1 = 12 +in_2 = 13 +in_3 = 15 +in_4 = 16 +in_5 = 18 +in_6 = 22 +in_7 = 7 + +# contatore: serve x match tra accoda ed invia x possibile controllo a posteriori... ogni volta che accodo incremento di 1, va da 0 a 999 +cont = '0' + +# variabile stato online/offline della macchina +onLine = '1' + +# variabile stato seinding/waiting x la parte invio URL +sending = '0' + +# variabile stato timer thread busy +timer_busy = False + +#-------------------------------------------------------------- +# Gestione coda (condivisa) x registrazione eventi ed invio URL +#print "Creazione coda 1000 elementi" + +Coda = Queue.Queue(0) + +#queueLock = threading.Lock() + +#--------------------------------------------------------------- +# lettura parallela +# ritorna il byte letto pulito ( due char hex ) + +def readParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + current = '' + +# print "input : " + + # ritorna '' se non ci sono abbastanza caratteri + try: + num_value = 255 + +# print "num_value : " , num_value , in_0 + + if GPIO.input(in_0): + num_value = num_value - 1 + + if GPIO.input(in_1): + num_value = num_value - 2 + + if GPIO.input(in_2): + num_value = num_value - 4 + + if GPIO.input(in_3): + num_value = num_value - 8 + + if GPIO.input(in_4): + num_value = num_value - 16 + + if GPIO.input(in_5): + num_value = num_value - 32 + + if GPIO.input(in_6): + num_value = num_value - 64 + + if GPIO.input(in_7): + num_value = num_value - 128 + + current = hex( num_value ).replace ( "0x" , "" ).upper() + +# print "\n\n\n\n\n" , num_value , current + + except: + pass + + return current + + +#-------------------------------------------------------------- +# MARCO: cambiare: chiama URL NON deve chiamare url MA METTERE IN CODA (riempiCoda!!!) +# la parte URL vera va messa in svuotaCoda, PARAMETRICA + +#--------------------------------------------------------------- +#Funzione di scrittura su coda con try-except + +def accoda(): + + try: +# url = URLBASE + idxMacchina + URLADV1 + value +# urllib.urlopen ( url ) + #dtEve = time.strftime("%y%m%d%H%M%S")+"000" + dtEve = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + #logPro.debug( "Nuovo valore inserito in coda: " + dtEve + "#" + value + '#' + cont) + #print(dtEve) + #queueLock.acquire() + Coda.put(dtEve + '#' + value + '#' + cont) + #queueLock.release() + #print "Nuovo valore inserito in coda: " + dtEve + "#", value + + except Queue.Full: + logPro.error( "Quque full" + dtEve + '#' + value + '#' + cont ) + except: + logPro.error( "NETWORK:Errore http-no com rete-timeout" + url ) +# print "Url aforte" , url + + +#-------------------------------------------------------------- +# MARCO: scrivere svuotaCoda come thread etc... +def svuota_coda(): + + global onLine + global sending + global timer_busy + + #print "start timer " + + if ( timer_busy == False ): + timer_busy = True + #print "start timer ok " + + try: + if not Coda.empty(): + #print "coda da svuotare!" + response = urllib.urlopen(URLALIVE) + answ = response.read() + if answ == 'OK': + #print "OK alive" + response2 = urllib.urlopen(URLENABLED + idxMacchina) + answ2 = response2.read() + if answ2 == 'OK': + # aggiorno stato ad online + if onLine == '0': + logPro.info("IOB ONLINE!") + #print("IOB ONLINE") + + onLine = '1' # imposto comunque online + else: + if onLine == '1': + logPro.error("IOB offline") + #print("IOB offline") + + onLine = '0' + else: + if onLine == '1': + logPro.error("Server offline") + #print("Server offline") + + onLine = '0' + + # ora verifico SE si possa inviare (ovvero sia online server e NON ci siano altri send attivi...) + if onLine == '1': + if sending == '0': + #segnalo che sono in sending! + sending = '1' + + # formatto dataOra corrente + #dtCurr = time.strftime("%y%m%d%H%M%S")+"000" + dtCurr = datetime.utcnow().strftime('%Y%m%d%H%M%S%f')[:-3] + # prendo 1 valore dalla coda... + #queueLock.acquire() + resp = Coda.get() + # RILASCIO SUBITO la coda x nuovi insert... + #queueLock.release() + + + # recupero valori da coda! + dtEve = resp.split("#")[0] + value = resp.split("#")[1] + cnt = resp.split("#")[2] + url = URLBASE + idxMacchina + URLADV1 + value + url = url + '&dtCurr=' + dtCurr + '&dtEve=' + dtEve + '&cnt=' + cnt + # CHIAMO URL + response3 = urllib.urlopen ( url ) + answ3 = response3.read() + #print(url) + #logPro.debug(url) + + + # log valore inviato! + logSnd.info( value + ' ['+ cnt +']' + ' R:' + answ3 ) + #print "Valore smaltito dalla coda" + + # completato invio, riporto sending a zero! + sending = '0' + else: + logPro.info("WAIT active send to complete") + + else: + pass + + else: + pass + + except: + if onLine == '1': + logPro.error("Server Non raggiungibile") + #print "Non raggiungibile" + + onLine = '0' + +# in ogni caso + + timer_busy = False + #print "end timer ok" + + + #print "end timer " + + +#--------------------------------------------------------------- +# funzione timer thread +#--------------------------------------------------------------- +def do_every (interval, worker_func, iterations = 0): + if iterations != 1: + threading.Timer ( + interval, + do_every, [interval, worker_func, 0 if iterations == 0 else iterations-1] + ).start (); + + worker_func (); + +#--------------------------------------------------------------- +# gestione contatore +#--------------------------------------------------------------- +def contatore(): + + try: + global cont + ctr = int(cont) + ctr +=1 + ctr = ctr % 1000 # round robin 1000 eventi x track + cont = str(ctr) + except: + print("errore incremento contatore") + +#--------------------------------------------------------------- +# avvia porta parallela +#--------------------------------------------------------------- +def avviaParallela(): + + global in_0 + global in_1 + global in_2 + global in_3 + global in_4 + global in_5 + global in_6 + global in_7 + + global GPIO + + try: + + GPIO.setmode(GPIO.BOARD) + + GPIO.setwarnings(False) + + #GPIO.setup(out_0, GPIO.OUT) # output 0 + #GPIO.setup(out_1, GPIO.OUT) # output 1 + + GPIO.setup(in_0, GPIO.IN) # input 0 + GPIO.setup(in_1, GPIO.IN) # input 1 + GPIO.setup(in_2, GPIO.IN) # input 2 + GPIO.setup(in_3, GPIO.IN) # input 3 + GPIO.setup(in_4, GPIO.IN) # input 4 + GPIO.setup(in_5, GPIO.IN) # input 5 + GPIO.setup(in_6, GPIO.IN) # input 6 + GPIO.setup(in_7, GPIO.IN) # input 7 + + except: + print( "\n\n" + PROGRAM_NAME + " - Error 3 on RPi.GPIO ! \n\n") + sys.exit(1) + + + print( "\n\n" + PROGRAM_NAME + " - init ok \n\n") + + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + SENDURLTIME = config.getfloat ( 'time' , 'SENDURLTIME' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLENABLED = config.get('web' , 'URLENABLED') + URLALIVE = config.get ('web' , 'URLALIVE') + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a' + ) + + # aggiungo 2 logger specifici x queue e send... + logQue = logging.getLogger('queue') + logSnd = logging.getLogger('sendUrl') + logPro = logging.getLogger('program') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logPro.info("Avvio Programma" + PROGRAM_NAME) + +## Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logPro.info( "Start " + PROGRAM_NAME ) + + +# lettura file configurazione + +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + + +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' SENDURLTIME = %4.2f' % ( SENDURLTIME ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + +#-------------------------------------------------------------- +# apertura parallela + +try: + import RPi.GPIO as GPIO +except RuntimeError: + print( "\n\n" + PROGRAM_NAME + " - Error 1 - you need superuser privileges") +except: + print( "\n\n" + PROGRAM_NAME + " - Error 2 - you need superuser privileges. USE 'sudo' to run your script\n\n") + sys.exit(1) + + +avviaParallela() + + +#-------------------------------------------------------------- +# MARCO: qui inserire avvio thread di "svuotaCoda" + +# avviaSvuotaCoda +#print "Avvia svuota coda" + +do_every ( SENDURLTIME , svuota_coda ); + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +#print "Avvio ciclo" +logPro.info("Avvio loop principale") +while 1: + + try: + time.sleep (SAMPLETIME) + except: + logPro.info("First_SLEEP: errore attesa sampletime") + + # lettura dati da IOB + value = readParallela() + + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logQue.info( value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logQue.info( '>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_short") + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logQue.info( '>>' + value + ' ['+ cont +']') + errormsglen = 0 + accoda() + contatore() + except: + logPro.error("URLBROWSER: errore registrazione valore e accoda TO_long") + pass + to_long = TIMEOUTLONG + + + + diff --git a/CONF-IOB/Donati/1027 - 185/readSeriale.py b/CONF-IOB/Donati/1027 - 185/readSeriale.py new file mode 100644 index 0000000..3c00644 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/readSeriale.py @@ -0,0 +1,363 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +#--------------------------------------------------------------- + +import serial +import time +import sys +import datetime +import urllib +import ConfigParser +import os, sys + +#--------------------------------------------------------------- + +# COSTANTI +MSGLEN = 9 +TIMEOUTSERIALE = 10 +MAXRETRY = 3 + +# DA FILE CONF +idxMacchina = "2001" +SAMPLETIME = 0.1 +TIMEOUTSHORT = (SAMPLETIME*20) +TIMEOUTLONG = (SAMPLETIME*600) + +# VAR +to_enable = False +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG +to_serial = TIMEOUTSERIALE +to_retry = MAXRETRY +errormsglen = 0 + +#--------------------------------------------------------------- +# classe logger + +class Logger: + def __init__(self, filename): + try: + self.filename = filename + except: + logga("LOGGER: errore try su self.filename") + sys.exit(1) + def __call__(self, string): + try: + file = open(self.filename, 'a') + file.write('[' + time.strftime("%Y-%m-%d %H:%M:%S") + '] ') + file.write(string + '\n') + file.close() + except: + logga("LOGGER: errore try su scrittura") + sys.exit(1) + +#--------------------------------------------------------------- +# lettura buffer seriale e pulizia caratteri non stampabili +# ritorna '' se non c'è un messaggio buono o il messaggio pulito ( due bytes hex ) +# il messaggio ha il formato xxi00 00xxx + +def readSeriale(): + + global to_serial + global to_retry + global errormsglen + + ret = '' + current = '' + i = 0 + + # ritorna '' se non ci sono abbastanza caratteri + try: + if ser.inWaiting() < MSGLEN : +# +# to_serial = to_serial - 1 # se non mi risponde, faccio un ' altra richiesta.... +# if to_serial <= 0: +# try: +# requestData () +# except: +# logga("SERIALE: errore su requestData") +# sys.exit(1) +# to_serial = TIMEOUTSERIALE # ripristino timer +# to_retry = to_retry - 1 # contatore retry +# if to_retry <= 0: +# logga ( 'IOB not responding' ) +# return ret + logga("SERIALE: errore msglen < 9 char - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + except: + if startstatus == 0: + logga ("Porta SERIALE non disponibile - ser.inWaiting error - exit... - Errore no. " + str(errormsglen)) + errormsglen = errormsglen +1 + avviaSeriale() + time.sleep(.2) + if errormsglen > 30: + sys.exit(1) + + # finchè c'è robba .. leggi e tieni i buoni + to_serial = TIMEOUTSERIALE + to_retry = MAXRETRY + try: + while ser.inWaiting() > 0 : + try: + c = ser.read(1) + except: + logga("SERIALE: errore su try ser.read") + sys.exit(1) + # filtra caratteri non stampabili + if c > ' ' : + current += c + #sys.stdout.write(current + '<<<<\n') + # ora il messaggio ha il formato xxxxxi00 00xxx : cerco la 'i' iniziale + try: + while i < len(current) and current[i] != 'i': + i = i + 1 + except: + logga("SERIALE: errore su ricerca i iniziale") + sys.exit(1) + # se non ho trovato la 'i' restituisco '' + if i == len(current)-1: + return ret + else: + current = current[i+1:i+3] + # richiesta dati ad IOB + requestData() + #sys.stdout.write ( current + '\n') + except: + if startstatus == 0: + logga ('Porta SERIALE non disponibile - ser.inWaiting e filtraggio error...exit') + sys.exit(1) + return current +#--------------------------------------------------------------- +# richiesta dati ad IOB : scrittura su seriale + +def requestData (): + try : + ser.write ("$i" + '\r\n') + ser.flush() + except : + if startstatus == 0: + logga ( "SERIAL: Errore di scrittura/flush") + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except + +def chiamaUrl(): + try: + url = URLBASE + idxMacchina + URLADV1 + value + urllib.urlopen ( url ) + except: + logga ( "NETWORK:Errore http-no com rete-timeout" + url ) + + +#--------------------------------------------------------------- +# Funzione che verifica possibilità di creare log e include testo corrente + +def logga(message) : + try: + log(message) + except : + pass + +#--------------------------------------------------------------- + + +def avviaSeriale(): + global ser + + try: + ser = serial.Serial( + port = comm_port , + baudrate = 9600 , + parity = serial.PARITY_NONE , + stopbits = serial.STOPBITS_ONE , + bytesize = serial.EIGHTBITS + ) + startstatus = 0 + except serial.serialutil.SerialException , e : + try: + if startstatus == 0: + logga ( "SERIAL:Errore apertura seriale - " + comm_port) + except: + pass + sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) + if errormsglen > 30: + sys.exit (1) + +#--------------------------------------------------------------- +#--------------------------------------------------------------- +# MAIN + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'readSeriale.cfg' ) + + SAMPLETIME = config.getfloat ( 'time' , 'SAMPLETIME' ) + TIMEOUTSHORT = config.getfloat ( 'time' , 'TIMEOUTSHORT' ) + TIMEOUTLONG = config.getfloat ( 'time' , 'TIMEOUTLONG' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + comm_port = config.get ( 'comm' , 'port' ) + + URLBASE = config.get ( 'web' , 'URLBASE' ) + URLADV1 = config.get ( 'web' , 'URLADV1' ) + + LOGFILE = config.get ( 'log' , 'LOGFILE' ) + LOGLEVEL = config.get ( 'log' , 'LOGLEVEL' ) +except: + sys.exit(1) + +# oggetto Logger +try: + log = Logger(LOGFILE) +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) + +print '\n\n Read seriale IOB v.0.2 !!!!\n' + +global startstatus +startstatus = 1 + +if startstatus == 1: + logga("Avvio Programma") + +# Verifica l'OS e di conseguenza carica il file relativo con metodo di lockfile appropriato + check singola istanza +if os.name == 'posix': + import unix +else: + import win + +logga ( "Start Read seriale IOB v.0.2") + + +# lettura file configurazione + +# [comm] +# port = /dev/ttyS0 +# [id] +# idxMacchina = 2001 +# [time] +# SAMPLETIME = 0.1 +# TIMEOUTSHORT = 200 +# TIMEOUTLONG = 6000 + +print ( ' comm_port = %s' % ( comm_port ) ) +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' SAMPLETIME = %4.2f' % ( SAMPLETIME ) ) +print ( ' TIMEOUTSHORT = %4.2f' % ( TIMEOUTSHORT ) ) +print ( ' TIMEOUTLONG = %4.2f' % ( TIMEOUTLONG ) ) +print ( ' URLBASE = %s' % ( URLBASE ) ) +print ( ' URLADV1 = %s' % ( URLADV1 ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) +print ( ' LOGLEVEL = %s' % ( LOGLEVEL ) ) + +# -sys.stdout.write ( 'idxMacchina ?' + idxMacchina + '\n') + +to_short = TIMEOUTSHORT +to_long = TIMEOUTLONG + + + +#-------------------------------------------------------------- + + +#--------------------------------------------------------------- +# apertura seriale + +avviaSeriale() + +#try: +# ser = serial.Serial( +# port = comm_port , +# baudrate = 9600 , +# parity = serial.PARITY_NONE , +# stopbits = serial.STOPBITS_ONE , +# bytesize = serial.EIGHTBITS +# ) +# print "Initialized!" +#except serial.serialutil.SerialException , e : +# try: +# logga ( "SERIAL:Errore apertura seriale - " + comm_port) +# except: +# pass +# sys.stdout.write ( '\nErrore apertura seriale\n\n%s\n\n' % e ) +# sys.exit (1) + +#--------------------------------------------------------------- +# ciclo forever and ever + +old = '' + +# richiesta dati ad IOB +try: + requestData() +except: + logga("SERIALE: errore sul try di requestData") + sys.exit(1) + + +while 1: + try: + time.sleep (SAMPLETIME) + except: + logga("SERIALE_SLEEP: errore attesa sampletime") + # lettura dati da IOB + try: + value = readSeriale() + except: + if startstatus == 0: + logga("errore PRIMA LETTURA SERIALE") + sys.exit(1) + if ( value != '' ) : + if value != old : + #loggo e invio dati + try: + logga ( value ) + errormsglen = 0 + chiamaUrl() + except: + logga("URLBROWSER: errore registrazione valore e chiamaUrl") + pass + #enable e reset timer + to_enable = True + to_short = TIMEOUTSHORT + to_long = TIMEOUTLONG + + old = value + + + # gestione timeout breve + if ( to_enable ) : + to_short = to_short - SAMPLETIME + if to_short <= 0: + #loggo e invio dati + try: + logga ( '>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_short = TIMEOUTSHORT + to_enable = False # dopo un colpo il timer breve viene disabilitato + to_long = TIMEOUTLONG + + # gestione timeout lungo + to_long = to_long - SAMPLETIME + if to_long <= 0: + #loggo e invio dati + try: + logga ( '>>' + value ) + errormsglen = 0 + chiamaUrl() + except: + pass + to_long = TIMEOUTLONG + + diff --git a/CONF-IOB/Donati/1027 - 185/saveTemp.sh b/CONF-IOB/Donati/1027 - 185/saveTemp.sh new file mode 100644 index 0000000..a2cd2be --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/saveTemp.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +#salva la temperatura CPU e GPU su chiamata... + +# imposto logfile... +logFile="/var/log/logTemp.txt" + +cpuTemp0=$(cat /sys/class/thermal/thermal_zone0/temp) +cpuTemp1=$(($cpuTemp0/1000)) +cpuTemp2=$(($cpuTemp0/100)) +cpuTempM=$(($cpuTemp2 % $cpuTemp1)) + +gpuTemp=`vcgencmd measure_temp` + +loadAvg=`cat /proc/loadavg` + +echo "$(date) | CPU: temp=$cpuTemp1.$cpuTempM ºC | GPU: $gpuTemp | LoadAvg: $loadAvg" >> $logFile diff --git a/CONF-IOB/Donati/1027 - 185/sendReboot.py b/CONF-IOB/Donati/1027 - 185/sendReboot.py new file mode 100644 index 0000000..021c400 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/sendReboot.py @@ -0,0 +1,130 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# sendReboot v. 1.8 + +#--------------------------------------------------------------- + + +import time +import sys + + +from datetime import datetime + +import urllib +import ConfigParser +import os, sys + +import logging + +import time + +#--------------------------------------------------------------- + +# COSTANTI +PROGRAM_NAME = "SendReboot IOB-pi v.1.8" + +# DA FILE CONF +idxMacchina = "99" + +# registro se ho fatto chiamata +global numTry +numTry = 1 + + +#--------------------------------------------------------------- +#Funzione di scrittura su url con try-except +#--------------------------------------------------------------- + +def chiamaUrl(numTry): + + try: + urllib.urlopen ( url ) + numTry = numTry + 10 + except Exception, e: + print e + logging.info ( e ) + print "Url aforte" , url + return numTry + + +#--------------------------------------------------------------- +# Funzione di recupero mac address per poterlo inviare a MPIO +#--------------------------------------------------------------- +def getMAC(interface): + # Return the MAC address of interface + try: + str = open('/sys/class/net/' + interface + '/address').read() + except: + str = "00:00:00:00:00:00" + return str[0:17] + +#--------------------------------------------------------------- +# MAIN +#--------------------------------------------------------------- + +try: + config = ConfigParser.RawConfigParser() + config.read ( 'IOB.cfg' ) + + idxMacchina = config.get ( 'id' , 'idxMacchina' ) + + + URLREBO = config.get ( 'web' , 'URLREBO' ) + + LOGFILE = config.get ( 'log' , 'LOGREBO' ) +except: + print "\n\n" + PROGRAM_NAME + ' - Error 4 - in config file ' 'IOB.cfg' + sys.exit(1) + + +#-------------------------------------------- +# oggetto Logger +#-------------------------------------------- +try: +# log = Logger(LOGFILE) + logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-8s %(levelname)-8s %(message)s', + datefmt='%Y-%m-%d %H:%M:%S', + filename=LOGFILE, + filemode='a') + +except: + # manda mail o simili - FARE!!! + print "LOG: Impossibile creare file log con nome " + print (LOGFILE) +#-------------------------------------------- + + +print "\n\n" + PROGRAM_NAME + "\n\n" + +global startstatus +startstatus = 1 + +if startstatus == 1: + logging.info("Avvio Programma " + PROGRAM_NAME) + + +# lettura file configurazione +print ( ' idxMacchina = %s' % ( idxMacchina ) ) +print ( ' URLREBO = %s' % ( URLREBO ) ) +print ( ' LOGFILE = %s' % ( LOGFILE ) ) + +# lettura mac address +myMac = getMAC('eth0') +print ( ' MAC Address = %s' % ( myMac ) ) + +# configuro URL da inviare +url = URLREBO + idxMacchina + "&mac=" + myMac + +# modifica: cerco se ho inviato segnale altrimenti ritento invio... +while (numTry < 11): + logging.info("Tentativo invio URL: " + `numTry` ) + numTry = chiamaUrl(numTry) + time.sleep(3) + numTry = numTry + 1 + + +# registro che ho inviato! +logging.info("Inviato segnale di reboot!: " + url ) diff --git a/CONF-IOB/Donati/1027 - 185/sendRebootIOB b/CONF-IOB/Donati/1027 - 185/sendRebootIOB new file mode 100644 index 0000000..191bfff --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/sendRebootIOB @@ -0,0 +1,33 @@ +#!/bin/sh - +# +### BEGIN INIT INFO +# Provides: sendReboot +# Required-Start: $network $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Steamware's IOB reboot signal +# Description: Steamware's sendReboot segnalazione reboot dispositivo +### END INIT INFO + +#! /bin/sh +# /etc/init.d/sendReboot + + + +export HOME +case "$1" in + start) + cd /home/pi/steamware + echo "Starting sendReboot" + /usr/bin/python ./sendReboot.py 2>&1 & + echo "Verifica Rete e file IOB" + /usr/local/bin/setIobConf.sh + ;; + *) + echo "Usage: /etc/init.d/sendReboot {start}" + exit 1 + ;; +esac +exit 0 + diff --git a/CONF-IOB/Donati/1027 - 185/sendRebootIOB.service b/CONF-IOB/Donati/1027 - 185/sendRebootIOB.service new file mode 100644 index 0000000..48e3690 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/sendRebootIOB.service @@ -0,0 +1,22 @@ +[Unit] +SourcePath=/etc/init.d/sendRebootIOB +Description=LSB: Steamware's IOB reboot signal +Before=runlevel2.target runlevel3.target runlevel4.target runlevel5.target shutdown.target +Wants=network-online.target +After=network.target network-online.target auditd.service +Conflicts=shutdown.target + +[Service] +Type=forking +Restart=no +TimeoutSec=5min +IgnoreSIGPIPE=no +KillMode=process +GuessMainPID=no +RemainAfterExit=yes +SysVStartPriority=2 +ExecStart=/etc/init.d/sendRebootIOB start +ExecStop=/etc/init.d/sendRebootIOB stop + +[Install] +WantedBy=multi-user.target diff --git a/CONF-IOB/Donati/1027 - 185/setIobConf.sh b/CONF-IOB/Donati/1027 - 185/setIobConf.sh new file mode 100644 index 0000000..30b4781 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/setIobConf.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# verifico se sia rete donati o rete steamware o offline... +netStatus=`cat /sys/class/net/eth0/operstate` +iaddr=`ifconfig eth0 | grep "inet addr" | cut -d ':' -f 2 | cut -d ' ' -f 1` + +cd /home/pi/steamware + +if [[ $netStatus != "up" ]] +then + echo "Siamo Offline, pagina demo!" +elif [[ $iaddr == "10.74.82"* ]] +then + cp IOB.cfg.steamware IOB.cfg -f + echo "Siamo in Steamware!" +elif [[ $iaddr == "192.168.51"* ]] +then + cp IOB.cfg.donati IOB.cfg -f + echo "Siamo a Passirano!" +else + echo "Siamo altrove, pagina demo!" +fi + +echo "$iaddr" + +chown pi:pi * \ No newline at end of file diff --git a/CONF-IOB/Donati/1027 - 185/test.py b/CONF-IOB/Donati/1027 - 185/test.py new file mode 100644 index 0000000..3145cbe --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/test.py @@ -0,0 +1,31 @@ +import logging + +# set up logging to file - see previous section for more details +logging.basicConfig(level=logging.DEBUG, + format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s', + datefmt='%m-%d %H:%M', + filename='test.log', + filemode='w') +# define a Handler which writes INFO messages or higher to the sys.stderr +console = logging.StreamHandler() +console.setLevel(logging.INFO) +# set a format which is simpler for console use +formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') +# tell the handler to use this format +console.setFormatter(formatter) +# add the handler to the root logger +logging.getLogger('').addHandler(console) + +# Now, we can log to the root logger, or any other logger. First the root... +logging.info('Jackdaws love my big sphinx of quartz.') + +# Now, define a couple of other loggers which might represent areas in your +# application: + +logger1 = logging.getLogger('myapp.area1') +logger2 = logging.getLogger('myapp.area2') + +logger1.debug('Quick zephyrs blow, vexing daft Jim.') +logger1.info('How quickly daft jumping zebras vex.') +logger2.warning('Jail zesty vixen who grabbed pay from quack.') +logger2.error('The five boxing wizards jump quickly.') diff --git a/CONF-IOB/Donati/1027 - 185/unix.py b/CONF-IOB/Donati/1027 - 185/unix.py new file mode 100644 index 0000000..12fb3dc --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/unix.py @@ -0,0 +1,31 @@ +import fcntl +import os +import logging + +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + except IOError: + return False + + return True + +if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logging.error( "LOCK: Piu istanze aperte") + #sys.exit ( 0 ) + +#- print '\n running alone ...\n' + + diff --git a/CONF-IOB/Donati/1027 - 185/unix.pyc b/CONF-IOB/Donati/1027 - 185/unix.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a42c57dccb546762ac8321fadd75696744be6872 GIT binary patch literal 669 zcma)3O>fgc5Ph?@o5oF$-~=2hOI&<%?g$}Blmeo1kdvw*m&%GaVN=H&c{hThaw@-( zKf(`y*`*&>)}GlnA3JZKHu&9-JHH;!m$+Sm_cv^&U{~=^sDZ^jCM@VKFR&1(1b%Wu z02!bPa6>RTsu1tqOMy*@Dsnk${HSSqz+=@PUip$3I=YB$#AcWU7T6H3{{i8{07I7z zF}xA@LAW}Gjj%buHF?nS{?M1{ym^Aqc5xY_Jp&Qh7}L2u!ZdY!dD?R%j#e8Rx@{*L z+hH)d7!~8Uvs*kX&hn8x^!f8*lAnHNPGGfcZ0%94mzOKwd^#C@yco|Pa6a_-!(`mH zy7k>BWo@MAo3(qHI(|RgPf@k>H(FIG=i!}s&S>yOZ{=X82FA*A`?YN4VBe^3+3xE8 z@ChI8bE|Q>AYM=)j;T+PFkOzbyZPoBM{&|<#nvQ7m0O({U8^L^ve-Q3s*~|D`K0!V zGPZ2K%cR`N*2>iBF1%v^FRj+=wQAPIBbRU`>6AX){=X%>+Ujaw%h&F0yo4U{7k7_( G6wzNWP=h!C literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1027 - 185/win.py b/CONF-IOB/Donati/1027 - 185/win.py new file mode 100644 index 0000000..f679f60 --- /dev/null +++ b/CONF-IOB/Donati/1027 - 185/win.py @@ -0,0 +1,32 @@ +import win32api +print " Running on WINDOWS\n" +import os +#--------------------------------------------------------------- +# meccanismo di file lock per evitare multiple instances +# The function will try to lock the file specified , if it success, return True, else return False. +# The nice thing is that the lock will be dropped when the program terminates. +# >>>Use : +# if not lockFile(".lock.pod"): +# sys.exit(0) + +def lockFile ( lockfile ) : + try: + fd = os.open ( lockfile , os.O_CREAT | os.O_TRUNC | os.O_WRONLY ) + except: + logga("Errore nel file WIN.PY per FD") + try: + # Request exclusive (EX) non-blocking (NB) advisory lock. + #fcntl.lockf ( fd , fcntl.LOCK_EX | fcntl.LOCK_NB ) + print " Dummy Method! Completa Lockfile\n" + except IOError: + return False + + return True +try: + if not lockFile ( ".lockfile" ) : + print '\n noi non siamo soli ...\n' + logga ( "LOCK: Piu istanze aperte") + sys.exit ( 0 ) +except: + logga("if not lockfile NON RIUSCITO in file WIN.PY") + sys.exit(1) diff --git a/CONF-IOB/Donati/1027 - 185/win.pyc b/CONF-IOB/Donati/1027 - 185/win.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ae9a11e6dca5bd435d4e6baf0fb24c05441229bd GIT binary patch literal 883 zcmbVJO>fgc5S_Kte3%vqR1h3M+XHGOq)3HZg%H$fA)>V-Cso=iQf0;4vc%c7ycM=3KTtxF`MC&Tz z2u%m=00iV8e34m)%9FWLQk`?H_^20kXQ-ecExC z8tq(o^p(*_-Ek}|sIlwDi`M0wBehO7Tc-~J>81-~wm}1SWSb!7qeo;O0e8z%mx3#i z^D~(X$E(vn=7lKvUe|0Of_LY$*@7Pk`(9@oJk+xy7dGYldNOq>LA!-0>t@i#*4$AD zg=R$YX_)N39xnA^au|hZ@9d)_j`okioG91l=V=wviz_yjbuZ10sHzRixoErURcgNM zTJ<~2+OSgv<_WZLdwgg_X~v?QrAp~>SD2~Q#rU8<5asxzRGngRU1tyMSCM7zx+=_P zn~>Yg_glcaXWU$!tA^$wZUI+XLKHVLooQ}#E_tWZ3Csg{_v7&0Ht)+hm&T^*v*0QA zXoZB2%u|3oL$c*pHF*?AJn0<{!rn0EQr&z4JU%9?11i3t{`^^5$OHyTZaHwvv+gC$ r;&SieleGU9@;_U7G1J*R7cX6Jb04tER@iE*wdS)mXaT#24F&8ksVTb- literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1501_172/IOB.cfg b/CONF-IOB/Donati/1501_172/IOB.cfg new file mode 100644 index 0000000..b14a649 --- /dev/null +++ b/CONF-IOB/Donati/1501_172/IOB.cfg @@ -0,0 +1,10 @@ +[id] +idxMacchina = 1501 + +[web] +URLREBO = http://10.74.82.218/MPIO/sendReboot.aspx?idxMacchina= +#URLREBO = http://192.168.51.71/MPIO/sendReboot.aspx?idxMacchina= + +[log] +LOGLEVEL = 10 +LOGREBO = /var/log/logReboot.txt diff --git a/CONF-IOB/Donati/1501_172/LogoHighResWhite.png b/CONF-IOB/Donati/1501_172/LogoHighResWhite.png new file mode 100644 index 0000000000000000000000000000000000000000..361a978d2fdfcbf8211896f88ce114c0f33cdbfe GIT binary patch literal 18907 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�nj1)k?ZH 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 Xw38KnWN+C3I$p=q)z4*}Q$iB}cq5-( literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1501_172/MP-MON-DEMO.html b/CONF-IOB/Donati/1501_172/MP-MON-DEMO.html new file mode 100644 index 0000000..7bd8331 --- /dev/null +++ b/CONF-IOB/Donati/1501_172/MP-MON-DEMO.html @@ -0,0 +1,540 @@ + + + + + + Index - MP-MONi DEMO + + + + + + + + + + + +

+
+ + + +
+
+
+ +
+
+ +
+
SMER.09
+
+
+
articolo:
+
-
+
fermo generico
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.03
+
+
+
articolo:
+
5010710
+
fermo generico
+
tempo ciclo:
+
07:31
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.04
+
+
+
articolo:
+
5009047
+
lavorazione
+
tempo ciclo:
+
07:01
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.02
+
+
+
articolo:
+
5010225
+
lavorazione
+
tempo ciclo:
+
07:00
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.03
+
+
+
articolo:
+
5009595
+
fermo generico
+
tempo ciclo:
+
10:49
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.08
+
+
+
articolo:
+
5009595
+
lavorazione
+
tempo ciclo:
+
09:07
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.07
+
+
+
articolo:
+
5009580
+
lavorazione
+
tempo ciclo:
+
07:34
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.02
+
+
+
articolo:
+
5003049
+
lavorazione
+
tempo ciclo:
+
06:55
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.01
+
+
+
articolo:
+
5009030
+
lavorazione
+
tempo ciclo:
+
08:04
+ + +
+
+
+
+
+
+
+
+ +
+
EXABB
+
+
+
articolo:
+
5010290
+
lavorazione
+
tempo ciclo:
+
10:03
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.04
+
+
+
articolo:
+
5010660
+
lavorazione
+
tempo ciclo:
+
14:43
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.10
+
+
+
articolo:
+
5009556
+
lavorazione
+
tempo ciclo:
+
14:03
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.01
+
+
+
articolo:
+
5010260
+
lavorazione
+
tempo ciclo:
+
06:45
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.06
+
+
+
articolo:
+
5007041
+
lavorazione
+
tempo ciclo:
+
02:00
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.02
+
+
+
articolo:
+
5010720
+
manuale
+
tempo ciclo:
+
02:01
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.01
+
+
+
articolo:
+
5010181
+
lavorazione
+
tempo ciclo:
+
01:43
+ + +
+
+
+
+
+
+
+
+ +
+
SBAV.05
+
+
+
articolo:
+
5007580
+
allarme CN
+
tempo ciclo:
+
03:13
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.11
+
+
+
articolo:
+
5009053
+
lavorazione
+
tempo ciclo:
+
08:45
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.COS
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.01
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.02
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.03
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ + + + + + + +
+
+
+

MoonPro MONitor

+
+
+ SteamWare +
+
+

Steamware s.r.l. - © 2007-2016

+
+
+ +
+
+ + + + + + + + + diff --git a/CONF-IOB/Donati/1501_172/MP-MON-DEMO_b.html b/CONF-IOB/Donati/1501_172/MP-MON-DEMO_b.html new file mode 100644 index 0000000..8ed3c2e --- /dev/null +++ b/CONF-IOB/Donati/1501_172/MP-MON-DEMO_b.html @@ -0,0 +1,540 @@ + + + + + + Index - MP-MONi DEMO + + + + + + + + + + + + +
+ + + +
+
+
+ +
+
+ +
+
SMER.09
+
+
+
articolo:
+
-
+
fermo generico
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.03
+
+
+
articolo:
+
5010710
+
fermo generico
+
tempo ciclo:
+
07:31
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.04
+
+
+
articolo:
+
5009047
+
lavorazione
+
tempo ciclo:
+
07:01
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.02
+
+
+
articolo:
+
5010225
+
lavorazione
+
tempo ciclo:
+
07:00
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.03
+
+
+
articolo:
+
5009595
+
fermo generico
+
tempo ciclo:
+
10:49
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.08
+
+
+
articolo:
+
5009595
+
lavorazione
+
tempo ciclo:
+
09:07
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.07
+
+
+
articolo:
+
5009580
+
lavorazione
+
tempo ciclo:
+
07:34
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.02
+
+
+
articolo:
+
5003049
+
lavorazione
+
tempo ciclo:
+
06:55
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.01
+
+
+
articolo:
+
5009030
+
lavorazione
+
tempo ciclo:
+
08:04
+ + +
+
+
+
+
+
+
+
+ +
+
EXABB
+
+
+
articolo:
+
5010290
+
lavorazione
+
tempo ciclo:
+
10:03
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.04
+
+
+
articolo:
+
5010660
+
lavorazione
+
tempo ciclo:
+
14:43
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.10
+
+
+
articolo:
+
5009556
+
lavorazione
+
tempo ciclo:
+
14:03
+ + +
+
+
+
+
+
+
+
+ +
+
PUL.01
+
+
+
articolo:
+
5010260
+
lavorazione
+
tempo ciclo:
+
06:45
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.06
+
+
+
articolo:
+
5007041
+
lavorazione
+
tempo ciclo:
+
02:00
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.02
+
+
+
articolo:
+
5010720
+
manuale
+
tempo ciclo:
+
02:01
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.01
+
+
+
articolo:
+
5010181
+
lavorazione
+
tempo ciclo:
+
01:43
+ + +
+
+
+
+
+
+
+
+ +
+
SBAV.05
+
+
+
articolo:
+
5007580
+
allarme CN
+
tempo ciclo:
+
03:13
+ + +
+
+
+
+
+
+
+
+ +
+
SMER.11
+
+
+
articolo:
+
5009053
+
lavorazione
+
tempo ciclo:
+
08:45
+ + +
+
+
+
+
+
+
+
+ +
+
TAV.COS
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.01
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.02
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ +
+
COMB.03
+
+
+
articolo:
+
-
+
n.d.
+
tempo ciclo:
+
00:00
+ + +
+
+
+
+
+
+
+
+ + + + + + + +
+
+
+

MoonPro MONitor

+
+
+ SteamWare +
+
+

Steamware s.r.l. - © 2007-2016

+
+
+ +
+
+ + + + + + + + + diff --git a/CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSans.woff b/CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSans.woff new file mode 100644 index 0000000000000000000000000000000000000000..55b25f867099eb26c436b1c9fecff14a51290d46 GIT binary patch literal 21956 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 V`l^D1+v7dzXWE*Ozus}S{{vS5Z1n&D literal 0 HcmV?d00001 diff --git a/CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSansCondensed.woff b/CONF-IOB/Donati/1501_172/MP-MON-DEMO_files/OpenSansCondensed.woff new file mode 100644 index 0000000000000000000000000000000000000000..aedbd930e4380af025f05283e843ff4ae3f52de6 GIT binary patch literal 22432 zcmYg%V{m3o*L94EC$??doY=N)b7I@p#I|kQw(aCf^5%ZNKVMg^I=xo)ZtSi)ed_Gq zZgOH`K)^shMJ*2q@xN!H@(=%?@*n&Ei8OO&*T-Dsh*&PT-00RgJ1mtHd^}Ht;2rCmuTOc5zpEbav009w$ z!KNTUTiY4^*vd2f%(wbKY?X|e+Zee2%tc}Mr!Rv40AdELYHMI)0tBS^LqUHuNLH`` z*=Tz^Cublal^+iLGZyfDfcx2!y`#yGt!mm2hxh?9eVumjkJ119Iu>rn_)`ZOQ#QQ( z-}7o!$vw+R-&ECj(LmpHS3i5maw-^c>V)%`K6HRN`hJX`742VGt_CF{6*T25L z>0fJQ)i>PH}X5d@{b48WnmG4p;&rA2(le&fIM-}&wBeEaPHd_MIr0%Z``_|#wYhXcPL zp%GZ}n-9RFtYPg>o%EQy}Mwu*>1O+Y{Xo7x!!Dz$R{Oa zc;p)z2(k%lpb3xAgcw4EJUZ51I9g(;URp{|gVs4&VJ2i~mf-U_?jNo>mB`*0bBx-* zoexO~q>nS7U}}11cy+v!OJ8PkMH`G~wKX8%^6HNE+E@OffCDO#@{0NKGqM4q*{#tQ z1c{VJOI?nM05HunYyqqj2F6zp@EzhIKN2GJ{FB-E_sjSDx9F$V{WotQpobUM7#JR^ zXbN!{acFl05t2lZBWjNdXw(AN{%7x8RA!Vm#89?TAz(3xl*SpB2rFza`}I?u6Pg7m zt!>6uT^0;snW;|&iO7sR_mhN+v+t^+B)(J09T_=~)`h=Aan`js$yOe_l4S^(m!Pb6 zUVN`#w&^TCZV6^TysoyEr{(zh-t*sl3cGb4x-5^lo0{IPhS@KyD)juGj?iD!_~=v7 z_^HvZ$Kc5Y zG-$YHAsNa2R0x0B*m%QPjh!R~mlmI+P*)BOZKQ(1PB;XeJUuO{=!wdIvvEnGJ?&yl z{;n|~5!8JbhCk9H?2DQ54^nF8OSd;0U-*wFAC1!D@wH3N@kbJl7)&$D9d^h@yxRA+ zSOGATYV8h#W`GKKcZH5;7M3IK2rH$f1BUpgTNg20A%`t>Z=Fb0OqjJS(x%mNb%!z%5}hC z2oTIY9XTUDvrr(QQ(-wz%3aswiK7?}$nq>mtH+lxkW;U071aY0o7w0<+0!aOVDJ$- z^@rF`Bwrm)i%8{Z*5*?$`#M&}g!ek#d-3Xfi4WeWWHshuT~44k;j-a#I>?2%=}LjP zaU^_jW>*P?rD|}Qas1PhdAF=5OfLj#;D7x=MWIu=<%c3}N(|`(4zebsZaj(tGdCwD zuxyP>h64oO388&klWgX(v?jylw+)0Wt3%L0f3IS%#(PtrQba2?@kOzT5e=6u(?W#L5lj7B4yEcWmX9BLt6YW?(WaZ7g`tf#A?N^Ej4AFy;te?h#teB7ta-Nm z!#*mMkrsKLFJLTWv)1;9&Kmnov(him7Iukfdfb$|c-Ijz&fo}6pQYcD^(L+3FMQ)* zhuW(9zbXG1r>4G)3c+|dsljw?*xyyJ1;T;%Rff?^NC?mc3zc`rZV?KA!gU+u@E zcWvR9zaP$P z-(tmNYa|c0+)EE^0@X~`)U^M&;Eq z3xK*lp+Z;GFsSIs!ulm#4aD%^m(jmfx;wtk&KZd7!7iceQdPq7Vtrqj<@d~?Cts79 zVECqXW!%O<0K%9eyRedMJ3%?tHye_(P;n?=IG9nYqE*AmtYo{TMkgolJsuuK>>f<- z2145gaWZmaD^qCnR4F1e%vA+O#|0$PaD>rdniVGyONNY_xX4E;mrGIIaWkrrFjb52 zBtJo+RL6#?nr@4JXJjHr8SmBd;E0Q%rHb^+rfN;XjB8*t3OhsGO1u_=7==#IW-?xT zmfIX|ExFO|`1pKYQ9G$QZ+7f$!#%0Dn#%fQGWm=*C7M=8PtJ_@=_y~fIczaMAB?ol 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 new Error("Bootstrap's JavaScript requires jQuery version 1.9.1 or higher, but lower than version 4");}(jQuery);+function(n){"use strict";function t(){var i=document.createElement("bootstrap"),n={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"oTransitionEnd otransitionend",transition:"transitionend"};for(var t in n)if(void 0!==i.style[t])return{end:n[t]};return!1}n.fn.emulateTransitionEnd=function(t){var i=!1,u=this,r;n(this).one("bsTransitionEnd",function(){i=!0});return r=function(){i||n(u).trigger(n.support.transition.end)},setTimeout(r,t),this};n(function(){n.support.transition=t();n.support.transition&&(n.event.special.bsTransitionEnd={bindType:n.support.transition.end,delegateType:n.support.transition.end,handle:function(t){if(n(t.target).is(this))return t.handleObj.handler.apply(this,arguments)}})})}(jQuery);+function(n){"use strict";function u(i){return this.each(function(){var r=n(this),u=r.data("bs.alert");u||r.data("bs.alert",u=new t(this));"string"==typeof i&&u[i].call(r)})}var i='[data-dismiss="alert"]',t=function(t){n(t).on("click",i,this.close)},r;t.VERSION="3.3.7";t.TRANSITION_DURATION=150;t.prototype.close=function(i){function e(){r.detach().trigger("closed.bs.alert").remove()}var f=n(this),u=f.attr("data-target"),r;u||(u=f.attr("href"),u=u&&u.replace(/.*(?=#[^\s]*$)/,""));r=n("#"===u?[]:u);i&&i.preventDefault();r.length||(r=f.closest(".alert"));r.trigger(i=n.Event("close.bs.alert"));i.isDefaultPrevented()||(r.removeClass("in"),n.support.transition&&r.hasClass("fade")?r.one("bsTransitionEnd",e).emulateTransitionEnd(t.TRANSITION_DURATION):e())};r=n.fn.alert;n.fn.alert=u;n.fn.alert.Constructor=t;n.fn.alert.noConflict=function(){return n.fn.alert=r,this};n(document).on("click.bs.alert.data-api",i,t.prototype.close)}(jQuery);+function(n){"use strict";function i(i){return this.each(function(){var u=n(this),r=u.data("bs.button"),f="object"==typeof i&&i;r||u.data("bs.button",r=new t(this,f));"toggle"==i?r.toggle():i&&r.setState(i)})}var t=function(i,r){this.$element=n(i);this.options=n.extend({},t.DEFAULTS,r);this.isLoading=!1},r;t.VERSION="3.3.7";t.DEFAULTS={loadingText:"loading..."};t.prototype.setState=function(t){var i="disabled",r=this.$element,f=r.is("input")?"val":"html",u=r.data();t+="Text";null==u.resetText&&r.data("resetText",r[f]());setTimeout(n.proxy(function(){r[f](null==u[t]?this.options[t]:u[t]);"loadingText"==t?(this.isLoading=!0,r.addClass(i).attr(i,i).prop(i,!0)):this.isLoading&&(this.isLoading=!1,r.removeClass(i).removeAttr(i).prop(i,!1))},this),0)};t.prototype.toggle=function(){var t=!0,i=this.$element.closest('[data-toggle="buttons"]'),n;i.length?(n=this.$element.find("input"),"radio"==n.prop("type")?(n.prop("checked")&&(t=!1),i.find(".active").removeClass("active"),this.$element.addClass("active")):"checkbox"==n.prop("type")&&(n.prop("checked")!==this.$element.hasClass("active")&&(t=!1),this.$element.toggleClass("active")),n.prop("checked",this.$element.hasClass("active")),t&&n.trigger("change")):(this.$element.attr("aria-pressed",!this.$element.hasClass("active")),this.$element.toggleClass("active"))};r=n.fn.button;n.fn.button=i;n.fn.button.Constructor=t;n.fn.button.noConflict=function(){return n.fn.button=r,this};n(document).on("click.bs.button.data-api",'[data-toggle^="button"]',function(t){var r=n(t.target).closest(".btn");i.call(r,"toggle");n(t.target).is('input[type="radio"], input[type="checkbox"]')||(t.preventDefault(),r.is("input,button")?r.trigger("focus"):r.find("input:visible,button:visible").first().trigger("focus"))}).on("focus.bs.button.data-api blur.bs.button.data-api",'[data-toggle^="button"]',function(t){n(t.target).closest(".btn").toggleClass("focus",/^focus(in)?$/.test(t.type))})}(jQuery);+function(n){"use strict";function i(i){return this.each(function(){var u=n(this),r=u.data("bs.carousel"),f=n.extend({},t.DEFAULTS,u.data(),"object"==typeof i&&i),e="string"==typeof i?i:f.slide;r||u.data("bs.carousel",r=new t(this,f));"number"==typeof i?r.to(i):e?r[e]():f.interval&&r.pause().cycle()})}var t=function(t,i){this.$element=n(t);this.$indicators=this.$element.find(".carousel-indicators");this.options=i;this.paused=null;this.sliding=null;this.interval=null;this.$active=null;this.$items=null;this.options.keyboard&&this.$element.on("keydown.bs.carousel",n.proxy(this.keydown,this));"hover"==this.options.pause&&!("ontouchstart"in document.documentElement)&&this.$element.on("mouseenter.bs.carousel",n.proxy(this.pause,this)).on("mouseleave.bs.carousel",n.proxy(this.cycle,this))},u,r;t.VERSION="3.3.7";t.TRANSITION_DURATION=600;t.DEFAULTS={interval:5e3,pause:"hover",wrap:!0,keyboard:!0};t.prototype.keydown=function(n){if(!/input|textarea/i.test(n.target.tagName)){switch(n.which){case 37:this.prev();break;case 39:this.next();break;default:return}n.preventDefault()}};t.prototype.cycle=function(t){return t||(this.paused=!1),this.interval&&clearInterval(this.interval),this.options.interval&&!this.paused&&(this.interval=setInterval(n.proxy(this.next,this),this.options.interval)),this};t.prototype.getItemIndex=function(n){return this.$items=n.parent().children(".item"),this.$items.index(n||this.$active)};t.prototype.getItemForDirection=function(n,t){var i=this.getItemIndex(t),f="prev"==n&&0===i||"next"==n&&i==this.$items.length-1,r,u;return f&&!this.options.wrap?t:(r="prev"==n?-1:1,u=(i+r)%this.$items.length,this.$items.eq(u))};t.prototype.to=function(n){var i=this,t=this.getItemIndex(this.$active=this.$element.find(".item.active"));if(!(n>this.$items.length-1||n<0))return this.sliding?this.$element.one("slid.bs.carousel",function(){i.to(n)}):t==n?this.pause().cycle():this.slide(n>t?"next":"prev",this.$items.eq(n))};t.prototype.pause=function(t){return t||(this.paused=!0),this.$element.find(".next, .prev").length&&n.support.transition&&(this.$element.trigger(n.support.transition.end),this.cycle(!0)),this.interval=clearInterval(this.interval),this};t.prototype.next=function(){if(!this.sliding)return this.slide("next")};t.prototype.prev=function(){if(!this.sliding)return this.slide("prev")};t.prototype.slide=function(i,r){var e=this.$element.find(".item.active"),u=r||this.getItemForDirection(i,e),l=this.interval,f="next"==i?"left":"right",a=this,o,s,h,c;return u.hasClass("active")?this.sliding=!1:(o=u[0],s=n.Event("slide.bs.carousel",{relatedTarget:o,direction:f}),(this.$element.trigger(s),!s.isDefaultPrevented())?((this.sliding=!0,l&&this.pause(),this.$indicators.length)&&(this.$indicators.find(".active").removeClass("active"),h=n(this.$indicators.children()[this.getItemIndex(u)]),h&&h.addClass("active")),c=n.Event("slid.bs.carousel",{relatedTarget:o,direction:f}),n.support.transition&&this.$element.hasClass("slide")?(u.addClass(i),u[0].offsetWidth,e.addClass(f),u.addClass(f),e.one("bsTransitionEnd",function(){u.removeClass([i,f].join(" ")).addClass("active");e.removeClass(["active",f].join(" "));a.sliding=!1;setTimeout(function(){a.$element.trigger(c)},0)}).emulateTransitionEnd(t.TRANSITION_DURATION)):(e.removeClass("active"),u.addClass("active"),this.sliding=!1,this.$element.trigger(c)),l&&this.cycle(),this):void 0)};u=n.fn.carousel;n.fn.carousel=i;n.fn.carousel.Constructor=t;n.fn.carousel.noConflict=function(){return n.fn.carousel=u,this};r=function(t){var o,r=n(this),u=n(r.attr("data-target")||(o=r.attr("href"))&&o.replace(/.*(?=#[^\s]+$)/,"")),e,f;u.hasClass("carousel")&&(e=n.extend({},u.data(),r.data()),f=r.attr("data-slide-to"),f&&(e.interval=!1),i.call(u,e),f&&u.data("bs.carousel").to(f),t.preventDefault())};n(document).on("click.bs.carousel.data-api","[data-slide]",r).on("click.bs.carousel.data-api","[data-slide-to]",r);n(window).on("load",function(){n('[data-ride="carousel"]').each(function(){var t=n(this);i.call(t,t.data())})})}(jQuery);+function(n){"use strict";function r(t){var i,r=t.attr("data-target")||(i=t.attr("href"))&&i.replace(/.*(?=#[^\s]+$)/,"");return n(r)}function i(i){return this.each(function(){var u=n(this),r=u.data("bs.collapse"),f=n.extend({},t.DEFAULTS,u.data(),"object"==typeof i&&i);!r&&f.toggle&&/show|hide/.test(i)&&(f.toggle=!1);r||u.data("bs.collapse",r=new t(this,f));"string"==typeof i&&r[i]()})}var t=function(i,r){this.$element=n(i);this.options=n.extend({},t.DEFAULTS,r);this.$trigger=n('[data-toggle="collapse"][href="#'+i.id+'"],[data-toggle="collapse"][data-target="#'+i.id+'"]');this.transitioning=null;this.options.parent?this.$parent=this.getParent():this.addAriaAndCollapsedClass(this.$element,this.$trigger);this.options.toggle&&this.toggle()},u;t.VERSION="3.3.7";t.TRANSITION_DURATION=350;t.DEFAULTS={toggle:!0};t.prototype.dimension=function(){var n=this.$element.hasClass("width");return n?"width":"height"};t.prototype.show=function(){var f,r,e,u,o,s;if(!this.transitioning&&!this.$element.hasClass("in")&&(r=this.$parent&&this.$parent.children(".panel").children(".in, .collapsing"),!(r&&r.length&&(f=r.data("bs.collapse"),f&&f.transitioning))&&(e=n.Event("show.bs.collapse"),this.$element.trigger(e),!e.isDefaultPrevented()))){if(r&&r.length&&(i.call(r,"hide"),f||r.data("bs.collapse",null)),u=this.dimension(),this.$element.removeClass("collapse").addClass("collapsing")[u](0).attr("aria-expanded",!0),this.$trigger.removeClass("collapsed").attr("aria-expanded",!0),this.transitioning=1,o=function(){this.$element.removeClass("collapsing").addClass("collapse in")[u]("");this.transitioning=0;this.$element.trigger("shown.bs.collapse")},!n.support.transition)return o.call(this);s=n.camelCase(["scroll",u].join("-"));this.$element.one("bsTransitionEnd",n.proxy(o,this)).emulateTransitionEnd(t.TRANSITION_DURATION)[u](this.$element[0][s])}};t.prototype.hide=function(){var r,i,u;if(!this.transitioning&&this.$element.hasClass("in")&&(r=n.Event("hide.bs.collapse"),this.$element.trigger(r),!r.isDefaultPrevented()))return i=this.dimension(),this.$element[i](this.$element[i]())[0].offsetHeight,this.$element.addClass("collapsing").removeClass("collapse in").attr("aria-expanded",!1),this.$trigger.addClass("collapsed").attr("aria-expanded",!1),this.transitioning=1,u=function(){this.transitioning=0;this.$element.removeClass("collapsing").addClass("collapse").trigger("hidden.bs.collapse")},n.support.transition?void this.$element[i](0).one("bsTransitionEnd",n.proxy(u,this)).emulateTransitionEnd(t.TRANSITION_DURATION):u.call(this)};t.prototype.toggle=function(){this[this.$element.hasClass("in")?"hide":"show"]()};t.prototype.getParent=function(){return n(this.options.parent).find('[data-toggle="collapse"][data-parent="'+this.options.parent+'"]').each(n.proxy(function(t,i){var u=n(i);this.addAriaAndCollapsedClass(r(u),u)},this)).end()};t.prototype.addAriaAndCollapsedClass=function(n,t){var i=n.hasClass("in");n.attr("aria-expanded",i);t.toggleClass("collapsed",!i).attr("aria-expanded",i)};u=n.fn.collapse;n.fn.collapse=i;n.fn.collapse.Constructor=t;n.fn.collapse.noConflict=function(){return n.fn.collapse=u,this};n(document).on("click.bs.collapse.data-api",'[data-toggle="collapse"]',function(t){var u=n(this);u.attr("data-target")||t.preventDefault();var f=r(u),e=f.data("bs.collapse"),o=e?"toggle":u.data();i.call(f,o)})}(jQuery);+function(n){"use strict";function r(t){var i=t.attr("data-target"),r;return i||(i=t.attr("href"),i=i&&/#[A-Za-z]/.test(i)&&i.replace(/.*(?=#[^\s]*$)/,"")),r=i&&n(i),r&&r.length?r:t.parent()}function u(t){t&&3===t.which||(n(o).remove(),n(i).each(function(){var u=n(this),i=r(u),f={relatedTarget:this};i.hasClass("open")&&(t&&"click"==t.type&&/input|textarea/i.test(t.target.tagName)&&n.contains(i[0],t.target)||(i.trigger(t=n.Event("hide.bs.dropdown",f)),t.isDefaultPrevented()||(u.attr("aria-expanded","false"),i.removeClass("open").trigger(n.Event("hidden.bs.dropdown",f)))))}))}function e(i){return this.each(function(){var r=n(this),u=r.data("bs.dropdown");u||r.data("bs.dropdown",u=new t(this));"string"==typeof i&&u[i].call(r)})}var o=".dropdown-backdrop",i='[data-toggle="dropdown"]',t=function(t){n(t).on("click.bs.dropdown",this.toggle)},f;t.VERSION="3.3.7";t.prototype.toggle=function(t){var f=n(this),i,o,e;if(!f.is(".disabled, :disabled")){if(i=r(f),o=i.hasClass("open"),u(),!o){if("ontouchstart"in document.documentElement&&!i.closest(".navbar-nav").length&&n(document.createElement("div")).addClass("dropdown-backdrop").insertAfter(n(this)).on("click",u),e={relatedTarget:this},i.trigger(t=n.Event("show.bs.dropdown",e)),t.isDefaultPrevented())return;f.trigger("focus").attr("aria-expanded","true");i.toggleClass("open").trigger(n.Event("shown.bs.dropdown",e))}return!1}};t.prototype.keydown=function(t){var e,o,s,h,f,u;if(/(38|40|27|32)/.test(t.which)&&!/input|textarea/i.test(t.target.tagName)&&(e=n(this),t.preventDefault(),t.stopPropagation(),!e.is(".disabled, :disabled"))){if(o=r(e),s=o.hasClass("open"),!s&&27!=t.which||s&&27==t.which)return 27==t.which&&o.find(i).trigger("focus"),e.trigger("click");h=" li:not(.disabled):visible a";f=o.find(".dropdown-menu"+h);f.length&&(u=f.index(t.target),38==t.which&&u>0&&u--,40==t.which&&udocument.documentElement.clientHeight;this.$element.css({paddingLeft:!this.bodyIsOverflowing&&n?this.scrollbarWidth:"",paddingRight:this.bodyIsOverflowing&&!n?this.scrollbarWidth:""})};t.prototype.resetAdjustments=function(){this.$element.css({paddingLeft:"",paddingRight:""})};t.prototype.checkScrollbar=function(){var n=window.innerWidth,t;n||(t=document.documentElement.getBoundingClientRect(),n=t.right-Math.abs(t.left));this.bodyIsOverflowing=document.body.clientWidth
<\/div>
<\/div><\/div>',trigger:"hover focus",title:"",delay:0,html:!1,container:!1,viewport:{selector:"body",padding:0}};t.prototype.init=function(t,i,r){var f,e,u,o,s;if(this.enabled=!0,this.type=t,this.$element=n(i),this.options=this.getOptions(r),this.$viewport=this.options.viewport&&n(n.isFunction(this.options.viewport)?this.options.viewport.call(this,this.$element):this.options.viewport.selector||this.options.viewport),this.inState={click:!1,hover:!1,focus:!1},this.$element[0]instanceof document.constructor&&!this.options.selector)throw new Error("`selector` option must be specified when initializing "+this.type+" on the window.document object!");for(f=this.options.trigger.split(" "),e=f.length;e--;)if(u=f[e],"click"==u)this.$element.on("click."+this.type,this.options.selector,n.proxy(this.toggle,this));else"manual"!=u&&(o="hover"==u?"mouseenter":"focusin",s="hover"==u?"mouseleave":"focusout",this.$element.on(o+"."+this.type,this.options.selector,n.proxy(this.enter,this)),this.$element.on(s+"."+this.type,this.options.selector,n.proxy(this.leave,this)));this.options.selector?this._options=n.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()};t.prototype.getDefaults=function(){return t.DEFAULTS};t.prototype.getOptions=function(t){return t=n.extend({},this.getDefaults(),this.$element.data(),t),t.delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t};t.prototype.getDelegateOptions=function(){var t={},i=this.getDefaults();return this._options&&n.each(this._options,function(n,r){i[n]!=r&&(t[n]=r)}),t};t.prototype.enter=function(t){var i=t instanceof this.constructor?t:n(t.currentTarget).data("bs."+this.type);return i||(i=new this.constructor(t.currentTarget,this.getDelegateOptions()),n(t.currentTarget).data("bs."+this.type,i)),t instanceof n.Event&&(i.inState["focusin"==t.type?"focus":"hover"]=!0),i.tip().hasClass("in")||"in"==i.hoverState?void(i.hoverState="in"):(clearTimeout(i.timeout),i.hoverState="in",i.options.delay&&i.options.delay.show?void(i.timeout=setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show)):i.show())};t.prototype.isInStateTrue=function(){for(var n in this.inState)if(this.inState[n])return!0;return!1};t.prototype.leave=function(t){var i=t instanceof this.constructor?t:n(t.currentTarget).data("bs."+this.type);if(i||(i=new this.constructor(t.currentTarget,this.getDelegateOptions()),n(t.currentTarget).data("bs."+this.type,i)),t instanceof n.Event&&(i.inState["focusout"==t.type?"focus":"hover"]=!1),!i.isInStateTrue())return clearTimeout(i.timeout),i.hoverState="out",i.options.delay&&i.options.delay.hide?void(i.timeout=setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide)):i.hide()};t.prototype.show=function(){var c=n.Event("show.bs."+this.type),l,p,e,w,h;if(this.hasContent()&&this.enabled){if(this.$element.trigger(c),l=n.contains(this.$element[0].ownerDocument.documentElement,this.$element[0]),c.isDefaultPrevented()||!l)return;var u=this,r=this.tip(),a=this.getUID(this.type);this.setContent();r.attr("id",a);this.$element.attr("aria-describedby",a);this.options.animation&&r.addClass("fade");var i="function"==typeof this.options.placement?this.options.placement.call(this,r[0],this.$element[0]):this.options.placement,v=/\s?auto?\s?/i,y=v.test(i);y&&(i=i.replace(v,"")||"top");r.detach().css({top:0,left:0,display:"block"}).addClass(i).data("bs."+this.type,this);this.options.container?r.appendTo(this.options.container):r.insertAfter(this.$element);this.$element.trigger("inserted.bs."+this.type);var f=this.getPosition(),o=r[0].offsetWidth,s=r[0].offsetHeight;y&&(p=i,e=this.getPosition(this.$viewport),i="bottom"==i&&f.bottom+s>e.bottom?"top":"top"==i&&f.top-se.width?"left":"left"==i&&f.left-ou.top+u.height&&(f.top=u.top+u.height-s)):(h=t.left-e,c=t.left+e+i,hu.right&&(f.left=u.left+u.width-c)),f):f};t.prototype.getTitle=function(){var t=this.$element,n=this.options;return t.attr("data-original-title")||("function"==typeof n.title?n.title.call(t[0]):n.title)};t.prototype.getUID=function(n){do n+=~~(1e6*Math.random());while(document.getElementById(n));return n};t.prototype.tip=function(){if(!this.$tip&&(this.$tip=n(this.options.template),1!=this.$tip.length))throw new Error(this.type+" `template` option must consist of exactly 1 top-level element!");return this.$tip};t.prototype.arrow=function(){return this.$arrow=this.$arrow||this.tip().find(".tooltip-arrow")};t.prototype.enable=function(){this.enabled=!0};t.prototype.disable=function(){this.enabled=!1};t.prototype.toggleEnabled=function(){this.enabled=!this.enabled};t.prototype.toggle=function(t){var i=this;t&&(i=n(t.currentTarget).data("bs."+this.type),i||(i=new this.constructor(t.currentTarget,this.getDelegateOptions()),n(t.currentTarget).data("bs."+this.type,i)));t?(i.inState.click=!i.inState.click,i.isInStateTrue()?i.enter(i):i.leave(i)):i.tip().hasClass("in")?i.leave(i):i.enter(i)};t.prototype.destroy=function(){var n=this;clearTimeout(this.timeout);this.hide(function(){n.$element.off("."+n.type).removeData("bs."+n.type);n.$tip&&n.$tip.detach();n.$tip=null;n.$arrow=null;n.$viewport=null;n.$element=null})};i=n.fn.tooltip;n.fn.tooltip=r;n.fn.tooltip.Constructor=t;n.fn.tooltip.noConflict=function(){return n.fn.tooltip=i,this}}(jQuery);+function(n){"use strict";function r(i){return this.each(function(){var u=n(this),r=u.data("bs.popover"),f="object"==typeof i&&i;!r&&/destroy|hide/.test(i)||(r||u.data("bs.popover",r=new t(this,f)),"string"==typeof i&&r[i]())})}var t=function(n,t){this.init("popover",n,t)},i;if(!n.fn.tooltip)throw new Error("Popover requires tooltip.js");t.VERSION="3.3.7";t.DEFAULTS=n.extend({},n.fn.tooltip.Constructor.DEFAULTS,{placement:"right",trigger:"click",content:"",template:'