diff --git a/3D-Druck-Daten/Interfaces/Interfaces_1_0.c4d b/3D-Druck-Daten/Interfaces/Interfaces_1_0.c4d new file mode 100644 index 0000000..625a380 Binary files /dev/null and b/3D-Druck-Daten/Interfaces/Interfaces_1_0.c4d differ diff --git a/3D-Druck-Daten/Interfaces/Interfaces_1_1.c4d b/3D-Druck-Daten/Interfaces/Interfaces_1_1.c4d new file mode 100644 index 0000000..a1bd07c Binary files /dev/null and b/3D-Druck-Daten/Interfaces/Interfaces_1_1.c4d differ diff --git a/3D-Druck-Daten/Interfaces/Interfaces_1_2.c4d b/3D-Druck-Daten/Interfaces/Interfaces_1_2.c4d new file mode 100644 index 0000000..da2f238 Binary files /dev/null and b/3D-Druck-Daten/Interfaces/Interfaces_1_2.c4d differ diff --git a/3D-Druck-Daten/Interfaces/Interfaces_1_3.c4d b/3D-Druck-Daten/Interfaces/Interfaces_1_3.c4d new file mode 100644 index 0000000..24e73f1 Binary files /dev/null and b/3D-Druck-Daten/Interfaces/Interfaces_1_3.c4d differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/Base_Case.stl b/3D-Druck-Daten/JB3Dprint_V.3/Base_Case.stl new file mode 100644 index 0000000..733bd2a Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/Base_Case.stl differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/Interfaces_1_2.stl b/3D-Druck-Daten/JB3Dprint_V.3/Interfaces_1_2.stl new file mode 100644 index 0000000..ed54d07 Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/Interfaces_1_2.stl differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungA_1_1.stl b/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungA_1_1.stl new file mode 100644 index 0000000..389f0cd Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungA_1_1.stl differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungB_1_0.stl b/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungB_1_0.stl new file mode 100644 index 0000000..927f92e Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/KamerahalterungB_1_0.stl differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/Modemhalterung_1_0.stl b/3D-Druck-Daten/JB3Dprint_V.3/Modemhalterung_1_0.stl new file mode 100644 index 0000000..36271f8 Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/Modemhalterung_1_0.stl differ diff --git a/3D-Druck-Daten/JB3Dprint_V.3/Top_Case.stl b/3D-Druck-Daten/JB3Dprint_V.3/Top_Case.stl new file mode 100644 index 0000000..5729c6f Binary files /dev/null and b/3D-Druck-Daten/JB3Dprint_V.3/Top_Case.stl differ diff --git a/3D-Druck-Daten/KamerahalterungA/CamMountV0.1.STL b/3D-Druck-Daten/KamerahalterungA/CamMountV0.1.STL new file mode 100644 index 0000000..3950a0f Binary files /dev/null and b/3D-Druck-Daten/KamerahalterungA/CamMountV0.1.STL differ diff --git a/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_0.c4d b/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_0.c4d new file mode 100644 index 0000000..bd93d88 Binary files /dev/null and b/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_0.c4d differ diff --git a/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_1.c4d b/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_1.c4d new file mode 100644 index 0000000..c35a29d Binary files /dev/null and b/3D-Druck-Daten/KamerahalterungA/KamerahalterungA_1_1.c4d differ diff --git a/3D-Druck-Daten/KamerahalterungB/KamerahalterungB_1_0.c4d b/3D-Druck-Daten/KamerahalterungB/KamerahalterungB_1_0.c4d new file mode 100644 index 0000000..ed5b3e4 Binary files /dev/null and b/3D-Druck-Daten/KamerahalterungB/KamerahalterungB_1_0.c4d differ diff --git a/3D-Druck-Daten/Modemhalterung/Modemhalterung_1_0.c4d b/3D-Druck-Daten/Modemhalterung/Modemhalterung_1_0.c4d new file mode 100644 index 0000000..fcaf71f Binary files /dev/null and b/3D-Druck-Daten/Modemhalterung/Modemhalterung_1_0.c4d differ diff --git a/3D-Druck-Daten/Raspberry Gehäuse/Base_Case.stl b/3D-Druck-Daten/Raspberry Gehäuse/Base_Case.stl new file mode 100644 index 0000000..733bd2a Binary files /dev/null and b/3D-Druck-Daten/Raspberry Gehäuse/Base_Case.stl differ diff --git a/3D-Druck-Daten/Raspberry Gehäuse/Gehäuse.c4d b/3D-Druck-Daten/Raspberry Gehäuse/Gehäuse.c4d new file mode 100644 index 0000000..5cf2ea7 Binary files /dev/null and b/3D-Druck-Daten/Raspberry Gehäuse/Gehäuse.c4d differ diff --git a/3D-Druck-Daten/Raspberry Gehäuse/Top_Case.stl b/3D-Druck-Daten/Raspberry Gehäuse/Top_Case.stl new file mode 100644 index 0000000..5729c6f Binary files /dev/null and b/3D-Druck-Daten/Raspberry Gehäuse/Top_Case.stl differ diff --git a/3D-Druck-Daten/Regenhaube/Regenhaube.3mf b/3D-Druck-Daten/Regenhaube/Regenhaube.3mf new file mode 100644 index 0000000..f9777ae Binary files /dev/null and b/3D-Druck-Daten/Regenhaube/Regenhaube.3mf differ diff --git a/3D-Druck-Daten/Regenhaube/Regenhaube.stl b/3D-Druck-Daten/Regenhaube/Regenhaube.stl new file mode 100644 index 0000000..95d5d14 Binary files /dev/null and b/3D-Druck-Daten/Regenhaube/Regenhaube.stl differ diff --git a/Hardware/Bilder/TLC01/IMG_8596.JPG b/Hardware/Bilder/TLC01/IMG_8596.JPG new file mode 100644 index 0000000..3a8aa16 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8596.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8597.JPG b/Hardware/Bilder/TLC01/IMG_8597.JPG new file mode 100644 index 0000000..5f4f443 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8597.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8598.JPG b/Hardware/Bilder/TLC01/IMG_8598.JPG new file mode 100644 index 0000000..c6ed410 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8598.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8599.JPG b/Hardware/Bilder/TLC01/IMG_8599.JPG new file mode 100644 index 0000000..fca4cfa Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8599.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8600.JPG b/Hardware/Bilder/TLC01/IMG_8600.JPG new file mode 100644 index 0000000..4a4ce60 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8600.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8601.JPG b/Hardware/Bilder/TLC01/IMG_8601.JPG new file mode 100644 index 0000000..795c8dd Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8601.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8602.JPG b/Hardware/Bilder/TLC01/IMG_8602.JPG new file mode 100644 index 0000000..6c62af9 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8602.JPG differ diff --git a/Hardware/Bilder/TLC01/IMG_8603.JPG b/Hardware/Bilder/TLC01/IMG_8603.JPG new file mode 100644 index 0000000..5418950 Binary files /dev/null and b/Hardware/Bilder/TLC01/IMG_8603.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8607.JPG b/Hardware/Bilder/TLC02/IMG_8607.JPG new file mode 100644 index 0000000..56993fd Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8607.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8608.JPG b/Hardware/Bilder/TLC02/IMG_8608.JPG new file mode 100644 index 0000000..d1aaa53 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8608.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8609.JPG b/Hardware/Bilder/TLC02/IMG_8609.JPG new file mode 100644 index 0000000..8673fa8 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8609.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8610.JPG b/Hardware/Bilder/TLC02/IMG_8610.JPG new file mode 100644 index 0000000..ca50294 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8610.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8611.JPG b/Hardware/Bilder/TLC02/IMG_8611.JPG new file mode 100644 index 0000000..fecccb0 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8611.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8612.JPG b/Hardware/Bilder/TLC02/IMG_8612.JPG new file mode 100644 index 0000000..c426ae7 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8612.JPG differ diff --git a/Hardware/Bilder/TLC02/IMG_8613.JPG b/Hardware/Bilder/TLC02/IMG_8613.JPG new file mode 100644 index 0000000..034d8d3 Binary files /dev/null and b/Hardware/Bilder/TLC02/IMG_8613.JPG differ diff --git a/Hardware/Datennutzung.odt b/Hardware/Datennutzung.odt new file mode 100644 index 0000000..d1df5c3 Binary files /dev/null and b/Hardware/Datennutzung.odt differ diff --git a/Hardware/Datennutzung.pdf b/Hardware/Datennutzung.pdf new file mode 100644 index 0000000..5232bcc Binary files /dev/null and b/Hardware/Datennutzung.pdf differ diff --git a/Hardware/IO_Board/.directory b/Hardware/IO_Board/.directory new file mode 100644 index 0000000..27f089b --- /dev/null +++ b/Hardware/IO_Board/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2017,8,30,22,25,36 +Version=4 diff --git a/Hardware/IO_Board/Bauteile/10 pol Buchsenleiste b/Hardware/IO_Board/Bauteile/10 pol Buchsenleiste new file mode 100644 index 0000000..333d0e4 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/10 pol Buchsenleiste @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Buchsenleisten/BL-1X10G8-2-54/3/index.html?ACTION=3&LA=2&ARTICLE=51826&GROUPID=7435&artnr=BL+1X10G8+2%2C54&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/16 Pin Sockel b/Hardware/IO_Board/Bauteile/16 Pin Sockel new file mode 100644 index 0000000..8bcbb59 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/16 Pin Sockel @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/IC-Sockel/GS-16/3/index.html?ACTION=3&LA=2&ARTICLE=8208&GROUPID=7429&artnr=GS+16&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/180 Ohm b/Hardware/IO_Board/Bauteile/180 Ohm new file mode 100644 index 0000000..1d847e6 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/180 Ohm @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/1-4W-5-100-Ohm-910-Ohm/1-4W-180/3/index.html?ACTION=3&LA=2&ARTICLE=1362&GROUPID=3064&artnr=1%2F4W+180&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/1k Ohm b/Hardware/IO_Board/Bauteile/1k Ohm new file mode 100644 index 0000000..358f584 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/1k Ohm @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/1-4W-5-1-0-k-Ohm-9-1-k-Ohm/1-4W-1-0K/3/index.html?ACTION=3&LA=2&ARTICLE=1315&GROUPID=3065&artnr=1%2F4W+1%2C0K&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/40 pol Stiftleiste b/Hardware/IO_Board/Bauteile/40 pol Stiftleiste new file mode 100644 index 0000000..edfc18f --- /dev/null +++ b/Hardware/IO_Board/Bauteile/40 pol Stiftleiste @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Stiftleisten/SL-1X40G-2-54/3/index.html?ACTION=3&LA=2&ARTICLE=19506&GROUPID=7434&artnr=SL+1X40G+2%2C54&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/6 Pin Sockel b/Hardware/IO_Board/Bauteile/6 Pin Sockel new file mode 100644 index 0000000..650ce92 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/6 Pin Sockel @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/IC-Sockel/GS-6/3/index.html?ACTION=3&LA=2&ARTICLE=8227&GROUPID=7429&artnr=GS+6&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/DC Buchse vertikal b/Hardware/IO_Board/Bauteile/DC Buchse vertikal new file mode 100644 index 0000000..bbc4df8 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/DC Buchse vertikal @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Hohlstecker/HEBG-21/3/index.html?ACTION=3&LA=5700&ARTICLE=35271&GROUPID=7488&artnr=HEBG+21 diff --git a/Hardware/IO_Board/Bauteile/DC Bucse horizontal b/Hardware/IO_Board/Bauteile/DC Bucse horizontal new file mode 100644 index 0000000..48bce39 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/DC Bucse horizontal @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Hohlstecker/DC-BU21-90/3/index.html?ACTION=3&LA=2&ARTICLE=183502&GROUPID=7488&artnr=DC+BU21+90&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/Klinkenbuchse b/Hardware/IO_Board/Bauteile/Klinkenbuchse new file mode 100644 index 0000000..e2b2a5f --- /dev/null +++ b/Hardware/IO_Board/Bauteile/Klinkenbuchse @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Klinkeneinbaubuchsen/EBSF-35/3/index.html?ACTION=3&LA=2&ARTICLE=153203&GROUPID=7448&artnr=EBSF+35&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile/Optokoppler b/Hardware/IO_Board/Bauteile/Optokoppler new file mode 100644 index 0000000..311ff8a --- /dev/null +++ b/Hardware/IO_Board/Bauteile/Optokoppler @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Optokoppler/4N-35/3/index.html?ACTION=3&GROUPID=3046&ARTICLE=2515&SEARCH=4N35&OFFSET=75& diff --git a/Hardware/IO_Board/Bauteile/Schraubklemme b/Hardware/IO_Board/Bauteile/Schraubklemme new file mode 100644 index 0000000..96eb3d9 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/Schraubklemme @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/RND-connect/RND-205-00012/3/index.html?ACTION=3&LA=5700&ARTICLE=170244&GROUPID=7552&artnr=RND+205-00012 diff --git a/Hardware/IO_Board/Bauteile/Transistor 3A b/Hardware/IO_Board/Bauteile/Transistor 3A new file mode 100644 index 0000000..e4978d9 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/Transistor 3A @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/2SD-Transistoren/SD-313/3/index.html?ACTION=3&LA=5700&ARTICLE=17220&GROUPID=2901&artnr=SD+313 diff --git a/Hardware/IO_Board/Bauteile/Wannenstecker b/Hardware/IO_Board/Bauteile/Wannenstecker new file mode 100644 index 0000000..e756de9 --- /dev/null +++ b/Hardware/IO_Board/Bauteile/Wannenstecker @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=https://www.reichelt.de/Pfosten-Wannenstecker/WSL-40G/3/index.html?ACTION=3&LA=2&ARTICLE=22834&GROUPID=7437&artnr=WSL+40G&SEARCH=%252A diff --git a/Hardware/IO_Board/Bauteile_Fritzing/MCP3008 8-channel 10-bit ADC.fzpz b/Hardware/IO_Board/Bauteile_Fritzing/MCP3008 8-channel 10-bit ADC.fzpz new file mode 100644 index 0000000..b1e8eeb Binary files /dev/null and b/Hardware/IO_Board/Bauteile_Fritzing/MCP3008 8-channel 10-bit ADC.fzpz differ diff --git a/Hardware/IO_Board/Bauteile_Fritzing/Piezo Speaker - PC Mount.fzpz b/Hardware/IO_Board/Bauteile_Fritzing/Piezo Speaker - PC Mount.fzpz new file mode 100644 index 0000000..04a2091 Binary files /dev/null and b/Hardware/IO_Board/Bauteile_Fritzing/Piezo Speaker - PC Mount.fzpz differ diff --git a/Hardware/IO_Board/Bauteile_Fritzing/Raspberry Pi Header 40pin.fzpz b/Hardware/IO_Board/Bauteile_Fritzing/Raspberry Pi Header 40pin.fzpz new file mode 100644 index 0000000..4f37093 Binary files /dev/null and b/Hardware/IO_Board/Bauteile_Fritzing/Raspberry Pi Header 40pin.fzpz differ diff --git a/Hardware/IO_Board/Bild (2).png b/Hardware/IO_Board/Bild (2).png new file mode 100644 index 0000000..9f06cb8 Binary files /dev/null and b/Hardware/IO_Board/Bild (2).png differ diff --git a/Hardware/IO_Board/Bild.png b/Hardware/IO_Board/Bild.png new file mode 100644 index 0000000..48ce9cc Binary files /dev/null and b/Hardware/IO_Board/Bild.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/.directory b/Hardware/IO_Board/Bilder Aisler/.directory new file mode 100644 index 0000000..e0f0c19 --- /dev/null +++ b/Hardware/IO_Board/Bilder Aisler/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=true +Timestamp=2017,8,31,11,8,6 +Version=4 diff --git a/Hardware/IO_Board/Bilder Aisler/Bottom copper layer.png b/Hardware/IO_Board/Bilder Aisler/Bottom copper layer.png new file mode 100644 index 0000000..878c940 Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/Bottom copper layer.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/Bottom silkscreen.png b/Hardware/IO_Board/Bilder Aisler/Bottom silkscreen.png new file mode 100644 index 0000000..3872f26 Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/Bottom silkscreen.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/Non-Plated holes.png b/Hardware/IO_Board/Bilder Aisler/Non-Plated holes.png new file mode 100644 index 0000000..e4dd357 Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/Non-Plated holes.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/PCB Bottom.png b/Hardware/IO_Board/Bilder Aisler/PCB Bottom.png new file mode 100644 index 0000000..a83f9bc Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/PCB Bottom.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/PCB Top.png b/Hardware/IO_Board/Bilder Aisler/PCB Top.png new file mode 100644 index 0000000..ed83e8d Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/PCB Top.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/Top copper layer.png b/Hardware/IO_Board/Bilder Aisler/Top copper layer.png new file mode 100644 index 0000000..f7178a1 Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/Top copper layer.png differ diff --git a/Hardware/IO_Board/Bilder Aisler/Top soldermask.png b/Hardware/IO_Board/Bilder Aisler/Top soldermask.png new file mode 100644 index 0000000..d125f4c Binary files /dev/null and b/Hardware/IO_Board/Bilder Aisler/Top soldermask.png differ diff --git a/Hardware/IO_Board/CheckListe.ods b/Hardware/IO_Board/CheckListe.ods new file mode 100644 index 0000000..36e1919 Binary files /dev/null and b/Hardware/IO_Board/CheckListe.ods differ diff --git a/Hardware/IO_Board/FZZ Backups/01_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/01_PCB_IO_Board.fzz new file mode 100644 index 0000000..bd193c4 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/01_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/02_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/02_PCB_IO_Board.fzz new file mode 100644 index 0000000..dd38349 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/02_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/03_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/03_PCB_IO_Board.fzz new file mode 100644 index 0000000..8139ec1 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/03_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/04B_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/04B_PCB_IO_Board.fzz new file mode 100644 index 0000000..491b419 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/04B_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/04_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/04_PCB_IO_Board.fzz new file mode 100644 index 0000000..849e062 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/04_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/05_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/05_PCB_IO_Board.fzz new file mode 100644 index 0000000..1b74c09 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/05_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/06_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/06_PCB_IO_Board.fzz new file mode 100644 index 0000000..af30028 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/06_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/07_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/07_PCB_IO_Board.fzz new file mode 100644 index 0000000..ff1f65a Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/07_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/08_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/08_PCB_IO_Board.fzz new file mode 100644 index 0000000..7d2eb3b Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/08_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/09_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/09_PCB_IO_Board.fzz new file mode 100644 index 0000000..5efe0d6 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/09_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/FZZ Backups/10_PCB_IO_Board.fzz b/Hardware/IO_Board/FZZ Backups/10_PCB_IO_Board.fzz new file mode 100644 index 0000000..fc8e3a8 Binary files /dev/null and b/Hardware/IO_Board/FZZ Backups/10_PCB_IO_Board.fzz differ diff --git a/Hardware/IO_Board/GPIO B+.png b/Hardware/IO_Board/GPIO B+.png new file mode 100644 index 0000000..eba6ab2 Binary files /dev/null and b/Hardware/IO_Board/GPIO B+.png differ diff --git a/Hardware/IO_Board/IO Board.vym b/Hardware/IO_Board/IO Board.vym new file mode 100644 index 0000000..263884e Binary files /dev/null and b/Hardware/IO_Board/IO Board.vym differ diff --git a/Hardware/IO_Board/Logo fertig.bmp b/Hardware/IO_Board/Logo fertig.bmp new file mode 100644 index 0000000..2cadca5 Binary files /dev/null and b/Hardware/IO_Board/Logo fertig.bmp differ diff --git a/Hardware/IO_Board/PCB_IO_Board_V1.0.fzz b/Hardware/IO_Board/PCB_IO_Board_V1.0.fzz new file mode 100644 index 0000000..3b691ca Binary files /dev/null and b/Hardware/IO_Board/PCB_IO_Board_V1.0.fzz differ diff --git a/Hardware/IO_Board/Software/Betriebsspannung/.directory b/Hardware/IO_Board/Software/Betriebsspannung/.directory new file mode 100644 index 0000000..dfbd648 --- /dev/null +++ b/Hardware/IO_Board/Software/Betriebsspannung/.directory @@ -0,0 +1,4 @@ +[Dolphin] +PreviewsShown=false +Timestamp=2018,6,23,12,56,2 +Version=4 diff --git a/Hardware/IO_Board/Software/Betriebsspannung/Betriebsspannung.py b/Hardware/IO_Board/Software/Betriebsspannung/Betriebsspannung.py new file mode 100644 index 0000000..47f6d56 --- /dev/null +++ b/Hardware/IO_Board/Software/Betriebsspannung/Betriebsspannung.py @@ -0,0 +1,17 @@ +from spidev import SpiDev +from time import sleep + +spi = SpiDev() +spi.open(0,0) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data +while 1: + + value = readMPC(0) + print("Anliegende Spannung: %.2f" % (((value / 1023.0 * 3.3)*6.62)*0.95) ) + sleep(0.5) + + diff --git a/Hardware/IO_Board/Software/GPIO install.txt b/Hardware/IO_Board/Software/GPIO install.txt new file mode 100644 index 0000000..caff93d --- /dev/null +++ b/Hardware/IO_Board/Software/GPIO install.txt @@ -0,0 +1 @@ +apt-get install python3-RPi.GPIO diff --git a/Hardware/IO_Board/Software/GPIO/test.py b/Hardware/IO_Board/Software/GPIO/test.py new file mode 100644 index 0000000..da88531 --- /dev/null +++ b/Hardware/IO_Board/Software/GPIO/test.py @@ -0,0 +1,29 @@ +# coding: utf-8 + +import RPi.GPIO as GPIO +from spidev import SpiDev +from time import sleep + + +spi = SpiDev() +spi.open(0,0) + +GPIO.setmode(GPIO.BCM) +GPIO.setup(25, GPIO.OUT) +GPIO.setup(18, GPIO.OUT) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +while 1: + value = readMPC(1) + if (value / 1023.0 * 3.3) > 0: + GPIO.output(25, GPIO.HIGH) + GPIO.output(18, GPIO.HIGH) + else: + GPIO.output(25, GPIO.LOW) + GPIO.output(18, GPIO.LOW) + sleep(0.1) + diff --git a/Hardware/IO_Board/Software/RTC/Install DS3231 Real Time Clock - Latest Info - Raspberry Pi Forums.pdf b/Hardware/IO_Board/Software/RTC/Install DS3231 Real Time Clock - Latest Info - Raspberry Pi Forums.pdf new file mode 100644 index 0000000..2c0825a Binary files /dev/null and b/Hardware/IO_Board/Software/RTC/Install DS3231 Real Time Clock - Latest Info - Raspberry Pi Forums.pdf differ diff --git a/Hardware/IO_Board/Software/RTC/hwclock_setup.txt b/Hardware/IO_Board/Software/RTC/hwclock_setup.txt new file mode 100644 index 0000000..94b9669 --- /dev/null +++ b/Hardware/IO_Board/Software/RTC/hwclock_setup.txt @@ -0,0 +1,45 @@ + + + + + +raspi-config + +--------------------------- +Interfacing Options + +I2C enable +---------------------------- + +nano /boot/config.txt + +add at end +-------------------------- +# Enable HWclock +dtoverlay=i2c-rtc,ds3231 +------------------------- + +nano /lib/udev/hwclock-set + +comment out +-------------------------- + +if [ -e /run/systemd/system ] ; then +exit 0 +fi +------------------------- + + +Good to know: + +read time directly from rtc module +hwclock -r + +update rtc module time from system time (system time should be regularly updated by ntp from the internet if your pi is networked): +hwclock -w + +update system time from the rtc module (this should happen on startup): +hwclock -s + +and the most fun of all - monitor the "drift" between your system clock and the rtc module: +hwclock -c diff --git a/Hardware/IO_Board/Software/SPI.txt b/Hardware/IO_Board/Software/SPI.txt new file mode 100644 index 0000000..35bffb1 --- /dev/null +++ b/Hardware/IO_Board/Software/SPI.txt @@ -0,0 +1,16 @@ +raspi-config + +-------------- +SPI an machen +------------- + +apt-get install python3-dev + +wget https://github.com/doceme/py-spidev/archive/master.zip + +unzip master.zip + +cd py-spidev-master + +python3 setup.py install + diff --git a/Hardware/IO_Board/Software/Scharfstellen/sharpness.sh b/Hardware/IO_Board/Software/Scharfstellen/sharpness.sh new file mode 100644 index 0000000..1f5e8f2 --- /dev/null +++ b/Hardware/IO_Board/Software/Scharfstellen/sharpness.sh @@ -0,0 +1,26 @@ +echo "-----------------------------" +echo "-----------------------------" +echo "-----------------------------" +echo "---starting sharpness tool---" +echo "-----------------------------" +echo "-----------------------------" +killall python3 +sleep 5 +while [ true ] +do + echo "normal output" + sleep 2 + raspivid -t -0 & + sleep 10 + killall raspivid + + echo "zoom output" + sleep 2 + raspivid -t -0 -roi 0.1,0.2,0.3,0.4 & + sleep 10 + killall raspivid +done + + + + diff --git a/Hardware/IO_Board/sensors_raspberry_pi_mcp3008pin.gif b/Hardware/IO_Board/sensors_raspberry_pi_mcp3008pin.gif new file mode 100644 index 0000000..92b287c Binary files /dev/null and b/Hardware/IO_Board/sensors_raspberry_pi_mcp3008pin.gif differ diff --git a/Hardware/Stromverbrauch.txt b/Hardware/Stromverbrauch.txt new file mode 100644 index 0000000..f478cbc --- /dev/null +++ b/Hardware/Stromverbrauch.txt @@ -0,0 +1,5 @@ +Ohne 3G und ohne Python: 0,24 A + +Ohne 3G, im Sleep: 0,38 A + +Ohne 3G, im Sleep, mit lokalem Camera Objekt: 0,24 A diff --git a/Hardware/USBspeed.txt b/Hardware/USBspeed.txt new file mode 100644 index 0000000..e26364f --- /dev/null +++ b/Hardware/USBspeed.txt @@ -0,0 +1,14 @@ +Tested with BMD Disk Speed Test on USB 2.0 +------------------------------------------ + +Transcend: R: 30 W: 16 + +Soennecker: R: 12 W: 3 + +VEGA: R: 28 W: 4 + +Samsung: R: 22 W: 30 + + + + diff --git a/Hardware/usb belegung.psd b/Hardware/usb belegung.psd new file mode 100644 index 0000000..fdaf7fc Binary files /dev/null and b/Hardware/usb belegung.psd differ diff --git a/Login TLC.ods b/Login TLC.ods new file mode 100644 index 0000000..0150d61 Binary files /dev/null and b/Login TLC.ods differ diff --git a/Materialen und Lohn.ods b/Materialen und Lohn.ods new file mode 100644 index 0000000..646c34a Binary files /dev/null and b/Materialen und Lohn.ods differ diff --git a/Materialen und Lohn.pdf b/Materialen und Lohn.pdf new file mode 100644 index 0000000..aaddf7d Binary files /dev/null and b/Materialen und Lohn.pdf differ diff --git a/Photobox/Label.odt b/Photobox/Label.odt new file mode 100644 index 0000000..267fb21 Binary files /dev/null and b/Photobox/Label.odt differ diff --git a/Software/3G Modem/Datenrate_Minumum.txt b/Software/3G Modem/Datenrate_Minumum.txt new file mode 100644 index 0000000..2412a12 --- /dev/null +++ b/Software/3G Modem/Datenrate_Minumum.txt @@ -0,0 +1,2 @@ + +5MB diff --git a/Software/3G Modem/Raspberry Pi GSM Modul - Mobiles Internet (LTE, 3G, UMTS).pdf b/Software/3G Modem/Raspberry Pi GSM Modul - Mobiles Internet (LTE, 3G, UMTS).pdf new file mode 100644 index 0000000..26ee29f Binary files /dev/null and b/Software/3G Modem/Raspberry Pi GSM Modul - Mobiles Internet (LTE, 3G, UMTS).pdf differ diff --git a/Software/3G Modem/Sakis3G wiki.pdf b/Software/3G Modem/Sakis3G wiki.pdf new file mode 100644 index 0000000..abc8bbe Binary files /dev/null and b/Software/3G Modem/Sakis3G wiki.pdf differ diff --git a/Software/3G Modem/Sakis3G/Installation.txt b/Software/3G Modem/Sakis3G/Installation.txt new file mode 100644 index 0000000..421ef7c --- /dev/null +++ b/Software/3G Modem/Sakis3G/Installation.txt @@ -0,0 +1,23 @@ +wget http://raspberry-at-home.com/files/sakis3g.tar.gz + +sudo mkdir /usr/bin/modem3g + +sudo chmod 777 /usr/bin/modem3g + +sudo cp sakis3g.tar.gz /usr/bin/modem3g + +cd /usr/bin/modem3g + +sudo tar -zxvf sakis3g.tar.gz + +sudo chmod +x sakis3g + +sudo ./sakis3g --interactive + +---------------- +1. 3G Verbinden +2. über USB +3. Huawei Mobile +4. Interface 0 +----------------- + diff --git a/Software/3G Modem/Sakis3G/sakis3g.sh b/Software/3G Modem/Sakis3G/sakis3g.sh new file mode 100644 index 0000000..ce1b612 --- /dev/null +++ b/Software/3G Modem/Sakis3G/sakis3g.sh @@ -0,0 +1,8502 @@ +#!/bin/sh +MYVERSION="0.2.0e" + +# Transform debug to DEBUG, in order to declare debug method. +if [ -n "${debug}" ]; then + echo "Warning: debug variable is obsolete. Use DEBUG instead." >> /dev/stderr + export DEBUG="${debug}" + unset debug +fi + +# Display formatted debug output if DEBUG variable is set. +# This method should have as less dependencies as possible. +debug() { + if [ "a$1" != "arun_command" -a "a$1" != "ashow_file" -a -z "${DEBUG}" ]; then + return 0 + elif [ "a$1" = "arun_command" -a -z "${DEBUG}" ]; then + shift + sh -c "$*" > /dev/null 2> /dev/null + return $? + elif [ "a$1" = "arun_command" -a -n "${DEBUG}" ]; then + shift + printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr" + printf "[%.5d] [%s] Will now run command: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "${*}" >> "/dev/stderr" + printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr" + sh -c "$*" >> "/dev/stderr" 2>&1 + rdebug=$? + printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr" + printf "[%.5d] [%s] Command returned %d.\n" "$$" "`date "+%H:%M:%S"`" "${rdebug}" >> "/dev/stderr" + printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr" + return ${rdebug} + elif [ -z "${DEBUG}" ]; then + return 0 + elif [ "a$1" = "ashow_file" ]; then + if [ -f "$2" ]; then + printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr" + printf "[%.5d] [%s] Will now display contents of: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "$2" >> "/dev/stderr" + printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr" + cat "$2" >> "/dev/stderr" + printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr" + ls -ld "$2" >> "/dev/stderr" + printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr" + else + printf "/-------------------------------------------------------------------------------\n" >> "/dev/stderr" + printf "[%.5d] [%s] File does not exist: \'%s\'\n" "$$" "`date "+%H:%M:%S"`" "$2" >> "/dev/stderr" + printf "\-------------------------------------------------------------------------------\n" >> "/dev/stderr" + fi + return 0 + else + rfmt="$1" + shift + if [ "a${YESFUNCNAME}" = "a" ]; then + if [ "$#" -ge "1" ]; then + printf "[%.5d] [%s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${@}" >> "/dev/stderr" + else + printf "[%.5d] [%s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" >> "/dev/stderr" + fi + else + if [ "$#" -ge "1" ]; then + printf "[%.5d] [%s] [%-20s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${FUNCNAME[1]}" "${@}" >> "/dev/stderr" + else + printf "[%.5d] [%s] [%-20s] ${rfmt}" "$$" "`date "+%H:%M:%S"`" "${FUNCNAME[1]}" >> "/dev/stderr" + fi + fi + unset rfmt + fi + return 0 +} + +# Print debug header +debug_header() { + if [ -n "${DEBUG}" ]; then + echo >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + echo "Sakis3G ${MYVERSION} running on DEBUG mode." >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + date >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + if [ "a${allargs}" = "a" ]; then + echo "Command line was: $0 $@" >> "/dev/stderr" + else + echo "Command line was: $0 ${allargs}" >> "/dev/stderr" + fi + echo "Running with PID: $$" >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + echo "Environment is:" >> "/dev/stderr" + set >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + echo "Will now proceed with Sakis3G execution." >> "/dev/stderr" + echo "-------------------------------------------" >> "/dev/stderr" + fi +} + +need_arg() { + [ "a`eval echo \\\$$1 2> /dev/null`" != "a" ] && return 0 + case "$1" in + foldwrapping) + export foldwrapping=60 + ;; + pppint) + export pppint="ppp0" + ;; + CHAT_ABORT_STRINGS) + # Abort strings that chat program may encounter + export CHAT_ABORT_STRINGS="ABORT BUSY ABORT ERROR ABORT BLOCKED ABORT NOCARRIER" + ;; + BAUD) + export BAUD="460800" + ;; + PPPD_OPTIONS) + # Options passed to pppd when called directly + export PPPD_OPTIONS="modem crtscts -detach defaultroute dump noipdefault usepeerdns usehostname ktune logfd 2 noauth name sakis3g lock maxfail 3" + ;; + PPPD_PEERS) + # Directory where pppd keeps its peers + export PPPD_PEERS=/etc/ppp/peers + ;; + SERIALDRIVERS) + export SERIALDRIVERS="ftdi_sio ipaq safe_serial usbserial visor" + ;; + LOGPOSITION) + export LOGPOSITION="/var/log/sakis3g.log" + ;; + XOSDFONT) + export XOSDFONT='-*-freesans-bold-r-*-*-36-*-*-*-*-*-*-*' + ;; + AOSDFONT) + export AOSDFONT='DejaVuSans 36' + ;; + MENUFONT) + export MENUFONT="-monotype-arial-medium-r-normal-*-18-*-*-*-*-*-*-*" + ;; + *) + debug "No default value for %s was found.\n" "$1" + ;; + esac + debug "Loaded default value for %s: %s\n" "$1" "`eval echo \\\$$1 2> /dev/null`" +} + +sanitize() { + echo "$@" 2> /dev/null | ${trbin} "\\" " " 2> /dev/null | ${trbin} "\"" " " | ${trbin} "'" " " | ${trbin} "\`" " " +} + +release_X_cookie() { + debug "Disposing stolen X session cookie for %s.\n" "${XCOOKIE}" + if [ -n "${XCOOKIE}" ] && find_binary "xauth"; then + # If having an authority file that does not belong to us, unset it. + if [ "a${XAUTHORITY}" = "a${runhome}/.Xauthority" -a "a$HOME" != "a${runhome}" ]; then + unset XAUTHORITY + fi + found=`${xauthbin} nlist ${XCOOKIE} | ${wcbin} -l` + found=`echo ${found}` + if [ "a${found}" = "a0" ]; then + debug "Cookie already disposed.\n" + else + ${xauthbin} remove ${XCOOKIE} + found=`xauth nlist ${XCOOKIE} | ${wcbin} -l` + found=`echo ${found}` + if [ "a${found}" = "a0" ]; then + debug "Cookie disposed as it should.\n" + unset XCOOKIE + else + debug "Failed to dispose cookie.\n" + fi + fi + unset found + fi +} + +# Callback function called on EXIT to execute traps. +exittrap() { + if [ -n "${TRAPS}" ]; then + debug "Now executing traps.\n" + for tr in ${TRAPS} + do + debug "Executing trap \"%s\".\n" "${tr}" + ${tr} + done + else + debug "No exit traps defined.\n" + fi + if ppp_fast_status; then + debug "\n>>>>>>>>> If program is paused, you may freely press Ctrl+C. <<<<<<<<<\n>>> This happens due to DEBUG being set. Connection will NOT drop. <<<\n" + fi +} + +# Adds trap to be executed on EXIT +addexittrap() { + [ "a$1" = "a" ] && return 0; + if [ "a${TRAPS}" = "a" ]; then + trap exittrap EXIT + debug "Established trap handler.\n" + fi + if ! strinstr "$1" "${TRAPS}" " "; then + TRAPS="$1 ${TRAPS}" + debug "Traps are now: %s\n" "${TRAPS}" + else + debug "Trap %s already registered.\n" "${1}" + fi +} + +translate_load() { + unset translatebase + ! find_binary "printf" && return 1 + ! find_binary "grep" && return 1 + ! find_binary "head" && return 1 + ! find_binary "tail" && return 1 + ! find_binary "sed" && return 1 + ! find_binary "cat" && return 1 + ! find_binary "cut" && return 1 + ! find_binary "tr" && return 1 + if [ "a${notranslate}" != "a" ]; then + export notranslate=yes; unset foldwrapping; need_arg "foldwrapping" + return 1 + fi + if [ "a${TRANSLATION}" != "a" ] && [ -f "${TRANSLATION}" ]; then + debug "Requested to use file %s for translations.\n" "${TRANSLATION}" + translatebase=`${catbin} "${TRANSLATION}" 2> /dev/null` + elif [ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ]; then + translatelocale="${LC_MESSAGES}" + [ "a${translatelocale}" = "a" ] && translatelocale="${LC_ALL}" + [ "a${translatelocale}" = "a" ] && translatelocale="${LOCALE}" + [ "a${translatelocale}" = "a" ] && translatelocale="${LANG}" + if [ "a${translatelocale}" = "a" ]; then + debug "No locale reported by system. Will not be using translations.\n" + export notranslate=yes; unset foldwrapping; need_arg "foldwrapping" + return 1 + fi + debug "Locale %s found in environment.\n" "${translatelocale}" + translatelocale=`echo ${translatelocale} | ${grepbin} -i "UTF\(.*\)8"` + if [ "a${translatelocale}" = "a" ]; then + debug "Reported locale is not UTF-8. Will not be using translations.\n" + export notranslate=yes; unset foldwrapping; need_arg "foldwrapping" + return 1 + fi + translatelocale=`echo ${translatelocale} | ${cutbin} -d. -f1 | ${sedbin} -e "s/$/.UTF-8/g"` + debug "Will attempt to get translation file from package: %s.\n" "messages/${translatelocale}" + translatebase=`${PROVIDER} getfile "messages/${translatelocale}" 2> /dev/null` + else + debug "Unable to retrieve any translation file. Will not be using translations.\n" + export notranslate=yes; unset foldwrapping; need_arg "foldwrapping" + return 1 + fi + helperfactor=`echo "${translatebase}" 2> /dev/null | ${headbin} -1 | ${grepbin} "^##\([0-9]\)$" | ${sedbin} -e "s/^##//g"` + [ "a${helperfactor}" = "a" ] && helperfactor=1 + unset foldwrapping; need_arg "foldwrapping"; + foldwrapping=`expr ${foldwrapping} \* ${helperfactor} 2> /dev/null`; foldwrapping=`echo ${foldwrapping}` + [ "a${foldwrapping}" = "a" ] && unset foldwrapping + need_arg "foldwrapping"; unset helperfactor + translatebase=`${printfbin} "%s" "${translatebase}" | ${grepbin} -v "^#"` + if [ "a${translatebase}" = "a" ]; then + debug "No translations retrieved from file. Will not be using translations.\n" + export notranslate=yes; unset foldwrapping; need_arg "foldwrapping" + return 1 + fi + export foldwrapping + debug "Translations loaded. Wrapping at %d bytes.\n" "${foldwrapping}" + return 0 +} + +# Translates argument to locale +translate_text() { + if [ "a${notranslate}" != "a" ]; then + ${printfbin} "%s" "$1" + return 0 + fi + [ "a${translatebase}" = "a" ] && translate_load + if [ "a${notranslate}" != "a" -o "a${translatebase}" = "a" ]; then + ${printfbin} "%s" "$1" + return 0 + fi + # Safer, still slower way to translate + #texttomatch=`${printfbin} "%s" "$1" | ${trbin} "\\n" ".." | ${trbin} "\n" "." | ${trbin} "\t" "." | ${trbin} "\\\\\\\" "." | ${sedbin} -e "s/\\\\\\/\./g" | ${sedbin} -e "s/\"/\./g"` + texttomatch=`${printfbin} "%s" "$1" | ${trbin} "\\\\\\\" "." | ${trbin} "\\\\\"" "." | ${trbin} "\n" "."` +# Comment below is to help gedit in colouring text +# `"` + if [ -n "${showtext}" ]; then + debug "Text to check: %s\n" "${1}" + debug "Text to match: %s\n" "${texttomatch}" + fi + texttranslated=`${printfbin} "%s" "${translatebase}" | ${grepbin} -A 1 -G "^.${texttomatch}.$" | ${headbin} -2 | ${tailbin} -1 | ${sedbin} -e "s/^\"\(.*\)\"$/\1/g"` + unset texttomatch + if [ "a${texttranslated}" != "a" -a "a${texttranslated}" != "a\"" ]; then + [ -n "${showtext}" ] && debug "Text returned: %s\n" "${texttranslated}" + ${printfbin} "%s" "${texttranslated}" + else + [ -n "${showtext}" ] && debug "No translation found, returning original text: %s\n" "$1" + ${printfbin} "%s" "$1" + fi + unset texttranslated + return 0 +} + +# Safety helper +safe_invoke() { + if [ "a${NOFUNCNAME}" != "a" ]; then + debug "FIXME: Called %s without FUNCNAME variables available.\n" "$0" + return 99 + fi + if [ "a${FUNCNAME[1]}" = "a" ]; then + debug "FIXME: %s called without FUNCNAME[1] being available.\n" + return 99 + fi + debug "Function %s requested to call it in a safe manner.\n" "${FUNCNAME[1]}" + callertimeout="$1"; callertimeout=`expr ${callertimeout} + 1 - 1 2> /dev/null` + if [ "a${callertimeout}" = "a$1" ]; then + debug "Timeout set by %s to %d seconds.\n" "${FUNCNAME[1]}" "${callertimeout}" + shift + else + callertimeout=5 + debug "Caller did not provide timeout. Using default (%d seconds).\n" "${callertimeout}" + fi + if [ "a${safetimeout}" != "a" ]; then + unset callertimeout + debug "FIXME: However, we are already within a safe session.\n" + ${FUNCNAME[1]} "safe" "$@" + ret=$? + debug "FIXME: Function %s returned from within a nested safe session.\n" "${FUNCNAME[1]}" + return ${ret} + elif [ "a${nosafety}" != "a" ]; then + unset callertimeout + debug "However, config instructs not to use safety-checks.\n" + ${FUNCNAME[1]} "safe" "$@" + ret=$? + unset TIMEOUTOCCURED + debug "Unsafe function %s returned.\n" "${FUNCNAME[1]}" + return ${ret} + fi + safetimeout="${callertimeout}" + callermethod="${FUNCNAME[1]}" + unset TIMEOUTOCCURED; unset callertimeout + if find_binary "mktemp"; then + debug "Using %s to store standard output and error of %s.\n" "${mktempbin}" "${callermethod}" + outputholder=`${mktempbin} -p /tmp -q sakis3g.safe.output.$$.XXXXXXXX` + errorholder=`${mktempbin} -p /tmp -q sakis3g.safe.error.$$.XXXXXXXX` + fi + if [ "a${outputholder}" = "a" ]; then + debug "Using backup method for creating temporary output holder.\n" + outputholder="/tmp/sakis3g.unsafe.output.$$" + fi + if [ "a${errorholder}" = "a" ]; then + debug "Using backup method for creating temporary output holder.\n" + errorholder="/tmp/sakis3g.unsafe.error.$$" + fi + debug "Will store output at: %s\n" "${outputholder}" + debug "Will store error at: %s\n" "${errorholder}" + debug "Initiating safe session for %s (%d seconds timeout).\n" "${callermethod}" "${safetimeout}" + "${callermethod}" "safe" "$@" > "${outputholder}" 2> "${errorholder}" & + safecallerpid=$!; eval "disown -a" > /dev/null 2> /dev/null + debug "Method spawned with PID %d.\n" "${safecallerpid}" + while ! notrunning "${safecallerpid}" + do + debug "%s still runs. %d seconds before killing.\n" "${callermethod}" "${safetimeout}" + if [ "a${safetimeout}" = "a0" ]; then + debug "Time expired with no results.\n" + if find_binary "kill"; then + debug "Will attempt to kill process with PID %d.\n" "${safecallerpid}" + ! notrunning "${safecallerpid}" && debug run_command "${killbin} -1 ${safecallerpid}" + ! notrunning "${safecallerpid}" && debug run_command "${killbin} -9 ${safecallerpid}" + ! notrunning "${safecallerpid}" && debug "Failed to kill it.\n" + fi + if find_binary "rm"; then + debug "Will attempt to unlink temporary holders.\n" + debug run_command "${rmbin} -f \"${outputholder}\" \"${errorholder}\"" + fi + export TIMEOUTOCCURED="${callermethod}" + unset callermethod; unset safecallerpid; unset outputholder; unset errorholder + debug "Method %s failed to respond within timeout.\n" + unset safetimeout + return 99 + fi + safetimeout=`expr ${safetimeout} - 1`; safetimeout=`echo ${safetimeout}` + sleep 1 + done + debug "Method returned while %d seconds were remaining.\n" "${safetimeout}" + debug show_file "${outputholder}" + debug show_file "${errorholder}" + if find_binary "cat"; then + debug "Will now route output and error to mine.\n" + [ -f "${outputholder}" ] && ${catbin} "${outputholder}" 2> /dev/null + [ -f "${errorholder}" ] && ${catbin} "${errorholder}" >> /dev/stderr 2> /dev/null + fi + if find_binary "rm"; then + debug "Will attempt to unlink temporary holders.\n" + debug run_command "${rmbin} -f \"${outputholder}\" \"${errorholder}\"" + fi + debug "Method %s responded within timeout specified.\n" "${FUNCNAME[1]}" + unset callermethod; unset safecallerpid; unset outputholder; unset errorholder + unset safetimeout + debug "Left safe mode.\n" + return 0 +} + +safe_lsusb() { + if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then + safe_invoke "5" "$@" + return $? + elif [ "a${NOFUNCNAME}" = "a" ]; then + shift + fi + [ "a${lsusbbin}" != "a" ] && ${lsusbbin} "$@" +} + +safe_chat() { + if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then + safe_invoke "10" "$@" + return $? + elif [ "a${NOFUNCNAME}" = "a" ]; then + shift + fi + [ "a${chatbin}" != "a" ] && ${chatbin} "$@" +} + +safe_cat() { + if [ "a$1" != "asafe" -a "a${NOFUNCNAME}" = "a" ]; then + safe_invoke "5" "$@" + return $? + elif [ "a${NOFUNCNAME}" = "a" ]; then + shift + fi + [ "a${catbin}" != "a" ] && ${catbin} "$@" +} + +# Formats text +format_text() { + if find_binary "printf"; then + rfmt="$1" + [ "$#" -gt "0" ] && shift + rfmt=`translate_text "${rfmt}"` + if [ "$#" -ge "1" ]; then + ${printfbin} "${rfmt}" "${@}" + else + ${printfbin} "${rfmt}" + fi + unset rfmt + else + echo "${@}" + fi +} + +# Clears terminal line if required +term_clearline() { + [ "a${COLUMNS}" != "a" ] && find_binary "printf" && [ -n "${interactive}" ] && ${printfbin} "\r%.-${COLUMNS}s\r" "" && return 0 + [ "a${COLUMNS}" = "a" ] && find_binary "printf" && [ -n "${interactive}" ] && ${printfbin} "\r%s\r" " " && return 0 +} + +# Prints argument to terminal +term_print() { + term_clearline + echo "${@}" +} + +# Sends error to terminal, colored if possible. +term_error() { + if find_binary "grep" && [ -n "${interactive}" ]; then + term_print "$@" | ${grepbin} --color "." + else + term_print "$@" + fi +} + +term_verbose() { + if [ -n "${interactive}" ]; then + if find_binary "grep" && find_binary "tr"; then + currentlyverbosing=yes + term_print "$@" | GREP_COLOR=2 ${grepbin} --color=always "." | ${trbin} "\n" " " + unset currentlyverbosing; lastlineverbose=yes + else + term_print "$@" + fi + fi +} + +term_notify() { + if find_binary "grep" && [ -n "${interactive}" ]; then + term_print "$@" | GREP_COLOR=1 ${grepbin} --color "." + else + term_print "$@" + fi +} + +select_example() { + examplevariable=`selection_argument variable "$@"` + exampleoptions=`selection_argument options "$@"` + [ "a${exampleoptions}" != "a" ] && format_text "\nAvailable options are:\n" && format_text "%s\n" "${exampleoptions}" + [ "a${exampleoptions}" = "a" ] && exampleoptions="foo" + format_text "\nExample:\n" + format_text "\t$ %s [...] %s=\"%s\"\n\r\n" "${ME}" "${examplevariable}" "`echo ${exampleoptions} | ${cutbin} -d\ -f1`" + unset exampletitle; unset examplevariable; unset exampleoptions +} + +term_select_example() { + examplevariable=`selection_argument variable "$@"` + exampleoptions=`selection_argument options "$@"` + [ "a${exampleoptions}" != "a" ] && notify "\nAvailable options are:\n" && notify "%s\n" "${exampleoptions}" + [ "a${exampleoptions}" = "a" ] && exampleoptions="foo" + notify "\nExample:\n" + notify "\t$ %s %s=\"%s\"\n\r\n" "${ME}" "${examplevariable}" "`echo ${exampleoptions} | ${cutbin} -d\ -f1`" + unset exampletitle; unset examplevariable; unset exampleoptions +} + +term_select() { + options=`selection_argument options "$@" | ${wcbin} -l`; options=`echo ${options}` + variable=`selection_argument variable "$@"` + if [ "a${options}" != "a1" ]; then + exampletitle=`selection_argument title "$@"` + notify "%s by using %s variable, or by enabling interactive mode.\n" "${exampletitle}" "${variable}" + notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}" + unset exampletitle + term_select_example "$@" + else + eval export ${variable}="`selection_argument option 1 "$@"`" + debug "Returning sole available option \"%s\" on behalf of user.\n" "`eval echo \\\${${variable}}`" + unset variable + return 1 + fi + unset variable; unset options + stop_with 98 + return 98 +} + +term_confirm() { + options=`selection_argument options "$@" | ${wcbin} -l`; options=`echo ${options}` + variable=`selection_argument variable "$@"` + exampletitle=`selection_argument title "$@"` + notify "%s by using --%syes or --%sno switches, or by enabling interactive mode.\n" "${exampletitle}" "${variable}" "${variable}" + notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}" + unset exampletitle + stop_with 98 + return 98 +} + +term_prompt() { + variable=`selection_argument variable "$@"` + exampletitle=`selection_argument title "$@"` + notify "%s by using %s variable, or by enabling interactive mode.\n" "${exampletitle}" "${variable}" + notify "\t$ %s --interactive %s\n" "${ME}" "${allargs}" + unset exampletitle + term_select_example "$@" + return 98 +} + +interactive_term_select() { + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}` + debug "Prompting user to select variable %s.\n" "${variable}" + [ "a${title}" != "a" ] && notify "%s\n\r\n" "${title}" + [ "a${text}" != "a" ] && ${printfbin} "%s\n\r\n" "${text}" + notify "Available options are:\n" + selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)/\1. \3/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "\([0-9]*\)\." + selection_argument button2 "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\)/0. \2/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "\([0-9]*\)\." + format_text "You can automate this selection by setting %s variable.\nEnter \"*\" to discover how.\n" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "." + notify "\r\n" + echo -n "`format_text "Please use numbers %d-%d to perform your selection: " "0" "${options}"`" + read termselection + debug "User typed: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "a*" ]; then + debug "Showing select example through variable %s.\n" "${variable}" + term_select_example "$@" + interactive_term_select "$@" + selection=$? + else + selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null` + [ "${selection}" -gt "${options}" ] && selection=0 + [ "${selection}" -eq "0" ] && selection=98 + [ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`" + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset options; unset termselection + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + return "${selection}" +} + +interactive_term_confirm() { + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + debug "Prompting user to select variable %s.\n" "${variable}" + [ "a${title}" != "a" ] && notify "%s\n\r\n" "${title}" + [ "a${text}" != "a" ] && ${printfbin} "%s\n\r\n" "${text}" + notify "Available options are:\n" + selection_argument button1 "$@" | ${sedbin} -e "s/^\(.*\)$/1. \1/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "^\([0-9]*\)\." + selection_argument button2 "$@" | ${sedbin} -e "s/^\(.*\)$/2. \1/g" | GREP_COLOR=1 ${grepbin} --color=AUTO "^\([0-9]*\)\." + [ "a$6" != "areset" ] && format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "." + notify "\r\n" + echo -n "`format_text "Please use numbers %d-%d to perform your selection: " "1" "2"`" + read termselection + debug "User typed: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "a1" ]; then + debug "User selected \"yes\".\n" + selection=0 + elif [ "a${termselection}" = "a2" ]; then + debug "User selected \"no\".\n" + selection=1 + else + interactive_term_confirm "$@" + selection=$? + return ${selection} + fi + unset variable; unset title; unset text; unset options; unset termselection + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + return "${selection}" +} + +interactive_term_prompt() { + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + debug "Prompting user to type variable %s.\n" "${variable}" + [ "a${title}" != "a" ] && notify "%s\n" "${title}" + format_text "You can automate this selection by setting %s variable.\nEnter \"*\" to discover how.\n" "${variable}" | GREP_COLOR=2 ${grepbin} --color=ALWAYS "." + notify "\r\n" + [ "a${text}" != "a" ] && ${printfbin} "%s: " "${text}" + read termselection + termselection=`sanitize "${termselection}"` + termselection=`echo "${termselection}" | ${sedbin} -e "s/^ *//g" | ${sedbin} -e "s/ *$//g"` + debug "User typed: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "a*" ]; then + debug "Showing select example through variable %s.\n" "${variable}" + term_select_example "$@" + interactive_term_prompt "$@" + selection=$? + elif [ "a${termselection}" = "a" ]; then + debug "User pressed enter which indicates to abort.\n" + selection=98 + else + eval "export ${variable}=\"${termselection}\"" + selection=0 + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset termselection + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + return "${selection}" +} + +nine_verbose() { + term_verbose "$@" +} + +nine_fixcolors() { + status_connected + [ "a${NINEISP}" != "a${ISPID}" -o "a${ISPID}" = "a" ] && unset NINEBGCOLOR && unset NINEFGCOLOR + [ "a${NINEFGCOLOR}" = "a" ] && NINEFGCOLOR=`echo ${ISP_FGCOLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"` + [ "a${NINEBGCOLOR}" = "a" ] && NINEBGCOLOR=`echo ${ISP_BGCOLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"` + [ "a${ISPID}" = "a" ] && unset NINEBGCOLOR && unset NINEFGCOLOR + [ "a${NINEFGCOLOR}" = "a" ] && NINEFGCOLOR="rgb:00/00/00" + [ "a${NINEBGCOLOR}" = "a" ] && NINEBGCOLOR="rgb:ec/ec/ec" + [ "a${NINEISP}" = "a" ] && NINEISP="${ISPID}" + export NINEISP; export NINEFGCOLOR; export NINEBGCOLOR +} + +nine_notify() { + unset nineerrormode + ! find_binary "9menu" && return 1 + if [ "a${1}" = "aerror" ]; then + nineerrormode=1 + shift + debug "Going into error mode.\n" + else + debug "Normal notification.\n" + fi + ninetext=`echo "$@" | ${sedbin} -e "s/:/;/g"` + need_arg "MENUFONT" + need_arg "foldwrapping" + if find_binary "fold"; then + ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}` + else + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"` + fi + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "` + debug "Displaying text to user through 9menu:%s\n" " $@ " + debug "Displaying text to user through 9menu:%s\n" " ${ninetext} " + if [ "a${nineerrormode}" = "a1" ]; then + result=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg \"rgb:ff/80/80\" -fg white -display \"${DISPLAY}\" -label \"\`translate_text "Error"\`\" ${ninetext} \":\" \"OK:exec echo OK-\"" 2> /dev/null | ${grepbin} "^OK-" | ${cutbin} -d- -f1` + else + nine_fixcolors + result=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"\`translate_text "Notification"\`\" ${ninetext} \":\" \"OK:exec echo OK-\"" 2> /dev/null | ${grepbin} "^OK-" | ${cutbin} -d- -f1` + fi + if [ "a${result}" = "aOK" ]; then + debug "User saw message.\n" + else + debug "9menu died or user closed it.\n" + fi + unset ninetext; unset result; unset nineerrormode +} + +nine_error() { + nine_notify "error" "$@" +} + +nine_select() { + ! find_binary "9menu" && return 1 + nine_fixcolors + need_arg "MENUFONT" + need_arg "foldwrapping" + debug "Prompting user to select variable %s with 9menu.\n" "${variable}" + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}` + helptext=`format_text "You can automate this selection by setting %s variable on command line, click here to discover how.\n" "${variable}" | ${sedbin} -e "s/:/;/g"` + localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel" + ninetext=`echo "${text}" | ${sedbin} -e "s/:/;/g"` + if find_binary "fold"; then + ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}` + helptext=`echo "${helptext}" | ${foldbin} -s -w ${foldwrapping}` + else + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"` + helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"` + fi + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "` + helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:exec echo OPTION-AUTOMATE\"/g" | ${trbin} " " " " | ${trbin} "\n" " "` + localarguments=`selection_argument options "$@" | ${sedbin} -e "s/:/;/g" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1. \3:exec echo OPTION-\1\"/g" | ${trbin} "\n" " "` + termselection=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"${title}\" ${ninetext} \":\" ${localarguments} \":\" ${helptext} \":\" \"${localbutton2}:exec echo OPTION-9menuexit\"" 2> /dev/null | ${grepbin} "^OPTION-" | ${cutbin} -d- -f2-` + debug "User selected: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "aAUTOMATE" ]; then + localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"` + notify "${localtext}\n`select_example "$@"`" + nine_select "$@" + selection=$? + return ${selection} + elif [ "a${termselection}" = "a9menuexit" -o "a${termselection}" = "a" ]; then + debug "User selected button: %s\n" "${localbutton2}" + selection=98 + else + termselection=`echo "${termselection}" | ${trbin} -t "." ""` + selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null` + [ "${selection}" -gt "${options}" ] && selection=0 + [ "${selection}" -eq "0" ] && selection=98 + [ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`" + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset ninetext; unset helptext; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2 + return "${selection}" +} + +nine_confirm() { + ! find_binary "9menu" && return 1 + nine_fixcolors + need_arg "MENUFONT" + need_arg "foldwrapping" + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + ninetext=`selection_argument text "$@" | ${sedbin} -e "s/:/;/g"` + localbutton1=`selection_argument button1 "$@"`; [ "a${localbutton1}" = "a" ] && localbutton1="OK" + localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel" + debug "Prompting user to confirm variable %s with 9menu.\n" "${variable}" + helptext="" + [ "a$6" != "areset" ] && helptext=`format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}" | ${sedbin} -e "s/:/;/g"` + if find_binary "fold"; then + ninetext=`echo "${ninetext}" | ${foldbin} -s -w ${foldwrapping}` + helptext=`echo "${helptext}" | ${foldbin} -s -w ${foldwrapping}` + else + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"` + helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(............................................................\)\(.*\)$/\1\\n\2/g"` + fi + ninetext=`echo "${ninetext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "` + helptext=`echo "${helptext}" | ${sedbin} -e "s/^\(.*\)$/\"\1:\"/g" | ${trbin} " " " " | ${trbin} "\n" " "` + localarguments="\"${localbutton1}:exec echo Answer-Yes\" \"${localbutton2}:exec echo Answer-No\"" + termselection=`eval "${ninemenubin} -font \"${MENUFONT}\" -bg ${NINEBGCOLOR} -fg ${NINEFGCOLOR} -display \"${DISPLAY}\" -label \"${title}\" ${ninetext} \":\" ${localarguments} \":\" ${helptext} \":\"" 2> /dev/null | ${grepbin} "^Answer-" | ${cutbin} -d- -f2-` + debug "User selected: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "aYes" ]; then + selection=0 + else + selection=1 + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset ninetext; unset helptext; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2; unset localbutton1 + return "${selection}" +} + +nine_prompt() { + ! find_binary "xterm" && return 1 + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + debug "Prompting user to type variable %s through xterm.\n" "${variable}" + localtext=`format_text "You can automate this selection by setting %s variable.\n" "${variable}"` + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\n\n%s: " "${localtext}" "${text}"` + locallines=`echo "${localtext}" | ${wcbin} -l`; locallines=`echo ${locallines}`; locallines=`expr ${locallines} + 10`; locallines=`echo ${locallines}`; + ${printfbin} "%s\n" "${localtext}" > "/tmp/sakis3g.xterm.pipe.$$" + ${xtermbin} -T "${title}" +cm +dc -e sh -c "${catbin} /tmp/sakis3g.xterm.pipe.$$; read XTERMANSWER; set >> /tmp/sakis3g.xterm.pipe.$$;" 2> /dev/null + debug show_file "/tmp/sakis3g.xterm.pipe.$$" + termselection=`${grepbin} "^XTERMANSWER=" "/tmp/sakis3g.xterm.pipe.$$" 2> /dev/null | ${cutbin} -d= -f2- | ${sedbin} -e "s/^\"\(.*\)\"$/\1/g" | ${sedbin} -e "s/^\'\(.*\)\'$/\1/g"`; ${rmbin} -f "/tmp/sakis3g.xterm.pipe.$$" + termselection=`sanitize "${termselection}"` + debug "User typed: \"%s\"\n" "${termselection}" + # TODO: Implement example + if [ "a${termselection}" != "a" ]; then + debug "User typed: %s\n" "${termselection}" + eval "export ${variable}=\"${termselection}\"" + selection=0 + elif [ "a${termselection}" = "a" ]; then + debug "User requested to cancel.\n" + selection=98 + else + debug "Unknown error.\n" + selection=99 + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset termselection; unset buttonselection; unset localtext + return "${selection}" +} + +dialog_error() { + dialog_cleanscreen + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + ${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --colors --title "\Z1\Zb`translate_text "Error occured"`" --ok-label `translate_text "OK"` --clear --colors --aspect 30 --msgbox "\Z1\ZB$@" 0 0 + elif [ "a${SGUI}" = "aXdialog" ]; then + ! find_binary "Xdialog" && return 1 + ${Xdialogbin} --backtitle `translate_text "Error occured"` --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --msgbox "$@ " 0 0 + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + ${zenitybin} --title "`translate_text "Error occured"`" --error --text "$@ " + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + ${kdialogbin} --title "`translate_text "Error occured"`" --error "$@ " > /dev/null 2> /dev/null + elif [ "a${SGUI}" = "awhiptail" ]; then + ! find_binary "whiptail" && return 1 + ${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title "`translate_text "Error occured"`" --clear --msgbox "$@ " 0 0 + fi +} + +dialog_notify() { + dialog_cleanscreen + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + ${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title `translate_text "Notification"` --ok-label `translate_text "OK"` --clear --aspect 30 --msgbox "$@" 0 0 + elif [ "a${SGUI}" = "aXdialog" ]; then + ! find_binary "Xdialog" && return 1 + ${Xdialogbin} --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --msgbox "$@" 0 0 + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + ${zenitybin} --title "Sakis3G ${MYVERSION}" --info --text "$@ " + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + ${kdialogbin} --title "Sakis3G ${MYVERSION}" --msgbox "$@ " > /dev/null 2> /dev/null + elif [ "a${SGUI}" = "awhiptail" ]; then + ! find_binary "whiptail" && return 1 + ${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title `translate_text "Notification"` --clear --msgbox "$@" 0 0 + fi +} + +dialog_cleanscreen() { + if [ "a${SGUI}" = "aXdialog" ]; then + if [ "a${XdialogVerbose}" != "a" -a "a${XdialogVerbose}" != "a0" ]; then + ! notrunning "${XdialogVerbose}" && find_binary "kill" && ${killbin} -1 "${XdialogVerbose}" 2> /dev/null + unset XdialogVerbose + fi + unset currentlyverbosing + elif [ "a${SGUI}" = "azenity" ]; then + [ -f "/tmp/sakis3g.zenity.pipe" ] && ${printfbin} "\n100\n" >> "/tmp/sakis3g.zenity.pipe" + [ -f "/tmp/sakis3g.zenity.pipe" ] && debug run_command "${rmbin} -f /tmp/sakis3g.zenity.pipe" + [ "a${zenityverbosepid}" != "a" ] && ! notrunning "${zenityverbosepid}" && ${killbin} -1 "${zenityverbosepid}" 2> /dev/null + [ "a${zenityverbosepid}" != "a" ] && ! notrunning "${zenityverbosepid}" && ${killbin} -9 "${zenityverbosepid}" 2> /dev/null + unset zenityverbosepid + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + if [ "a${kdialogaddress}" != "a" ]; then + dcopbased=`echo ${kdialogaddress} | ${grepbin} -i "dcop"` + if [ "a${dcopbased}" != "a" ]; then + if find_binary "dcop"; then + debug run_command "${dcopbin} \"${kdialogaddress}\" close" + fi + else + ! find_binary "dbus-send" && find_binary "qdbus" + if [ "a${dbus_sendbin}" != "a" ]; then + debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.kde.kdialog.ProgressDialog.close\"" + elif [ "a${qdbusbin}" != "a" ]; then + debug run_command "${qdbusbin} ${kdialogaddress} \"org.kde.kdialog.ProgressDialog.close\"" + fi + fi + else + term_clearline + fi + unset kdialogaddress + fi +} + +dialog_verbose() { + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + verbwidth=`echo "${COLUMNS}"`; verbwidth=`expr ${verbwidth} + 1 - 1`; verbwidth=`echo ${verbwidth}` + verbheight=0; [ "${verbwidth}" -gt "40" ] && verbheight=3 + currentlyverbosing=yes + ${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title "Working" --aspect 40 --infobox "$@..." ${verbheight} ${verbwidth} + unset currentlyverbosing; lastlineverbose=yes; unset verbwidth; unset verbheight + elif [ "a${SGUI}" = "aXdialog" ]; then +# ! find_binary "Xdialog" && return 1 +# ${Xdialogbin} --title "Sakis3G is working" --infobox "$@..." 0 0 30000 & +# XdialogVerbose=$!; currentlyverbosing=yes + term_verbose "$@" + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + if ! find_binary "dbus-send" && ! find_binary "qdbus"; then + term_verbose "$@"; return 0 + fi + if [ "a${kdialogaddress}" = "a" ]; then + temptext=`translate_text Working...` + kdialogaddress=`${kdialogbin} --title "Sakis3G ${MYVERSION}" --progressbar "${temptext}" 100` +# kdialogaddress=`${kdialogbin} --title "Sakis3G ${MYVERSION}" --progressbar "${temptext}" 100 2> /dev/null` + debug "Returned 1\n" + unset temptext + [ "a${kdialogaddress}" != "a" ] && export kdialogaddress + fi + debug "Returned 2\n" + if [ "a${kdialogaddress}" != "a" ]; then + dcopbased=`echo ${kdialogaddress} | ${grepbin} -i "dcop"` + if [ "a${dcopbased}" != "a" ]; then + if find_binary "dcop"; then + debug run_command "${dcopbin} --user \"${runner}\" --all-sessions \"${kdialogaddress}\" setProgress ${verbosecurrentcount}" + debug run_command "${dcopbin} --user \"${runner}\" --all-sessions \"${kdialogaddress}\" setLabel \"$@\"" + fi + else + if [ "a${kdialogaddress}" != "a" ] && [ "a${dbus_sendbin}" != "a" ]; then + debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.freedesktop.DBus.Properties.Set\" string:'org.kde.kdialog.ProgressDialog' string:'value' variant:int32:${verbosecurrentcount}" + debug run_command "${dbus_sendbin} --print-reply --dest=${kdialogaddress} \"org.kde.kdialog.ProgressDialog.setLabelText\" \"string:$@\"" + elif [ "a${kdialogaddress}" != "a" ] && [ "a${qdbusbin}" != "a" ]; then + debug run_command "qdbus ${kdialogaddress} \"org.kde.kdialog.ProgressDialog.setLabelText\" \"$@\"" + debug run_command "qdbus ${kdialogaddress} \"org.freedesktop.DBus.Properties.Set\" \"\" \"value\" \"${verbosecurrentcount}\"" + fi + fi + else + term_verbose "$@" + fi + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + [ "a${zenityverbosepid}" != "a" ] && notrunning "${zenityverbosepid}" && unset zenityverbosepid + [ ! -f "/tmp/sakis3g.zenity.pipe" ] && unset zenityverbosepid + if [ "a${zenityverbosepid}" = "a" ] && find_binary "rm" && find_binary "tail" && find_binary "kill" && find_binary "printf" && find_binary "touch" && find_binary "chmod" && find_binary "setsid"; then + debug "Establishing zenity verbose helper.\n" + [ -f "/tmp/sakis3g.zenity.pipe" ] && ${printfbin} "\n100\n" >> "/tmp/sakis3g.zenity.pipe" + [ -f "/tmp/sakis3g.zenity.pipe" ] && debug run_command "${rmbin} -f /tmp/sakis3g.zenity.pipe" + debug run_command "${touchbin} /tmp/sakis3g.zenity.pipe" + debug run_command "${chmodbin} 666 /tmp/sakis3g.zenity.pipe" + if [ -f "/tmp/sakis3g.zenity.pipe" ]; then + eval ${tailbin} -f "/tmp/sakis3g.zenity.pipe" "2> /dev/null" | ${zenitybin} --title="Sakis3G ${MYVERSION}" --text="`translate_text Working...`" --progress --percentage=0 --auto-close "> /dev/null 2> /dev/null" & + zenityverbosepid=$! + eval "disown -a" > /dev/null 2> /dev/null + export zenityverbosepid + fi + fi + [ "a${zenityverbosepid}" != "a" ] && notrunning "${zenityverbosepid}" && unset zenityverbosepid + [ "a${zenityverbosepid}" = "a" ] && term_verbose "$@" && return 1 + ${printfbin} "\n%d\n# $@...\n\n" "${verbosecurrentcount}" >> "/tmp/sakis3g.zenity.pipe" + elif [ "a${SGUI}" = "awhiptail" ]; then + term_verbose "$@" + fi +} + +dialog_confirm() { + dialog_cleanscreen + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + elif [ "a${SGUI}" = "aXdialog" ]; then + ! find_binary "Xdialog" && return 1 + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + elif [ "a${SGUI}" = "awhiptail" ]; then + ! find_binary "whiptail" && return 1 + fi + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + debug "Prompting user to select yes%s or no%s.\n" "${variable}" "${variable}" + localtext="" + [ "a$6" != "areset" ] && localtext=`format_text "You can automate this selection by setting --%syes or --%sno switches.\n" "${variable}" "${variable}"` + if [ "a${SGUI}" = "adialog" ]; then + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"` + ${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --cr-wrap --yesno "${localtext}" 0 0 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "aXdialog" ]; then + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"` + ${Xdialogbin} --backtitle " ${title} " --title "Sakis3G ${MYVERSION}" --wrap --fill --yesno "${localtext}" 0 0 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "akdialog" ]; then + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"` + ${kdialogbin} --title " ${title} " --yesno "${text}" 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "azenity" ]; then + need_arg "foldwrapping" + text=`echo "${text}" | ${sedbin} -e "s/_/__/g"` + localtext=`echo "${localtext}" | ${sedbin} -e "s/_/__/g"` +# if find_binary "fold"; then +# localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}` +# text=`echo "${text}" | ${foldbin} -s -w ${foldwrapping}` +# fi + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"` + ${zenitybin} --title " ${title} " --question --text "${localtext}" 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "awhiptail" ]; then + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${text}" "${localtext}"` + ${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --yesno "${localtext}" 0 0 2> /dev/null + buttonselection=$?; + fi + if [ "a${buttonselection}" = "a0" ]; then + debug "User selected \"yes\" (%d).\n" "${buttonselection}" + return 0 + else + debug "User selected \"no\" (%d).\n" "${buttonselection}" + return 1 + fi +} + +dialog_select() { + dialog_cleanscreen + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + elif [ "a${SGUI}" = "aXdialog" ]; then + ! find_binary "Xdialog" && return 1 + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + elif [ "a${SGUI}" = "awhiptail" ]; then + ! find_binary "whiptail" && return 1 + fi + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + options=`selection_argument options "$@" | ${wcbin} -l` ; options=`echo ${options}` + debug "Prompting user to select variable %s.\n" "${variable}" + localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"` + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\\\\\\n\\\\\\n%s\n" "${localtext}" "${text}"` + localbutton2=`selection_argument button2 "$@"`; [ "a${localbutton2}" = "a" ] && localbutton2="Cancel" + if [ "a${SGUI}" = "adialog" ]; then + localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\" \"${variable}=\\\\\"\2\\\\\"\"/g"` + eval ${dialogbin} --backtitle \"Sakis3G ${MYVERSION}\" --title \" ${title} \" --ok-label \"`translate_text "OK"`\" --cancel-label \"${localbutton2}\" --item-help --clear --cr-wrap --menu \"${localtext}\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "aXdialog" ]; then + localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\" \"${variable}=\\\\\"\2\\\\\"\"/g"` + eval ${Xdialogbin} --backtitle \" ${title} \" --title \"Sakis3G ${MYVERSION}\" --ok-label \"`translate_text "OK"`\" --cancel-label \"${localbutton2}\" --item-help --wrap --fill --menubox \""${localtext}"\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "akdialog" ]; then + localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\"/g"` + eval ${kdialogbin} --title \" ${title} \" --menu \""${text}"\" ${localarguments} \"AUTOMATE\" \"`translate_text "Help with this question"`\" > "/tmp/sakis3g.dialog.$$" 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "azenity" ]; then + need_arg "foldwrapping" + localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1.\" \"\3\"/g"` + localtext=`echo "${text}" | ${sedbin} -e "s/_/__/g"` + find_binary "fold" && localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}` + eval ${zenitybin} --title \" ${title} \" --list --text \""${localtext}"\" --hide-column 1 --column Index --column `translate_text "Option"` ${localarguments} \"AUTOMATE\" \"`translate_text "Help with this question"`\" > "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "awhiptail" ]; then + localarguments=`selection_argument options "$@" | ${grepbin} -n "." | ${sedbin} -e "s/^\([0-9]*\):\(.*\) \(.*\)$/\"\1. \3\" \"\2\"/g"` + eval ${whiptailbin} --backtitle \"Sakis3G ${MYVERSION}\" --title \" ${title} \" --noitem --clear --menu \"${localtext}\" 0 0 0 ${localarguments} 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$?; + fi + termselection=`${catbin} "/tmp/sakis3g.dialog.$$" 2> /dev/null`; ${rmbin} -f "/tmp/sakis3g.dialog.$$" + debug "User selected: \"%s\"\n" "${termselection}" + if [ "a${termselection}" = "aAUTOMATE" ]; then + variable=`selection_argument variable "$@"` + localtext=`format_text "You can automate this selection by setting %s variable on command line.\n" "${variable}"` + notify "${localtext}\n`select_example "$@" | ${sedbin} -e "s/ /\\\n /g"`" + dialog_select "$@" + selection=$? + return ${selection} + elif [ "a${buttonselection}" != "a0" ]; then + debug "User selected button: %d\n" "${buttonselection}" + selection=98 + else + termselection=`echo "${termselection}" | ${trbin} -t "." ""` + selection=`${printfbin} "%d\n" "${termselection}" 2> /dev/null` + [ "${selection}" -gt "${options}" ] && selection=0 + [ "${selection}" -eq "0" ] && selection=98 + [ "${selection}" -gt "0" -a "${selection}" -le "${options}" ] && eval export ${variable}="`selection_argument option ${selection} "$@"`" + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset options; unset termselection; unset buttonselection; unset localtext; unset localarguments; unset localbutton2 + return "${selection}" +} + +dialog_prompt() { + dialog_cleanscreen + if [ "a${SGUI}" = "adialog" ]; then + ! find_binary "dialog" && return 1 + elif [ "a${SGUI}" = "aXdialog" ]; then + ! find_binary "Xdialog" && return 1 + elif [ "a${SGUI}" = "azenity" ]; then + ! find_binary "zenity" && return 1 + elif [ "a${SGUI}" = "akdialog" ]; then + ! find_binary "kdialog" && return 1 + elif [ "a${SGUI}" = "awhiptail" ]; then + ! find_binary "whiptail" && return 1 + fi + variable=`selection_argument variable "$@"` + title=`selection_argument title "$@"` + text=`selection_argument text "$@"` + debug "Prompting user to type variable %s.\n" "${variable}" + localtext=`format_text "You can automate this selection by setting %s variable.\n" "${variable}"` + [ "a${text}" != "a" ] && localtext=`${printfbin} "%s\n\n%s: " "${localtext}" "${text}"` + locallines=`echo "${localtext}" | ${wcbin} -l`; locallines=`echo ${locallines}`; locallines=`expr ${locallines} + 10`; locallines=`echo ${locallines}`; + if [ "a${SGUI}" = "adialog" ]; then + ${dialogbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --ok-label `translate_text "OK"` --cancel-label `translate_text "Cancel"` --clear --inputbox "${localtext}" ${locallines} 0 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "aXdialog" ]; then + ${Xdialogbin} --backtitle " ${title} " --title "Sakis3G ${MYVERSION}" --ok-label `translate_text "OK"` --cancel-label `translate_text "Cancel"` --wrap --fill --clear --inputbox "${localtext}" ${locallines} 0 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "akdialog" ]; then + ${kdialogbin} --title " ${title} " --inputbox "${localtext}" "" > "/tmp/sakis3g.dialog.$$" 2> /dev/null + buttonselection=$? + elif [ "a${SGUI}" = "azenity" ]; then + need_arg "foldwrapping" + localtext=`echo "${localtext}" | ${sedbin} -e "s/_/__/g"` + find_binary "fold" && localtext=`echo "${localtext}" | ${foldbin} -s -w ${foldwrapping}` + ${zenitybin} --title " ${title} " --entry --text "${localtext}" > "/tmp/sakis3g.dialog.$$" + buttonselection=$? + elif [ "a${SGUI}" = "awhiptail" ]; then + ${whiptailbin} --backtitle "Sakis3G ${MYVERSION}" --title " ${title} " --clear --inputbox "${localtext}" 0 0 2> "/tmp/sakis3g.dialog.$$" + buttonselection=$? + fi + termselection=`${catbin} "/tmp/sakis3g.dialog.$$" 2> /dev/null`; ${rmbin} -f "/tmp/sakis3g.dialog.$$" + termselection=`sanitize "${termselection}"` + debug "User pressed button %d while typed: \"%s\"\n" "${buttonselection}" "${termselection}" + # TODO: Implement example + if [ "a${buttonselection}" = "a0" ]; then + debug "User pressed OK.\n" + if [ "a${termselection}" != "a" ]; then + debug "User typed: %s\n" "${termselection}" + eval "export ${variable}=\"${termselection}\"" + selection=0 + else + debug "User entered no text.\n" "${variable}" + selection=98 + fi + elif [ "a${termselection}" = "a" -o "a${buttonselection}" != "a0" ]; then + debug "User requested to cancel.\n" + selection=98 + else + debug "Unknown error.\n" + selection=99 + fi + debug "Considering selection: %d\n" "${selection}" + unset variable; unset title; unset text; unset termselection; unset buttonselection; unset localtext + return "${selection}" +} + +dialog_clearscreen() { + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + return 0 +} + +selection_argument() { + selectarg="$1" + [ "$#" -gt "0" ] && shift + case "${selectarg}" in + variable) + echo "$1" + ;; + title) + echo "$2" + ;; + text) + echo "$3" + ;; + button1) + echo "$4" + ;; + button2) + echo "$5" + ;; + options) + for selectind in `${seqbin} 6 2 $#` + do + eval selcode=\${${selectind}} + selectinc=`expr ${selectind} + 1`; selectinc=`echo ${selectinc}` + eval seloption=\${${selectinc}} + echo "${selcode} ${seloption}" + unset selcode; unset seloption; unset selectinc + done + unset selectind + ;; + option) + selectind=$1 + [ "$#" -gt "0" ] && shift + selectind=`expr ${selectind} \* 2`; selectind=`echo ${selectind}` + selectind=`expr ${selectind} + 4`; selectind=`echo ${selectind}` + eval selcode=\${${selectind}} + echo "${selcode}" + unset selcode; unset selectind + ;; + invalid) + for selectind in `${seqbin} 7 2 $#` + do + eval selcode=\${${selectind}} + if [ "a${selcode}" = "a$1" ]; then + debug "%s==%s.\n" "$1" "${selcode}" + unset selcode; unset selectarg + selectind=`expr ${selectind} - 5`; selectind=`echo ${selectind}` + selectind=`expr ${selectind} / 2`; selectind=`echo ${selectind}` + return ${selectind} + fi + debug "%s!=%s\n" "${selcode}" "${1}" + unset selcode + done + debug "Not a valid option \"%s\".\n" "$1" + unset selectind + return 0 + ;; + *) + debug "Unknown selection id %s.\n" "${selectarg}" + ;; + esac + unset selectarg +} + +# Returns true if $1 is found within $2. +strinstr() { + [ "a$1" = "a" -o "a$2" = "a" ] && return 1 + if [ "a$3" = "a" ]; then + strinstrsep=":" + else + strinstrsep="$3" + fi + strinstrfound=`echo "${strinstrsep}${2}${strinstrsep}" | grep "${strinstrsep}${1}${strinstrsep}"` + strinstrfound=`echo "${strinstrfound}"` + unset strinstrsep + if [ "a${strinstrfound}" != "a" ]; then + unset strinstrfound + return 0 + fi + unset strinstrfound + return 1 +} + +# Checks if running with root priviledges +we_are_root_already() { + if [ "a${UID}" = "a0" -o "a${USER}" = "aroot" -o "a${EUID}" = "a0" ]; then + return 0 + fi + debug "Not currently running with root privileges.\n" + return 1 +} + +# Makes sure we are root +we_are_root() { + if we_are_root_already; then + debug "We are root already. Proceeding.\n" + return 0 + fi + state_variables + verbose "Acquiring root privileges" + [ -z "${SUMETHOD}" ] && check_su_software + [ -z "${ME}" ] && have_me + cleanscreen + debug "This instance will call %s and abort.\n" "${SUMETHOD}" + case "${SUMETHOD}" in + "sudo") + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + eval ${sudobin} ${ME} ${allargs} ${statevariables} + ret=$? + if [ "$ret" -eq "1" ]; then + echo + echo If it didn\'t worked, you need to add yourself + echo to sudo file: as root, type visudo and add the + echo following line at the end of file: + echo ${runner} ALL=\(root\) NOPASSWD: ${ME} + stop_fmt_error 1 "Failed to become root." + fi + ;; + "gksu") + # Nusty workaround because gksu does not properly handle arguments containing whitespaces + ${touchbin} "/tmp/sakis3g.gksu.wrapper.$$" + ${chmodbin} +x "/tmp/sakis3g.gksu.wrapper.$$" + ${printfbin} "#!/bin/sh\nexport PROVIDER=\"%s\"\n%s %s %s\nexit \$?\n\n" "${PROVIDER}" "${ME}" "${allargs}" "${statevariables}" > "/tmp/sakis3g.gksu.wrapper.$$" + [ ! -f "/tmp/sakis3g.gksu.wrapper.$$" ] && stop_fmt_error 3 "No method for acquiring root privileges found." + debug show_file "/tmp/sakis3g.gksu.wrapper.$$" + ${gksubin} /tmp/sakis3g.gksu.wrapper.$$ + ret=$? + ${rmbin} -f "/tmp/sakis3g.gksu.wrapper.$$" + ;; + "kdesu") + ${kdesubin} "${ME} ${allargs} ${statevariables}" + ret=$? + ;; + "su") + if [ -n "${stick_to_console}" -a -z "${interactive}" ]; then + notify "\nUtility \"%s\" found but cannot be used since we are not interactive.\n" "su" + notify "Either enable interactive mode:\n" + notify "\t%s --interactive %s\n" "${ME}" "${allargs}" + notify "or, force using %s instead:\n" "sudo" + notify "\t%s --sudo %s\n\r\n" "${ME}" "${allargs}" + stop_fmt_error 3 "No method for acquiring root privileges found." + fi + [ "a${DEBUG}" = "a" ] && find_binary "clear" && ${clearbin} + term_print "Please supply root password, or press enter to abort." + ${subin} -c "${ME} ${allargs} ${statevariables}" + ret=$? + ;; + esac + stop_with ${ret} +} + +# Shows error +show_fmt_error() { + errortext=`format_text "$@"` + debug "Error: %s\n" "${errortext}" + if [ "a${noerror}" != "a" ]; then + debug "Skipping error notification due to configuration.\n" + unset errortext + return 0 + fi + guruplug_error + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_error "${errortext}" + ;; + "9menu") + nine_error "${errortext}" + ;; + "interactive terminal") + term_error "${errortext}" + ;; + "terminal") + term_error "${errortext}" + ;; + *) + term_error "${errortext}" + ;; + esac + unset errortext +} + +cleanscreen() { + osd_cleanscreen + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_cleanscreen + term_clearline + ;; + "9menu") + term_clearline + ;; + "interactive terminal") + term_clearline + ;; + "terminal") + term_clearline + ;; + *) + term_clearline + ;; + esac +} + +osd_cleanscreen() { + if [ "a${OSDPID}" != "a" ]; then + if find_binary "kill"; then + ! notrunning "${OSDPID}" && ${killbin} -1 "${OSDPID}" 2> /dev/null + ! notrunning "${OSDPID}" && ${killbin} -9 "${OSDPID}" 2> /dev/null + fi + unset OSDPID + fi + return 0 +} + +osd_verbose() { + [ "a${OSDOUTPUT}" = "a" ] && return 1 + osd_cleanscreen + case "${OSDOUTPUT}" in + osd_cat) + need_arg "XOSDFONT" + if [ "a${OSDISP}" != "a${ISPID}" ]; then + unset OSDFGCOLOR; unset OSDBGCOLOR; + fi + [ "a${OSDFGCOLOR}" = "a" ] && OSDFGCOLOR=`echo ${ISP_FG_COLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"` + [ "a${OSDBGCOLOR}" = "a" ] && OSDBGCOLOR=`echo ${ISP_BG_COLOR} | ${sedbin} -e "s/^\(..\)\(..\)\(..\)$/rgb:\1\/\2\/\3/g"` + [ "a${OSDFGCOLOR}" = "a" ] && OSDFGCOLOR="rgb:80/ff/80" + [ "a${OSDBGCOLOR}" = "a" ] && OSDBGCOLOR="rgb:00/40/00" + OSDISP="${ISPID}" + export OSDISP; export OSDFGCOLOR; export OSDBGCOLOR; + ${OSDOUTPUT} -T "Sakis3G: $1" -P ${verbosecurrentcount} -b percentage -O 2 -c ${OSDFGCOLOR} -u ${OSDBGCOLOR} -f "${XOSDFONT}" -p bottom -a 0 -d 10 -A center & + OSDPID=$! + eval "disown -a" > /dev/null 2> /dev/null + export OSDPID + [ "a${verbosecurrentcount}" = "a100" ] && sleep 3 + ;; + aosd_cat) + need_arg "AOSDFONT" + ${OSDOUTPUT} -n "${AOSDFONT}" -f 100 -t 2 --input=- -u 10000 -o 3000 < /dev/null 2> /dev/null + export OSDPID + [ "a${verbosecurrentcount}" = "a100" ] && sleep 3 + ;; + esac +} + +verbose() { + need_binary "printf" + if [ "a$1" = "a100" ]; then + verbosecurrentcount=93 + shift + fi + verbosetext=`format_text "$@"` + [ "${verbosecurrentcount}" = "a" ] && verbosecurrentcount=0 + if [ "a${verbosetext}" = "a${lastverbosetext}" ]; then + verbosecurrentcount=`expr ${verbosecurrentcount} + 1`; + guruplug_verbose_same + else + verbosecurrentcount=`expr ${verbosecurrentcount} + 7`; + guruplug_verbose + fi + lastverbosetext="${verbosetext}" + verbosecurrentcount=`echo ${verbosecurrentcount}` + export lastverbosetext + export verbosecurrentcount + debug "Verbosing: %d%% %s\n" "${verbosecurrentcount}" "${verbosetext}" + if [ "a${noverbose}" != "a" ]; then + debug "Skipping verbose due to configuration.\n" + unset verbosetext + return 0 + fi + if [ "a${OSDOUTPUT}" != "a" ]; then + osdtext=`${printfbin} "$@"` + osd_verbose "${osdtext}" + unset osdtext + else + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_verbose "${verbosetext}" + ;; + "9menu") + nine_verbose "${verbosetext}" + ;; + "interactive terminal") + term_verbose "${verbosetext}" + ;; + "terminal") + term_verbose "${verbosetext}" + ;; + *) + term_verbose "${verbosetext}" + ;; + esac + fi + unset verbosetext +} + +notify() { + notificationtext=`format_text "$@"` + debug "Notify: %s\n" "${notificationtext}" + if [ "a${nonotify}" != "a" ]; then + debug "Skipping notification due to configuration.\n" + unset notificationtext + return 0 + fi + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_notify "${notificationtext}" + ;; + "9menu") + nine_notify "${notificationtext}" + ;; + "interactive terminal") + term_notify "${notificationtext}" + ;; + "terminal") + term_notify "${notificationtext}" + ;; + *) + term_notify "${notificationtext}" + ;; + esac + unset notificationtext +} + +balloon_notify() { + notificationtext=`format_text "$@"` + if [ "a${nonotify}" != "a" ]; then + debug "Skipping balloon notification due to configuration: %s\n" "${notificationtext}" + unset notificationtext + return 0 + fi + # File is deleted during release_X_cookie + [ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ] && ${PROVIDER} getfile "files/sakis3g.png" 2> /dev/null > "/tmp/sakis3g.notification.icon.$$.png" + debug "Will display final message using libnotify.\n" + if [ ! -f "/tmp/sakis3g.notification.icon.$$.png" ]; then + debug "Notifying user without icon.\n" + debug run_command "${notify_sendbin} \"Sakis3G\" \"${notificationtext}\"" + else + debug "Notifying user with icon.\n" + debug run_command "${notify_sendbin} --icon=\"/tmp/sakis3g.notification.icon.$$.png\" \"Sakis3G\" \"${notificationtext}\"" + debug run_command "${rmbin} -f \"/tmp/sakis3g.notification.icon.$$.png\"" + fi + unset notificationtext +} + +finalnotify() { + guruplug_notify + if [ "a${prefer_osd}" != "a" -a "a${OSDOUTPUT}" != "a" ]; then + verbose "100" "$@" + elif [ "a${prefer_osd}" = "a" -a "a${balloons}" != "a" -a "a${stick_to_console}" = "a" ] && find_binary "notify-send" && [ "a${DBUS_SESSION_BUS_ADDRESS}" != "a" -a "a${SESSION_MANAGER}" != "a" ]; then + balloon_notify "$@" + else + notify "$@" + fi +} + +translate_selection() { + unset translatedarguments + localcounter=0 + for localargument in "$@" + do + localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}` + if [ "${localcounter}" -eq "1" ]; then + translatedarguments="\"${localargument}\"" + elif [ "${localcounter}" -le "5" ]; then + translatedtext=`translate_text "${localargument}"` + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"` + unset translatedtext + elif [ "${localcounter}" -gt "5" ]; then + verification=`expr \( ${localcounter} / 2 \) \* 2`; verification=`echo ${verification}` + if [ "a${verification}" = "a${localcounter}" ]; then + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"` + else + translatedtext=`translate_text "${localargument}"` + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"` + unset translatedtext + fi + unset verification + fi + done + unset localcounter; unset + eval "user_select \"translated\" ${translatedarguments}" + translatedselection=$? + unset translatedarguments + return ${translatedselection} +} + +translate_confirm() { + unset translatedarguments + localcounter=0 + for localargument in "$@" + do + localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}` + if [ "${localcounter}" -eq "1" ]; then + translatedarguments="\"${localargument}\"" + elif [ "${localcounter}" -le "5" ]; then + translatedtext=`translate_text "${localargument}"` + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"` + unset translatedtext + elif [ "${localcounter}" -gt "5" ]; then + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"` + fi + done + unset localcounter; unset + eval "user_confirm \"translated\" ${translatedarguments}" + translatedselection=$? + unset translatedarguments + return ${translatedselection} +} + +translate_prompt() { + unset translatedarguments + localcounter=0 + for localargument in "$@" + do + localcounter=`expr ${localcounter} + 1`; localcounter=`echo ${localcounter}` + if [ "${localcounter}" -eq "1" ]; then + translatedarguments="\"${localargument}\"" + elif [ "${localcounter}" -le "5" ]; then + translatedtext=`translate_text "${localargument}"` + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"` + unset translatedtext + elif [ "${localcounter}" -gt "5" ]; then + verification=`expr \( ${localcounter} / 2 \) \* 2`; verification=`echo ${verification}` + if [ "a${verification}" = "a${localcounter}" ]; then + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${localargument}"` + else + translatedtext=`translate_text "${localargument}"` + translatedarguments=`${printfbin} "%s \"%s\"" "${translatedarguments}" "${translatedtext}"` + unset translatedtext + fi + unset verification + fi + done + unset localcounter; unset + eval "user_prompt \"translated\" ${translatedarguments}" + translatedselection=$? + unset translatedarguments + return ${translatedselection} +} + +user_confirm() { + unset selection + if [ "a$1" != "atranslated" ]; then + debug "Asking user to confirm: %s\n" "`echo "$@"`" + translate_confirm "$@" + return $? + else + shift + debug "Asking user to confirm: %s\n" "`echo "$@"`" + fi + if [ "$#" -lt 3 ]; then + debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#" + return 99 + fi + variable=`selection_argument variable "$@"` + if [ "a$6" = "areset" -a "a${interactive}" != "a" ]; then + eval unset ${variable}yes + eval unset ${variable}no + else + eval alreadyset=\${${variable}yes} + if [ "a${alreadyset}" != "a" ]; then + debug "Switch %syes is already set.\n" "${variable}" + return 0 + fi + eval alreadyset=\${${variable}no} + if [ "a${alreadyset}" != "a" ]; then + debug "Switch %sno is already set.\n" "${variable}" + return 1 + fi + fi + if voodoo_mode; then + debug "Voodoo-mode is enabled. Will consider it a yes.\n" + eval unset ${variable}no + eval ${variable}yes=1 + eval export ${variable}yes + selection=0 + return 0 + fi + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_confirm "$@" + selection=$? + ;; + "9menu") + nine_confirm "$@" + selection=$? + ;; + "interactive terminal") + interactive_term_confirm "$@" + selection=$? + ;; + "terminal") + term_confirm "$@" + selection=$? + ;; + *) + term_confirm "$@" + selection=$? + ;; + esac + variable=`selection_argument variable "$@"` + if [ "a${selection}" = "a0" ]; then + debug "User answered \"yes\".\n" + eval unset ${variable}no + eval ${variable}yes=1 + eval export ${variable}yes + selection=0 + else + debug "User answered \"no\".\n" + eval unset ${variable}yes + eval ${variable}no=1 + eval export ${variable}no + selection=1 + fi + unset variable + return ${selection} +} + +user_select() { + unset selection + if [ "a$1" != "atranslated" ]; then + debug "Asking user to select: %s\n" "`echo "$@"`" + translate_selection "$@" + return $? + else + shift + debug "Asking user to select: %s\n" "`echo "$@"`" + fi + if [ "$#" -lt 3 ]; then + debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#" + return 99 + fi + variable=`selection_argument variable "$@"` + eval alreadyset=\${${variable}} + if [ "a${alreadyset}" != "a" ]; then + debug "%s=%s\n" "${variable}" "${alreadyset}" + # Check tokens first + for selectioniterator in ${alreadyset} + do + selection_argument invalid "${selectioniterator}" "$@" + selection=$? + if [ "a${selection}" != "a0" -a "a${selection}" != "a" ]; then + debug "User has already selected %s=\"%s\". Returning %d.\n" "${variable}" "${selectioniterator}" "${selection}" + eval export ${variable}="${selectioniterator}" + unset variable; unset alreadyset; unset selectioniterator + return ${selection} + fi + unset selection; + done + unset selectioniterator + # Check whole value then + selection_argument invalid "${alreadyset}" "$@" + selection=$? + if [ "a${selection}" != "a0" -a "a${selection}" != "a" ]; then + debug "User has already selected %s=\"%s\". Returning %d.\n" "${variable}" "${alreadyset}" "${selection}" + eval export ${variable}="${alreadyset}" + unset variable; unset alreadyset + return ${selection} + fi + # Else warn + show_fmt_error "Already selected value %s=\"%s\". Is not valid.\n" "${variable}" "${alreadyset}" + eval unset ${variable} + unset variable; unset alreadyset; + else + debug "Variable %s is not set already.\n" "${variable}" + unset alreadyset; unset variable + fi + if voodoo_mode; then + variable=`selection_argument variable "$@"` + selectioncount=`selection_argument options "$@" | ${wcbin} -l`; selectioncount=`echo ${selectioncount}` + if [ "a${selectioncount}" = "a1" ]; then + selection=1 + eval export ${variable}="`selection_argument option 1 "$@"`" + debug "Employed voodoo-mode in selecting %s from unique option: %s\n" "${variable}" "`eval echo \\${${variable}}`" + unset selectioncount; unset variable + return ${selection} + elif [ "a${selectioncount}" = "a2" ]; then + for selection in 1 2 + do + voodoovalue=`selection_argument option ${selection} "$@" | ${grepbin} -i "custom" | ${wcbin} -l`; voodoovalue=`echo ${voodoovalue}` + [ "a${voodoovalue}" = "a0" ] && voodoovalue=`selection_argument option ${selection} "$@" | ${grepbin} -i "other" | ${wcbin} -l`; voodoovalue=`echo ${voodoovalue}` + if [ "a${voodoovalue}" = "a1" ]; then + debug "Voodoo determined that selection %d leads to custom/other.\n" "${selection}" + if [ "${selection}" -eq "1" ]; then + selection=2 + else + selection=1 + fi + eval export ${variable}="`selection_argument option 1 "$@"`" + debug "Employed voodoo-mode in selecting %s from option %d: %s\n" "${variable}" "${selection}" "`eval echo \\${${variable}}`" + unset selectioncount; unset voodoovalue; unset variable + return ${selection} + fi + unset voodoovalue + done + unset selection + fi + unset selectioncount; unset variable + fi + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_select "$@" + selection=$? + ;; + "9menu") + nine_select "$@" + selection=$? + ;; + "interactive terminal") + interactive_term_select "$@" + selection=$? + ;; + "terminal") + term_select "$@" + selection=$? + ;; + *) + term_select "$@" + selection=$? + ;; + esac + debug "User selection was %d.\n" "${selection}" + return ${selection} +} + +# Prompts user to enter text +user_prompt() { + if [ "a$1" != "atranslated" ]; then + debug "Asking user to enter: %s\n" "`echo "$@"`" + translate_prompt "$@" + return $? + else + shift + debug "Asking user to enter: %s\n" "`echo "$@"`" + fi + if [ "$#" -lt 3 ]; then + debug "FIXME: Wrong number of arguments (%d). Returning 99.\n" "$#" + return 99 + fi + promptvariable=`selection_argument variable "$@"` + eval alreadyset=\${${promptvariable}} + if [ "a${alreadyset}" != "a" ]; then + selection=0 + debug "%s=%s\n" "${promptvariable}" "${alreadyset}" + debug "User has already entered %s=\"%s\". Returning %d.\n" "${promptvariable}" "${alreadyset}" "${selection}" + unset alreadyset; unset promptvariable + return ${selection} + else + debug "Variable %s is not set already.\n" "${promptvariable}" + unset alreadyset; unset promptvariable + fi + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + dialog_prompt "$@" + selection=$? + ;; + "9menu") + nine_prompt "$@" + selection=$? + ;; + "interactive terminal") + interactive_term_prompt "$@" + selection=$? + ;; + "terminal") + term_prompt "$@" + selection=$? + ;; + *) + term_prompt "$@" + selection=$? + ;; + esac + promptvariable=`selection_argument variable "$@"` + eval "alreadyset=\"\${${promptvariable}}\"" + debug "New value is %s=\"%s\". Returning %d.\n" "${promptvariable}" "${alreadyset}" "${selection}" + unset alreadyset; unset promptvariable + return ${selection} +} + +# Stops execution with return status $1 +stop_with() { + verbose "Cleaning" + if [ "a$1" = "a" ]; then + debug "Stopping operation with return status: %d\n" "99" + exit 99 + else + debug "Stopping operation with return status: %d\n" "$1" + exit $1 + fi +} + +# Shows error and aborts execution +stop_fmt_error() { + errorcode="$1" + [ "$#" -gt "0" ] && shift + show_fmt_error "$@" + stop_with ${errorcode} +} + + +# Make sure usual binary containing directories exist in PATH, even +# if not running as root. Some distributions do not include those +# folders in PATH (although they contain some useful user oriented +# utilities) if not running as root, or if not running from an +# interactive shell. +fix_path() { + [ -n "${PATHFIXXED}" ] && return 0 + for fixpathi in "/bin" "/usr/bin" "/sbin" "/usr/sbin" + do + if strinstr "${fixpathi}" "${PATH}"; then + debug "Dir \"%s\" exists in PATH.\n" "${fixpathi}" + else + export PATH="${fixpathi}:${PATH}" + debug "Added \"%s\" to PATH.\n" "${fixpathi}" + fi + done + unset fixpathi + PATHFIXXED=YES + debug "Done setting up PATH.\n" +} + + +# Locates full path of binary specified in argument +find_binary() { + [ "a$1" = "a" ] && return 1 + binaryvariable=`echo "$1" | sed -e "s/-/_/g"` + binaryvariable=`echo "${binaryvariable}" | sed -e "s/9/nine/g"` + [ "a${binaryvariable}" = "a" ] && binaryvariable="$1" + findbinaryfound=`eval echo \\\${${binaryvariable}bin}` + if [ "a${findbinaryfound}" = "a" ]; then + if [ "a${whichbin}" = "a" ]; then + findbinaryfound=`which which 2> /dev/null` + elif [ ! -x "${whichbin}" ]; then + findbinaryfound=`which which 2> /dev/null` + else + findbinaryfound="${whichbin}" + fi + if [ "a${findbinaryfound}" = "a" ]; then + debug "Unable to locate \"%s\" within PATH, because \"%s\" utility is not available.\n" "$1" "which" + unset findbinaryfound + return 1 + else + if [ -z "${whichbin}" ]; then + export whichbin="${findbinaryfound}" + debug "Can search through PATH, \"%s\" binary found.\n" "which" + fi + findbinaryfound=`${findbinaryfound} "${1}" 2> /dev/null` + if [ "a${findbinaryfound}" = "a" ]; then + debug "Unable to locate \"%s\" within PATH.\n" "$1" + unset findbinaryfound + return 1 + elif [ -x "${findbinaryfound}" ]; then + debug "Located \"%s\" within PATH (%s).\n" "$1" "${findbinaryfound}" + eval export ${binaryvariable}bin="${findbinaryfound}" + fi + fi + fi + if [ -x "${findbinaryfound}" ]; then + unset findbinaryfound + return 0 + else + debug "Unable to execute \"%s\" from \"%s\".\n" "$1" "${findbinaryfound}" + unset findbinaryfound + eval unset ${binaryvariable}bin + return 1 + fi +} + +# Aborts execution if "$1" binary is not found. +need_binary() { + [ "a$1" = "a" ] && term_error "FIXME: Executed need_binary with no argument." + ! find_binary "$1" && stop_fmt_error 4 "Unable to locate dependency \"%s\". Script will now abort." "$1" +} + +# Check dependencies. Only really required staff should be placed here. +# We cannot yet search in PATH. +check_level_one_deps() { + for checkdependency in which echo grep + do + need_binary "${checkdependency}" + done + unset checkdependency + debug "Level 1 dependencies met.\n" +} + +# Checks if communication software is available and aborts if not +check_com_software() { + ! find_binary "wvdial" && direct_pppd=yes + if [ -n "${direct_pppd}" ]; then + need_binary "pppd" + need_arg "PPPD_PEERS" + if [ ! -d "${PPPD_PEERS}" ]; then + debug "Unable to locate pppd peers directory (%s)." "${pppdpeerdir}" + fi + fi + for checkdependency in chat + do + need_binary "${checkdependency}" + done + unset checkdependency + return 0 +} + +# Checks if method for becoming root, exists. +check_su_software() { + unset SUMETHOD + if [ -z "${alwayssudo}" ]; then + if [ -z "${stick_to_console}" ]; then + if find_binary "gksu"; then + debug "Running on a GNOME system.\n" + SUMETHOD="gksu" + elif find_binary "kdesu"; then + debug "Running on a KDE system.\n" + SUMETHOD="kdesu" + elif [ -x "/usr/lib/kde4/libexec/kdesu" ]; then + export kdesubin="/usr/lib/kde4/libexec/kdesu" + debug "Running on a KDE4 system.\n" + SUMETHOD="kdesu" + fi + fi + if [ -z "${SUMETHOD}" ]; then + if find_binary "su"; then + debug "Using plain text mode su.\n" + SUMETHOD="su" + else + debug "No su method found. Will check if sudo available.\n" + export alwayssudo=yes + fi + fi + fi + if [ -n "${alwayssudo}" ]; then + ! find_binary "sudo" && stop_fmt_error 3 "No method for acquiring root privileges found." + debug "Running with sudo configuration.\n" + SUMETHOD="sudo" + fi + return 0 +} + +# Forces use of text mode utilities for getting root privileges +console_su_software() { + if [ "${SUMETHOD}" = "kdesu" -o "${SUMETHOD}" = "gksu" ]; then + if find_binary "su"; then + debug "Reverting to plain text mode su.\n" + SUMETHOD="su" + else + debug "No text mode su found. Will check if sudo available.\n" + export alwayssudo=yes + check_su_software + fi + fi +} + + +# Check dependencies. Only really required staff should be placed here. +# We can now search within path. +check_level_two_deps() { + for checkdependency in printf wc cut cat tail head sort uniq ls sed setsid getent ps chmod chown touch expr tr seq cp rm who mv expr basename dirname + do + need_binary "${checkdependency}" + done + unset checkdependency + debug "Level 2 dependencies met.\n" + if [ "a${PROVIDER}" != "a" ] && [ ! -x "${PROVIDER}" ]; then + debug run_command "${chmodbin} +x \"${PROVIDER}\"" + if [ ! -x "${PROVIDER}" ]; then + stop_fmt_error 5 "Unable to determine my path.\n" + fi + debug "Successfully turned myself an executable.\n" + fi +} + +# If running as root, checks dependencies that should be met +# once running as root. If not running as root, checks if +# software for becoming root, is available. +check_root_deps() { + if ! we_are_root_already; then + check_su_software + else + for checkdependency in ifconfig + do + need_binary "${checkdependency}" + done + unset checkdependency + fi + debug "Root level dependencies met.\n" +} + +# Locate required utilities within PATH +resolv_binaries() { + check_level_one_deps + fix_path + get_me ${1} + check_level_two_deps + debug "Basic binaries are resolved.\n" +} + +# Provides a writable log position +need_log() { + need_arg "LOGPOSITION" + for logcandidate in "${LOGPOSITION}" "/var/log/sakis3g.log" "sakis3g.log.$$" "/tmp/sakis3g.log.$$" + do + if [ "a${logcandidate}" != "a" ]; then + ${touchbin} "${logcandidate}" 2> /dev/null + if [ -w "${logcandidate}" ]; then + export LOGPOSITION="${logcandidate}" + debug "Log file is set to \"%s\".\n" "${LOGPOSITION}" + return 0 + else + unset logposition + fi + fi + done + debug "Failed to find a place to store log.\n" + export LOGPOSITION="/dev/null" + debug "Log file is set to \"%s\".\n" "${logposition}" + return 1 +} + +# Returns true(0) if process with PID given as +# argument, is not running any more. +notrunning() { + if [ -n "$1" ]; then + pidrunning=`${psbin} -p $1 -o pid= 2> /dev/null | wc -l` + pidrunning=`echo ${pidrunning}` + else + pidrunning=1 + fi + if [ "${pidrunning}" -ne "0" ]; then + debug "PID %s is still running.\n" "$1" + else + debug "PID %s is not running any more.\n" "$1" + fi + return ${pidrunning} +} + +# Sets PPROCESS variable +get_parent_process() { + pidtocheck=$1 + [ "a${pidtocheck}" = "a" ] && pidtocheck="${PPID}" + PPROCESS=`${psbin} -p ${pidtocheck} -o comm= 2> /dev/null` + export PPROCESS + if [ "a${PPROCESS}" = "a" ]; then + debug "Unable to get parent process name.\n" + unset PPROCESS; unset pidtocheck + return 1 + fi + unset pidtocheck + return 0 +} + +# Check if called by udevd. If yes, spawn in background +# and exit this instance. +check_udevd() { + if [ "a${PROVIDER}" = "a" ]; then + get_parent_process + else + pppid=`${psbin} -p ${PPID} -o ppid= 2> /dev/null` + pppid=`echo ${pppid}` + get_parent_process "${pppid}" + unset pppid + fi + debug "Parent process is: %s\n" "${PPROCESS}" + if [ "a${PPROCESS}" = "audevd" ]; then + debug "Running by a udevd event.\n" + need_log + if have_me; then + debug "Unconditionally setting DISPLAY to :0.\n" + export DISPLAY=:0 + debug "Will now spawn child process in background.\n" + ${ME} "$@" > "${LOGPOSITION}" 2>&1 & + stop_with 0 + fi + else + debug "Running by user request.\n" + fi +} + +# Get my location if possible +get_me() { + unset metarget + [ -x "${PROVIDER}" ] && metarget="${PROVIDER}" + [ -z "${metarget}" ] && metarget="$1" + find_binary "readlink" && ME=`${readlinkbin} -e ${metarget} 2> /dev/null` + [ -z "${ME}" ] && find_binary "which" && ME="`${whichbin} ${metarget} 2> /dev/null`" + unset metarget + [ -n "${ME}" ] && [ ! -x "${ME}" ] && unset ME + if [ -z "${ME}" ]; then + unset ME + debug "Unable to determine my own location.\n" + else + debug "My location is \"%s\".\n" "${ME}" + fi + +} + +# Makes sure we know our own executable +have_me() { + [ -n "${ME}" ] && [ -x "${ME}" ] && return 0; + stop_fmt_error 5 "Unable to determine my path.\n" +} + +# If we are root, attempts to determine real user +# behind it, by looking back the process tree. Goes +# back 15 processes before giving up. +resolv_root() { + [ -z "$1" ] && pid=$$ + [ -z "${pid}" ] && pid=$1 + puser=`${psbin} -p ${pid} -o user= 2> /dev/null` + if [ -z "${puser}" ]; then + unset pid; unset puser + return + elif [ "${puser}" != "root" ]; then + runner="${puser}" + unset pid; unset puser + return + fi + unset puser + ppid=`${psbin} -p ${pid} -o ppid= 2> /dev/null`; unset pid + if [ -z "${ppid}" ]; then + unset ppid + return + elif [ "a${ppid}" = "a1" ]; then + unset ppid + return + fi + [ -z "$2" ] && count=0 + count=`expr $2 + 1` + count=`echo ${count}` + [ "$count" -lt 15 ] && resolv_root ${ppid} ${count} + unset ppid; unset count +} + +# Locates really running user. If root, attempts to resolv +# it to real user. +find_user() { + unset runner; unset runhome + [ -n "${USER}" ] && runner="${USER}" + [ -n "${LOGNAME}" ] && runner="${LOGNAME}" + [ -n "${USERNAME}" ] && runner="${USERNAME}" + [ -z "${runner}" ] && find_binary "who" && runner=`${whobin} -m | ${cutbin} -d\ -f1` + [ -z "${runner}" ] && we_are_root_already && runner="root" + [ -n "${runner}" ] && [ "${runner}" = "root" ] && resolv_root $$ 0 + if [ -n "${runner}" ]; then + runhome=`${getentbin} passwd ${runner} 2> /dev/null | ${cutbin} -d: -f6` + [ -n "${runhome}" ] && [ ! -d "${runhome}" ] && unset runhome + [ -z "${runhome}" ] && unset runner + [ -n "${runner}" ] && debug "Person behind screen is %s.\n" "${runner}" + fi + [ -z "${runner}" ] && debug "Unable to find our username.\n" +} + +# Determines if display $1 is unique local display. +unique_local_display() { + debug "Will check if display %s belongs to unique user logged in.\n" "$1" + [ "a$1" = "a" ] && return 1 + ! find_binary "who" && return 1 + loggedusers=`${whobin} | ${grepbin} -v root | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin} | ${wcbin} -l` + loggedusers=`echo ${loggedusers}` + if [ "a${loggedusers}" != "a1" ]; then + debug "Found %d logged users. Cannot make sure who will really see message.\n" "${loggedusers}" + unset loggedusers + return 1 + fi + unset loggedusers + loggeduser=`${whobin} | ${grepbin} -v root | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin}` + confirm=`${whobin} | ${grepbin} ${1} | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin} | ${grepbin} "^${loggeduser}$"` + if [ "a${loggeduser}" = "a${confirm}" ]; then + debug "Unique display %s belongs to user %s.\n" "$1" "${loggeduser}" + unset confirm; unset loggeduser; + return 0 + fi + debug "Display %s does not belongs to user %s.\n" "$1" "${loggeduser}" + unset confirm; unset loggeduser; + return 1 +} + +# Attemtps to get access to display $1 +access_display() { + debug "Will attempt to get access to display %s.\n" "$1" + [ "a$1" = "a" ] && return 1 + ! find_binary "xauth" && return 1 + [ "a${XAUTHORITY}" = "a" ] && unset XAUTHORITY + gotaccess=`${xauthbin} nlist $1 2> /dev/null | ${wcbin} -l` + gotaccess=`echo ${gotaccess}` + if [ "a${gotaccess}" = "a0" ]; then + xuser=`${whobin} -u | ${grepbin} -v "^root" | ${grepbin} ${1} | ${cutbin} -d\ -f1 | ${sortbin} | ${uniqbin}` + xhome=$(${getentbin} passwd ${xuser} | ${cutbin} -d: -f6) + debug "Not currently trusted to display %s belonging to %s.\n" "${1}" "${xuser}" + if [ "a${LOCALAUTHORITY}" != "a" ] && [ -r "${LOCALAUTHORITY}" ]; then + xholder="${LOCALAUTHORITY}" + elif [ -d "${xhome}" ] && [ -r "${xhome}/.Xauthority" ]; then + xholder="${xhome}/.Xauthority" + else + unset xholder + fi + if [ "a${xholder}" = "a" ]; then + debug "Unable to locate Xauthority file of %s.\n" "${xuser}" + else + debug "Will attempt to steal cookie from %s.\n" "${xholder}" + if [ "a${HOME}" = "a" ]; then + rruser="${runner}" + we_are_root_already && rruser="root" + rrhome=$(${getentbin} passwd ${rruser} | ${cutbin} -d: -f6) + if [ -d "${rrhome}" -a "a${xhome}" != "a${rrhome}" ]; then + debug "HOME variable not set already. Setting HOME for %s: %s\n" "${rruser}" "${rrhome}" + export HOME="${rrhome}" + fi + unset rruser; unset rrhome; + else + debug "HOME directory set already (%s).\n" "${HOME}" + fi + ${xauthbin} -f "${xholder}" nextract - $1 2> /dev/null | ${xauthbin} nmerge - 2> /dev/null + gotaccess=`${xauthbin} nlist ${1} 2> /dev/null | ${wcbin} -l` + gotaccess=`echo ${gotaccess}` + if [ "a${gotaccess}" = "a0" ]; then + debug "Failed to steal cookie.\n" + else + debug "Cookie stolen from %s(%s) to %s.\n" "${xuser}" "${1}" "${HOME}/.Xauthority" + export XCOOKIE="$1" + addexittrap "release_X_cookie" EXIT + unset xuser; unset xhome; unset gotaccess; unset xholder + return 0 + fi + fi + unset xuser; unset xhome; unset gotaccess; unset xholder + else + debug "Already granted access to display %s.\n" "${1}" + [ "a${XAUTHORITY}" != "a" ] && export LOCALAUTHORITY="${XAUTHORITY}" + unset gotaccess + return 0 + fi + return 1 +} + +# Find DISPLAY +find_display() { + if [ -n "${stick_to_console}" ]; then + unset DISPLAY; unset display; + debug "Not using an X display due to stick-to-console variable.\n" + else + display="${DISPLAY}" + # If display is not set, or is remote, attempt to find a local display of runner user. + [ -z "${DISPLAY}" -o "`echo ${DISPLAY} | ${cutbin} -b1`" != ":" ] \ + && display="" \ + && [ -n "${runner}" -a "a${runner}" != "aroot" ] \ + && find_binary "who" \ + && display=`${whobin} -m | ${grepbin} "^${runner}" | ${grepbin} "(\:.*)" | ${cutbin} -d\( -f2 | ${cutbin} -d\) -f1 | ${sortbin} | ${headbin} -1` + # If DISPLAY is set to a local display, but we are run + # from root himself, and that X display is the unique + # local X display available, use it no matter what. + [ -n "${display}" -a -n "${DISPLAY}" -a "a${runner}" = "aroot" ] \ + && ! unique_local_display "${DISPLAY}" && unset display + # Get number of display (if any) + displaynum=`echo ${display} | ${cutbin} -b2- | ${cutbin} -d. -f1` + display=":${displaynum}" + # Validate that determined xsession exists. + [ ! -S "/tmp/.X11-unix/X${displaynum}" ] && unset display + unset displaynum + [ -n "${display}" ] && ! access_display "${display}" && unset display + if [ -z "${display}" ]; then + debug "Unable to find a local X display, will stick to terminal.\n" + unset DISPLAY; unset display; + export stick_to_console=yes + find_gui + else + export display + export DISPLAY="${display}" + fi + fi + if [ -z "${display}" ]; then + unset DISPLAY; unset display; + export stick_to_console=yes + console_su_software + else + debug "Will be using display %s.\n" "${display}" + fi +} + +# Selects GUI to be used if not already set by SGUI variable. +find_gui() { + debug "Selecting GUI.\n" + if [ -n "${stick_to_console}" -a -n "$SGUI" ]; then + debug "Validating pre-selected GUI: %s\n" "${SGUI}" + [ "a$SGUI" = "azenity" ] && unset SGUI + [ "a$SGUI" = "agdialog" ] && unset SGUI + [ "a$SGUI" = "akdialog" ] && unset SGUI + [ "a$SGUI" = "aXdialog" ] && unset SGUI + [ "a$SGUI" = "a9menu" ] && unset SGUI + [ "a$SGUI" = "agnome-terminal" ] && unset SGUI + [ "a$SGUI" = "akonsole" ] && unset SGUI + [ "a$SGUI" = "axterm" ] && unset SGUI + [ -z "${SGUI}" ] && debug "Could not be used from console. Will seek an alternative.\n" + fi + if [ "a${SGUI}" != "a" -a "a${SGUI}" != "ainteractive terminal" -a "a${SGUI}" != "aterminal" ] && ! find_binary "${SGUI}"; then + debug "%s not found. Will search for another GUI provider.\n" "${SGUI}" + unset SGUI + fi + if [ "a${stick_to_console}" = "a" ]; then + [ "a${SGUI}" = "a9menu" ] && ! find_binary "9menu" && unset SGUI + [ "a${SGUI}" = "a9menu" ] && ! find_binary "xterm" && unset SGUI + [ -z "${SGUI}" ] && find_binary "kdialog" && SGUI="kdialog" + [ -z "${SGUI}" ] && find_binary "zenity" && SGUI="zenity" + [ -z "${SGUI}" ] && find_binary "Xdialog" && SGUI="Xdialog" + [ -z "${SGUI}" ] && find_binary "gnome-terminal" && SGUI="gnome-terminal" + [ -z "${SGUI}" ] && find_binary "konsole" && SGUI="konsole" + [ -z "${SGUI}" ] && find_binary "xterm" && SGUI="xterm" + if [ -z "${SGUI}" ]; then + debug "No graphical GUI found. Forced to stick to terminal.\n" + export stick_to_console=yes + fi + fi + if [ "a${interactive}" != "a" ]; then + [ -z "${SGUI}" ] && find_binary "dialog" && SGUI="dialog" + [ -z "${SGUI}" ] && find_binary "whiptail" && SGUI="whiptail" + [ -z "${SGUI}" ] && SGUI="interactive terminal" + fi + [ -z "${SGUI}" ] && SGUI="terminal" + # Custom setup per GUI + [ "a${SGUI}" = "adialog" ] && addexittrap "dialog_clearscreen" + [ "a${SGUI}" = "aXdialog" -o "a${SGUI}" = "a9menu" ] && export notranslate=yes && unset foldwrapping && need_arg "foldwrapping" + [ "a${SGUI}" = "adialog" -o "a${SGUI}" = "awhiptail" -o "a${SGUI}" = "aterminal" -o "a${SGUI}" = "ainteractive terminal" ] && export stick_to_console=yes + [ "a${SGUI}" = "adialog" -o "a${SGUI}" = "awhiptail" -o "a${SGUI}" = "ainteractive terminal" -o "a${SGUI}" = "aXdialog" -o "a${SGUI}" = "azenity" -o "a${SGUI}" = "akdialog" -o "a${SGUI}" = "a9menu" ] && export interactive=yes + debug "%s selected as GUI.\n" "${SGUI}" + # Forward to terminal if have to do so + case "${SGUI}" in + xterm) + debug "Will spawn xterm window.\n" + unset SGUI; export stick_to_console=yes; export interactive=yes; + state_variables + eval ${xtermbin} -T "Sakis3G" +cm +dc -e ${ME} ${allargs} ${statevariables} + stop_with $? + ;; + gnome-terminal) + debug "Will spawn gnome-terminal window.\n" + unset SGUI; export stick_to_console=yes; export interactive=yes; + state_variables + eval ${gnome_terminalbin} -t "Sakis3G" -x ${ME} ${allargs} ${statevariables} + stop_with $? + ;; + konsole) + debug "Will spawn konsole window.\n" + unset SGUI; export stick_to_console=yes; export interactive=yes; + state_variables + eval ${konsolebin} --title "Sakis3G" -e "${ME} ${allargs} ${statevariables}" + stop_with $? + ;; + esac + # Check for OSD + unset OSDOUTPUT + if [ "a${stick_to_console}" = "a" -a "a${prefer_osd}" != "a" ]; then + if find_binary "osd_cat"; then + export OSDOUTPUT="osd_cat" + elif find_binary "aosd_cat"; then + export OSDOUTPUT="aosd_cat" + fi + [ "a${OSDOUTPUT}" != "a" ] && debug "Will be using \"%s\" for displaying OSD messages.\n" "${OSDOUTPUT}" + fi + [ "a${prefer_osd}" != "a" -a "a${OSDOUTPUT}" = "a" ] && unset prefer_osd && debug "OSD will not appear.\n" + return 0 +} + +# Checks if module $1 is loaded +module_loaded() { + [ "a$1" = "a" ] && return 99 + unset moduleloaded + debug "Checking if module \"%s\" is currently loaded.\n" "$1" + if [ -r "/proc/modules" ]; then + moduleloaded=`${grepbin} "^$1 " "/proc/modules" 2> /dev/null | ${sedbin} -e "s/^$1 \([0-9][0-9]*\) \([0-9][0-9]*\) \(.*\)$/\1 \3/g"` + if [ "a${moduleloaded}" = "a" ]; then + debug "Module \"%s\" is not currently loaded.\n" "$1" + unset moduleloaded + return 1 + elif [ "a${moduleloaded}" = "a$1 0" ]; then + debug "Module \"%s\" is currently loaded having no users.\n" "$1" + unset moduleloaded + return 0 + else + debug "Module \"%s\" is currently loaded and occupied.\n" "$1" + unset moduleloaded + return 0 + fi + elif find_binary "lsmod"; then + moduleloaded=`${lsmodbin} | ${grepbin} "^$1 " | ${wcbin} -l`; moduleloaded=`echo ${moduleloaded}` + if [ "a${moduleloaded}" = "a" -o "a${moduleloaded}" = "a0" ]; then + debug "Module \"%s\" is not currently loaded.\n" "$1" + unset moduleloaded + return 1 + else + debug "Module \"%s\" is currently loaded.\n" "$1" + unset moduleloaded + return 0 + fi + else + show_fmt_error "Unable to check if module is currently loaded or if it has users.\n" + return 1 + fi +} + +# Unloads module from system if possible +module_unload() { + [ "a$1" = "a" ] && return 99 + ! module_loaded "$1" && return 0 + ! find_binary "modprobe" && return 1 + debug "Attempting to unload module \"%s\".\n" "$1" + debug run_command "${modprobebin} -r -v $1" + debug "Waiting for module to vanish.\n" + if module_loaded "$1"; then + show_fmt_error "Failed to unload module \"%s\".\n" "$1" + return 1 + else + debug "Module \"%s\" succesfully unloaded.\n" "$1" + return 0 + fi +} + +# Loads module $1 if possible, providing arguments for device $2 if applicable +module_load() { + [ "a$1" = "a" ] && return 99 + module_loaded "$1" && return 0 + ! find_binary "modprobe" && return 1 + debug "Attempting to load module \"%s\".\n" "$1" + need_arg "SERIALDRIVERS" + needsarg=`echo " ${SERIALDRIVERS} " | ${grepbin} " $1 " | ${wcbin} -l`; needsarg=`echo ${needsarg}` + if [ "a${needsarg}" = "a1" -a "a$2" != "a" ]; then + if usb_device_connected "$2"; then + modulevend=`echo "$2" | ${cutbin} -d: -f1` + moduleprod=`echo "$2" | ${cutbin} -d: -f2` + modargs="vendor=0x${modulevend} product=0x${moduleprod}" + unset modulevend; unset moduleprod + debug "Will provide arguments to \"%s\": %s\n" "$1" "${modargs}" + else + debug "Warning: Module \"%s\" needs arguments, but \"%s\" does not refer to a connected device.\n" "$1" "$2" + unset modargs + fi + elif [ "a${needsarg}" = "a1" ]; then + debug "Warning: Module \"%s\" needs arguments but device was not specified.\n" "$1" + unset modargs + fi + debug run_command "${modprobebin} $1 ${modargs}" + debug "Waiting for module to get loaded.\n" + unset modargs; unset needsarg + counter=0 + while [ "${counter}" -lt "6" ] + do + if ! module_loaded "$1"; then + debug "Module \"%s\" still not live. Waiting a second.\n" "$1" + sleep 1 + fi + if module_loaded "$1"; then + debug "Module \"%s\" succesfully loaded.\n" "$1" + unset counter + return 0 + fi + counter=`expr ${counter} + 1`; counter=`echo ${counter}` + done + unset counter + show_fmt_error "Failed to load module \"%s\".\n" "$1" + return 1 +} + +# Attempts to detach driver $1 from device $2 interface $3 +# If failed to detach, attempts to completely unload $1 before failing. +module_unbind() { + [ "a$1" = "a" ] && return 99 + verbose "Unloading driver %s" "$1" + if [ "a$2" = "a" -a "a$3" = "a" ]; then + debug "Requested to unbind module \"%s\" without device specified. Will try to unload it.\n" "$1" + module_unload "$1" + return $? + fi + moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "$1" | ${wcbin} -l` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + moduleattached=`echo ${moduleattached}` + if [ "a${moduleattached}" = "a" -o "a${moduleattached}" = "a0" ]; then + debug "Module \"%s\" does not appear to be attached to device \"%s\".\n" "$1" "$2" + unset moduleattached + return 0 + fi + debug "Module \"%s\" is currently attached to \"%s\".\n" "$1" "$2" + [ "a$3" != "a" ] && usb_sysfsdir_int "$2" "$3" && unbindvalue=`${basenamebin} ${sysfsintloc}` + [ "a$3" = "a" ] && usb_sysfsdir && unbindvalue=`cd "${sysfsloc}"; ${lsbin} -1d \`${basenamebin} ${sysfsloc}\`*` + [ "a${unbindvalue}" = "a" ] && unbindvalue=`echo "$2" | ${sedbin} -e "s/:/ /g"` + sent=0 + [ "a$1" = "ausb_storage" ] && localdrivername="usb-storage" + for endpoint in /sys/bus/usb/drivers/${localdrivername}/unbind /sys/bus/usb/drivers/$1/unbind + do + for destination in ${unbindvalue} + do + if [ -w "${endpoint}" ]; then + echo -n "${destination}" > "${endpoint}" 2> /dev/null + debug "Sent \"%s\" to \"%s\".\n" "${destination}" "${endpoint}" + sent=1 + fi + done + unset destination + done + unset unbindvalue; unset endpoint; unset localdrivername + if [ "${sent}" -eq "1" ]; then + debug "Expecting module to detach from device.\n" + while [ "${sent}" -lt "6" ] + do + unset moduleattached + moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "$1" | ${wcbin} -l` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + break + fi + moduleattached=`echo ${moduleattached}` + if [ "a${moduleattached}" = "a" -o "a${moduleattached}" = "a0" ]; then + debug "Module \"%s\" has detached from device \"%s\".\n" "$1" "$2" + unset moduleattached; unset sent + if find_binary "modprobe"; then + if [ "a$1" != "ausb_storage" -a "a$1" != "ausb-storage" ]; then + debug "Will attempt to also remove it.\n" + debug run_command "${modprobebin} -r -v $1" + module_loaded "$1" + fi + fi + return 0 + fi + debug "Module still attached. Waiting for %d second(s).\n" "${sent}" + sent=`expr ${sent} + 1`; sent=`echo ${sent}` + sleep 1 + done + debug "Module \"%s\" did not detach from device \"%s\". Will try to unload it.\n" "$1" "$2" + fi + module_unload "$1" + return $? +} + +# Attempts to bind module $1 to device $2, interface $3 (optional) +module_bind() { + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + verbose "Loading driver %s" "$1" + module_load "$1" "$2" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + unset moduleattached + modulename="$1" + [ "a${modulename}" = "ausb-storage" ] && modulename="usb_storage" + [ "a${modulename}" = "acdc-acm" ] && modulename="cdc_acm" + moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + moduleattached=`echo ${moduleattached}` + if [ "a${moduleattached}" != "a" -a "a${moduleattached}" != "a0" ]; then + debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2" + unset moduleattached; unset sent; unset modulename + return 0 + fi + unset moduleattached + debug "Module \"%s\" not yet attached to \"%s\".\n" "$1" "$2" + bindvalue=`echo "$2" | ${sedbin} -e "s/:/ /g"` + sent=0 + for endpoint in /sys/module/${modulename}/drivers/usb-serial:*/new_id + do + if [ -w "${endpoint}" ]; then + echo -n "${bindvalue}" > "${endpoint}" 2> /dev/null + if [ "$?" -eq "0" ]; then + debug "Sent \"%s\" to \"%s\".\n" "${bindvalue}" "${endpoint}" + sent=1 + fi + fi + done + if [ "a${sent}" != "a1" ]; then + for endpoint in /sys/module/${modulename}/drivers/usb:*/new_id + do + echo -n "${bindvalue}" > "${endpoint}" 2> /dev/null + if [ "$?" -eq "0" ]; then + debug "Sent \"%s\" to \"%s\".\n" "${bindvalue}" "${endpoint}" + sent=1 + fi + done + fi + unset bindvalue; unset endpoint + if [ "a${sent}" = "a1" ]; then + counter=0 + while [ "${counter}" -lt "10" ] + do + moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + break; + fi + moduleattached=`echo ${moduleattached}` + if [ "a${moduleattached}" != "a1" ]; then + debug "Waiting one second.\n" + sleep 1 + fi + moduleattached=`usb_loaded_driver "$2" "$3" | ${tailbin} -1 | ${grepbin} "${modulename}" | ${wcbin} -l` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + break; + fi + moduleattached=`echo ${moduleattached}` + if [ "a${moduleattached}" != "a" -a "a${moduleattached}" != "a0" ]; then + debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2" + unset moduleattached; unset sent; unset counter; unset modulename + return 0 + fi + unset moduleattached + counter=`expr ${counter} + 1`; counter=`echo ${counter}` + done + unset counter + fi + debug "Module \"%s\" did not bind to device \"%s\".\n" "$1" "$2" + if [ "a$4" != "anoreload" ]; then + debug "Will attempt to do a reload cycle.\n" + if module_unload "$1" "$2" "$3"; then + if module_bind "$1" "$2" "$3" "noreload"; then + unset counter; unset sent; unset moduleattached; unset modulename + debug "Reload cycle did the trick.\n" + debug "Module \"%s\" attached to device \"%s\".\n" "$1" "$2" + return 0 + else + return $? + fi + fi + fi + unset moduleattached; unset modulename + if [ "${sent}" -eq "0" ]; then + show_fmt_error "Module \"%s\" loaded but did not bind to device \"%s\".\n" "$1" "$2" + else + show_fmt_error "Module \"%s\" loaded but refused to bind to device \"%s\".\n" "$1" "$2" + fi + unset sent; unset counter + return 1 + return 99 +} + +# Unlocks a previously acquired lock to hal +hal_unlock() { + [ "a${nohal}" != "a" ] && return 0 + [ "a${HAL_LOCK}" = "a" ] && return 0 + debug "Releasing HAL lock %d.\n" "${HAL_LOCK}" + if notrunning "${HAL_LOCK}"; then + debug "Already unlocked.\n" + else + if [ -f "/tmp/sakis3g.hal.lock.$$" ]; then + ${rmbin} -f "/tmp/sakis3g.hal.lock.$$" + sleep 2 + fi + if ! notrunning "${HAL_LOCK}"; then + debug "Failed to unlock by unlinking mutex file. Will try to kill.\n" + term_clearline + ${killbin} -1 ${HAL_LOCK} 2> /dev/null + if ! notrunning "${HAL_LOCK}"; then + debug "Failed to kill PID %d.\n" "${HAL_LOCK}" + return 1 + fi + fi + debug "Unlocked.\n" + fi + unset HAL_LOCK + return 0 +} + +# Attempts to establish lock of interface $1 (i.e. org.freedesktop.Hal.Device.Storage) +hal_acquire_lock() { + [ "a${nohal}" != "a" ] && return 0 + [ "a${HAL_LOCK}" != "a" ] && ! hal_unlock && return 1 + ! find_binary "hal-lock" && return 1 + ! find_binary "kill" && return 1 + ! find_binary "touch" && return 1 + ! we_are_root && return 1 + debug "Acquiring lock in HAL for \"%s\".\n" "$1" + ${touchbin} "/tmp/sakis3g.hal.lock.$$" + hal-lock --interface "$1" --exclusive --run "${ME} holdlock /tmp/sakis3g.hal.lock.$$" & + halpid=$!; unset informed + while ! notrunning ${halpid} + do + hallocksuccess=`${catbin} "/tmp/sakis3g.hal.lock.$$" 2> /dev/null`; hallocksuccess=`echo ${hallocksuccess} | ${sedbin} -e "s/ //g"` + if [ "a${hallocksuccess}" = "a" ]; then + unset hallocksuccess + [ "a${informed}" = "a" ] && verbose "Acquiring exclusive lock to HAL" + informed=`expr ${informed} + 1`; informed=`echo ${informed}` + if [ "${informed}" -le "20" ]; then + debug "Waiting for spawned process to acquire lock (%d secs will have passed).\n" "${informed}" + sleep 1 + else + debug "Giving up waiting for lock to occur. Will try to terminate current lock attempt.\n" + export HAL_LOCK=${halpid} + hal_unlock; unset HAL_LOCK + break + fi + else + debug "Exclusive lock granted to PID %d.\n" "${hallocksuccess}" + break; + fi + done + if [ "a${hallocksuccess}" != "a" ]; then + export HAL_LOCK=${halpid} + addexittrap hal_unlock + debug "Succesfully locked HAL interface \"%s\" (hal-lock itself running with PID %d).\n" "$1" "${HAL_LOCK}" + unset halpid; unset informed; unset hallocksuccess + return 0 + fi + unset halpid; unset informed; unset hallocksuccess + debug "Failed to acquire exclusive lock to %s.\n" "$1" + return 1 +} + +# Makes sure that only one instance of $3 is contained within +# list $2 of hal udi $1. +hal_add_to_list() { + ! find_binary "hal-get-property" && return 1 + ! find_binary "hal-set-property" && return 1 + [ "$#" -ne "3" ] && return 1 + halfound=0 + while [ "${halfound}" -ne "1" ]; + do + contents=`hal-get-property --udi "$1" --key "$2" 2> /dev/null` + halfound=0 + for op in ${contents} + do + if [ "a${op}" = "a$3" ]; then + halfound=`expr ${halfound} + 1` + halfound=`echo ${halfound}` + fi + done + if [ "${halfound}" -eq "0" ]; then + debug "Will attempt to add \"%s\" inside \"%s\".\n" "$3" "$2" + hal-set-property --udi "$1" --key "$2" --strlist-post "$3" 2> /dev/null + elif [ "${halfound}" -gt "1" ]; then + debug "Will attempt to remove multiple instance of \"%s\" inside \"%s\".\n" "$3" "$2" + hal-set-property --udi "$1" --key "$2" --strlist-rem "$3" 2> /dev/null + fi + hala=$? + if [ "a${hala}" != "a0" ]; then + debug "Unable to properly modify HAL.\n" + break + fi + done + [ "${halfound}" -eq "1" ] && debug "HAL is updated.\n" + unset contents; unset op; unset hala + if [ "a${halfound}" = "a1" ]; then + unset halfound + return 0 + fi + unset halfound + return 1 +} + +# Makes sure modem $1 capabilities are loaded on hal +hal_tty_update() { + [ "a${nohal}" != "a" ] && return 0 + [ "a${nohalinform}" != "a" ] && return 0 + ! find_binary "hal-get-property" && return 1 + ! find_binary "hal-set-property" && return 1 + ! find_binary "hal-find-by-property" && return 1 + unset halcapabilities + case "a${TTY_CAPABILITIES}" in + aGSM) + halcapabilities="GSM-07.07 GSM-07.05" + ;; + a) + debug "No capabilities found. Don't know what to tell to HAL.\n" + ;; + *) + debug "FIX ME: Unknown capabilities %s. Don't know what to tell to HAL.\n" "${TTY_CAPABILITIES}" + ;; + esac + [ "a${halcapabilities}" = "a" ] && unset halcapabilities && return 1 + debug "Capabilities of %s are: %s\n" "$1" "${halcapabilities}" + haludi=`hal-find-by-property --key "linux.device_file" --string "$1" 2> /dev/null | ${tailbin} -1` + if [ "a${haludi}" = "a" ]; then + unset haludi; unset halcapabilities + debug "No HAL device referring to %s was found.\n" "$1" + return 1 + fi + debug "Found device in HAL: %s\n" "${haludi}" + verbose "Updating HAL" + hal_add_to_list "${haludi}" info.capabilities "modem" + for cap in ${halcapabilities} + do + hal_add_to_list "${haludi}" modem.command_sets "${cap}" + done + debug "HAL was updated that %s is a modem.\n" "$1" + find_binary "hal-device" && debug run_command "hal-device \"${haludi}\"" + unset cap; unset halcapabilities; unset haludi + return 0 +} + +# If $1 node does not exist, creates it with major $2 and minor $3 +dev_create_node() { + [ "a$1" = "a" -o "a$2" = "a" -o "a$3" = "a" ] && return 99 + if [ ! -c "$1" ]; then + debug "Device node \"%s\" does not exist.\n" "$1" + if ! find_binary "mknod"; then + show_fmt_error "Unable to create device node \"%s\"." "$1" + return 1 + fi + debug run_command "${mknodbin} \"$1\" c $2 $3" + if [ ! -c "$1" ]; then + show_fmt_error "Failed to create device node \"%s\"." "$1" + return 1 + fi + debug "Made node \"%s (%d,%d)\" ourselves.\n" "$1" "$2" "$3" + return 0 + else + debug "Device node \"%s\" already exists.\n" "$1" + return 0 + fi +} + +pin_valid() { + [ "a$1" = "a" ] && return 1 + need_binary "expr" + givenpin=`echo $1` + mathpin=`${exprbin} 1${givenpin} + 1 - 1 2> /dev/null`; mathpin=`echo ${mathpin}` + if [ "a${mathpin}" = "a1${givenpin}" ]; then + if [ "1${givenpin}" -ge "10000" -a "1${givenpin}" -le "19999" ]; then + debug "Valid PIN %s.\n" "$1" + return 0 + fi + fi + debug "Invalid PIN %s.\n" "$1" + return 1 +} + +pin_prompt() { + user_prompt "SIM_PIN" "Modem needs PIN" "Please enter PIN number, or leave empty to abort" "OK" "Cancel" + case "a${SIM_PIN}" in + a) + debug "User did not provide PIN.\n" + unset SIM_PIN + return 98 + ;; + *) + if ! pin_valid "${SIM_PIN}"; then + debug "PIN supplied by user was not a valid PIN number (%s).\n" "${SIM_PIN}" + unset SIM_PIN + pin_prompt + ret=$? + fi + export SIM_PIN + return 0 + ;; + esac +} + + +# Makes sure tty $1 is not busy +tty_not_busy() { + [ "a$1" = "a" ] && return 1 + [ ! -c "$1" ] && return 1 + if we_are_root; then + ttyusers=`${lsbin} -l /proc/*/fd/* 2> /dev/null | ${grepbin} "${1}$" | ${sedbin} -e "s/\(.*\)\/proc\/\([0-9][0-9]*\)\/fd\/\(.*\)/\2/g" | ${sortbin} | ${uniqbin} | ${wcbin} -l` ; ttyusers=`echo ${ttyusers}` + if [ "a${ttyusers}" = "a0" ]; then + unset ttyusers + debug "Device %s is not busy.\n" "$1" + [ "a$2" != "a" ] && verbose "Resuming" + return 0 + fi + debug "Device %s is currently occupied by %d process(es).\n" "$1" "${users}" + ttyusers=`${lsbin} -l /proc/*/fd/* 2> /dev/null | ${grepbin} "${1}$" | ${sedbin} -e "s/\(.*\)\/proc\/\([0-9][0-9]*\)\/fd\/\(.*\)/\2/g" | ${sortbin} | ${uniqbin}` ; ttyusers=`echo ${ttyusers}` + debug "PID(s) are: %s\n" "${ttyusers}" + for ttyp in ${ttyusers} + do + debug run_command "${psbin} -p ${ttyp} -o pid,comm= | ${tailbin} -1" + ttyusers="${ttyusers} `${psbin} -p ${ttyp} -o comm= 2> /dev/null`" + done + unset ttyp + if [ "a$2" = "a" ]; then + debug "Will wait for 10 seconds in case port is freed.\n" + verbose "Waiting %s to be released by PID %s." "$1" "${ttyusers}" + ttycount=11 + else + ttycount=$2 + fi + ttycount=`expr ${ttycount} - 1` + if [ "a${ttycount}" = "a0" ]; then + show_fmt_error "Port %s is currently occupied by %s." "$1" "${ttyusers}" + unset ttyusers; unset ttycount; + return 1 + else + debug "Wait for another %d seconds in case port %s is freed.\n" "${ttycount}" "$1" + sleep 1 + if tty_not_busy $1 $ttycount; then + unset ttyusers; unset ttycount; + return 0 + else + unset ttyusers; unset ttycount; + return 1 + fi + fi + unset ttyusers; unset ttycount; + else + show_fmt_error "Unable to check if %s is occupied. Not root." "$1" + fi + return 1 +} + +at_default_commands() { + unset ttycommands + [ "a$1" = "a" ] && return 1 + case "a$1" in + aPROBEGSM) + ttycommands="ATI OK 'AT+GCAP' OK 'AT+CGSN' OK" + ;; + aIDENTIFY) + ttycommands="AT+CGMM OK" + ;; + aSTAGE0) + if [ "a${INIT_STAGE0}" != "a" ]; then + ttycommands="${INIT_STAGE0}" + fi + ;; + aSTAGE1) + if [ "a${INIT_STAGE1}" != "a" ]; then + ttycommands="${INIT_STAGE1}" + fi + ;; + aPINCHECK) + if [ "a${INIT_STAGE2}" != "a" ]; then + ttycommands="${INIT_STAGE2}" + debug "Using instructed PINCHECK.\n" + else + ttycommands="'AT+CPIN?' OK" + debug "Using default PINCHECK.\n" + fi + ;; + aPINSUPPLY) + if pin_valid "${2}"; then + if [ "a${INIT_STAGE3}" != "a" ]; then + ttycommands=`${printfbin} "${INIT_STAGE3}\n" "${2}"` + debug "Using instructed PINSUPPLY.\n" + else + ttycommands=`${printfbin} "'AT+CPIN=\"%s\"' OK\n" "${2}"` + debug "Using default PINSUPPLY.\n" + fi + fi + ;; + aSTAGE4) + if [ "a${INIT_STAGE4}" != "a" ]; then + ttycommands="${INIT_STAGE4}" + fi + ;; + aOPERATOR) + ttycommands="AT+COPS=3,2 OK 'AT+COPS?' OK" + ;; + aOPERATORS) + ttycommands="AT+COPS=3,2 OK 'AT+COPS=?' TIMEOUT 120 OK" + ;; + aOPERATORNAME) + ttycommands="AT+COPS=3,0 OK 'AT+COPS?' OK" + ;; + aSIMOPERATORNAME) + ttycommands="'AT+CRSM=176,28486,0,0,17' OK" + ;; + aSETOPERATOR) + ttycommands=`${printfbin} "'AT+COPS=1,2,\"%s\"' OK\n" "${2}"` + ;; + aSTAGE5) + if [ "a${INIT_STAGE5}" != "a" ]; then + ttycommands="${INIT_STAGE5}" + fi + ;; + aDETECTAPN) + ttycommands="AT+CGDCONT? OK" + ;; + aINITIALIZE) + if [ "a${APN}" != "a" ]; then + apnpart=`echo "${APN}" | ${cutbin} -d: -f1` + [ "a${apnpart}" = "aCUSTOM_APN" ] && apnpart="${CUSTOM_APN}" + if [ "a${INIT_STAGE6}" != "a" ]; then + ttycommands=`${printfbin} "${INIT_STAGE6}\n" "${apnpart}"` + debug "Using instructed INITIALIZE.\n" + else + ttycommands=`${printfbin} "ATZ OK 'AT&F' OK 'ATQ0 V1 E1' OK 'AT&D2 &C1' OK AT+FCLASS=0 OK ATS0=0 OK 'AT+CGDCONT=1,\"IP\",\"%s\"' OK\n" "${apnpart}"` + debug "Using default INITIALIZE.\n" + fi + unset apnpart + fi + ;; + aSTAGE7) + if [ "a${INIT_STAGE7}" != "a" ]; then + ttycommands="${INIT_STAGE7}" + fi + ;; + aSTAGE8) + if [ "a${INIT_STAGE8}" != "a" ]; then + ttycommands="${INIT_STAGE8}" + fi + ;; + aDIAL) + dialphone="${ISP_DIAL}" + [ "a${dialphone}" = "a" ] && dialphone="*99#" + ttycommands=`${printfbin} "ATD%s\n" "${dialphone}"` + unset dialphone + ;; + esac + [ "a${ttycommands}" != "a" ] && debug "Command \"%s\" refers to AT commands: %s\n" "$1" "${ttycommands}" && return 0 + debug "Unknown command \"%s\".\n" "$1" + return 1 +} + +# Send command $2 to tty $1 +tty_send_command() { + unset LASTTTYLOG + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + if [ ! -c "$1" ]; then + debug "Device node %s did not exist while trying \"%s\" command.\n" "$1" "$2" + if [ "a${informedspurious}" != "a1" ] && [ "a${usbdevice}" != "a" ] && usb_device_connected "${usbdevice}" && usb_has_storage "$1" && [ "a${killstorage}" = "a" ]; then + show_fmt_error "Spurious changes in tty %s. Consider using \"killstorage\" switch in case it improves stability." "$1" + export informedspurious=1 + fi + if [ "a${informedspurious}" != "a1" ]; then + show_fmt_error "Spurious changes in tty %s. Problem may be solved by upgrading your kernel or by choosing another driver." "$1" + export informedspurious=1 + fi + [ ! -c "$1" ] && debug "Waiting one second in case it appears.\n" && sleep 1 + [ ! -c "$1" ] && debug "Device still missing. Aborting.\n" && return 1 + debug "Device %s appeared. Will proceed sending %s commands.\n" "$1" "$2" + fi + ! find_binary "chat" && return 4 + need_arg "CHAT_ABORT_STRINGS" + ! at_default_commands "$2" "$3" && return 1 + ttycommands="\"\" '\pAT' OK ${ttycommands} '\pAT' OK" + debug "Will send %s commands to tty %s: %s\n" "$2" "$1" "${ttycommands}" + ! tty_not_busy "$1" && return 1 + timestamp_before=`${lsbin} --full-time -G1 $1 2> /dev/null`; timestamp_before=`echo ${timestamp_before}` + sh -c "${chatbin} -t 2 -e ${CHAT_ABORT_STRINGS} ${ttycommands} >> ${1} < ${1} 2> /tmp/sakis3g.chat.$$.log" + timestamp_after=`${lsbin} --full-time -G1 $1 2> /dev/null`; timestamp_before=`echo ${timestamp_after}` + if [ "a${timestamp_before}" != "a${timestamp_after}" ]; then + debug "Spurious changes in tty %s.\n" "$1" + if [ "a${usbdevice}" != "a" ] && usb_device_connected "${usbdevice}" && usb_has_storage "$1" && [ "a${killstorage}" = "a" ] && [ "a${informedspurious}" != "a1" ]; then + show_fmt_error "Spurious changes in tty %s. Consider using \"killstorage\" switch in case it improves stability." "$1" + export informedspurious=1 + fi + if [ "a${informedspurious}" != "a1" ]; then + show_fmt_error "Spurious changes in tty %s. Problem may be solved by upgrading your kernel or by choosing another driver." "$1" + export informedspurious=1 + fi + fi + unset ttycommands + if [ -f "/tmp/sakis3g.chat.$$.log" ]; then + LASTTTYLOG=`${catbin} "/tmp/sakis3g.chat.$$.log"` + debug "Got response from tty:\n%s\n" "${LASTTTYLOG}" + rm -f "/tmp/sakis3g.chat.$$.log" + return 0 + else + debug "No response from tty %s.\n" "$1" + return 1 + fi +} + +# Finds capabilities of tty $1 and sets TTY_CAPABILITIES variable +tty_get_caps() { + unset TTY_CAPABILITIES + [ "a$1" = "a" ] && return 1 + ! tty_send_command "$1" "PROBEGSM" && return 1 + gsmfound=`echo "${LASTTTYLOG}" | ${grepbin} "+CGSM" | wc -l`; gsmfound=`echo ${gsmfound}` + if [ "a${gsmfound}" = "a0" ]; then + debug "No GSM capabilities were advertised.\n" + gsmfound=`echo "${LASTTTYLOG}" | ${grepbin} "^\([0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]\)$" | wc -l` ; gsmfound=`echo ${gsmfound}` + if [ "a${gsmfound}" = "a1" ]; then + debug "However, IMEI information was provided. Will consider it GSM capable.\n" + fi + fi + [ "a${gsmfound}" = "a0" -o "a${gsmfound}" = "a" ] && [ "a${NOPROBEGSM}" != "a" ] && debug "Forced by user to consider tty %s GSM capable.\n" "$1" && gsmfound=1 + if [ "a${gsmfound}" != "a0" ]; then + export TTY_CAPABILITIES="GSM" + debug "Found GSM capabilities on tty %s.\n" "$1" + return 0 + fi + # TODO: Implement support for non GSM devices. + debug "Device did not report GSM capabilities.\n" + if [ "a$2" != "anoretry" ]; then + debug "Will check one more time.\n" + tty_get_caps "$1" "noretry" + return $? + fi + show_fmt_error "Device did not report GSM capabilities. You can skip this by adding --noprobe command line switch.\n" + return 1 +} + +# Sets MODEM_VARIANT, if possible, for tty $1 +tty_identify() { + unset MODEM_VARIANT + [ "a$1" = "a" ] && return 1 + ! tty_send_command "$1" "IDENTIFY" && return 1 + MODEM_VARIANT=`echo "${LASTTTYLOG}" | ${grepbin} -v "^AT" | ${sedbin} -e "s/AT//g" | ${sedbin} -e "s/OK//g" | ${sedbin} -e "s/ERROR//g" | ${trbin} "\n" " " | ${trbin} "\t" " " | ${sedbin} -e "s/ */ /g" | ${sedbin} -e "s/^ *//g" | ${sedbin} -e "s/ *$//g"` + MODEM_VARIANT=`echo ${MODEM_VARIANT}` + if [ "a${MODEM_VARIANT}" = "a" ]; then + debug "Modem did not report a name.\n" + unset MODEM_VARIANT + else + debug "Modem on tty identified itself as: %s\n" "${MODEM_VARIANT}" + base_modem "${usbdevice}" "${MODEM_VARIANT}" + fi + return 0 +} + +# Checks if tty $1 needs PIN. +tty_needspin() { + unset pinrequirement + [ "a$1" = "a" ] && return 1 + ! tty_send_command "$1" "PINCHECK" && return 1 + pinrequirement=`echo "${LASTTTYLOG}" | ${grepbin} "ERROR"` + [ "a${pinrequirement}" != "a" ] && pinrequirement="ERROR" + [ "a${pinrequirement}" = "a" ] && pinrequirement=`echo "${LASTTTYLOG}" | ${grepbin} "^.CPIN: " | ${cutbin} -d\ -f2-` + [ "a${pinrequirement}" = "a" ] && pinrequirement="ERROR" + [ "a${pinrequirement}" = "aREADY" ] && debug "Modem on %s does not need PIN.\n" "$1" && return 1 + [ "a${pinrequirement}" = "aSIM PIN" ] && debug "Modem on %s needs PIN.\n" "$1" && return 0 + debug "Got \"%s\" while checking modem on %s for PIN requirement.\n" "${pinrequirement}" "$1" + return 0 +} + +# Unlocks tty $1 from PIN. +tty_pin_unlock() { + [ "a$1" = "a" ] && return 1 + ! tty_needspin "$1" && unset pinrequirement && return 0 + if [ "a${pinrequirement}" = "a" ]; then + show_fmt_error "Failed to get valid response from modem while checking for PIN." + unset pinrequirement + return 1 + elif [ "a${pinrequirement}" != "aSIM PIN" ]; then + show_fmt_error "Modem responded \"%s\" while checking for PIN." "${pinrequirement}" + unset pinrequirement + return 1 + fi + unset pinrequirement + if ! pin_valid "${SIM_PIN}"; then + unset SIM_PIN + ! pin_prompt && return 98 + ! pin_valid "${SIM_PIN}" && return 1 + fi + verbose "Sending PIN" + ! tty_send_command "$1" "PINSUPPLY" "${SIM_PIN}" && return 1 + debug "PIN sent to %s. Waiting 3 seconds before checking success.\n" "$1" + sleep 3 + if ! tty_needspin "$1"; then + unset pinrequirement + debug "SIM is now READY.\n" + return 0 + fi + unset SIM_PIN + stop_fmt_error 12 "WRONG PIN. Aborting to prevent you from locking your SIM card." + return 1 +} + +tty_detect_apn() { + unset MODEM_APN + [ "a${MODEM_TTY}" = "a" ] && return 1 + ! tty_send_command "${MODEM_TTY}" "DETECTAPN" && return 1 + MODEM_APN=`echo "${LASTTTYLOG}" | ${grepbin} "^+CGDCONT" | ${sedbin} -e "s/^\(.*\)IP\",\"\(.*\)\",\"\(.*\)$/\2/g" | ${grepbin} -v "^+CGDCONT"` + export MODEM_APN + debug "APN stored in modem was: %s\n" "${MODEM_APN}" + [ "a${MODEM_APN}" = "a" ] && unset MODEM_APN && return 1 + return 0 +} + +tty_sim_provider_name() { + unset ISPSIMNAME + [ "a$1" = "a" ] && return 1 + if tty_send_command "$1" "SIMOPERATORNAME"; then + ISPSIMNAME=`echo "${LASTTTYLOG}" | ${grepbin} "^+CRSM:\( *\)144," | ${sedbin} -e "s/^.CRSM:\( *\)144,\(.*\),\"\(.*\)\"\(.*\)$/ISPSIMNAME=\3/g" | ${grepbin} "^ISPSIMNAME=" | ${cutbin} -d= -f2-` + [ "a${ISPSIMNAME}" = "a" ] && unset ISPSIMNAME && return 1 + ISPSIMNAME=`${printfbin} "\`echo "${ISPSIMNAME}" | ${sedbin} -e "s/\([0-9A-Fa-f][0-9A-Fa-f]\)/\\\\\\\\\\x\1/g" | ${sedbin} -e "s/\\\\\\\\\\xFF//g" | ${sedbin} -e "s/\\\\\\\\\\x01//g" | ${sedbin} -e "s/\\\\\\\\\\x02//g"\`\n"` + ISPSIMNAME=`echo ${ISPSIMNAME}` + [ "a${ISPSIMNAME}" = "a" ] && unset ISPSIMNAME && return 1 + debug "SIM contains \"service provider\" name: %s\n" "${ISPSIMNAME}" + export ISPSIMNAME + return 0 + fi + return 1 +} + +tty_select_network() { + unset FORCE_ISP + verbose "Scanning networks" + ! tty_send_command "$1" "OPERATORS" && return 1 + networks=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${cutbin} -d: -f2- -s | ${sedbin} -e "s/(/\\\n(/g" | ${sedbin} -e "s/)/)\\\n/g" | ${grepbin} "^([1-3],\"\(.*\)\",\"\(.*\)\",\"\([0-9][0-9]*\)\",0)$" | ${sedbin} -e "s/^(1,/(Allowed,/g" | ${sedbin} -e "s/^(2,/(Current,/g" | ${sedbin} -e "s/^(3,/(Forbidden,/g" | ${sedbin} -e "s/^(\(.*\),\"\(.*\)\",\"\(.*\)\",\"\([0-9][0-9]*\)\",0)$/\"\4\" \"\2 (\1\)\" /g"` + eval user_select \"FORCE_ISP\" \"Please select a network\" \"Select network for modem to register.\" \"Select\" \"Cancel\" ${networks} +# in + case "$?" in + 0) + unset FORCE_ISP; unset networks + return 98 + ;; + 98) + unset FORCE_ISP; unset networks + return 98 + ;; + 99) + unset FORCE_ISP; unset networks + return 99 + ;; + *) + case "a${FORCE_ISP}" in + a) + unset FORCE_ISP; unset networks + return 98 + ;; + *) + debug "User selected %s.\n" "${FORCE_ISP}" + return 0 + ;; + esac + ;; + esac + return 1 +} + +tty_registered_network() { + unset ISPID; unset ISPNAME; unset ISPTEXT + [ "a$1" = "a" ] && return 1 + ! tty_send_command "$1" "OPERATOR" && return 1 + ISPID=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${cutbin} -d\" -f2`; ISPID=`echo ${ISPID}` + if [ "a${ISPID}" = "a+COPS: 0" -o "a${ISPID}" = "a" ]; then + debug "Modem not registered to a network yet.\n" + unset ISPID + return 1 + fi + debug "Modem registered to network ID \"%s\".\n" "${ISPID}" + if [ -n "${FORCE_ISP}" ]; then + if [ "a${ISPID}" != "a${FORCE_ISP}" ]; then + debug "FORCE_ISP variable instructs to use \"%s\" instead.\n" "${FORCE_ISP}" + fi + debug "Will attempt to manually set %s and prevent roaming.\n" "${FORCE_ISP}" + ! tty_send_command "$1" "SETOPERATOR" "${FORCE_ISP}" + if [ "a$2" != "aFORCE_ISP" ]; then + tty_registered_network "$1" "FORCE_ISP" + else + if [ "a${ISPID}" != "a" ]; then + show_fmt_error "Modem refused to register operator \"%s\" (currently registered to \"%s\").\n" "${FORCE_ISP}" "${ISPID}" + else + show_fmt_error "Modem refused to register operator \"%s\".\n" "${FORCE_ISP}" + fi + unset ISPID + return 1 + fi + unset ISPID + return $? + fi + export ISPID + if tty_send_command "$1" "OPERATORNAME"; then + ISPNAME=`echo "${LASTTTYLOG}" | ${grepbin} "^+COPS:" | ${sedbin} -e "s/^.COPS: 0,0,\"\(.*\)\"\(.*\)$/ISPNAME=\1/g" | ${grepbin} "^ISPNAME=" | ${cutbin} -d= -f2-` + if tty_sim_provider_name "$1" && [ "a${ISPSIMNAME}" != "a" -a "a${ISPSIMNAME}" != "a${ISPNAME}" ]; then + debug "SIM card instructs to use \"%s\" as service provider name, instead of \"%s\".\n" "${ISPSIMNAME}" "${ISPNAME}" + ISPNAME="${ISPSIMNAME}" + fi + # Some modems return numeric ID, even if instructed to display name. + [ "a${ISPNAME}" = "a${ISPID}" ] && unset ISPNAME + # Some SIMs incorrectly confuse modem to display FFs as service provider name. + [ "a`echo ${ISPNAME} | ${cutbin} -b1-8`" = "aFFFFFFFF" ] && unset ISPNAME + # Huawei E160 does not correctly report operator name. + # This is not true. Was a SIM issue. This is not true. + #[ "a${MODEM_VARIANT}" = "aE160" ] && unset ISPNAME + export ISPNAME + [ "a${ISPNAME}" = "a" ] && net_info "${ISPID}" + [ "a${ISPNAME}" = "a" ] && unset ISPNAME + fi + export ISPTEXT="${ISPID}" + [ "a${ISPNAME}" != "a" ] && export ISPTEXT="${ISPNAME}" + return 0 +} + +tty_register_network() { + [ "a$1" = "a" ] && return 1 + wat=0 + if [ -n "${FORCE_ISP}" ]; then + debug "FORCE_ISP variable instructs to enter network \"%s\".\n" "${FORCE_ISP}" + debug "Will attempt to manually set %s and prevent roaming.\n" "${FORCE_ISP}" + ! tty_send_command "$1" "SETOPERATOR" "${FORCE_ISP}" + fi + while ! tty_registered_network $1; + do + if [ "${wat}" -gt "20" ]; then + debug "Giving up after %d seconds have passed.\n" "${wat}" + break + else + wat=`expr ${wat} + 4` + wat=`echo ${wat}` + fi + debug "Waiting modem to register network (%d seconds).\n" "${wat}" + verbose "Registering network" + sleep 4 + done + unset wat + if [ "a${ISPID}" = "a" ]; then + show_fmt_error "Modem unable to register a network." + unset ISPID + if user_confirm "scan" "Scan for network" "Modem was unable to register a network. Would you like to manually select a network?" "Yes" "No" "reset"; then + if tty_select_network "$@"; then + tty_register_network "$@" + return $? + fi + fi + return 13 + else + debug "Modem on %s has registered %s.\n" "$1" "${ISPID}" + return 0 + fi +} + +# Makes sure tty $1 is ready for connection to be established. +tty_prepare() { + check_com_software + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + [ "a$1" = "a" ] && return 1 + verbose "Preparing modem" + tty_send_command "$1" "STAGE0" + ! tty_get_caps "$@" && return 1 + ! tty_identify "$@" && return 1 + tty_send_command "$1" "STAGE1" + ! tty_pin_unlock "$@" && return 1 + tty_send_command "$1" "STAGE4" + tty_register_network "$@"; ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + tty_send_command "$1" "STAGE5" + hal_tty_update "$@" + debug "Modem on device node %s is now ready for connection.\n" "$1" + return 0 +} + +# Attempts to get connected USB devices, exiting if it fails. +usb_connected_devices() { + unset usb_devices + need_binary "sort"; need_binary "uniq"; need_binary "sed" + if [ -r "/proc/bus/usb/devices" ]; then + debug "Fetching connected USB devices by using \"%s\".\n" "/proc/bus/usb/devices" + usb_devices=`safe_cat "/proc/bus/usb/devices" | ${grepbin} -A 4 "^P:" | ${sedbin} -e "s/^\(.*\)Ven\(.*\)=\(....\) Pro\(.*\)=\(....\) \(.*\)$/\3:\5:/g" | ${sedbin} -e "s/^S:\(.*\)Pro\(.*\)=\(.*\)$/\3/g" | ${sedbin} -e "s/^.:\(.*\)$//g" | ${grepbin} -v "^$"` + usb_devices=`echo ${usb_devices} | ${sedbin} -e "s/: */:/g" | ${sedbin} -e "s/ -- /\\\n/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "HCI Host Controller"` + elif [ -d "/sys/bus/usb/devices" ]; then + debug "Fetching connected USB devices by using \"%s\".\n" "/sys/bus/usb/devices" + usb_devices=`cd /sys/bus/usb/devices/; ${grepbin} . */idProduct */idVendor */product */uevent | ${sortbin} | ${sedbin} -e "s/idProduct:\(.*\)$/idProduct:\1:/g" | ${sedbin} -e "s/idVendor:\(.*\)$/idVendor:\1:/g" | ${grepbin} -A 2 "idProduct" | ${sedbin} -e "s/^\(.*\):\(..*\):*$/\2/g"` + usb_devices=`echo ${usb_devices} | ${sedbin} -e "s/: */:/g" | ${sedbin} -e "s/ -- /\\\n/g" | ${sortbin} | ${uniqbin} | ${sedbin} -e "s/^\(....\):\(....\):/\2:\1:/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "HCI Host Controller"` + elif find_binary "lsusb"; then + debug "Fetching connected USB devices by using \"%s\".\n" "${lsusbbin}" + usb_devices=`safe_lsusb | ${sedbin} -e "s/\(.*\)ID \(....\):\(....\) \(.*\)$/\2:\3:\4/g" | ${sortbin} | ${uniqbin} | ${grepbin} -v "root hub"` + else + stop_fmt_error 7 "Unable to discover connected USB devices. Script will now abort." + fi + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + debug "Connected USB devices are:\n%s\n" "${usb_devices}" + return 0 +} + +# Helper method. Prints equivalent of usb_devices only for those devices in $1 +usb_device_list() { + for condevice in $@ + do + echo "${usb_devices}" | ${grepbin} "^${condevice}:" + done +} + +# Does scoring things to determine if which usb device looks like a sure candidate for being a modem. +# On success, returns 0 and sets usb_modems. +# On failure, returns 1 +voodoo_connected_modems() { + unset usb_modems + need_binary "uname" + debug "Voodoo mode employed to discover a possible modem.\n" + debug "Attempting to enumerate interfaces.\n" + uevents=`cd /sys/bus/usb/devices; ${grepbin} . [0-9]*/uevent 2> /dev/null` + interfaces=`echo "${uevents}" | ${cutbin} -d/ -f1 -s | ${grepbin} ":" | ${sortbin} | ${uniqbin}` ; interfaces=`echo ${interfaces}` + debug "uevent contents are:\n%s\n" "${uevents}" + debug "Interfaces are:\n%s\n" "${interfaces}" + unset orphaninterfaces; unset storageinterfaces; unset communicationdevices; unset suspectdevices; unset serialinterfaces; unset interruptinterfaces + for intstr in ${interfaces} + do + intclass=`echo "${uevents}" | ${grepbin} "^${intstr}\/" | ${grepbin} "uevent:INTERFACE=" | ${cutbin} -d= -f2 -s | ${cutbin} -d/ -f1` + [ "a${intclass}" = "a9" ] && continue + intdriver=`echo "${uevents}" | ${grepbin} "^${intstr}\/" | ${grepbin} "uevent:DRIVER=" | ${cutbin} -d= -f2 -s | ${sedbin} -e "s/-/_/g"` + intserial=0; [ "a${intdriver}" != "a" ] && intserial=`usb_serial_drivers ${intdriver} 2> /dev/null | ${wcbin} -w`; intserial=`echo ${intserial}` + intpoint=`cd /sys/bus/usb/devices; ${grepbin} . ${intstr}/ep_*/type 2> /dev/null | ${grepbin} -i "interrupt$" | ${wcbin} -l`; intpoint=`echo ${intpoint}` + intdevice=`echo "${intstr}" | ${cutbin} -d: -f1 -s` + intvendor=`${catbin} /sys/bus/usb/devices/${intdevice}/idVendor 2> /dev/null` + intmodemmaker=`${grepbin} -i "usb:v${intvendor}" /lib/modules/\`${unamebin} -r\`/modules.alias 2> /dev/null | ${cutbin} -d\ -f3 -s | ${sortbin} | ${uniqbin}` + intmodemmaker=`usb_serial_drivers ${intmodemmaker} 2> /dev/null` + intbrothers=`echo "${interfaces}" | ${trbin} " " "\n" | ${sedbin} -e "s/^\( *\)//g" | ${grepbin} "^${intdevice}:" | ${wcbin} -l`; intbrothers=`echo ${intbrothers}` + if [ "a${intdriver}" = "a" ]; then + orphaninterfaces="${orphaninterfaces} ${intstr} ${intstr} ${intstr}" + debug "Added interface %s to orphan interfaces.\n" "${intstr}" + fi + if [ "a${intpoint}" = "a1" ]; then + interruptinterfaces="${interruptinterfaces} ${intstr} ${intstr} ${intstr}" + debug "Added interface %s to interrupt interfaces.\n" "${intstr}" + fi + if [ "a${intdriver}" = "ausb-storage" -o "a${intdriver}" = "ausb_storage" -o "a${intclass}" = "a8" ]; then + storageinterfaces="${storageinterfaces} ${intstr} ${intstr} ${intstr} ${intstr}" + debug "Added interface %s to storage interfaces.\n" "${intstr}" + if [ "a${intbrothers}" = "a1" ]; then + storageinterfaces="${storageinterfaces} ${intstr} ${intstr}" + debug "+2 for being unique interface of device %s.\n" "${intdevice}" + fi + if [ "a${intbrothers}" = "a1" ] && [ "a${intmodemmaker}" != "a" ]; then + storageinterfaces="${storageinterfaces} ${intstr} ${intstr} ${intstr}" + debug "+3 for vendor %s being a modem maker.\n" "${intvendor}" + fi + fi + if [ "a${intclass}" = "a2" ]; then + communicationdevices="${communicationdevices} ${intstr} ${intstr}" + debug "Added interface %s to communication interfaces.\n" "${intstr}" + fi + if [ "a${intclass}" = "a255" -o "a${intclass}" = "a224" ]; then + suspectdevices="${suspectdevices} ${intstr}" + debug "Added interface %s to suspect interfaces.\n" "${intstr}" + fi + if [ "a${intserial}" = "a1" ]; then + serialinterfaces="${serialinterfaces} ${intstr} ${intstr} ${intstr} ${intstr} ${intstr}" + debug "Added interface %s to serial interfaces.\n" "${intstr}" + fi + done + unset interfaces; unset uevents + unset intstr; unset intclass; unset intdriver; unset intserial; unset intpoint; unset intdevice; unset intvendor; unset intmodemmaker; unset intbrothers + devicescore=`echo ${serialinterfaces} ${suspectdevices} ${communicationdevices} ${storageinterfaces} ${orphaninterfaces} ${interruptinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${grepbin} -v "^$" | ${cutbin} -d: -f1 -s | ${sortbin} | ${uniqbin} -c | ${sedbin} -e "s/^\( *\)//g" | ${sedbin} -e "s/\( *\)/ /g" | ${sedbin} -e "s/^\([0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9][0-9]\) /0\1 /g" | ${sortbin} -r` + interfacescore=`echo ${serialinterfaces} ${suspectdevices} ${communicationdevices} ${storageinterfaces} ${orphaninterfaces} ${interruptinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${grepbin} -v "^$" | ${sortbin} | ${uniqbin} -c | ${sedbin} -e "s/^\( *\)//g" | ${sedbin} -e "s/\( *\)/ /g" | ${sedbin} -e "s/^\([0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9]\) /0\1 /g" | ${sedbin} -e "s/^\([0-9][0-9][0-9]\) /0\1 /g" | ${sortbin} -r` + unset serialinterfaces; unset suspectdevices; unset communicationdevices; unset storageinterfaces; unset orphaninterfaces; unset interruptinterfaces; + debug "Device score is:\n%s\n" "${devicescore}" + debug "Interface score is:\n%s\n" "${interfacescore}" + besttwo=`echo "${interfacescore}" | ${headbin} -2 | ${cutbin} -d\ -f2 -s | ${cutbin} -d: -f1 -s | ${uniqbin}` + besttwocount=`echo "${besttwo}" | ${wcbin} -w`; besttwocount=`echo ${besttwocount}` + if [ "a${besttwocount}" != "a" ] && [ "${besttwocount}" -eq "1" ]; then + intvendor=`${catbin} /sys/bus/usb/devices/${besttwo}/idVendor 2> /dev/null` + intproduct=`${catbin} /sys/bus/usb/devices/${besttwo}/idProduct 2> /dev/null` + if usb_device_connected "${intvendor}:${intproduct}"; then + export usb_modems="${intvendor}:${intproduct}" + unset intvendor; unset intproduct + debug "Voodoo operations determined device %s (%s) is a modem.\n" "${usb_modems}" "${besttwo}" + unset besttwocount; unset besttwo; unset interfacescore; unset devicescore + return 0 + fi + unset intvendor; unset intproduct + fi + debug "No device is the absolute winner. Will check for dominating score.\n" + firstscore=`echo "${interfacescore}" | ${headbin} -1 | ${cutbin} -d\ -f1 -s | ${sedbin} -e "s/^\(0*\)//g" | ${sedbin} -e "s/^$/0/g"` + firstscore=`${printfbin} "%d\n" "${firstscore}" 2> /dev/null`; [ "a${firstscore}" = "a" ] && firstscore=0 + secondscore=`echo "${interfacescore}" | ${headbin} -2 | ${tailbin} -1 | ${cutbin} -d\ -f1 -s | ${sedbin} -e "s/^\(0*\)//g" | ${sedbin} -e "s/^$/0/g"` + secondscore=`${printfbin} "%d\n" "${secondscore}" 2> /dev/null`; [ "a${secondscore}" = "a" ] && secondscore=0 + if [ "a${firstscore}" != "a" -a "a${secondscore}" != "a" ] && [ "a${firstscore}" != "a${secondscore}" ] && [ "${firstscore}" -gt "0" -a "${firstscore}" -gt "${secondscore}" ]; then + secondscore=`expr ${secondscore} + ${secondscore}`; secondscore=`echo ${secondscore}` + if [ "${firstscore}" -gt "${secondscore}" ]; then + besttwo=`echo "${interfacescore}" | ${headbin} -1 | ${cutbin} -d\ -f2 -s | ${cutbin} -d: -f1 -s | ${uniqbin}` + intvendor=`${catbin} /sys/bus/usb/devices/${besttwo}/idVendor 2> /dev/null` + intproduct=`${catbin} /sys/bus/usb/devices/${besttwo}/idProduct 2> /dev/null` + if usb_device_connected "${intvendor}:${intproduct}"; then + export usb_modems="${intvendor}:${intproduct}" + unset intvendor; unset intproduct + debug "Device %s (%s) out-numbered second candidate and will be considered a modem.\n" "${usb_modems}" "${besttwo}" + unset firstscore; unset secondscore + unset besttwocount; unset besttwo; unset interfacescore; unset devicescore + return 0 + fi + fi + fi + unset firstscore; unset secondscore + debug "No device dominates the other in score. Cannot decide.\n" + unset besttwo; unset besttwocount; unset interfacescore; unset devicescore + return 1 +} + +# Attempts to get connected modems, and sets usb_modems and usb_modem_devices variables +usb_connected_modems() { + unset usb_modems; unset usb_modem_devices + [ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1 + ! usb_connected_devices && return 1 + connectedevices=`echo "${usb_devices}" | ${cutbin} -d: -f1,2` + for condevice in ${connectedevices} + do + devfound=`${printfbin} "%s\n%s\n%s\n" "${KNOWN_devices}" "${MODEM}" "${USBMODEM}" | ${grepbin} "${condevice}"` + [ "a${devfound}" != "a" ] && usb_modems="${usb_modems} ${condevice}" + unset devfound + done + unset condevice; unset connectedevices + usb_modems=`echo ${usb_modems}` + export usb_modems + if [ "a${usb_modems}" = "a" ] && unset usb_modems; then + debug "No plugged modems found.\n" + ! voodoo_mode && return 1 + ! voodoo_connected_modems && return 1 + fi + usb_modem_devices=`usb_device_list ${usb_modems}` + export usb_modem_devices + debug "Connected USB modems are:\n%s\n" "${usb_modem_devices}" + return 0 +} + +# Returns true if device $1 is currently connected +usb_device_connected() { + [ "a$1" = "a" ] && return 99 + usb_connected_devices + usbconnected=`echo "${usb_devices}" | ${cutbin} -d: -f1,2 | ${grepbin} "^$1"` + [ "a${usbconnected}" = "a$1" ] && unset usbconnected && return 0 + unset usbconnected + debug "Device \"%s\" is not connected.\n" "$1" + return 1 +} + +# Parses /proc/bus/usb/devices and only returns block referring to $1. +usb_device_block() { + unset usbdeviceblock + [ "a$1" = "a" ] && return 1 + if [ -r "/proc/bus/usb/devices" ]; then + usbvend=`echo "$1" | ${cutbin} -d: -f1` + usbprod=`echo "$1" | ${cutbin} -d: -f2` + usbdevcat=`safe_cat /proc/bus/usb/devices` + usblines=`${printfbin} "%s\n\n" "${usbdevcat}" | ${grepbin} -A 60 "=${usbvend} \(.*\)=${usbprod}" | ${grepbin} -n "^$" | ${headbin} -1 | ${sedbin} -e "s/:$//g"`; usblines=`echo ${usblines}` + [ "a${usblines}" = "a" ] && usblines=0 + [ "${usblines}" -gt "0" ] && usbdeviceblock=`echo "${usbdevcat}" | ${grepbin} -A 60 "Vendor=${usbvend} ProdID=${usbprod}" | ${headbin} -${usblines}` + unset usblines; unset usbvend; unset usbprod; unset usbdevcat + echo "${usbdeviceblock}" | ${grepbin} -v "^$" + return 0 + fi + return 1 +} + +# Filters arguments and returns back only those that usb serial drivers +usb_serial_drivers() { + [ "a${kernel}" = "a" ] && find_binary "uname" && kernel=`${unamebin} -r` + [ "a${kernel}" = "a" ] && return 1 + export kernel + for driver in $@ + do + [ -f "/lib/modules/${kernel}/kernel/drivers/usb/serial/${driver}.ko" ] && echo "${driver}" && continue + [ "a${driver}" = "acdc_acm" ] && [ -f "/lib/modules/${kernel}/kernel/drivers/usb/class/cdc-acm.ko" ] && echo "${driver}" + done +} + +# Attempts to find appropriate driver for USB device $1, and sets USBDRIVER +usb_serial_detect_driver() { + unset USBDRIVER + [ "a$1" = "a" ] && return 99 + serialvend=`echo "$1" | ${cutbin} -d: -f1` + serialprod=`echo "$1" | ${cutbin} -d: -f2` + if ! find_binary "uname"; then + debug "Failed to locate running kernel's modules. Uname missing.\n" + else + kernel=`${unamebin} -r` + if [ -f "/lib/modules/${kernel}/modules.alias" ]; then + drivercandidates=`${grepbin} -i "usb:v${serialvend}p${serialprod}" "/lib/modules/${kernel}/modules.alias" | ${cutbin} -d\ -f3 | ${sortbin} | ${uniqbin}`; + drivercandidates=`usb_serial_drivers ${drivercandidates}` + if [ "a${drivercandidates}" = "a" ]; then + debug "No perfect match found for device \"%s\".\n" "$1" + debug "Will seek if exists a driver for other devices from vendor \"%s\".\n" "${serialvend}" + drivercandidates=`${grepbin} -i "usb:v${serialvend}p" "/lib/modules/${kernel}/modules.alias" | ${cutbin} -d\ -f3 | ${sortbin} | ${uniqbin}`; + drivercandidates=`usb_serial_drivers ${drivercandidates}` + if [ "a${drivercandidates}" = "a" ]; then + debug "No candidates were found.\n" + else + debug "Found driver(s) for other devices of same vendor: %s\n" "${drivercandidates}" + fi + drivercandidates=`echo "${drivercandidates}" | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}` + else + debug "Found driver(s) available for \"%s\": %s\n" "$1" "${drivercandidates}" + fi + fi + unset kernel + fi + if base_drivers "${serialvend}" "${serialprod}"; then + drivercandidates=`echo ${drivercandidates} ${basedrivercandidates}` + unset basedrivercandidates + fi + drivercandidates=`echo ${drivercandidates} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}` + candidatenum=`echo ${drivercandidates} | ${wcbin} -w`; candidatenum=`echo ${candidatenum}` + if [ "a${candidatenum}" = "a1" ]; then + USBDRIVER=`echo ${drivercandidates}` + export USBDRIVER + debug "Only one candidate, will use it unconditionally: %s\n" "${USBDRIVER}" + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 0 + elif [ "a${candidatenum}" = "a0" ]; then + drivercandidates="option" + debug "No driver found, will propose \"%s\" driver.\n" "${drivercandidates}" + if usb_usable_interfaces "$1" && [ "a${usableinterfacecount}" != "a" ] && [ "${usableinterfacecount}" -gt "1" ]; then + debug "Device has %d usable interfaces. Will propose cdc_acm also.\n" + drivercandidates="cdc_acm option" + fi + fi + debug "Driver candidates are: %s\n" "${drivercandidates}" + if voodoo_mode; then + for safetoprobe in cdc_acm + do + debug "Will try safe to probe driver %s.\n" "${safetoprobe}" + if module_bind "${safetoprobe}" "$1"; then + debug "Appropriate driver %s determined.\n" "${safetoprobe}" + export USBDRIVER="${safetoprobe}" + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 0 + else + debug "Determined %s is not a valid candidate. Will make sure is not within list of candidates either.\n" "${safetoprobe}" + drivercandidates=`echo ${drivercandidates} | ${sedbin} -e "s/\( *\)${safetoprobe}\( *\)/ /g" | ${sedbin} -e "s/ / /g"` + drivercandidates=`echo ${drivercandidates}` + debug "Driver candidates are: %s\n" "${drivercandidates}" + fi + done + fi + drivers=`echo ${drivercandidates} | ${trbin} " " "\n" | ${sedbin} -e "s/^\( *\)\(.*\)\( *\)$/\2/g" | ${sortbin} | ${uniqbin} | ${sedbin} -e "s/^\(.*\)$/\"\1\" \"\1 kernel module\"/g"` + eval user_select \"USBDRIVER\" \"Please select appropriate driver\" \"Select kernel module that should be used.\" \"Select\" \"Cancel\" ${drivers} \"OTHER\" \"Other driver...\" + case "$?" in + 0) + unset drivers + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 98 + ;; + 98) + unset drivers + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 98 + ;; + 99) + unset drivers + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 99 + ;; + *) + case "a${USBDRIVER}" in + aOTHER) + unset USBDRIVER + user_prompt "USBDRIVER" "Please enter name of driver" "Enter name of appropriate kernel module that should be used, or leave empty to abort" "OK" "Cancel" + if [ "a${USBDRIVER}" != "a" ]; then + unset drivers + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 0 + fi + usb_serial_detect_driver "$@" + return $? + ;; + *) + unset drivers + unset candidatenum; unset drivercandidates; unset serialvend; unset serialprod + return 0 + ;; + esac + ;; + esac + return 99 +} + +# Returns driver attached to interface $2 of device $1 +usb_loaded_driver() { + [ "a$1" = "a" ] && return 99 + if [ -r "/proc/bus/usb/devices" ]; then + usbblock=`usb_device_block "$1"`; [ "a${usbblock}" = "a" ] && return 7 + if [ "a$2" != "a" ]; then + usbdriver=`echo "${usbblock}" | ${grepbin} "^I:\(.*\)If.=\( *\)$2 " | ${sedbin} -e "s/^I:\(.*\)If.=\( *\)$2 \(.*\) Driver=\(.*\)/\4/g"` + else + usbdriver=`echo "${usbblock}" | ${grepbin} "^I:\(.*\)If.=" | ${sedbin} -e "s/^I:\(.*\)If.=\( *\) \(.*\) Driver=\(.*\)/\4/g"` + fi + case "a${usbdriver}" in + a) + usbdriver="FAIL" + echo ${usbdriver} + unset usbdriver + return 1 + ;; + "a(none)") + usbdriver="NONE" + echo ${usbdriver} + unset usbdriver + return 0 + ;; + *) + usbdriver=`echo ${usbdriver} | ${trbin} "-" "_"` + usbdriver=`echo ${usbdriver} | ${sedbin} -e "s/usbserial_generic/usbserial/g"` + echo ${usbdriver} + unset usbdriver + return 1 + esac + elif usb_sysfsdir "$1"; then + if [ "a$2" != "a" ]; then + usbdriver=`${grepbin} . ${sysfsloc}/*-*\:*.$2/uevent | ${grepbin} -i DRIVER= | ${cutbin} -d= -f2 -s` + else + usbdriver=`${grepbin} . ${sysfsloc}/*-*\:*.*/uevent | ${grepbin} -i DRIVER= | ${cutbin} -d= -f2 -s`; usbdriver=`echo ${usbdriver}` + fi + usbdriver=`echo ${usbdriver} | ${trbin} "-" "_"` + usbdriver=`echo ${usbdriver} | ${sedbin} -e "s/usbserial_generic/usbserial/g"` + [ "a${usbdriver}" = "a" ] && usbdriver="NONE" + echo ${usbdriver} + unset usbdriver + return 0 + else + debug "Unable to determine driver attached to interface %s of device %s.\n" "$2" "$1" + usbdriver="FAIL" + echo ${usbdriver} + unset usbdriver + return 1 + fi +} + +usb_usable_interfaces() { + unset usableinterfaces; usableinterfacecount=0 + [ "a$1" = "a" ] && return 99 + if [ -r "/proc/bus/usb/devices" ]; then + debug "Using information of %s to determine usable interfaces.\n" "/proc/bus/usb/devices" + usbblock=`usb_device_block "$1"` + usbinter=`echo "${usbblock}" | ${grepbin} "^I:" | ${wcbin} -l`; usbinter=`echo ${usbinter}` + debug "USB Device %s provides %d interface(s).\n" "$1" "${usbinter}" + usbinter=`echo "${usbblock}" | ${grepbin} "(I)\(.*\)Atr=...Int\.. " | ${wcbin} -l`; usbinter=`echo ${usbinter}` + debug "USB Device %s provides %d interruptable endpoint(s).\n" "$1" "${usbinter}" + if [ "a${usbinter}" = "a0" -o "a${usbinter}" = "a" ]; then + debug "USB device block output was:\n%s\n" "${usbblock}" + debug "No modem lines on USB device \"%s\". Device may need switching.\n" "$1" + else + usbinter=`echo "${usbblock}" | ${grepbin} "(I)\(.*\)Atr=...Int\.. " | ${sedbin} -e "s/^E:\(.*\)Ad=\(.*\)(I)\(.*\)Atr=...Int\..\(.*\)$/\2/g"`; usbinter=`echo ${usbinter}` + debug "Interruptable endpoint(s) are: %s\n" "${usbinter}" + unset USB_INTERFACE + for endpoint in ${usbinter} + do + localinter=`echo "${usbblock}" | ${grepbin} -B 10 "^E\(.*\)Ad=${endpoint}(I)" | ${grepbin} "^I" | ${tailbin} -1 | ${sedbin} -e "s/^\(.*\)If.=\( *\)\([0-9][0-9]*\) \(.*\)$/\3/g"` + if [ "a${localinter}" != "a" ]; then + localinter=`${printfbin} "%d\n" ${localinter} 2> /dev/null` + if [ "a${localinter}" != "a" ]; then + debug "Added interface %s, containing endpoint %s.\n" "${localinter}" "${endpoint}" + usableinterfaces="${usableinterfaces} ${localinter}" + fi + fi + unset localinter + done + unset localinter; unset endpoint + fi + unset usbinter; unset usbblock + usableinterfaces=`echo ${usableinterfaces}` + export usableinterfaces + debug "Interfaces collected from %s are: %s\n" "/proc/bus/usb/devices" "${usableinterfaces}" + fi + if find_binary "lsusb"; then + debug "Using information of %s to determine usable interfaces.\n" "lsusb" + usbvend=`echo "$1" | ${cutbin} -d: -f1`; usbprod=`echo "$1" | ${cutbin} -d: -f2` + usbblock=`safe_lsusb -v -d ${usbvend}:${usbprod}` + usbinter=`echo "${usbblock}" | ${sedbin} -e "s/ */ /g" | ${grepbin} -i "transfer type interrupt" | ${wcbin} -l`; usbinter=`echo ${usbinter}` + debug "USB Device %s provides %d interruptable endpoint(s).\n" "$1" "${usbinter}" + if [ "a${usbinter}" = "a0" -o "a${usbinter}" = "a" ]; then + debug "lsusb output was:\n%s\n" "${usbblock}" + debug "No modem lines on USB device \"%s\". Device may need switching.\n" "$1" + unset usbinter + else + # Enter character after "interrupt" word on following line IS NOT a mistake + usbinter=`echo "${usbblock}" | ${sedbin} -e "s/ */ /g" | ${grepbin} -F -i "transfer type interrupt +binterfacenumber" | ${grepbin} -B 1 -i interrupt | ${grepbin} -i "binterfacenumber" | ${cutbin} -d\ -f3 -s`; usbinter=`echo ${usbinter}` + fi + debug "Interfaces collected from %s are: %s\n" "lsusb" "${usbinter}" + [ "a${usbinter}" != "a" ] && usableinterfaces=`echo "${usableinterfaces} ${usbinter}"` + export usableinterfaces + unset usbvend; unset usbprod; unset usbblock; unset usbinter; + elif [ ! -r "/proc/bus/usb/devices" ]; then + debug "Failed to read USB information.\n" + show_fmt_error "Both \"%s\" and \"%s\" are missing." "lsusb" "/proc/bus/usb/devices" + return 7 + fi + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + usableinterfaces=`echo ${usableinterfaces} | ${trbin} " " "\n" | ${sedbin} -e "s/ //g" | ${sortbin} | ${uniqbin}` + usableinterfaces=`echo ${usableinterfaces}` + usableinterfacecount=`echo ${usableinterfaces} | ${wcbin} -w`; usableinterfacecount=`echo ${usableinterfacecount}` + return 0 +} + +usb_get_interface() { + unset USB_INTERFACE + [ "a$1" = "a" ] && return 99 + usb_usable_interfaces "$1" + ret=$?; [ "a${ret}" != "a0" ] && return ${ret} + USB_INTERFACE=`echo ${usableinterfaces}` + export USB_INTERFACE + if [ "a${USB_INTERFACE}" = "a" -o "a${usableinterfacecount}" = "a0" ]; then + debug "Failed to locate any usable interface for device %s.\n" "$1" + unset USB_INTERFACE + return 8 + fi + debug "Collected %d interface(s): %s\n" "${usableinterfacecount}" "${USB_INTERFACE}" + if [ "a${usableinterfacecount}" = "a1" ]; then + debug "Only one interface available. Will use that one unconditionally.\n" + return 0 + fi + usbvend=`echo "$1" | ${cutbin} -d: -f1 -s` + usbprod=`echo "$1" | ${cutbin} -d: -f2 -s` + if base_drivers "${usbvend}" "${usbprod}"; then + if [ "a${baseintercandidates}" != "a" ]; then + ifvalid=`echo ${USB_INTERFACE} | ${trbin} " " "\n" | ${grepbin} "^${baseintercandidates}$"` + if [ "a${ifvalid}" = "a${baseintercandidates}" ]; then + if [ "a${USBINTERFACE}" = "a" ]; then + export USB_INTERFACE="${baseintercandidates}" + debug "Will use interface #%d derived by config.\n" "${USB_INTERFACE}" + unset ifvalid; unset usbvend; unset usbprod; unset baseintercandidates + return 0 + else + debug "However, will not use it in favor of already selected USBINTERFACE: %s\n" "${USBINTERFACE}" + fi + else + debug "However, this interface is not available from device.\n" + fi + unset ifvalid + else + debug "Config does not specify interface for device %s.\n" "$1" + fi + unset baseintercandidates + else + debug "No configuration for device %s.\n" "$1" + fi + unset usbvend; unset usbprod + if flow_select_interface "$1" "${USB_INTERFACE}"; then + [ "a${USBINTERFACE}" = "a" ] && return 98 + export USB_INTERFACE="${USBINTERFACE}" + debug "Will use interface #%d of USB device \"%s\".\n" "${USB_INTERFACE}" "$1" + return 0 + else + unset USB_INTERFACE + debug "User did not provide an interface.\n" + return 98 + fi + return 99 +} + +usb_sysfsdir() { + unset sysfsloc + [ "a$1" = "a" ] && return 1 + ! find_binary "dirname" && return 1 + usbven=`echo "$1" | ${cutbin} -d: -f1`; usbpro=`echo "$1" | ${cutbin} -d: -f2` + venentry=`${grepbin} -H . /sys/bus/usb/devices/*/*/idVendor 2> /dev/null | ${grepbin} ":${usbven}$"` + if [ "a${venentry}" != "a" ]; then + for ff in ${venentry} + do + unset dirloc + dirloc=`${dirnamebin} \`echo ${ff} | ${sedbin} -e "s/:${usbven}$//g"\` 2> /dev/null` + if [ "a${dirloc}" != "a" ]; then + if [ -d "${dirloc}" ]; then + dirpro=`${catbin} ${dirloc}/idProduct` + if [ "a${dirpro}" = "a${usbpro}" ]; then + export sysfsloc="${dirloc}" + debug "Device %s sysfs dir found: %s\n" "$1" "${sysfsloc}" + unset dirpro; unset dirloc; unset venentry; unset usbven; unset usbpro + return 0 + fi + unset dirpro + fi + fi + unset dirloc + done + fi + debug "No device %s located in sysfs.\n" "$1" + unset venentry; unset usbven; unset usbpro + return 1 +} + +usb_sysfsdir_int() { + unset sysfsintloc + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + ! usb_sysfsdir "$1" && return 1 + intnum="$2"; [ "${intnum}" -lt "10" ] && intnum="0$2" + intdir=`${grepbin} "." ${sysfsloc}/*/bInterfaceNumber | ${grepbin} "bInterfaceNumber:${intnum}$" | ${sedbin} -e "s/bInterfaceNumber:${intnum}$/bInterfaceNumber/g"`; intdir=`${dirnamebin} "${intdir}" 2> /dev/null`; unset intnum + if [ "a${intdir}" = "a" ]; then + unset intdir; debug "Failed to retrieve sysfs directory of interface #%d.\n" "$2" + return 1 + elif [ ! -d "${intdir}" ]; then + unset intdir; debug "Unable to retrieve sysfs directory of interface #%d.\n" "$2" + return 1 + fi + debug "Interface #%d sysfs dir is: %s\n" "$2" "${intdir}" + export sysfsintloc="${intdir}" + unset intdir + return 0 +} + +# Finds tty which resides on interface $2 of usb device $1 and sets USBTTY +usb_sysfs_locate_tty() { + unset USBTTY + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + ! usb_sysfsdir_int "$1" "$2" && return 1 + intstr=`cd ${sysfsintloc} ; ${grepbin} -H "." tty*/dev tty*/tty*/dev tty*/tty*/tty*/dev 2> /dev/null | ${sortbin} | ${uniqbin}`; unset intdir + if [ "a${intstr}" = "a" ]; then + unset intstr; debug "Failed to retrieve sysfs tty for interface #%d.\n" "$2" + return 1 + fi + debug "Interface #%d tty string is: %s\n" "$2" "${intstr}" + unset ttynode + [ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyUSB\([0-9][0-9]*\)\(.*\)$/ttyUSB\2/g" | ${grepbin} "^ttyUSB"` + [ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyACM\([0-9][0-9]*\)\(.*\)$/ttyACM\2/g" | ${grepbin} "^ttyACM"` + [ "a${ttynode}" = "a" ] && ttynode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)ttyHS\([0-9][0-9]*\)\(.*\)$/ttyHS\2/g" | ${grepbin} "^ttyHS"` + devicenode=`echo "${intstr}" | ${sedbin} -e "s/^\(.*\)dev:\([0-9][0-9]*\):\([0-9][0-9]*\)$/\2:\3/g"` + ttymajor=`echo "${devicenode}" | ${cutbin} -d: -f1` + ttyminor=`echo "${devicenode}" | ${cutbin} -d: -f2` + unset intstr; unset devicenode + debug "Will check if \"%s\" exists, or will create it with major %d and minor %d.\n" "/dev/${ttynode}" "${ttymajor}" "${ttyminor}" + if dev_create_node "/dev/${ttynode}" "${ttymajor}" "${ttyminor}"; then + export USBTTY="/dev/${ttynode}" + unset ttynode; unset ttymajor; unset ttyminor + debug "Found tty device node of interface #%d from device \"%s\": %s\n" "$2" "$1" "${USBTTY}" + return 0 + else + debug "Failed to create tty device of interface #%d from device \"%s\".\n" "$2" "$1" + unset ttynode; unset ttymajor; unset ttyminor + return 8 + fi + unset ttynode; unset ttymajor; unset ttyminor + return 99 +} + +usb_sysfsattr() { + unset SYSFS_USB_Manufacturer + unset SYSFS_USB_Product + unset SYSFS_USB_Serial + [ "a$1" = "a" ] && return 1 + ! usb_sysfsdir "$1" && return 1 + [ "a${sysfsloc}" = "a" ] && return 1 + [ ! -d "${sysfsloc}" ] && return 1 + SYSFS_USB_Manufacturer=`${sedbin} -e "s/ /_/g" "${sysfsloc}/manufacturer" 2> /dev/null` + SYSFS_USB_Product=`${sedbin} -e "s/ /_/g" "${sysfsloc}/product" 2> /dev/null` + SYSFS_USB_Serial=`${sedbin} -e "s/ /_/g" "${sysfsloc}/serial" 2> /dev/null` + debug "Information from sysfs:\nUSB Manufacturer: %s\nUSB Product: %s\nUSB Serial: %s\n" "${SYSFS_USB_Manufacturer}" "${SYSFS_USB_Product}" "${SYSFS_USB_Serial}" + return 0 +} + +usb_scsisysfsattr() { + unset scsidir + unset SYSFS_SCSI_Vendor + unset SYSFS_SCSI_Model + unset SYSFS_SCSI_Revision + [ "a$1" = "a" ] && return 1 + ! usb_sysfsattr "$1" && return 1 + ! find_binary "dirname" && return 1 + # How many seconds to wait for SCSI device to settle + counter=30 + while [ "a${scsidir}" = "a" ]; + do + if [ "a$2" = "a" ]; then + debug "Checking interface #%d of device %s.\n" "0" "$1" + target=`${lsbin} -1d ${sysfsloc}/*.0/host*/target*/*/vendor 2> /dev/null` + else + debug "Checking interface #%d of device %s.\n" "$2" "$1" + target=`${lsbin} -1d ${sysfsloc}/*.$2/host*/target*/*/vendor 2> /dev/null | ${tailbin} -1` + fi + [ "a${target}" != "a" ] && scsidir=`${dirnamebin} "${target}" 2> /dev/null` + [ "a${scsidir}" = "a" ] && unset scsidir + [ "a${scsidir}" != "a" ] && [ ! -d "${scsidir}" ] && unset scsidir + unset target + if [ "a${scsidir}" = "a" ]; then + if [ "${counter}" -gt "0" ]; then + debug "Device not yet settled. Will be waiting for another %d second(s).\n" "${counter}" + [ "${counter}" -eq "30" ] && verbose "Waiting device to settle" + sleep 1 + else + debug "Giving up. SCSI device did not settle, or is switched already.\n" + break + fi + counter=`expr ${counter} - 1`; counter=`echo ${counter}` + fi + done + unset counter + [ "a${scsidir}" = "a" ] && unset scsidir && return 1 + SYSFS_SCSI_Vendor=`${sedbin} -e "s/ /_/g" "${scsidir}/vendor" 2> /dev/null` + SYSFS_SCSI_Model=`${sedbin} -e "s/ /_/g" "${scsidir}/model" 2> /dev/null` + SYSFS_SCSI_Revision=`${sedbin} -e "s/ /_/g" "${scsidir}/rev" 2> /dev/null` + debug "SCSI device is settled:\nSCSI Vendor: %s\nSCSI Model: %s\nSCSI Revision: %s\n" "${SYSFS_SCSI_Vendor}" "${SYSFS_SCSI_Model}" "${SYSFS_SCSI_Revision}" + return 0 +} + +# Returns true if device $1 has a storage interface +usb_has_storage() { + unset STORAGEIF + [ "a$1" = "a" ] && return 99 + if [ -r "/proc/bus/usb/devices" ]; then + usbblock=`usb_device_block "$1"` + if [ "a${usbblock}" = "a" ]; then + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + debug "No information for device was available. Is device really connected?\n" + debug "Will consider storage part does not exist.\n" + debug "However, this may lead into problems later.\n" + unset usbblock + return 1 + fi + storageclass=`echo "${usbblock}" | ${grepbin} "Cls=08.stor."` + [ "a${storageclass}" = "a" ] && storageclass=`echo "${usbblock}" | ${grepbin} "river=usb_storage"` + [ "a${storageclass}" = "a" ] && storageclass=`echo "${usbblock}" | ${grepbin} "river=usb-storage"` + if [ "a${storageclass}" = "a" ]; then + debug "Device \"%s\" has no storage part.\n" "$1" + unset usbblock; unset storageclass + return 1 + fi + storageclass=`echo "${storageclass}" | ${sedbin} -e "s/^I:\(.*\)If.=\( *\)\([0-9][0-9]*\) \(.*\)$/\3/g"` + debug "Device has storage part on interface #%s.\n" "${storageclass}" + STORAGEIF=`echo "${storageclass}" | ${headbin} -1 | ${cutbin} "-d " -f1` + export STORAGEIF + unset usbblock; unset storageclass + return 0 + elif find_binary "lsusb"; then + storageclass=`safe_lsusb -d "$1" -v | ${grepbin} -B 10 -A 10 -i storage | ${grepbin} -i "bInterfaceNumber" | ${tailbin} -1 | ${sedbin} -e "s/ */ /g" | ${sedbin} -e "s/^ //g" | ${cutbin} -d\ -f2` + if [ "a${storageclass}" = "a" ]; then + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + debug "Device \"%s\" has no storage part.\n" "$1" + unset storageclass + return 1 + fi + debug "Device has storage part on interface #%s.\n" "${storageclass}" + # TODO: What happens when more storage interfaces exist? + STORAGEIF=`echo "${storageclass}" | ${headbin} -1 | ${cutbin} -d\ -f1` + export STORAGEIF + unset storageclass + return 0 + else + debug "Both %s and %s are not available.\n" "/proc/bus/usb/devices" "lsusb" + debug "Failed to determine if device %s has a storage interface.\n" "$1" + debug "Will consider storage part does not exist.\n" + debug "However, this may lead into problems later.\n" + return 1 + fi +} + +# Newer kernels provide this feature +usb_stabilize() { + [ "a$1" = "a" ] && return 1 + ! usb_sysfsdir "$1" && return 1 + [ "a${sysfsloc}" = "a" ] && return 1 + [ ! -d "${sysfsloc}" ] && return 1 + [ ! -w "${sysfsloc}/avoid_reset_quirk" ] && return 1 + debug "Kernel provides AVOID_RESET_QUIRK for device %s.\n" "$1" + echo "1" > "${sysfsloc}/avoid_reset_quirk" 2> /dev/null + ret=$? + [ "a${ret}" = "a0" ] && debug "Succesfully enabled AVOID_RESET_QUIRK for device %s.\n" "$1" + [ "a${ret}" = "a0" ] && debug "Failed to enable AVOID_RESET_QUIRK for device %s.\n" "$1" + return ${ret} +} + +# Makes sure that if device $1 has a storage part, this part +# is settled. +usb_storage_settled() { + if ! usb_has_storage "$1"; then + hal_unlock + return 0 + fi + debug "Device %s, provides storage interface #%s.\n" "$1" "${STORAGEIF}" + storageloaded=`usb_loaded_driver "$1" "${STORAGEIF}" | ${tailbin} -1` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + if [ "a${storageloaded}" != "ausb-storage" -a "a${storageloaded}" != "ausb_storage" ]; then + debug "Interface %s of device %s is bound to driver: %s\n" "${STORAGEIF}" "$1" "${storageloaded}" + debug "No need to wait for storage interface to settle.\n" + unset storageloaded + hal_unlock + return 0 + fi + debug "Storage interface #%s is binded by %s driver.\n" "${STORAGEIF}" "${storageloaded}" + if [ "a${killstorage}" != "a" ]; then + debug "User has set \"%s\" switch. Will try to unbind %s driver from interface #%d.\n" "killstorage" "${storageloaded}" "${STORAGEIF}" + if module_unbind "${storageloaded}" "$1" "${STORAGEIF}"; then + debug "Storage interface has been freed as instructed.\n" + debug "No need to wait for storage interface to settle.\n" + unset storageloaded + hal_unlock + return 0 + else + debug "Failed to unbind it. Too bad.\n" + show_fmt_error "Failed to unbind driver %s. I am sorry." "${storageloaded}" + fi + fi + unset storageloaded + if ! usb_scsisysfsattr "$1" "${STORAGEIF}"; then + debug "Will consider storage part is settled.\n" + debug "However, this may lead into problems later.\n" + fi + storagedevices=`${grepbin} . ${sysfsloc}/*.${STORAGEIF}/host*/target*/*/block*/size 2> /dev/null | ${grepbin} -v ":0$" | ${sedbin} -e "s/^\(.*\)\/block:\(.*\)\/size:\(.*\)$/\2/g" | ${trbin} "\n" " "`; storagedevices=`echo ${storagedevices}` + if [ "a${storagedevices}" = "a" ]; then + debug "No storage device(s) with inserted media exist. Safe to unlock HAL.\n" + hal_unlock + unset storagedevices; unset STORAGEIF + return 0 + fi + debug "Media found on following device(s) provided by interface #%s of device %s: %s\n" "${STORAGEIF}" "$1" "${storagedevices}" + if [ "a${HAL_LOCK}" != "a" ]; then + hal_unlock + debug "HAL is unlocked. Checking if HAL will kick in.\n" + pausecounter=21 + while [ "${pausecounter}" -gt "0" ] + do + blocking="" + for blockdevice in ${storagedevices} + do + poller=`${psbin} -Af | ${grepbin} "hald" | ${grepbin} "storage" | ${grepbin} "polling \(.*\)${blockdevice}" | ${grepbin} -v "${grepbin}"` + if [ "a${poller}" = "a" ]; then + debug "No polling process exists for %s.\n" "${blockdevice}" + continue + fi + debug "Polling process exists for %s: %s\n" "${blockdevice}" "${poller}" + poller=`${grepbin} "\/${blockdevice} " "/proc/mounts" 2> /dev/null` + if [ "a${poller}" != "a" ]; then + debug "Device %s mounted: %s\n" "${blockdevice}" "${poller}" + else + debug "Device %s still not mounted.\n" "${blockdevice}" + blocking="${blocking} ${blockdevice}" + fi + done + unset blockdevice; unset poller; blocking=`echo ${blocking}` + if [ "a${blocking}" = "a" ]; then + debug "HAL has finished mounting media on device(s): %s\n" "${storagedevices}" + break + fi + pausecounter=`expr ${pausecounter} - 1`; pausecounter=`echo ${pausecounter}` + if [ "${pausecounter}" -eq "0" ]; then + debug "Giving up waiting for HAL to mount devices.\n" + debug "This may lead into problems later on.\n" + else + [ "${pausecounter}" -eq "20" ] && verbose "Waiting HAL to mount device(s)" + debug "Waiting for HAL to mount all devices. %d second(s) to abort.\n" "${pausecounter}" + sleep 1 + fi + done + unset poller; unset blockdevice + unset pausecounter; unset blocking + else + debug "HAL was not locked. Will skip waiting for device mount.\n" + fi + unset storagedevices; unset STORAGEIF + return 0 +} + + +# Scans for bluetooth devices +bluetooth_scan_devices() { + ! find_binary "hcitool" && return 1 + verbose "Scanning bluetooth devices" + bluetooth_devices=`${hcitoolbin} scan 2> /dev/null | ${grepbin} "^ " | ${sedbin} -e "s/^ \(.*\) \(.*\)/\1 \2/g"` + debug "Found bluetooth devices:\n%s\n" "${bluetooth_devices}" + return 0 +} + +# Returns rfcomm channel for service $2 for device $1 +bluetooth_rfcomm_channel() { + ! find_binary "sdptool" && return 0 + rfchannel=`${sdptoolbin} search --raw --bdaddr "$1" "$2" 2> /dev/null | ${grepbin} -A 1 --binary-files=text "RFCOMM" | ${grepbin} "UINT8" | ${sedbin} -e "s/^\(.*\)UINT8 \(.*\)/\2/g"` + rfchannel=`echo ${rfchannel}` + debug "Found RFCOMM channel \"%s\" of service \"%s\" on device \"%s\".\n" "${rfchannel}" "$2" "$1" + [ "a${rfchannel}" != "a" ] && rfchannel=`${printfbin} "%d\n" ${rfchannel} 2> /dev/null` + [ "a${rfchannel}" = "a" ] && rfchannel="0" + debug "Returning RFCOMM channels \"%s\".\n" "`echo ${rfchannel}`" + return `echo ${rfchannel} | ${cutbin} -d\ -f1` +} + +# Returns true if device $1, channel $2 is on tty $3 +# NOTE: Does not depend on bluetooth_rfcomm_dev because +# bluetooth_rfcomm_dev only returns 1st valid +# channel +bluetooth_rfcomm_match() { + ! find_binary "rfcomm" && return 1 + [ "a${3}" != "a" ] && [ ! -c "${3}" ] && return 1 + bluematch=`${rfcommbin} -a --raw | ${grepbin} --binary-files=text " $1 " | ${grepbin} --binary-files=text " channel $2 " | ${grepbin} "^\`${basenamebin} $3\`:" | ${wcbin} -l`; bluematch=`echo ${bluematch}` + if [ "a${bluematch}" = "a1" ]; then + debug "%s refers to RFCOMM channel %d of device %s.\n" "$3" "$2" "$1" + unset bluematch + return 0 + fi + debug "%s does not refer to RFCOMM channel %d of device %s.\n" "$3" "$2" "$1" + unset bluematch + return 1 +} + +# Returns tty where device $1, channel $2 resides (if any) +bluetooth_rfcomm_dev() { + ! find_binary "rfcomm" > /dev/null && return 1 + bluematch=`${rfcommbin} -a --raw 2> /dev/null | ${grepbin} --binary-files=text " $1 " | ${grepbin} --binary-files=text " channel $2 " | ${headbin} -1 | ${cutbin} -d: -f1` + if [ "a${bluematch}" = "a" ]; then + unset bluematch + return 1 + fi + echo "${bluematch}" + unset bluematch + return 0 +} + +# Creates rfcomm device for device $1, channel $2 and sets RFCOMM_TTY +bluetooth_create_dev() { + ! we_are_root_already && debug "Need root privileges to create rfcomm nodes.\n" + ! we_are_root && return 1 + need_binary "rfcomm" + for devindex in 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + do + unset occupied + occupied=`${rfcommbin} show ${devindex} 2> /dev/null` + [ "a${occupied}" = "a" ] && break + done + if [ "a${occupied}" != "a" ]; then + unset occupied + unset devindex + show_fmt_error "Unable to find available rfcomm device index. Minors occupied." + return 1 + fi + unset occupied + debug "Found available rfcomm device node %d.\n" "${devindex}" + debug run_command "${rfcommbin} bind ${devindex} \"$1\" \"$2\"" + if ! bluetooth_rfcomm_match "$1" "$2" "/dev/rfcomm${devindex}"; then + show_fmt_error "Unable to create rfcomm node %s." "rfcomm${devindex}" + unset devindex + return 1 + fi + if [ ! -c "/dev/rfcomm${devindex}" ]; then + debug "Device node \"%s\" was not automatically created.\n" "/dev/rfcomm${devindex}" + if ! dev_create_node "/dev/rfcomm${devindex}" "216" "${devindex}"; then + show_fmt_error "Unable to create rfcomm device node \"%s\"." "/dev/rfcomm${devindex}" + unset devindex + return 1 + fi + debug "Made node \"%s\" ourselves.\n" "/dev/rfcomm${devindex}" + fi + export RFCOMM_TTY="/dev/rfcomm${devindex}" + unset devindex +} + +# Setups rfcomm device for device $1, channel $2 and sets RFCOMM_TTY +bluetooth_setup_rfcomm() { + if [ "a${RFCOMM_TTY}" != "a" ]; then + if bluetooth_rfcomm_match "$1" "$2" "${RFCOMM_TTY}"; then + debug "Will use already set RFCOMM_TTY (%s).\n" "${RFCOMM_TTY}" + return 0 + else + debug "Already set RFCOMM_TTY does not refer to a tty of \"%s\": \"%s\"\n" "$1" "${RFCOMM_TTY}" + unset RFCOMM_TTY + fi + fi + RFCOMM_TTY=`bluetooth_rfcomm_dev "$1" "$2"` + if [ "a${RFCOMM_TTY}" != "a" ]; then + export RFCOMM_TTY="/dev/${RFCOMM_TTY}" + if [ -c "${RFCOMM_TTY}" ]; then + debug "Found already binded rfcomm tty %s.\n" "${RFCOMM_TTY}" + return 0 + fi + unset RFCOMM_TTY + fi + unset RFCOMM_TTY + if bluetooth_create_dev "$1" "$2"; then + debug "Succesfully binded to rfcomm tty %s.\n" "${RFCOMM_TTY}" + return 0 + fi + debug "Failed to setup rfcomm tty for device \"%s\".\n" "$1" + return 1 +} + +# Method invoked when "status" action was requested. +ppp_fast_status() { + need_binary "grep" + need_arg "pppint" + unset status + [ -f "/proc/net/dev" ] && [ -r "/proc/net/dev" ] && status=`${grepbin} "${pppint}:" /proc/net/dev` + [ -z "${status}" ] && find_binary "ifconfig" && status=`${ifconfigbin} ${pppint} 2> /dev/null | ${grepbin} " UP "` + if [ "a${status}" = "a" ]; then + unset status + return 1 + else + unset status + return 0 + fi +} + +# Called by ispconnect to determine if connection is established +ppp_slow_status() { + need_arg "pppint" + need_binary "netstat" + [ "a${pppint}" = "a" ] && pppint="ppp0" + pppcon=`${catbin} /proc/net/dev | ${grepbin} "^\( *\)${pppint}:" | ${wcbin} -l`; pppcon=`echo ${pppcon}` + [ "a${pppcon}" = "a0" ] && unset pppcon && return 1 + debug "Interface %s is up.\n" "${pppint}" + pppcon=`${netstatbin} -rn | ${grepbin} " ${pppint}$" | ${grepbin} -v "^0.0.0.0" | ${wcbin} -l`; pppcon=`echo ${pppcon}` + [ "a${pppcon}" = "a0" ] && unset pppcon && return 1 + debug "Default route through %s is established.\n" "${pppint}" + debug "Really connected.\n" + return 0 +} + +# Shows version +show_version() { + if find_binary "printf"; then + format_text "Sakis 3G All-in-one script - Version %s\n" "${MYVERSION}" + format_text "(c) Sakis Dimopoulos 2009, 2010 under GNU GPL v2\n\n" + else + need_binary "echo" + echo "Sakis 3G All-in-one script - Version ${MYVERSION}" + echo "(c) Sakis Dimopoulos 2009, 2010 under GNU GPL v2" + echo + fi +} + +# Shows usage help +show_help() { + helptext=`raw_help` + notify "%s\n" "${helptext}" + return 0 +} + +raw_help() { + [ "a${PROVIDER}" = "a" ] && return 1 + [ ! -x "${PROVIDER}" ] && return 1 + show_version + echo + "${PROVIDER}" getfile "files/help.txt" 2> /dev/null +} + +modeswitch_load_realtime() { + debug "Loading system supplied device database.\n" + for dep in sed rm grep tr sort uniq cut printf basename + do + ! find_binary "${dep}" && return 1 + done + unset dep; unset realtime_switchable; unset realtime_switched; + unset CheckSuccess; unset Configuration; + unset GCTMode; unset HuaweiMode; unset SierraMode; unset SonyMode; + unset Interface; unset MessageContent; unset ResponseNeeded + unset DefaultProduct; unset DefaultVendor; + unset TargetClass; unset TargetProduct; unset TargetProductList; unset TargetVendor + for filename in /etc/usb_modeswitch.d/* /etc/usb_modeswitch.d/* + do + current_device=`${basenamebin} ${filename} | ${cutbin} -d: -f1,2 -s` + [ "a${current_device}" = "a" ] && unset current_device && continue + realtime_switchable="${realtime_switchable} ${current_device}" + ${sedbin} -e "s/ //g" "${filename}" > "/tmp/$$.tmp" 2> /dev/null + . "/tmp/$$.tmp" > /dev/null 2> /dev/null + ${rmbin} -f "/tmp/$$.tmp" > /dev/null 2> /dev/null + for ven in ${TargetVendor} + do + if [ -n "${TargetProductList}" ]; then + list=`echo ${TargetProductList} | ${sedbin} -e "s/,/ /g"` + for pro in $list + do + realtime_switched="${realtime_switched} ${ven}:${pro}" + done + unset list + elif [ -n "${TargetProduct}" ]; then + realtime_switched="${realtime_switched} ${ven}:${TargetProduct}" + fi + done + unset current_device + unset CheckSuccess; unset Configuration; + unset GCTMode; unset HuaweiMode; unset SierraMode; unset SonyMode; + unset Interface; unset MessageContent; unset ResponseNeeded + unset DefaultProduct; unset DefaultVendor; + unset TargetClass; unset TargetProduct; unset TargetProductList; unset TargetVendor + done + realtime_switched=`echo ${realtime_switched} | ${sedbin} -e "s/0x//g" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + realtime_switched=`echo ${realtime_switched}` + realtime_switchable=`echo ${realtime_switchable} | ${sedbin} -e "s/0x//g" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + realtime_switchable=`echo ${realtime_switchable}` + debug "Switchable devices within system device database:\n%s\n" "${realtime_switchable}" + debug "Switched devices within system device database:\n%s\n" "${realtime_switched}" + ${printfbin} "%s\n%s\n" "${realtime_switchable}" "${realtime_switched}" + unset realtime_switched; unset realtime_switchable + return 0 +} + +# Loads Usb-ModeSwitch device database, both embedded and system supplied +modeswitch_load() { + unset SWITCHABLE_devices; unset SWITCHED_devices; unset KNOWN_devices + debug "Loading Usb-ModeSwitch device database.\n" + # Check if possible to include embedded database + if [ "a${PROVIDER}" = "a" ]; then + debug "Unable to locate package provider.\n" + elif [ ! -x "${PROVIDER}" ]; then + debug "Unable to execute package provider.\n" + else + "${PROVIDER}" getfile "build/switchconfig" > "/tmp/sakis3g.$$.sw" + if [ ! -f "/tmp/sakis3g.$$.sw" ]; then + debug "Unable to find device database.\n" + elif [ ! -s "/tmp/sakis3g.$$.sw" ]; then + rm -f "/tmp/sakis3g.$$.sw" + debug "Embedded device database contains 0 entries.\n" + else + . "/tmp/sakis3g.$$.sw" + rm -f "/tmp/sakis3g.$$.sw" + getswitchabledevices 2> /dev/null + # TODO: Comment following line to render embedded device database unusable. + #unset usbswitchabledevices && unset usbswitcheddevices && debug "DELETED DATABASE TO EMULATE VOODOO MODE.\n" + ret=$?; + if [ "${ret}" -ne "0" ]; then + debug "Failed to load embedded Usb-ModeSwitch device database.\n" + else + debug "Embedded device database loaded.\n" + export SWITCHABLE_devices="${usbswitchabledevices}" + export SWITCHED_devices="${usbswitcheddevices}" + debug "Switchable devices within embedded device database:\n%s\n" "${SWITCHABLE_devices}" + debug "Switched devices within embedded device database:\n%s\n" "${SWITCHED_devices}" + KNOWN_devices=`echo "${SWITCHABLE_devices} ${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + KNOWN_devices=`echo "${KNOWN_devices}"` + export KNOWN_devices + devicecount=`echo "${KNOWN_devices}" | ${wcbin} -w`; devicecount=`echo ${devicecount}`; [ "a${devicecount}" = "a" ] && devicecount=0 + debug "Embedded Usb-ModeSwitch device database contains %d entries.\n" "${devicecount}" + unset devicecount + fi + fi + fi + # Check if system supplied Usb-ModeSwitch database exists + if [ -d "/etc/usb_modeswitch.d" ]; then + debug "Folder \"%s\" exists. Will check if it contains configuration files.\n" "/etc/usb_modeswitch.d" + realtime_devices=`modeswitch_load_realtime` + if [ "a${realtime_devices}" != "a" ]; then + usbswitchabledevices=`echo "${realtime_devices}" | ${tailbin} -2 | ${headbin} -1` + usbswitcheddevices=`echo "${realtime_devices}" | ${tailbin} -1` + SWITCHABLE_devices="${SWITCHABLE_devices} ${usbswitchabledevices}" + SWITCHED_devices="${SWITCHED_devices} ${usbswitcheddevices}" + SWITCHABLE_devices=`echo "${SWITCHABLE_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + SWITCHED_devices=`echo "${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + SWITCHABLE_devices=`echo ${SWITCHABLE_devices}` + SWITCHED_devices=`echo ${SWITCHED_devices}` + KNOWN_devices=`echo "${SWITCHABLE_devices} ${SWITCHED_devices}" | ${trbin} " " "\n" | ${sortbin} | ${uniqbin}` + KNOWN_devices=`echo "${KNOWN_devices}"` + export SWITCHABLE_devices + export SWITCHED_devices + export KNOWN_devices + devicecount=`echo "${KNOWN_devices}" | ${wcbin} -w`; devicecount=`echo ${devicecount}`; [ "a${devicecount}" = "a" ] && devicecount=0 + debug "Device database now contains %d entries.\n" "${devicecount}" + unset devicecount + fi + unset realtime_devices + fi + unset usbswitchabledevices; unset usbswitcheddevices + return 0 +} + +# Returns 0 if device $1 is switchable +modeswitch_is_switchable() { + [ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1 + isswitchable=`echo "${SWITCHABLE_devices}" | ${grepbin} "$1" | ${wcbin} -l`; isswitchable=`echo ${isswitchable}` + [ "a${isswitchable}" = "a" ] && isswitchable="0" + if [ "a${isswitchable}" = "a0" ]; then + if [ -f "/etc/usb_modeswitch.d/$1" ]; then + debug "Since file \"%s\" exists, will consider device \"%s\" switchable.\n" "/etc/usb_modeswitch.d/$1" "$1" + unset isswitchable + return 0 + fi + debug "Device \"%s\" is not switchable.\n" "$1" + unset isswitchable + return 1 + else + unset isswitchable + return 0 + fi +} + +modeswitch_switchable_devices() { + ! usb_connected_modems && return 1 + for condevice in ${usb_modems} + do + if modeswitch_is_switchable "${condevice}"; then + debug "There is at least one (%s) switchable device plugged.\n" "${condevice}" + unset condevice + return 0 + fi + done + unset condevice + debug "No switchable device plugged.\n" "${condevice}" + return 1 +} + +modeswitch_conf_realtime() { + unset modeswitch_config + debug "Seeking a system supplied configuration file for switching device %s.\n" "$1" + [ ! -d "/etc/usb_modeswitch.d" -a ! -d "/etc/usb-modeswitch.d" ] && return 1 + # Check if exists a candidate which needs SCSI information + needscsi=`${lsbin} -1r /etc/usb_modeswitch.d/$1:s* /etc/usb-modeswitch.d/$1:s* 2> /dev/null | ${wcbin} -l` + needscsi=`echo ${needscsi}` + if [ "a${needscsi}" != "a0" -a "a${needscsi}" != "a" ]; then + debug "Will need SCSI information for finding appropriate file.\n" + usb_scsisysfsattr "$1" + fi + unset needscsi + # Iterate through files + files=`${lsbin} -1r /etc/usb_modeswitch.d/$1* /etc/usb-modeswitch.d/$1* 2> /dev/null` + for filename in ${files} + do + debug "Checking if file \"%s\" matches.\n" "${filename}" + bn=`${basenamebin} "${filename}"` + crit=`echo "${bn}" | ${cutbin} -d: -f3-`; crit=`echo ${crit}` + if [ "a${crit}" != "a" ]; then + field=`echo "${crit}" | ${cutbin} -d= -f1 -s` + value=`echo "${crit}" | ${cutbin} -d= -f2 -s` + if [ "a${field}" = "a" ]; then + debug "File %s does not specify criteria to match. Skipping it." "${bn}" + unset bn; unset crit; unset field; unset value + continue + fi + if [ "a${value}" = "a" ]; then + debug "File %s does not specify value for attribute %s. Skipping it." "${bn}" "${field}" + unset bn; unset crit; unset field; unset value + continue + fi + len=`echo "${value}" | ${wcbin} -c`; len=`echo ${len}`; len=`expr ${len} - 1 2> /dev/null`; len=`echo ${len}` + if [ "a${len}" = "a" ] || [ "${len}" -eq "0" ]; then + debug "Value \"%s\" to be checked is not valid. Skipping file %s." "${value}" "${bn}" + unset bn; unset crit; unset field; unset value + continue + fi + unset attribute + case "${field}" in + sVe) + attribute=`echo ${SYSFS_SCSI_Vendor}` + ;; + sMo) + attribute=`echo ${SYSFS_SCSI_Model}` + ;; + sRe) + attribute=`echo ${SYSFS_SCSI_Revision}` + ;; + uMa) + attribute=`echo ${SYSFS_USB_Manufacturer}` + ;; + uPr) + attribute=`echo ${SYSFS_USB_Product}` + ;; + uSe) + attribute=`echo ${SYSFS_USB_Serial}` + ;; + *) + debug "FIXME: Unknown field \"%s\". Try downloading a newer Sakis3G version.\n" "${field}" + ;; + esac + if [ "a${attribute}" = "a" ]; then + debug "No value for field %s exists for device %s.\n" "${field}" "$1" + unset attribute; unset len; unset field; unset value; unset bn; unset crit + continue + fi + debug "Found %s.%s=\"%s\".\n" "$1" "${field}" "${attribute}" + attribute=`echo ${attribute} | ${cutbin} -b1-${len} 2> /dev/null` + if [ "a${attribute}" != "a" -a "a${attribute}" = "a${value}" ]; then + debug "File %s matches information derived from device.\n" "${bn}" + modeswitch_config="${filename}" + unset attribute; unset len; unset field; unset value; unset bn; unset crit + break; + fi + debug "File %s does not match.\n" "${bn}" + unset attribute; unset len; unset field; unset value; + else + debug "Found an exact match file: %s\n" "${filename}" + modeswitch_config="${filename}" + fi + unset crit; unset bn + done + filename="${modeswitch_config}" + unset modeswitch_config + if [ "a${filename}" != "a" ] && [ -f "${filename}" ]; then + ${catbin} "${filename}" > "/tmp/sakis3g.sw.dev.$$" 2> /dev/null + if [ -s "/tmp/sakis3g.sw.dev.$$" ]; then + export modeswitch_config="/tmp/sakis3g.sw.dev.$$" + unset filename + return 0 + else + ${rmbin} -f "/tmp/sakis3g.sw.dev.$$" + fi + fi + unset filename + debug "No system supplied configuration file found for switching device \"%s\".\n" "$1" + return 1 +} + +# Returns location of extracted configuration file that should be used to switch device $1 within modeswitch_config variable +modeswitch_conf_embedded() { + unset modeswitch_config + debug "Seeking embedded configuration file for switching device %s.\n" "$1" + switchfunc="usbswitchconf_`echo "$1" | ${sedbin} -e "s/:/_/g"`" + unset modeswitchconf + eval ${switchfunc} 2> /dev/null + ret=$?; unset switchfunc + if [ "${ret}" -ne "0" ]; then + debug "Failed to retrieve configuration for switching device \"%s\".\n" "$1" + return 1 + fi + [ "a${modeswitchconf}" = "a" ] && debug "No configuration file found for switching device \"%s\".\n" "$1" && return 1 + [ "a${PROVIDER}" = "a" ] && debug "Unable to locate package provider.\n" && unset modeswitchconf && return 1 + [ ! -x "${PROVIDER}" ] && debug "Unable to execute package provider.\n" && unset modeswitchconf && return 1 + eval "${PROVIDER}" getfile "${modeswitchconf}" > "/tmp/sakis3g.sw.dev.$$" + [ ! -f "/tmp/sakis3g.sw.dev.$$" ] && debug "Configuration file \"%s\" for switching device \"%s\" not found within package.\n" "${modeswitchconf}" "$1" && unset modeswitchconf && return 1 + if [ ! -s "/tmp/sakis3g.sw.dev.$$" ]; then + ${rmbin} -f "/tmp/sakis3g.sw.dev.$$" + debug "Configuration file \"%s\" for switching device \"%s\" not found within package.\n" "${modeswitchconf}" "$1" + unset modeswitchconf + return 1 + fi + unset modeswitchconf + export modeswitch_config="/tmp/sakis3g.sw.dev.$$" + return 0 +} + +modeswitch_conf() { + unset modeswitch_config + debug "Seeking configuration file for switching device %s.\n" "$1" + [ "a${KNOWN_devices}" = "a" ] && ! modeswitch_load && return 1 + ! modeswitch_conf_embedded "$1" && modeswitch_conf_realtime "$1" + if [ "a${modeswitch_config}" = "a" ] || [ ! -f "${modeswitch_config}" ] || [ ! -s "${modeswitch_config}" ]; then + unset modeswitch_config + show_fmt_error "Unable to locate a configuration file for switching device %s.\n" "$1" + return 1 + fi + debug run_command "${catbin} \"${modeswitch_config}\"" + debug "Configuration file for switching device \"%s\" at: %s\n" "$1" "${modeswitch_config}" + return 0 +} + +# Executed when binary Usb-ModeSwitch is binary incompatible on running platform. +modeswitch_emergency() { + ! usb_has_storage "$1" && return 1 + debug "Will attempt to switch device by detaching usb-storage driver.\n" + storageloaded=`usb_loaded_driver "$1" "${STORAGEIF}" | ${tailbin} -1` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + [ "a${storageloaded}" = "aNONE" ] && ! module_bind "usb_storage" "$1" "${STORAGEIF}" + ! module_unbind "usb_storage" "$1" "${STORAGEIF}" + unset STORAGEIF + return 0 +} + +# Switches device $1. Caller should check NEWIDS variable, because device most likely will change its ID. +modeswitch_switch() { + [ "a$1" = "a" ] && return 1 + ! modeswitch_is_switchable "$1" && return 1 + ! modeswitch_conf "$1" && return 1 + [ ! -f "${modeswitch_config}" ] && debug "Configuration file \"%s\" disappeared.\n" "${modeswitch_config}" + # Block hal from messing with us + hal_acquire_lock "org.freedesktop.Hal.Device.Storage" + verbose "Switching modem" + debug "Connected devices before switching.\n" + usb_connected_devices + previously=`echo "${usb_devices}" | ${grepbin} -v "^$1:" | ${cutbin} -d: -f1,2` + if [ "a${binaryfree}" = "a" ]; then + debug run_command "${PROVIDER} usb_modeswitch -W -I -c \"${modeswitch_config}\"" + ret=$? + else + ret=95 + fi + if [ "${ret}" -eq "95" ]; then + [ "a${binaryfree}" = "a" ] && debug "Binary incompatibility of package provided usb-modeswitch.\n" + if find_binary "usb_modeswitch"; then + debug "Will try system provided binary, hoping it is a recent one: %s\n" "${usb_modeswitchbin}" + verbose "Switching modem (using %s)" "${usb_modeswitchbin}" + debug run_command "${usb_modeswitchbin} --version" + debug run_command "${usb_modeswitchbin} -W -I -c \"${modeswitch_config}\"" + ret=$? + elif [ "a${binaryfree}" = "a" ]; then + show_fmt_error "Embedded Usb-ModeSwitch binary is not valid for your architect. You need to recompile for devices to switch properly. Start by issueing: %s recompile" "${PROVIDER}" + debug "Will try emergency mode.\n" + verbose "Trying emergency switch" + modeswitch_emergency "$1" + ret=$? + else + show_fmt_error "%s is not installed on your system.\n" "Usb-ModeSwitch" + return 4 + fi + fi + rm -f "${modeswitch_config}"; unset modeswitch_config + counter=0 + while [ "${counter}" -lt "20" ] + do + usb_connected_devices + after=`echo "${usb_devices}" | ${grepbin} "^$1:"` + if [ "a${after}" != "a" -a "${counter}" -eq "0" ]; then + debug "Device \"%s\" still there. Lets hope it has switched.\n" "$1" + unset after; unset previously + export NEWIDS="$1" + return 0 + fi + after="`echo "${usb_devices}" | ${cutbin} -d: -f1,2`" + for device in ${after} + do + newdevice=`echo "${previously}" | ${grepbin} "^${device}"` + if [ "a${newdevice}" = "a" ]; then + export NEWIDS="${device}" + debug "New device \"%s\" appeared.\n" "${NEWIDS}" + unset device; unset after; unset previously + return 0 + fi + done + unset device + counter=`expr ${counter} + 1`; counter=`echo ${counter}` + [ "${counter}" -lt "20" ] && debug "Waiting a second for device to appear.\n" && sleep 1 + done + debug "Giving up waiting for new device to appear after %d seconds.\n" "${counter}" + unset after; unset previously; unset counter + return 1 +} + +# Detects usable interface of device $1 and sets USB_INTERFACE variable. Device will get switched if required. +# Callers should check NEWIDS variable +modem_usb_detect_int() { + [ "a$1" = "a" ] && return 99 + usb_get_interface "$1"; ret=$? + case "${ret}" in + 7) + debug "Failed to get USB interface.\n" + return 7 + ;; + 98) + debug "Failed to get USB interface, by user request.\n" + return 98 + ;; + 8) + debug "Failed to get an interface for device.\n" + if modeswitch_is_switchable "$1"; then + if [ "a$2" != "aNOSWITCH" ]; then + debug "This is normal, device \"%s\" is switchable.\n" "$1" + modeswitch_switch "$1" + ret=$? + if [ "${ret}" -eq "0" -a "a${NEWIDS}" != "a" -a "a$2" != "aNOSWITCH" ]; then + debug "Device \"%s\" is now switched to \"%s\". Will attempt to setup this one instead.\n" "$1" "${NEWIDS}" + modem_usb_detect_int "${NEWIDS}" "NOSWITCH" + ret=$? + return ${ret} + else + debug "Failed to switch device \"%s\".\n" "$1" + return ${ret} + fi + else + debug "However, device \"%s\" is already switched.\n" "$1" + return 8 + fi + fi + debug "Failed setting up USB modem \"%s\".\n" "$1" + return 8 + ;; + 0) + debug "Got valid USB interface %d of USB modem \"%s\".\n" "${USB_INTERFACE}" "$1" + return 0 + ;; + *) + debug "Unknown error %d while retrieving interface number of USB Device.\n" "${ret}" + return ${ret} + ;; + esac +} + +# Sets USBTTY one way or another +modem_usb_locate_tty() { + verbose "Locating tty" + lcounter=0 + while ! usb_sysfs_locate_tty "$1" "$2" "$3" + do + lcounter=`expr ${lcounter} + 1`; lcounter=`echo ${lcounter}` + if [ "${lcounter}" -le "20" ]; then + if [ "a$3" != "a" ]; then + debug "Waiting for driver %s to create tty of device %s (interface #%d). [%d second(s) will have pass]\n" "$3" "$1" "$2" "${lcounter}" + else + debug "Waiting for tty of device %s (interface #%d). [%d second(s) will have pass]\n" "$1" "$2" "${lcounter}" + fi + sleep 1 + else + if [ "a$3" != "a" ]; then + debug "Driver %s failed to create a tty node for interface #%d of device %s.\n" "$3" "$2" "$1" + else + debug "No tty node created for interface #%d of device %s.\n" "$2" "$1" + fi + debug "Failed to locate tty device of interface #%d from device \"%s\".\n" "$2" "$1" + unset lcounter + return 8 + fi + done + return 0 +} + +modem_usb_fix_driver() { + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + usb_stabilize "$1" + # Make sure storage part (if exists), is settled before + # we start playing with drivers. This should eliminate + # cases that appeared on 2.6.31+ kernels. + usb_storage_settled "$1" + # Retrieve loaded driver + usbdriver=`usb_loaded_driver "$1" "$2" | ${tailbin} -1` + if [ "a${TIMEOUTOCCURED}" != "a" ]; then + show_fmt_error "Seems like an electrical/USB bus error occured. You may need to replug your modem for it to properly work.\n" + unset TIMEOUTOCCURED + fi + # Check value + if [ "a${usbdriver}" = "a" -o "a${usbdriver}" = "aFAIL" ]; then + show_fmt_error "Failed to detect driver of interface %d.\n" "$2" + unset usbdriver + return 7 + elif [ "a${usbdriver}" = "aNONE" ]; then + debug "No driver attached to interface #%d of \"%s\".\n" "$2" "$1" + else + debug "Found already loaded driver \"%s\".\n" "${usbdriver}" + fi + # If driver mismatch, unload wrong driver + if [ "a${USBDRIVER}" != "a" -a "a${usbdriver}" != "a" -a "a${usbdriver}" != "a${USBDRIVER}" -a "a${usbdriver}" != "aNONE" ]; then + debug "USBDRIVER variable instructs to use \"%s\" instead.\n" "${USBDRIVER}" + if ! module_unbind "${usbdriver}" "$1" "$2"; then + show_fmt_error "Failed to detach wrong driver \"%s\". Please do it yourself and retry.\n" "${usbdriver}" + unset usbdriver + return 9 + fi + usbdriver="NONE" + fi + # If no driver, attempt to detect one + [ "a${USBDRIVER}" = "a" -a "a${usbdriver}" != "aNONE" ] && USBDRIVER="${usbdriver}" + if [ "a${USBDRIVER}" = "a" -a "a${usbdriver}" = "aNONE" ]; then + if [ "a${USB_INTERFACE}" != "a" ]; then + usb_serial_detect_driver "$1" "$2" + if [ "a${USB_INTERFACE}" = "a" ]; then + # "usb_serial_detect_driver" call above, called "usb_usable_interfaces" which reset USB_INTERFACE + USB_INTERFACE="$2" ; export USB_INTERFACE + debug "Interface of device \"%s\" is still #%d.\n" "$1" "${USB_INTERFACE}" + fi + else + usb_serial_detect_driver "$1" "$2" + fi + fi + # We should know a driver now + if [ "a${USBDRIVER}" = "a" ]; then + unset usbdriver + show_fmt_error "Unable to locate driver to use for device \"%s\"" "$1" + return 10 + fi + # Load driver (if required) + if [ "${USBDRIVER}" = "${usbdriver}" ]; then + debug "Driver \"%s\" already attached to interface #%d of device \"%s\".\n" "${USBDRIVER}" "$2" "$1" + unset usbdriver + return 0 + elif module_bind "${USBDRIVER}" "$1" "$2"; then + debug "Driver \"%s\" loaded for interface #%d of device \"%s\".\n" "${USBDRIVER}" "$2" "$1" + unset usbdriver + return 0 + else + show_fmt_error "Unable to load driver \"%s\" for device \"%s\"" "${USBDRIVER}" "$1" + unset usbdriver + return 11 + fi +} + +modem_usb() { + unset MODEM_TTY + [ "a$1" = "a" ] && return 99 + ! usb_device_connected "$1" && debug "Device \"%s\" not found.\n" "$1" && return 7 + export usbdevice="$1" + + # Find appropriate interface, switching if required + modem_usb_detect_int "${usbdevice}" + ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret} + # Check if device is switched + [ "a${NEWIDS}" != "a" ] && export usbdevice="${NEWIDS}" + # Load driver + modem_usb_fix_driver "${usbdevice}" "${USB_INTERFACE}" + ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret} + # Locate tty + modem_usb_locate_tty "${usbdevice}" "${USB_INTERFACE}" "${USBDRIVER}" + ret=$?; [ "${ret}" -ne "0" ] && unset usbdevice && return ${ret} + if [ "a${USBTTY}" != "a" ]; then + if [ -c "${USBTTY}" ]; then + debug "Nothing more to do for setting it up device \"%s\".\n" "$1" + export MODEM_TTY="${USBTTY}" + return 0 + fi + fi + unset USB_INTERFACE + unset USBTTY + unset MODEM_TTY + unset usbdevice + return 99 +} + +modem_bluetooth() { + unset MODEM_TTY + [ "a$1" = "a" -o "a$2" = "a" ] && return 99 + debug "Attempting to setup bluetooth modem \"%s\" on channel \"%s\".\n" "$1" "$2" + bluetooth_setup_rfcomm "$1" "$2" + ret=$? + if [ "a${ret}" = "a0" ]; then + if [ "a${RFCOMM_TTY}" = "a" ]; then + debug "No RFCOMM tty returned.\n" + elif [ ! -c "${RFCOMM_TTY}" ]; then + debug "RFCOMM tty returned (%s), does exist.\n" "${RFCOMM_TTY}" + else + debug "Nothing more to do for setting it up %s(channel #%d).\n" "$1" "$2" + export MODEM_TTY="${RFCOMM_TTY}" + return 0 + fi + fi + return 8 +} + +modem_custom() { + [ "a$1" = "a" ] && return 99 + debug "Attempting to setup custom tty modem on \"%s\".\n" "$1" + if [ -c "$1" ]; then + debug "Custom tty \"%s\" exists. Nothing more to do for setting it up.\n" "$1" + export MODEM_TTY="$1" + return 0 + else + debug "Custom tty \"%s\" does not exist. Unable to proceed.\n" "$1" + show_fmt_error "Device node \"%s\" does not exist. Setup failed." "$1" + unset MODEM_TTY + return 8 + fi +} + +modem_setup() { + unset MODEM_TTY + debug "Setting up modem.\n" + ! we_are_root && return 3 + [ "a${MODEM}" = "a" ] && ! flow_select_modem "$@" && return 98 + if [ "a${MODEM}" = "aOTHER" ]; then + [ "a${OTHER}" = "a" ] && ! flow_other_modem "$@" && return 98 + if [ "a${OTHER}" = "aUSBMODEM" ]; then + [ "a${USBMODEM}" = "a" ] && ! flow_usb_modem "$@" && return 98 + if [ "a${USBMODEM}" != "a" ]; then + debug "Setting up USB modem %s.\n" "${USBMODEM}" + modem_usb "${USBMODEM}" "$@" + ret=$? + [ "a${usbdevice}" != "a" -a "a${usbdevice}" = "a${NEWIDS}" ] && export USBMODEM="${USBMODEM} ${usbdevice}" + return ${ret} + fi + elif [ "a${OTHER}" = "aBLUETOOTH" ]; then + [ "a${BLUETOOTH}" = "a" ] && ! flow_blue_modem "$@" && return 98 + if [ "a${BLUETOOTH}" = "aUNDISCOVERABLE" ]; then + [ "a${UNDISCOVERABLE}" = "a" ] && ! flow_undiscoverable "$@" && return 98 + if [ "a${UNDISCOVERABLE}" != "a" ]; then + [ "a${RFSERVICE}" = "a" ] && ! flow_rfchannel "$@" && return 98 + if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then + [ "a${RFCHANNEL}" = "a" ] && ! flow_manual_rfcomm "$@" && return 98 + if [ "a${RFCHANNEL}" != "a" ]; then + debug "Setting up Bluetooth modem %s on channel %s.\n" "${UNDISCOVERABLE}" "${RFCHANNEL}" + modem_bluetooth "${UNDISCOVERABLE}" "${RFCHANNEL}" "$@" + return $? + fi + elif [ "a${RFSERVICE}" != "a" ]; then + debug "Setting up Bluetooth modem %s on channel %s.\n" "${UNDISCOVERABLE}" "${RFSERVICE}" + modem_bluetooth "${UNDISCOVERABLE}" "${RFSERVICE}" "$@" + return $? + fi + fi + elif [ "a${BLUETOOTH}" != "a" ]; then + [ "a${RFSERVICE}" = "a" ] && ! flow_rfchannel "$@" && return 98 + if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then + [ "a${RFCHANNEL}" = "a" ] && ! flow_manual_rfcomm "$@" && return 98 + if [ "a${RFCHANNEL}" != "a" ]; then + debug "Setting up Bluetooth modem %s on channel %s.\n" "${BLUETOOTH}" "${RFCHANNEL}" + modem_bluetooth "${BLUETOOTH}" "${RFCHANNEL}" "$@" + return $? + fi + elif [ "a${RFSERVICE}" != "a" ]; then + debug "Setting up Bluetooth modem %s on channel %s.\n" "${BLUETOOTH}" "${RFSERVICE}" + modem_bluetooth "${BLUETOOTH}" "${RFSERVICE}" "$@" + return $? + fi + fi + elif [ "a${OTHER}" = "aCUSTOM_TTY" ]; then + [ "a${CUSTOM_TTY}" = "a" ] && ! flow_custom_tty "$@" && return 98 + if [ "a${CUSTOM_TTY}" != "a" ]; then + debug "Setting up custom modem on %s.\n" "${CUSTOM_TTY}" + modem_custom "${CUSTOM_TTY}" "$@" + return $? + fi + fi + elif [ "a${MODEM}" != "a" ]; then + debug "Setting up USB modem %s.\n" "${MODEM}" + modem_usb "${MODEM}" "$@" + ret=$? + [ "a${usbdevice}" != "a" -a "a${usbdevice}" = "a${NEWIDS}" ] && export MODEM="${MODEM} ${usbdevice}" + return ${ret} + fi + debug "Failed to setup any modem.\n" + return 99 +} + +# Gets entries from file $1 that start with $2:$3 +base_fetch() { + unset BASERESULT + [ "a$1" = "a" ] && return 1 + [ "a${PROVIDER}" = "a" ] && debug "Unable to locate package provider.\n" && return 1 + [ ! -x "${PROVIDER}" ] && debug "Unable to execute package provider.\n" && return 1 + baseentries=`"${PROVIDER}" getfile "$1" | ${grepbin} -v "^#" | ${grepbin} -i "^$2:"` + if [ "a${baseentries}" = "a" ]; then + unset baseentries + debug "No information found for %s within %s database.\n" "$2" "$1" + return 1 + fi + [ "a$3" != "a" ] && BASERESULT=`echo "${baseentries}" | ${grepbin} -i "^$2:$3:"` + [ "a${BASERESULT}" = "a" ] && BASERESULT=`echo "${baseentries}" | ${grepbin} -i "^$2::"` + export BASERESULT + unset baseentries + if [ "a${BASERESULT}" = "a" ]; then + unset BASERESULT + [ "a$3" != "a" ] && debug "No information found for \"%s:%s:\" within %s.\n" "$2" "$3" "$1" + [ "a$3" = "a" ] && debug "No default entry \"%s::\" found within %s.\n" "$2" "$1" + return 1 + fi + debug "Loaded entries from %s:\n%s\n" "$1" "${BASERESULT}" + return 0 +} + +base_drivers() { + unset basedrivercandidates; unset baseintercandidates + [ "a$1" = "a" ] && return 1 + ! base_fetch "files/usb_devices.db" "$1" "$2" && return 1 + [ "a${BASERESULT}" = "a" ] && return 1 + BASERESULT=`echo "${BASERESULT}" | ${headbin} -1` + basedrivercandidates=`echo "${BASERESULT}" | ${cutbin} -f2 -s` + baseintercandidates=`echo "${BASERESULT}" | ${cutbin} -f3 -s` + [ "a${basedrivercandidates}" != "a" ] && debug "Device database indicates to use \"%s\" driver(s) for device %s.\n" "${basedrivercandidates}" "$1" + [ "a${baseintercandidates}" != "a" ] && debug "Device database indicates to use interface #%d for device %s.\n" "${baseintercandidates}" "$1" + unset BASERESULT + return 0 +} + +# Sets INIT_STAGES of modem $1 with optional name $2. +# Parses files/modem_init.db. +base_modem() { + unset INIT_STAGE0; unset INIT_STAGE1; unset INIT_STAGE2; unset INIT_STAGE3; unset INIT_STAGE4; unset INIT_STAGE5; unset INIT_STAGE6; unset INIT_STAGE7; unset INIT_STAGE8; + [ "a$1" = "a" -a "a$2" = "a" ] && return 1 + ! base_fetch "files/modem_init.db" "$1" "$2" && return 1 + [ "a${BASERESULT}" = "a" ] && return 1 + BASERESULT=`echo "${BASERESULT}" | ${headbin} -1` + for item in 0 1 2 3 4 5 6 7 8 + do + plusone=`expr ${item} + 1`; plusone=`echo ${plusone}` + if [ "${item}" -le "7" -a "${item}" -ge "1" ]; then + contents=`${printfbin} "%s\n" "${BASERESULT}" | ${cutbin} -f${plusone}` + elif [ "${item}" -eq "8" ]; then + contents=`${printfbin} "%s\n" "${MODEM_INIT}"` + elif [ "${item}" -eq "0" ]; then + contents=`${printfbin} "%s\n" "${MODEM_PREPARE}"` + fi + if [ "a${contents}" != "a" ]; then + replacement=`${printfbin} "%s\n" "${contents}" | ${sedbin} -e "s/AT/\\nAT/g" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${grepbin} "^AT" | ${sedbin} -e "s/^\(.*\)$/\\\'\1\\\' OK/g" | ${trbin} "\n" " "` + eval "INIT_STAGE${item}=\${replacement}" + eval export INIT_STAGE${item} + unset replacement + if [ "a$1" != "a" ]; then + if [ "a$2" != "a" ]; then + debug "Loaded INIT Stage #%d for %s(%s): %s\n" "${item}" "$1" "$2" "`eval echo \\"\\${INIT_STAGE${item}}\\"`" + else + debug "Loaded INIT Stage #%d for %s: %s\n" "${item}" "$1" "`eval echo \\"\\${INIT_STAGE${item}}\\"`" + fi + else + debug "Loaded INIT Stage #%d for %s: %s\n" "${item}" "$2" "`eval echo \\"\\${INIT_STAGE${item}}\\"`" + fi + else + eval unset INIT_STAGE${item} + fi + unset contents; unset plusone + done + debug run_command "set | ${grepbin} \"^INIT_STAGE\"" + unset item + return 0 +} + +# Sets NETINFO of ISP $1 with optional name $2. If $1==$ISPID sets ISP_ fields also +# Parses files/operators.db. +base_net() { + unset NETINFO + [ "a$1" = "a" ] && return 1 + ! base_fetch "files/operators.db" "$1" "$2" && return 1 + [ "a${BASERESULT}" = "a" ] && return 1 + BASERESULT=`echo "${BASERESULT}" | ${headbin} -1` + ISP_NAME=`echo "${BASERESULT}" | ${cutbin} -f2` + ISP_PRODUCT=`echo "${BASERESULT}" | ${cutbin} -f3` + ISP_FGCOLOR=`echo "${BASERESULT}" | ${cutbin} -f4` + ISP_BGCOLOR=`echo "${BASERESULT}" | ${cutbin} -f5` + ISP_DIAL=`echo "${BASERESULT}" | ${cutbin} -f6` + ISP_APNS=`echo "${BASERESULT}" | ${cutbin} -f7 | ${trbin} " " "\n"` + ISP_ICON=`echo "${BASERESULT}" | ${cutbin} -f8` + export ISP_NAME + export ISP_PRODUCT + export ISP_FGCOLOR + export ISP_BGCOLOR + export ISP_DIAL + export ISP_APNS + export ISP_ICON + return 0 +} + +# Gathers information about ISP $1 with optional name $2 +net_info() { + [ "a$1" != "a" ] && base_net "$@" + [ "a$1" != "a${ISPID}" -a "a$1" != "a" ] && return 0 + [ "a${ISP_NAME}" = "a" ] && export ISP_NAME="${ISPNAME}" + [ "a${ISP_NAME}" = "a" ] && export ISP_NAME="Unknown operator ${ISPID}" + [ "a${ISPNAME}" = "a${ISPID}" -o "a${ISPNAME}" = "a" ] && export ISPNAME="${ISP_NAME}" + [ "a${ISPNAME}" = "a${ISPID}" -o "a${ISPNAME}" = "a" ] && export ISPNAME="${ISP_NAME}" + export ISPTEXT="${ISPNAME}" + [ "a${ISP_PRODUCT}" = "a" ] && export ISP_PRODUCT="${ISP_NAME} Internet" + [ "a${ISP_FGCOLOR}" = "a" ] && export ISP_FGCOLOR="ffffff" + [ "a${ISP_BGCOLOR}" = "a" ] && export ISP_BGCOLOR="000000" + [ "a${ISP_DIAL}" = "a" ] && export ISP_DIAL="*99#" + [ "a${ISP_ICON}" = "a" ] && export ISP_ICON="files/sakis3g.png" + if [ "a${CUSTOM_DIAL}" != "a" -a "a${CUSTOM_DIAL}" != "a${ISP_DIAL}" ]; then + debug "Will dial \"%s\" specified by user instead of \"%s\" found in database.\n" "${CUSTOM_DIAL}" "${ISP_DIAL}" + export ISP_DIAL="${CUSTOM_DIAL}" + fi + debug "ISPID: %s / ISPNAME: %s / ISPTEXT: %s\n" "${ISPID}" "${ISPNAME}" "${ISPTEXT}" + return 0 +} + + +# Select a device interface +flow_select_interface() { + usbinterfaces=`echo "$2" | ${trbin} " " "\n" | ${sedbin} -e "s/^\(.*\)$/\"\1\" \"Interface #\1\"/g" | ${trbin} "\n" " "` + eval user_select \"USBINTERFACE\" \"Please appropriate interface\" \"Select modem interface of USB device that provides modem capabilities.\" \"Select\" \"Cancel\" ${usbinterfaces} + case "$?" in + 0) + unset usbinterfaces + return 98 + ;; + 98) + unset usbinterfaces + return 98 + ;; + 99) + unset usbinterfaces + return 99 + ;; + *) + unset usbinterfaces + return 0 + ;; + esac + return 99 +} + + +# Makes sure one USB modem exists +flow_usb_modem() { + usb_connected_devices + usbmodems=`echo "${usb_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\"\1:\2\" \"\3\"/g"` + eval user_select \"USBMODEM\" \"Please select USB modem\" \"Select USB device that provides modem capabilities.\" \"Select\" \"Cancel\" ${usbmodems} + case "$?" in + 0) + unset usbmodems + return 98 + ;; + 98) + unset usbmodems + return 98 + ;; + 99) + unset usbmodems + return 99 + ;; + *) + unset usbmodems + usb_connected_devices + usbmodems=`echo "${usb_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/ \1:\2 /g" | ${grepbin} " ${USBMODEM} "`; usbmodems=`echo ${usbmodems}` + if [ "a${usbmodems}" = "a${USBMODEM}" ]; then + debug "User selected USB modem \"%s\".\n" "${USBMODEM}" + unset usbmodems + return 0 + else + debug "USB modem \"%s\" is not currently plugged.\n" "${USBMODEM}" + unset usbmodems; unset USBMODEM + flow_usb_modem "$@" + return "$?" + fi + ;; + esac + return 99 +} + +flow_manual_rfcomm() { + user_prompt "RFCHANNEL" "Please enter RFCOMM channel" "Enter RFCOMM channel that should be used, or leave empty to abort [1-255]" "OK" "Cancel" + case "a${RFCHANNEL}" in + a) + return 98 + ;; + *) + RFCHANNEL=`${printfbin} "%d\n" "${RFCHANNEL}" 2> /dev/null` + [ "a$RFCHANNEL" = "a" ] && RFCHANNEL=0 + [ "$RFCHANNEL" -gt "255" ] && RFCHANNEL=0 + export RFCHANNEL + if [ "$RFCHANNEL" -eq "0" ]; then + unset RFCHANNEL + return 98 + fi + return 0 + ;; + esac +} + +flow_custom_tty() { + user_prompt "CUSTOM_TTY" "Please enter tty" "Enter tty node where your 3G modem resides, or leave empty to abort" "OK" "Cancel" + case "a${CUSTOM_TTY}" in + a) + unset CUSTOM_TTY + return 98 + ;; + *) + [ ! -c "${CUSTOM_TTY}" ] && [ -c "/dev/${CUSTOM_TTY}" ] && CUSTOM_TTY="/dev/${CUSTOM_TTY}" + [ ! -c "${CUSTOM_TTY}" ] && [ -c "/dev${CUSTOM_TTY}" ] && CUSTOM_TTY="/dev${CUSTOM_TTY}" + if [ ! -c "${CUSTOM_TTY}" ]; then + show_fmt_error "Device node \"%s\" does not exist.\n" "${CUSTOM_TTY}" + unset CUSTOM_TTY + flow_custom_tty "$@" + return $? + else + debug "Using device node \"%s\".\n" "${CUSTOM_TTY}" + export CUSTOM_TTY + return 0 + fi + ;; + esac +} + +flow_rfchannel() { + [ "a${BLUETOOTH}" = "a" ] && ! flow_blue_modem "$@" && return $? + if [ "a${RFSERVICE}" = "aRFCHANNEL" ]; then + if ! flow_manual_rfcomm; then + unset RFSERVICE + flow_rfchannel "$@" + return "$?" + fi + return 0 + fi + verbose "Seeking %s" "${BLUETOOTH}" + if bluetooth_rfcomm_channel "${BLUETOOTH}" "DUN"; then + debug "No DUN rfcomm channels returned from \"%s\".\n" "${BLUETOOTH}" + bluetooth_rfcomm_channel "${BLUETOOTH}" "SP" + rfchannels=`echo "${rfchannel}" | ${sedbin} -e "s/^\([0-9][0-9]*\)$/\"\1\" \"Serial Port from RFCOMM channel #\1\"/g"` + else + rfchannels=`echo "${rfchannel}" | ${sedbin} -e "s/^\([0-9][0-9]*\)$/\"\1\" \"Dialup Networking from RFCOMM channel #\1\"/g"` + bluetooth_rfcomm_channel "${BLUETOOTH}" "SP" + rfchannels="${rfchannels} `echo \"${rfchannel}\" | ${sedbin} -e \"s/^\\\([0-9][0-9]*\\\)$/\\\"\\\1\\\" \\\"Serial Port from RFCOMM channel #\\\1\\\"/g\"`" + fi + eval user_select \"RFSERVICE\" \"Please select RFCOMM service\" \"Select RFCOMM service of Bluetooth device that provides 3G modem capabilities.\" \"Select\" \"Cancel\" \"RESCAN\" \"Scan device again\" ${rfchannels} \"RFCHANNEL\" \"Manually enter non-discovered channel...\" + case "$?" in + 0) + unset rfchannels + return 98 + ;; + 98) + unset rfchannels + return 98 + ;; + 99) + unset rfchannels + return 99 + ;; + *) + unset rfchannels + case "a${RFSERVICE}" in + aRESCAN) + unset RFSERVICE + flow_rfchannel "$@" + return "$?" + ;; + aRFCHANNEL) + if ! flow_manual_rfcomm; then + unset RFSERVICE + flow_rfchannel "$@" + return "$?" + fi + return 0 + ;; + *) + export RFCHANNEL="${RFSERVICE}" + return 0 + ;; + esac + ;; + esac + return 99 + + +} + +# Makes sure one UNDISCOVERABLE BLUETOOTH modem exists +flow_undiscoverable() { + user_prompt "UNDISCOVERABLE" "Enter Bluetooth address" "Enter Bluetooth address of undiscoverable device, or leave empty to abort" "OK" "Cancel" + case "a${UNDISCOVERABLE}" in + a) + return 98 + ;; + *) + export BLUETOOTH="${UNDISCOVERABLE}" + if ! flow_rfchannel; then + unset UNDISCOVERABLE; unset BLUETOOTH + return 98 + fi + export BLUETOOTH="UNDISCOVERABLE" + return 0 + ;; + esac +} + + +# Makes sure one BLUETOOTH modem exists +flow_blue_modem() { + if [ "a${BLUETOOTH}" = "aUNDISCOVERABLE" ]; then + if ! flow_undiscoverable; then + unset BLUETOOTH + flow_blue_modem "$@" + return "$?" + fi + return 0 + fi + bluetooth_scan_devices + bluemodems=`echo "${bluetooth_devices}" | ${sedbin} -e "s/^\(.*\) \(.*\)$/\"\1\" \"\2 (\1)\"/g"` + eval user_select \"BLUETOOTH\" \"Please select Bluetooth device\" \"Select Bluetooth device that provides 3G modem capabilities.\" \"Select\" \"Cancel\" \"RESCAN\" \"Scan devices again\" ${bluemodems} \"UNDISCOVERABLE\" \"Manually enter undiscoverable device...\" + case "$?" in + 0) + unset bluemodems + return 98 + ;; + 98) + unset bluemodems + return 98 + ;; + 99) + unset bluemodems + return 99 + ;; + *) + unset bluemodems + case "a${BLUETOOTH}" in + aRESCAN) + unset BLUETOOTH + flow_blue_modem "$@" + return "$?" + ;; + aUNDISCOVERABLE) + if ! flow_undiscoverable; then + unset BLUETOOTH + flow_blue_modem "$@" + return "$?" + fi + return 0 + ;; + *) + if ! flow_rfchannel; then + unset BLUETOOTH + flow_blue_modem "$@" + return "$?" + fi + return 0 + ;; + esac + ;; + esac + return 99 +} + +# Makes sure one other modem is selected +flow_other_modem() { + user_select "OTHER" "Please select modem type" "Select modem category that best fits your 3G modem." "Select" "Cancel" "USBMODEM" "USB device" "BLUETOOTH" "Bluetooth modem" "CUSTOM_TTY" "Custom tty..." + case "$?" in + 0) + return 98 + ;; + 98) + return 98 + ;; + 99) + return 99 + ;; + *) + case "a${OTHER}" in + aUSBMODEM) + if ! flow_usb_modem; then + unset OTHER + flow_other_modem "$@" + return "$?" + fi + return 0 + ;; + aBLUETOOTH) + if ! flow_blue_modem; then + unset OTHER + flow_other_modem "$@" + return "$?" + fi + return 0 + ;; + aCUSTOM_TTY) + if ! flow_custom_tty; then + unset OTHER + flow_other_modem "$@" + return "$?" + fi + return 0 + ;; + *) + return 99 + ;; + esac + ;; + esac + return 99 +} + + +# Makes sure one selected modem exists +flow_select_modem() { + verbose "Locating device" + usb_connected_modems + modems=`echo "${usb_modem_devices}" | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\"\1:\2\" \"\3\"/g"` + if [ "a${modems}" != "a" ]; then + modemscount=`echo "${usb_modem_devices}" | ${wcbin} -l`; modemscount=`echo ${modemscount}` + if [ "a${modemscount}" = "a1" -a "a${MODEM}" = "a" ]; then + MODEM=`echo "${usb_modem_devices}" | ${headbin} -1 | ${sedbin} -e "s/^\(....\):\(....\):\(.*\)$/\1:\2/g"` + export MODEM + debug "Autoselecting unique USB modem plugged: %s\n" "${MODEM}" + ret=1 + else + eval user_select \"MODEM\" \"Please select modem\" \"Select modem that will be used for establishing 3G connection.\" \"Select\" \"Cancel\" ${modems} \"OTHER\" \"Other...\" +# in + ret=$? + fi + unset modemscount + else + export MODEM="OTHER" + ret=97 + fi + case "${ret}" in + 0) + return 98 + ;; + 98) + return 98 + ;; + 99) + return 99 + ;; + *) + case "a${MODEM}" in + aOTHER) + if [ "${ret}" -eq "97" ]; then + flow_other_modem "$@" + ret=$? + [ "${ret}" -ne "0" ] && unset MODEM + return ${ret} + else + if ! flow_other_modem "$@"; then + unset MODEM + flow_select_modem "$@" + return "$?" + fi + fi + return 0 + ;; + a) + return 98 + ;; + *) + return 0 + ;; + esac + return 99 + ;; + esac + return 0 +} + +flow_custom_apn() { + user_prompt "CUSTOM_APN" "Please enter APN" "Enter correct APN, or leave empty to abort. Contact your operator if unsure" "OK" "Cancel" + case "a${CUSTOM_APN}" in + a) + unset CUSTOM_APN + return 98 + ;; + *) + export CUSTOM_APN + return 0 + ;; + esac +} + + +# Makes selected APN exists +flow_select_apn() { + net_info "${ISPID}" "${ISPNAME}" + [ "a${FORCE_APN}" != "a" ] && export ISP_APNS="${FORCE_APN}" + [ "a${ISP_APNS}" = "a" ] && tty_detect_apn && export ISP_APNS="${MODEM_APN}" + if [ "a${ISP_APNS}" != "a" -a "a${FORCE_APN}" = "a" ]; then + apnoptions="" + for apnoption in ${ISP_APNS} + do + apnname=`echo "${apnoption}" | ${cutbin} -d: -f1 -s` + if [ "a${apnname}" = "a" ]; then + apnname="${apnoption}" + apndesc="${apnoption}" + apnuser="" ; apnpass="" + else + apndesc=`echo "${apnoption}" | ${cutbin} -d: -f2 | ${sedbin} -e "s/_/ /g"` + apndesc="${apndesc} (${apnname})" + apnuser=`echo "${apnoption}" | ${cutbin} -d: -f3` + apnpass=`echo "${apnoption}" | ${cutbin} -d: -f4` + fi + if [ "a${apnname}" = "a${MODEM_APN}" -a "a${MODEM_APN}" != "a" ]; then + apndesc=`format_text "Reported by your modem (%s)" "${apnname}"` + fi + apnoptions="${apnoptions} \"${apnname}\" \"${apndesc}\"" + unset apnname; unset apndesc; unset apnuser; unset apnpass + done + unset apnoption + eval user_select \"APN\" \"Please select APN\" \"Select APN that best describes your connection. Contact your operator if unsure. This information, along with APN username and password, is usually easily retrieved through a fast call to customer support\" \"Select\" \"Cancel\" ${apnoptions} \"CUSTOM_APN\" \"Custom APN...\" + ret=$? + unset apnoptions + elif [ "a${FORCE_APN}" != "a" ]; then + debug "Selected APN by FORCE_APN: %s\n" "${FORCE_APN}" + APN=`echo "${FORCE_APN}" | ${cutbin} -d: -f1` + export APN + ret=1 + else + export APN="CUSTOM_APN" + ret=97 + fi + case "${ret}" in + 0) + return 98 + ;; + 98) + return 98 + ;; + 99) + return 99 + ;; + *) + case "a${APN}" in + aCUSTOM_APN) + if [ "${ret}" -eq "97" ]; then + if ! flow_custom_apn "$@"; then + unset APN + return 98 + fi + else + if ! flow_custom_apn "$@"; then + unset APN + flow_select_apn "$@" + return "$?" + fi + fi + return 0 + ;; + a) + return 98 + ;; + *) + APN=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f1` + export APN + if [ "a${APN}" = "a" ]; then + unset APN + flow_select_apn "$@" + return "$?" + else + apnuser=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f3 -s` + [ "a${apnuser}" != "a" -a "a${APN_USER}" = "a" ] && export APN_USER="${apnuser}" + apnpass=`echo "${ISP_APNS}" | ${grepbin} "^${APN}\(:*\)" | ${cutbin} -d: -f4 -s` + [ "a${apnuser}" != "a" -a "a${APN_PASS}" = "a" ] && export APN_PASS="${apnpass}" + unset apnuser; unset apnpass + fi + return 0 + ;; + esac + return 99 + ;; + esac + return 0 +} + +flow_apn_user() { + [ "a${APN}" = "a" ] && return 98 + if [ "a${APN_USER}" = "a" ]; then + if [ "a${APN}" != "a" ]; then + if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then + APN_USER=`echo "${CUSTOM_APN}" | ${cutbin} -d: -s -f3` + else + APN_USER=`echo "${APN}" | ${cutbin} -d: -s -f3` + fi + fi + fi + [ "a${APN_USER}" = "a" ] && unset APN_USER + if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then + apntitle=`echo "${CUSTOM_APN}" | ${cutbin} -d: -f1` + elif [ "a${APN}" != "a" ]; then + apntitle=`echo "${APN}" | ${cutbin} -d: -f1` + fi + user_prompt "APN_USER" "APN: ${apntitle}" "Enter username required by APN, or leave empty to abort. Contact your operator if unsure. This information, along with APN password, is usually easily retrieved through a fast call to customer support" "OK" "Cancel" + case "a${APN_USER}" in + a) + unset APN_USER + return 98 + ;; + *) + export APN_USER + return 0 + ;; + esac +} + +flow_apn_pass() { + [ "a${APN}" = "a" ] && return 98 + if [ "a${APN_PASS}" = "a" ]; then + if [ "a${APN}" != "a" ]; then + if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then + APN_PASS=`echo "${CUSTOM_APN}" | ${cutbin} -d: -s -f4` + else + APN_PASS=`echo "${APN}" | ${cutbin} -d: -s -f4` + fi + fi + fi + [ "a${APN_PASS}" = "a" ] && unset APN_PASS + if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then + apntitle=`echo "${CUSTOM_APN}" | ${cutbin} -d: -f1` + elif [ "a${APN}" != "a" ]; then + apntitle=`echo "${APN}" | ${cutbin} -d: -f1` + fi + user_prompt "APN_PASS" "APN: ${apntitle}" "Enter password required by APN, or leave empty to abort. Contact your operator if unsure. This information is usually easily retrieved through a fast call to customer support" "OK" "Cancel" + case "a${APN_PASS}" in + a) + unset APN_PASS + return 98 + ;; + *) + export APN_PASS + return 0 + ;; + esac +} + +flow_switch() { + flow_select_modem "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + unset NEWIDS + if modeswitch_is_switchable "${MODEM}" && usb_device_connected "${MODEM}"; then + modeswitch_switch "${MODEM}" + ret=$? + if [ "a${NEWIDS}" != "a" -a "a${NEWIDS}" != "a${MODEM}" ]; then + debug "Device changed ID. From \"%s\" to \"%s\".\n" "${MODEM}" "${NEWIDS}" + export MODEM="${NEWIDS}" + fi + localdev="${MODEM}" + elif modeswitch_is_switchable "${USBMODEM}" && usb_device_connected "${USBMODEM}"; then + modeswitch_switch "${USBMODEM}" + ret=$? + if [ "a${NEWIDS}" != "a" -a "a${NEWIDS}" != "a${USBMODEM}" ]; then + debug "Device changed ID. From \"%s\" to \"%s\".\n" "${USBMODEM}" "${NEWIDS}" + export USBMODEM="${NEWIDS}" + fi + localdev="${USBMODEM}" + else + debug "Currently selected modem cannot be switched. No need to switch anything.\n" + return 0 + fi + # Should normally unlock HAL here. But we don't. + # If we will stay within program, it will get unlocked during driver setup. + # If stand-alone action, exit trap will unlock it. + # So, line below should be commented out. + #hal_unlock + return ${ret} +} + +flow_setup() { + flow_select_modem "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + if modem_setup "$@"; then + debug "Modem is now setup and resides on %s.\n" "${MODEM_TTY}" + return 0 + else + return $? + fi +} + +flow_prepare() { + flow_setup "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + if tty_prepare "${MODEM_TTY}" "$@"; then + debug "Device %s is now prepared and registered to %s.\n" "${MODEM_TTY}" "${ISPTEXT}" + else + return $? + fi +} + +pppd_config() { + need_binary "pppd" + need_arg "PPPD_OPTIONS"; need_arg "BAUD" + unset CONNECTION_CONF; unset CONNECTION_COMMAND + ${touchbin} "/tmp/pppd.tmp.$$" + if [ ! -w "/tmp/pppd.tmp.$$" ]; then + show_fmt_error "Unable to create temporary pppd config file within %s directory.\n" "/tmp" + return 99 + fi + CONNECTION_CONF="/tmp/pppd.tmp.$$" + find_binary "chmod" && ${chmodbin} 600 "${CONNECTION_CONF}" + ${catbin} > "${CONNECTION_CONF}" <> "${CONNECTION_CONF}" + unset initstrings + if [ ! -s "${CONNECTION_CONF}" ]; then + ${rmbin} -f "${CONNECTION_CONF}" + show_fmt_error "Failure to write on %s.\n" "${CONNECTION_CONF}" + unset CONNECTION_CONF + return 99 + fi + debug "Config file that will be used is: \"%s\".\n" "${CONNECTION_CONF}" + debug show_file "${CONNECTION_CONF}" + pppdoptions="${PPPD_OPTIONS}" + [ "a${pppdoptions}" = "a" ] && pppdoptions="modem crtscts -detach defaultroute dump noipdefault usepeerdns usehostname ktune logfd 2 noauth name sakis3g lock maxfail 3" + if [ "a${PPPD_PEERS}" != "a" ]; then + if [ -d "${PPPD_PEERS}" ]; then + if [ -f "${PPPD_PEERS}/sakis3g" ]; then + debug "Found peers file %s.\n" "${PPPD_PEERS}/sakis3g" + pppdoptions="-detach dump logfd 2 name sakis3gpeer maxfail 3 call sakis3g" + fi + fi + fi + export CONNECTION_COMMAND="${setsidbin} ${pppdbin} ${MODEM_TTY} ${BAUD} ${pppdoptions} connect \"${chatbin} -v -f ${CONNECTION_CONF}\" user \"${APN_USER}\" password \"${APN_PASS}\"" + unset pppdoptions + debug "Connection command that will be used is: %s\n" "${CONNECTION_COMMAND}" + return 0 +} + +wvdial_config() { + need_binary "wvdial" + need_arg "BAUD" + unset CONNECTION_CONF; unset CONNECTION_COMMAND + ${touchbin} "/tmp/wvdial.tmp.$$" + if [ ! -w "/tmp/wvdial.tmp.$$" ]; then + show_fmt_error "Unable to create temporary wvdial config file within %s directory.\n" "/tmp" + return 99 + fi + CONNECTION_CONF="/tmp/wvdial.tmp.$$" + find_binary "chmod" && ${chmodbin} 600 "${CONNECTION_CONF}" + ${catbin} > "${CONNECTION_CONF}" <> "${CONNECTION_CONF}" + if [ ! -s "${CONNECTION_CONF}" ]; then + ${rmbin} -f "${CONNECTION_CONF}" + show_fmt_error "Failure to write on %s.\n" "${CONNECTION_CONF}" + unset CONNECTION_CONF + return 99 + fi + debug "Config file that will be used is: \"%s\".\n" "${CONNECTION_CONF}" + debug show_file "${CONNECTION_CONF}" + export CONNECTION_COMMAND="${setsidbin} ${wvdialbin} --config \"${CONNECTION_CONF}\"" + debug "Connection command that will be used is: %s\n" "${CONNECTION_COMMAND}" + return 0 +} + +ispconnect() { + [ "a${CONNECTION_COMMAND}" = "a" ] && return 95 + if ppp_fast_status; then + debug "Already connected.\n" + return 0 + fi + ! we_are_root && return 1 + debug run_command "${rmbin} -f \"/tmp/sakis3g.3gnet\"" + ! tty_not_busy "${MODEM_TTY}" && return 1 + if [ "a$1" = "anoretry" ]; then + verbose "Connecting (second attempt)" + else + verbose "Connecting" + fi + logpid=0 + if [ -n "${DEBUG}" ]; then + eval "${CONNECTION_COMMAND} &" + logpid=$! + else + eval "${CONNECTION_COMMAND} <&- >&- 2>&- &" + logpid=$! + fi + passed=0 + while ! notrunning "${logpid}" + do + ppp_slow_status && break + debug "Waiting for interface to go up (%d seconds passed).\n" "${passed}" + passed=`expr ${passed} + 1`; passed=`echo ${passed}` + if [ "a${passed}" = "a21" ]; then + debug "Giving up waiting for connection to occur.\n" + if find_binary "kill"; then + ${killbin} -1 ${logpid} 2> /dev/null + ! notrunning "${logpid}" && sleep 1 + ! notrunning "${logpid}" && sleep 1 + fi + break + fi + sleep 1 + done + if notrunning "${logpid}" && [ "a$1" != "anoretry" ]; then + unset logpid + ispconnect "noretry" + return $? + fi + unset passed + if ! ppp_slow_status; then + debug "Failed to connect.\n" + unset logpid + return 95 + fi + debug "Connection is established.\n" + ${printfbin} "%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n%s\n" "${ISPID}" "${ISPTEXT}" "${MODEM_VARIANT}" "${USBDRIVER}" "${MODEM_TTY}" "${MODEM}" "${OTHER}" "${APN}" "${CUSTOM_APN}" "${APN_USER}" "${APN_PASS}" "${logpid}" > "/tmp/sakis3g.3gnet" + [ -f "/tmp/sakis3g.3gnet" ] && ${chmodbin} 644 "/tmp/sakis3g.3gnet" + unset logpid + return 0 +} + +# Deletes all currently existing default gateways. +routing_delete_gateways() { + ! we_are_root && return 1 + ! find_binary "netstat" && return 1 + ! find_binary "route" && return 1 + while [ "1" = "1" ]; + do + gatehost=`${netstatbin} -rn | ${grepbin} "^0.0.0.0 " | ${tailbin} -1 | ${sedbin} -e "s/ */ /g" | ${cutbin} -d\ -f2` + if [ "a${gatehost}" != "a" ]; then + debug "Deleting default gateway %s.\n" "${gatehost}" + debug run_command "${routebin} del default gw ${gatehost}" + else + debug "Deleted all default gateways.\n" + break + fi + done + unset gatehost + return 0 +} + +# Makes sure only our pppint(ppp0) peer is used as default gateway. +routing_fix() { + ! find_binary "netstat" && return 1 + ! find_binary "route" && return 1 + need_arg "pppint" + hostpeer=`${netstatbin} -rn | ${grepbin} " ${pppint}$" | ${grepbin} -v "^0.0.0.0 " | ${cutbin} -d\ -f1` + if [ "a${hostpeer}" != "a" ]; then + routing_delete_gateways + debug run_command "${routebin} add default gw ${hostpeer}" + debug "Added correct default gateway: %s.\n" "${hostpeer}" + debug run_command "${netstatbin} -rn" + fi + unset hostpeer + return 0 +} + +dns_fix() { + debug "Checking if required to fix DNS settings.\n" + unset needdnsfix + if [ ! -f "/etc/resolv.conf" ]; then + needdnsfix=1 + debug "No %s exists. Will make it ourselves.\n" "/etc/resolv.conf" + else + debug show_file "/etc/resolv.conf" + baddns=`${grepbin} "10.11.12.13" "/etc/resolv.conf" | ${wcbin} -l`; baddns=`echo ${baddns}` + [ "a${baddns}" = "a0" ] && baddns=`${grepbin} "10.11.12.14" "/etc/resolv.conf" | ${wcbin} -l` + baddns=`echo ${baddns}` + if [ "a${baddns}" != "a0" ]; then + needdnsfix=1 + debug "File %s contains bad DNS servers. Will fix it.\n" "/etc/resolv.conf" + fi + unset baddns + fi + if [ "a${DNS}" != "a" ]; then + needdnsfix=1 + debug "Will fix DNS due to DNS servers being set: %s\n" "${DNS}" + fi + if [ "a${needdnsfix}" != "a1" ]; then + debug "No need to fix DNS servers. Skipping it.\n" + unset needdnsfix + return 0 + fi + if [ "a${DNS}" = "a" ]; then + debug "No DNS servers where set. Will use Google DNS.\n" + export DNS="8.8.8.8 8.8.4.4" + fi + ${rmbin} -f "/etc/resolv.conf" + ${touchbin} "/etc/resolv.conf" + ${chmodbin} 644 "/etc/resolv.conf" + for dnsserver in ${DNS} + do + ${printfbin} "nameserver %s\n" "${dnsserver}" >> "/etc/resolv.conf" + debug "Added name server %s to %s.\n" "${dnsserver}" "/etc/resolv.conf" + done + unset dnsserver + ${printfbin} "\n# This file was autogenerated by %s.\n\n" "Sakis3G script" >> "/etc/resolv.conf" + debug "Done setting up custom DNS server(s).\n" + return 0 +} + + +flow_post_connection() { + if [ "a${NOSMART}" != "a" ]; then + debug "Requested not to smart-fix connection.\n" + return 0 + fi + verbose "Fixing connection" + debug "Running post-connection setup.\n" + routing_fix + dns_fix +} + +flow_connect() { + ppp_fast_status && return 0 + flow_prepare "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + verbose "Resolving connection details" + flow_select_apn "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + flow_apn_user "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + flow_apn_pass "$@" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + [ "a${MODEM_TTY}" = "a" ] && return 99 + [ ! -c "${MODEM_TTY}" ] && return 99 + [ "a${APN}" = "a" -o "a${APN_USER}" = "a" -o "a${APN_PASS}" = "a" -o "a${ISP_DIAL}" = "a" ] && return 99 + ! at_default_commands "DIAL" && return 99 + [ "a${ttycommands}" = "a" ] && return 99 + export DIAL_COMMANDS="${ttycommands}" + if [ "a${direct_pppd}" != "a" ]; then + pppd_config "$@" + ret=$? + else + wvdial_config "$@" + ret=$? + fi + unset DIAL_COMMANDS + [ "${ret}" -ne "0" ] && return ${ret} + verbose "Initializing modem" + tty_send_command "${MODEM_TTY}" "INITIALIZE" + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + tty_send_command "${MODEM_TTY}" "STAGE7" + tty_send_command "${MODEM_TTY}" "STAGE8" + ispconnect "$@" + ret=$? + [ "a${CONNECTION_CONF}" != "a" ] && [ -f "${CONNECTION_CONF}" ] && ${rmbin} -f "${CONNECTION_CONF}" + unset CONNECTION_CONF; unset CONNECTION_COMMAND + [ "${ret}" -ne "0" ] && return ${ret} + flow_post_connection "$@" + if [ "a${CONNECTION_HOOK}" != "a" ]; then + debug "Will now execute CONNECTION_HOOK: %s.\n" "${CONNECTION_HOOK}" + term_clearline + debug run_command "${CONNECTION_HOOK}" + debug "Connection hook returned.\n" + fi + ! ppp_slow_status && return 99 + return ${ret} +} + +flow_disconnect() { + ! ppp_fast_status && return 0 + ! we_are_root && return 1 + verbose "Disconnecting" + if find_binary "killall"; then + ${killallbin} -q -1 pppd + sleep 1 + ppp_fast_status && ${killallbin} -q -9 pppd + elif find_binary "ps" && find_binary "kill"; then + ppppid=`${psbin} -C "pppd" -o pid= 2> /dev/null | ${grepbin} -i "PID"`; ppppid=`echo ${ppppid}` + for propid in ${ppppid} + do + debug run_command "kill -1 ${propid}" + done + ppppid=`${psbin} -C "pppd" -o pid= 2> /dev/null | ${grepbin} -i "PID"`; ppppid=`echo ${ppppid}` + for propid in ${ppppid} + do + debug run_command "kill -9 ${propid}" + done + unset ppppid; unset propid + else + show_fmt_error "Unable to stop running pppd session. Both %s and % were not found.\n" "kill" "killall" + return 1 + fi + sleep 1 + if ppp_fast_status; then + debug "Failed to disconnect.\n" + return 1 + fi + debug "Disconnected.\n" + return 0 +} + +compile_check_local_requirements() { + if [ "a${PROVIDER}" = "a" ]; then + show_fmt_error "Not running from within package.\n" + return 1 + fi + if [ ! -x "${PROVIDER}" ]; then + show_fmt_error "Reported package location is not executable: %s\n" "${PROVIDER}" + return 1 + fi + if [ ! -w "${PROVIDER}" ] && we_are_root; then + show_fmt_error "Unable to overwrite existing package %s. Check if on read-only filesystem.\n" "${PROVIDER}" + return 1 + fi + return 0 +} + +compile_check_dependencies() { + unset missing + for localdependency in bzip2 bunzip2 pwd basename dirname gcc tar dd stat cp chmod rm mkdir mv find rmdir printf grep expr ls sort uniq cut sed tr cat touch + do + ! find_binary "${localdependency}" && missing="${missing} ${localdependency}" + done + missing=`echo ${missing}` + if [ "a${missing}" != "a" ]; then + show_fmt_error "Following dependencies not found within path: %s\n" "${missing}" + unset missing + return 1 + fi + unset missing + return 0 +} + +compile_compilation_dependencies() { + [ "a${PROVIDER}" = "a" ] && return 1 + [ ! -x "${PROVIDER}" ] && return 1 + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null + ${touchbin} "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null + if [ ! -f "/tmp/sakis3g.source.$$.combined.c" ]; then + show_fmt_error "Unable to create file %s.\n" "/tmp/sakis3g.source.$$.combined.c" + return 1 + fi + ${PROVIDER} getfile usb_modeswitch.c 2> /dev/null > "/tmp/sakis3g.source.$$.c" + ${PROVIDER} getfile usb_modeswitch.h 2> /dev/null > "/tmp/sakis3g.source.$$.h" + ${catbin} "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > "/tmp/sakis3g.source.$$.combined.c" + if [ ! -s "/tmp/sakis3g.source.$$.combined.c" ]; then + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + show_fmt_error "Unable to extract %s source from package.\n" "Usb-ModeSwitch" + return 1 + fi + headerfiles=`${grepbin} "^#include <" "/tmp/sakis3g.source.$$.combined.c" | ${sedbin} -e "s/\( *\)/ /g" | ${cutbin} -d\ -f2 -s | ${sedbin} -e "s/^<\(.*\)>$/INCLUDE:\1/g" | ${grepbin} "^INCLUDE:" | ${cutbin} -d: -f2- -s` + if [ "a${headerfiles}" = "a" ]; then + unset headerfiles + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + show_fmt_error "Problem while parsing %s sources.\n" "Usb-ModeSwitch" + return 1 + fi + debug "Header files are:\n%s\n" "${headerfiles}" + accumulative="" + for header in ${headerfiles} + do + debug "Probing: %s\n" "${header}" + accumulative=`${printfbin} "%s\n%s\n" "${accumulative}" "${header}" | ${grepbin} -v "^$"` + echo "${accumulative}" | ${sedbin} -e "s/^\(.*\)$/#include <\1\>/g" > "/tmp/sakis3g.source.$$.combined.c" + ${printfbin} "int main(int argc, char **argv) {\nreturn 22;\n}\n\n" >> "/tmp/sakis3g.source.$$.combined.c" + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + if [ -f "/tmp/sakis3g.object.$$" ]; then + unset headerfiles; unset header; unset accumulative; + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + show_fmt_error "Unable to delete \"%s\".\n" "/tmp/sakis3g.object.$$" + return 1 + fi + debug run_command "${gccbin} -Wall -o \"/tmp/sakis3g.object.$$\" \"/tmp/sakis3g.source.$$.combined.c\"" + if [ ! -x "/tmp/sakis3g.object.$$" ]; then + if [ "a${header}" != "ausb.h" ]; then + show_fmt_error "Header file %s missing from your system.\n" "${header}" + else + show_fmt_error "Header file %s missing from your system. This usually indicates libusb (or libusb-compat) development kit missing.\n" "${header}" + fi + unset headerfiles; unset header; unset accumulative; + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + return 1 + fi + debug run_command "/tmp/sakis3g.object.$$" + ret=$? + if [ "${ret}" -ne "22" ]; then + show_fmt_error "Unusable binary after including \"%s\".\n" "${header}" + unset headerfiles; unset header; unset accumulative; + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + return 1 + fi + debug "No problem encountered when including \"%s\".\n" "${header}" + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + done + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" > /dev/null 2> /dev/null + unset header; unset headerfiles; + debug "Will now attempt linking.\n" + echo "${accumulative}" | ${sedbin} -e "s/^\(.*\)$/#include <\1\>/g" > "/tmp/sakis3g.source.$$.combined.c" + ${catbin} "/tmp/sakis3g.source.$$.h" "/tmp/sakis3g.source.$$.c" | ${grepbin} -v "^#include" >> "/tmp/sakis3g.source.$$.combined.c" + debug show_file "/tmp/sakis3g.source.$$.combined.c" + debug run_command "${gccbin} -Wall -lusb -o \"/tmp/sakis3g.object.$$\" \"/tmp/sakis3g.source.$$.combined.c\"" + unset accumulative; + ${rmbin} -f "/tmp/sakis3g.source.$$.combined.c" "/tmp/sakis3g.source.$$.c" "/tmp/sakis3g.source.$$.h" > /dev/null 2> /dev/null + if [ ! -x "/tmp/sakis3g.object.$$" ]; then + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + show_fmt_error "Failed to link %s. This usually indicates libusb (or libusb-compat) development kit missing.\n" "Usb-ModeSwitch" + return 1 + fi + ${rmbin} -f "/tmp/sakis3g.object.$$" > /dev/null 2> /dev/null + debug "Linking test was successful.\n" + return 0 +} + +compile_perform() { + [ "a${PROVIDER}" = "a" ] && return 1 + [ ! -x "${PROVIDER}" ] && return 1 + tempdestination="/tmp/sakis3g.recompile.$$" + debug run_command "${rmbin} -rf \"${tempdestination}\"" + debug run_command "${mkdirbin} \"${tempdestination}\"" + if [ ! -d "${tempdestination}" ]; then + show_fmt_error "Unable to create temporary folder \"%s\".\n" "${tempdestination}" + unset tempdestination + return 1 + fi + debug run_command "${touchbin} \"${tempdestination}/test.$$\"" + if [ ! -w "${tempdestination}/test.$$" ]; then + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "No write access to temporary folder \"%s\".\n" "${tempdestination}" + unset tempdestination + return 1 + fi + debug run_command "${rmbin} -rf \"${tempdestination}/\"*" + if [ ! -d "${tempdestination}" ]; then + show_fmt_error "Oops. Weird \"%s\" version. Deleted temporary folder \"%s\".\n" "${rmbin}" "${tempdestination}" + unset tempdestination + return 1 + fi + debug run_command "${PROVIDER} disassemble \"${tempdestination}/.\"" + if [ ! -x "${tempdestination}/sakis3g-${MYVERSION}/compile" ]; then + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "Failed to disassemble Sakis3G package.\n" "${tempdestination}" + unset tempdestination + return 1 + fi + debug run_command "${rmbin} -f \"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz\"" + compilation_error=`cd "${tempdestination}/sakis3g-${MYVERSION}"; ./compile 2>&1` + debug "Compilation output:\n%s\n" "${compilation_error}" + if [ ! -x "${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" -o ! -s "${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" ]; then + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "Failed to compile. Compilation output:\n%s\n" "${compilation_error}" + unset compilation_error; unset tempdestination + return 1 + fi + unset compilation_error + verification=`"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz" usb_modeswitch --version 2> /dev/null | ${grepbin} -i "josua" | ${wcbin} -l`; verification=`echo ${verification}` + if [ "a${verification}" = "a" -o "a${verification}" = "a0" ]; then + unset verification + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "Failed to verify result of compilation.\n" + unset tempdestination + return 1 + fi + unset verification + debug run_command "${rmbin} -f \"${PROVIDER}.backup\"" + if [ -f "${PROVIDER}.backup" ]; then + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "Unable to delete previously existing \"%s\".\n" "${PROVIDER}.backup" + unset tempdestination + return 1 + fi + debug run_command "${cpbin} \"${PROVIDER}\" \"${PROVIDER}.backup\"" + if [ ! -f "${PROVIDER}.backup" ]; then + debug run_command "${rmbin} -rf \"${tempdestination}\"" + show_fmt_error "Unable to create a safe backup to \"%s\".\n" "${PROVIDER}.backup" + unset tempdestination + return 1 + fi + debug run_command "${lsbin} -l \"${PROVIDER}\"" + # No rm, or we loose owner and rights information + #debug run_command "${rmbin} -f \"${PROVIDER}\"" + #debug run_command "${lsbin} -l \"${PROVIDER}\"" + debug run_command "${cpbin} \"${tempdestination}/sakis3g-${MYVERSION}/build/sakis3gz\" \"${PROVIDER}\"" + debug run_command "${lsbin} -l \"${PROVIDER}\"" + debug run_command "${rmbin} -rf \"${tempdestination}\"" + unset tempdestination + verification=`"${PROVIDER}" usb_modeswitch --version 2> /dev/null | ${grepbin} -i "josua" | ${wcbin} -l`; verification=`echo ${verification}` + if [ "a${verification}" = "a" -o "a${verification}" = "a0" ]; then + debug "Verification failed. Restoring previous version.\n" + debug run_command "${cpbin} \"${PROVIDER}.backup\" \"${PROVIDER}\"" + unset verification + if [ -x "${PROVIDER}" ]; then + show_fmt_error "Failed to succesfully place new version. You are still using old version.\n" + elif [ -x "${PROVIDER}.backup" ]; then + show_fmt_error "Failed to succesfully create new version. Old version is still available at \"%s\".\n" "${PROVIDER}.backup" + else + show_fmt_error "Something really bad happened. I am really sorry. You may need to re-download Sakis3G.\n" + fi + return 1 + fi + unset verification + debug run_command "${rmbin} -f \"${PROVIDER}.backup\"" + debug run_command "${lsbin} -l \"${PROVIDER}.backup\"" + debug "Succesfully recompiled.\n" + return 0 +} + +flow_compile() { + if [ "a${binaryfree}" != "a" ]; then + show_fmt_error "You are running a binary free version of Sakis3G. Unable to recompile %s.\n" "Usb-ModeSwitch" + return 99 + fi + verbose "Checking tools availability" + compile_check_local_requirements + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + verbose "Checking dependencies" + compile_check_dependencies + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + verbose "Testing compiler" + compile_compilation_dependencies + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + verbose "Compiling" + compile_perform + ret=$?; [ "${ret}" -ne "0" ] && return ${ret} + return 0 +} + +flow_report() { + if ! status_connected; then + show_fmt_error "You need to be connected for generating report.\n" + return 6 + fi + unset report_text + old_translation=${notranslate} + export notranslate=1 + report_text="Sakis3G version: ${MYVERSION}" + if [ "a${PROVIDER}" = "a" ]; then + report_text=`${printfbin} "%s\nNot running from within package.\n" "${report_text}"` + elif [ ! -x "${PROVIDER}" ]; then + report_text=`${printfbin} "%s\nPackage is not executable.\n" "${report_text}"` + else + if [ "a${binaryfree}" != "a" ]; then + if [ "a${stripped}" != "a" ]; then + report_text=`${printfbin} "%s\nRunning a binary free version.\n" "${report_text}"` + else + report_text=`${printfbin} "%s\nRunning a stripped version.\n" "${report_text}"` + fi + switchversion="95" + else + switchversion=`${PROVIDER} usb_modeswitch --version 2> /dev/null || echo $?` + fi + if [ "a${switchversion}" = "a95" ]; then + if find_binary "usb_modeswitch"; then + switchversion=`${usb_modeswitchbin} --version 2> /dev/null` + report_text=`${printfbin} "%s\nSystem provided Usb-ModeSwitch:\n%s\n" "${report_text}" "${switchversion}"` + else + report_text=`${printfbin} "%s\nUsb-ModeSwitch is not available.\n" "${report_text}"` + fi + else + switchversion=`${printfbin} "%s\n" "${switchversion}" | ${grepbin} -i version` + report_text=`${printfbin} "%s\nUsing embedded Usb-ModeSwitch version:\n%s\n" "${report_text}" "${switchversion}"` + fi + fi + if find_binary "uname"; then + report_text=`${printfbin} "%s\nKernel version: %s\nArchitect: %s\n" "${report_text}" "\`${unamebin} -r\`" "\`${unamebin} -m\`"` + else + report_text=`${printfbin} "%s\nUtility uname is not available.\n" "${report_text}"` + fi + report_text=`${printfbin} "%s\nSelected UI is: %s\n" "${report_text}" "${SGUI}"` + info_text=`action_info report | ${grepbin} -v "^$" | ${grepbin} -v "^ $"` + report_text=`${printfbin} "%s\n%s\n" "${report_text}" "${info_text}"` + state_variables "APN_USER APN_PASS SIM_PIN SGUI UNDISCOVERABLE BLUETOOTH MENU MOREMENU BALOONIZER" + report_text=`${printfbin} "%s\nVariables: %s\n" "${report_text}" "${statevariables}"` + unset info_text + export notranslate="${old_translation}" + [ "a${notranslate}" = "a" ] && unset notranslate + unset old_translation + trtext=`format_text "Please report following text:\n"` + notify "%s\n\n%s\n" "${trtext}" "${report_text}" + unset trtext; unset switchversion; unset report_text + return 0 +} + + +# Returns 0 if connected, 1 if not connected. +# Sets as much of the following information: +# - statusnet containing numeric ID of ISP +# - statusname containing text of ISP or nothing +# - statusicon if statusnet exists within operator database and contains icon. +# Sets ISPID only if not set already. +# It is possible that it returns 0 and not set variables. This happens +# if ppp interface was initiated by another application. +status_connected() { + unset statusnet; unset statusname; unset statusicon; unset localpid + ! ppp_fast_status && return 1 + if [ -r "/tmp/sakis3g.3gnet" ]; then + statusnet=`${headbin} -1 "/tmp/sakis3g.3gnet"` + statusname=`${headbin} -2 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + debug "Retrieved from %s: \"%s\" - \"%s\"\n" "/tmp/sakis3g.3gnet" "${statusnet}" "${statusname}" + statusnet=`echo "${statusnet}" | ${grepbin} "^[0-9][0-9][0-9][0-9][0-9]"` + if [ "a${statusnet}" != "a" ]; then + [ "a${statusname}" = "a${statusnet}" ] && unset statusname + debug "Retrieved ISP ID from %s: %s\n" "/tmp/sakis3g.3gnet" "${statusnet}" + [ "a${statusname}" != "a" ] && debug "Also retrieved ISP name: %s\n" "${statusname}" + else + unset statusname; unset statusnet + debug "Invalid or not existing %s within %s.\n" "ISPID" "/tmp/sakis3g.3gnet" + fi + if [ "a${statusnet}" != "a" ] && [ "a${ISPID}" = "a" -o "a${ISPID}" = "a${statusnet}" ]; then + if [ "a${MODEM_VARIANT}" = "a" ]; then + MODEM_VARIANT=`${headbin} -3 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${MODEM_VARIANT}" != "a" ] && export MODEM_VARIANT && debug "Also read: %s\n" "${MODEM_VARIANT}" + fi + if [ "a${USBDRIVER}" = "a" ]; then + USBDRIVER=`${headbin} -4 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${USBDRIVER}" != "a" ] && export USBDRIVER && debug "Also read: %s\n" "${USBDRIVER}" + fi + if [ "a${MODEM_TTY}" = "a" ]; then + MODEM_TTY=`${headbin} -5 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${MODEM_TTY}" != "a" ] && export MODEM_TTY && debug "Also read: %s\n" "${MODEM_TTY}" + fi + if [ "a${MODEM}" = "a" ]; then + MODEM=`${headbin} -6 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${MODEM}" != "a" ] && export MODEM && debug "Also read: %s\n" "${MODEM}" + fi + if [ "a${OTHER}" = "a" ]; then + OTHER=`${headbin} -7 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${OTHER}" != "a" ] && export OTHER && debug "Also read: %s\n" "${OTHER}" + fi + if [ "a${APN}" = "a" ]; then + APN=`${headbin} -8 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${APN}" != "a" ] && export APN && debug "Also read: %s\n" "${APN}" + fi + if [ "a${CUSTOM_APN}" = "a" -a "a${APN}" = "aCUSTOM_APN" ]; then + CUSTOM_APN=`${headbin} -9 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${CUSTOM_APN}" != "a" ] && export CUSTOM_APN && debug "Also read: %s\n" "${CUSTOM_APN}" + fi + if [ "a${APN_USER}" = "a" ]; then + APN_USER=`${headbin} -10 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${APN_USER}" != "a" ] && export APN_USER && debug "Also read: %s\n" "${APN_USER}" + fi + if [ "a${APN_PASS}" = "a" ]; then + APN_PASS=`${headbin} -11 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + [ "a${APN_PASS}" != "a" ] && export APN_PASS && debug "Also read: %s\n" "${APN_PASS}" + fi + localpid=`${headbin} -12 "/tmp/sakis3g.3gnet" | ${tailbin} -1` + if [ "a${localpid}" != "a" ]; then + localprocess=`${psbin} -p ${localpid} -o comm= 2> /dev/null` + if [ "a${localprocess}" != "a" ]; then + debug "Process ID %s is: %s\n" "${localpid}" "${localprocess}" + [ "${localprocess}" != "pppd" -a "${localprocess}" != "wvdial" ] && unset localprocess + elif notrunning "${localpid}"; then + debug "Process ID %s is not running.\n" "${localpid}" + elif [ "a${localprocess}" = "a" ]; then + debug "Process ID %s is not valid.\n" "${localpid}" + fi + if [ "a${localprocess}" = "a" -a "a${ISPID}" = "a" ]; then + debug "Status file %s is stalled. Will discard information read from it.\n" "/tmp/sakis3g.3gnet" + unset statusnet; unset statusname + fi + fi + unset localpid; unset localprocess + fi + else + debug "Invalid or not existing %s.\n" "/tmp/sakis3g.3gnet" + fi + if [ "a${ISPID}" != "a" ]; then + debug "%s is set to: %s\n" "ISPID" "${ISPID}" + if [ "a${statusnet}" = "a" ]; then + statusnet="${ISPID}" + debug "Was adapted since file not available.\n" "statusnet" + if [ "a${ISPTEXT}" != "a" -a "a${ISPTEXT}" != "a${ISPID}" ]; then + statusname="${ISPTEXT}" + debug "Also adapted %s: %s\n" "ISPTEXT" "${ISPTEXT}" + fi + elif [ "a${statusnet}" = "a${ISPID}" ]; then + debug "It matches value retrieved from file.\n" + if [ "a${ISPTEXT}" != "a" -a "a${ISPTEXT}" != "a${ISPID}" -a "a${statusname}" = "a" ]; then + statusname="${ISPTEXT}" + debug "Also adapted %s since networks match: %s\n" "ISPTEXT" "${ISPTEXT}" + fi + else + debug "Does not match value retrieved from file.\n" + debug "Will trust file.\n" + fi + else + debug "%s is not set.\n" "ISPID" + if [ "a${statusnet}" = "a" ]; then + debug "Unable to determine on which network we are connected.\n" + else + export ISPID="${statusnet}" + debug "All information derived from file.\n" + debug "Also set %s from file contents.\n" "ISPID" + fi + fi + if net_info "${statusnet}" "${statusname}" && [ "a${BASERESULT}" != "a" ]; then + statusproduct=`echo "${BASERESULT}" | ${cutbin} -f3 -s` + [ "a${statusproduct}" != "a" ] && export statusproduct + statusicon=`echo "${BASERESULT}" | ${cutbin} -f8 -s` + [ "a${statusicon}" != "a" ] && export statusicon + if [ "a${statusname}" = "a" ]; then + statusname=`echo "${BASERESULT}" | ${cutbin} -d: -f2 -s` + [ "a${statusname}" != "a" ] && debug "Retrieved %s name from database: %s\n" "${statusnet}" "${statusname}" + fi + fi + if [ "a${statusnet}" = "a" ]; then + unset statusnet; unset statusname + else + export statusnet + if [ "a${statusname}" = "a" ]; then + unset statusname + else + export statusname + fi + fi + return 0 +} + +# Method invoked when "status" action was requested. +action_status() { + unset verbosecurrentcount + if ! ppp_fast_status; then + show_fmt_error "Not connected.\n" + return 6 + fi + status_connected + if [ "a${statusnet}" != "a" ]; then + if [ "a${statusnet}" != "a${statusname}" -a "a${statusname}" != "a" ]; then + if [ "a${MODEM_VARIANT}" != "a" ]; then + finalnotify "%s connected to %s (%s)." "${MODEM_VARIANT}" "${statusname}" "${statusnet}" + else + finalnotify "Connected to %s (%s)." "${statusname}" "${statusnet}" + fi + else + if [ "a${MODEM_VARIANT}" != "a" ]; then + finalnotify "%s connected to %s." "${MODEM_VARIANT}" "${statusnet}" + else + finalnotify "Connected to %s." "${statusnet}" + fi + fi + else + finalnotify "Connected." + fi + return 0 +} + +action_info() { + unset verbosecurrentcount + if ! ppp_fast_status; then + notify "Not connected.\n" + return 0 + fi + status_connected + if [ "a${statusnet}" = "a" ]; then + notify "Unable to gather connection information.\n" + return 0 + fi + if [ "a$1" != "areport" ]; then + infotext=`translate_text "Connection Information"` + infotext=`${printfbin} "%s\n \n" "${infotext}"` + fi + [ "a${pppint}" != "a" ] && localtext=`format_text "Interface:\t\t\tP-t-P (%s)\n" "${pppint}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + infotext=`${printfbin} "%s\n \n" "${infotext}"` + if [ "a$1" != "areport" ]; then + if find_binary "stat"; then + upsince=`${statbin} --printf="%z" "/tmp/sakis3g.3gnet" | ${cutbin} -d: -f1,2 -s` + if [ "a${upsince}" != "a" ]; then + localtext=`format_text "Connected since:\t%s\n" "${upsince}"` + infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + fi + unset upsince + fi + if [ -r "/proc/net/dev" -a "a${pppint}" != "a" ]; then + traffic=`${sedbin} -e "s/ */ /g" "/proc/net/dev" | ${grepbin} "^\( *\)${pppint}:" | ${headbin} -1 | ${cutbin} -d: -f2- | ${sedbin} -e "s/^ *//g" | ${cutbin} -d\ -f1,9` + debug "Traffic details are: %s\n" "${traffic}" + bytesreceived=`echo ${traffic} | ${cutbin} -d\ -f1 -s` + [ "a${bytesreceived}" != "a" ] && bytesreceived=`expr \( ${bytesreceived} + 512 \) / 1024 2> /dev/null` + [ "a${bytesreceived}" != "a" ] && localtext=`format_text "Kilobytes received:\t%d\n" ${bytesreceived}` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + bytessent=`echo ${traffic} | ${cutbin} -d\ -f2 -s` + [ "a${bytessent}" != "a" ] && bytessent=`expr \( ${bytessent} + 512 \) / 1024 2> /dev/null` + [ "a${bytessent}" != "a" ] && localtext=`format_text "Kilobytes sent:\t%d\n" ${bytessent}` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + unset traffic; unset bytesreceived; unset bytessent + fi + fi + localtext=`format_text "Network ID:\t\t%s" "${statusnet}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n\n%s\n" "${infotext}" "${localtext}"`; unset localtext + [ "a${statusname}" != "a" ] && localtext=`format_text "Operator name:\t%s" "${statusname}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + if [ "a${APN}" != "a" ]; then + if [ "a${APN}" = "aCUSTOM_APN" -a "a${CUSTOM_APN}" != "a" ]; then + localtext=`format_text "APN:\t\t\t%s" "${CUSTOM_APN}"` + elif [ "a${APN}" != "aCUSTOM_APN" ]; then + localtext=`format_text "APN:\t\t\t%s" "${APN}"` + fi + fi + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + infotext=`${printfbin} "%s\n \n" "${infotext}"` + [ "a${MODEM_VARIANT}" != "a" ] && localtext=`format_text "Modem:\t\t\t%s\n" "${MODEM_VARIANT}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + if [ "a${MODEM}" != "a" ]; then + if [ "a${MODEM}" != "a" -a "a${MODEM}" != "aOTHER" ]; then + localtext=`format_text "Modem type:\t\tUSB\n"` + elif [ "a${MODEM}" = "aOTHER" ]; then + if [ "a${OTHER}" = "aUSBMODEM" ]; then + localtext=`format_text "Modem type:\t\tUSB\n"` + elif [ "a${OTHER}" = "aBLUETOOTH" ]; then + localtext=`format_text "Modem type:\t\tBluetooth\n"` + else + localtext=`format_text "Modem type:\t\tCustom\n"` + fi + else + localtext=`format_text "Modem type:\t\tUnknown\n"` + fi + else + localtext=`format_text "Modem type:\t\tUnspecified\n"` + fi + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + [ "a${USBDRIVER}" != "a" ] && localtext=`format_text "Kernel driver:\t\t%s\n" "${USBDRIVER}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + [ "a${MODEM_TTY}" != "a" ] && localtext=`format_text "Device:\t\t\t%s\n" "${MODEM_TTY}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + infotext=`${printfbin} "%s\n \n" "${infotext}"` + if [ "a$1" != "areport" ]; then + if find_binary "ifconfig" && [ "a${pppint}" != "a" ]; then + ipaddress=`${ifconfigbin} ${pppint} | ${sedbin} -e "s/^.*:\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\) .*:\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\) \(.*\):\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)\.\([0-9][0-9]*\)$/IPADDRESSES: \1.\2.\3.\4 \5.\6.\7.\8/g" | ${grepbin} "^IPADDRESSES:" | ${cutbin} -d: -f2- -s` + if [ "a${ipaddress}" != "a" ]; then + localip=`echo ${ipaddress} | ${cutbin} -d\ -f1 -s` + localpeer=`echo ${ipaddress} | ${cutbin} -d\ -f2 -s` + localmask="255.255.255.255" + [ "a${localip}" != "a" ] && localtext=`format_text "IP Address:\t\t%s\n" "${localip}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + [ "a${localip}" != "a" ] && localtext=`format_text "Subnet Mask:\t\t%s\n" "${localmask}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + [ "a${localpeer}" != "a" ] && localtext=`format_text "Peer IP Address:\t%s\n" "${localpeer}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + unset localip; unset localpeer; unset localmask + fi + unset ipaddress + fi + if find_binary "netstat" && [ "a${pppint}" != "a" ]; then + localpeer=`${netstatbin} -rn | ${grepbin} "^0.0.0.0 " | ${sedbin} -e "s/ */ /g" | ${cutbin} -d\ -f2 -s`; localpeer=`echo ${localpeer}` + [ "a${localpeer}" != "a" ] && localtext=`format_text "Default route(s):\t%s\n" "${localpeer}"` + [ "a${localtext}" != "a" ] && infotext=`${printfbin} "%s\n%s\n" "${infotext}" "${localtext}"`; unset localtext + unset localpeer + fi + [ "a${SGUI}" != "azenity" ] && infotext=`echo "${infotext}" | ${sedbin} -e "s/\( *\)/ /g"` + notify "%s\n" "${infotext}" + else + infotext=`echo "${infotext}" | ${sedbin} -e "s/\( *\)/ /g"` + ${printfbin} "%s\n" "${infotext}" + fi + unset localtext; unset infotext + return 0 +} + +action_desktop() { + # Retrieve icon information if possible + [ "a${runner}" = "a" ] && return 1 + [ "a${runhome}" = "a" ] && return 1 + [ ! -d "${runhome}" ] && return 1 + need_binary "touch"; need_binary "mkdir"; need_binary "chown"; need_binary "chmod"; need_binary "cat" + unset desktopdestination + if [ "a${DESKTOP}" = "a" ] && find_binary "xdg-user-dir"; then + DESKTOP=`${xdg_user_dirbin} DESKTOP` + [ "a${DESKTOP}" = "a" ] && DESKTOP=`${xdg_user_dirbin} desktop` + if [ "a${DESKTOP}" != "a" ]; then + DESKTOP=`echo "${DESKTOP}" | ${sedbin} -e "s/\/$//g"` + DESKTOP=`${basenamebin} "${DESKTOP}"` + fi + fi + if [ "a${DESKTOP}" != "a" ] && [ -d "${DESKTOP}" ]; then + desktopdestination="${DESKTOP}" + elif [ -d "${runhome}/Desktop" ]; then + desktopdestination="${runhome}/Desktop" + elif [ -d "${runhome}/desktop" ]; then + desktopdestination="${runhome}/desktop" + elif [ "a${HOME}" != "a" -a "a${DESKTOP}" != "a" ] && [ -d "${HOME}/${DESKTOP}" ]; then + desktopdestination="${HOME}/${DESKTOP}" + elif find_binary "pwd"; then + desktopdestination="`${pwdbin} 2> /dev/null`" + else + desktopdestination="." + fi + [ "a${desktopdestination}" = "a" ] && desktopdestination="." + debug "Destination of shortcut is: %s\n" "${desktopdestination}" + if status_connected && [ "a${statusicon}" != "a" -a "a${statusname}" != "a" ] && find_binary "wget" && find_binary "basename"; then + user_select "DESKTOPICON" "Desktop icon" "Select icon to use for shortcut" "OK" "Cancel" "SAKIS3G" "Sakis3G tux icon" "OPERATOR" "${statusname} icon" + selection=$? + case "${selection}" in + 1) + DESKTOPICON="SAKIS3G" + ;; + 2) + DESKTOPICON="OPERATOR" + + + ;; + 98) + return 98 + ;; + *) + return 99 + ;; + esac + else + debug "${statusicon} ${statusname}\n" + debug "Automatically selecting %s icon.\n" "Sakis3G" + DESKTOPICON="SAKIS3G" + fi + if [ "a${DESKTOPICON}" = "aOPERATOR" ]; then + extension=`${basenamebin} "${statusicon}" | ${cutbin} -d. -f2-` + verbose "Retrieving operator icon" + debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + debug run_command "${wgetbin} -O \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${statusicon}\"" + if [ ! -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then + debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + show_fmt_error "Unable to get %s icon, unknown reason." "${statusname}" + DESKTOPICON="SAKIS3G" + else + debug "Successfully retrieved %s icon.\n" "operator" + fi + fi + if [ "a${DESKTOPICON}" = "aSAKIS3G" ] && [ "a${PROVIDER}" != "a" ] && [ -x "${PROVIDER}" ]; then + extension="png" + "${PROVIDER}" getfile "files/sakis3g.png" > "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" 2> /dev/null + if [ ! -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then + debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + show_fmt_error "Unable to get %s icon, unknown reason." "Sakis3G" + DESKTOPICON="" + else + debug "Successfully retrieved %s icon.\n" "Sakis3G" + fi + fi + if [ -s "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ]; then + debug run_command "${mkdirbin} -p \"${runhome}/.local\"" + debug run_command "${chownbin} ${runner} \"${runhome}/.local\"" + debug run_command "${mkdirbin} -p \"${runhome}/.local/share\"" + debug run_command "${chownbin} ${runner} \"${runhome}/.local/share\"" + debug run_command "${mkdirbin} -p \"${runhome}/.local/share/icons\"" + debug run_command "${chownbin} ${runner} \"${runhome}/.local/share/icons\"" + if [ "a${extension}" = "agif" -o "a${extension}" = "aGIF" -o "a${extension}" = "aGif" ]; then + debug run_command "${mvbin} \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${runhome}/.local/share/icons/sakis3g.png\"" + debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + extension="png" + else + debug run_command "${mvbin} \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\" \"${runhome}/.local/share/icons/sakis3g.${extension}\"" + debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + fi + if [ -s "${runhome}/.local/share/icons/sakis3g.${extension}" ]; then + debug run_command "${chownbin} ${runner} \"${runhome}/.local/share/icons/sakis3g.${extension}\"" + debug run_command "${chmodbin} 644 \"${runhome}/.local/share/icons/sakis3g.${extension}\"" + icon="${runhome}/.local/share/icons/sakis3g.${extension}" + debug "Successfully installed icon to \"%s\".\n" "${runhome}/.local/share/icons/sakis3g.${extension}" + fi + else + debug "File %s does not exist or is empty.\n" "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" + [ -f "/tmp/sakis3g.$$.${ISPID}_logo.${extension}" ] && debug run_command "${rmbin} -f \"/tmp/sakis3g.$$.${ISPID}_logo.${extension}\"" + if [ -f "/usr/share/icons/gnome/scalable/status/nm-device-wireless.svg" ]; then + debug "Selecting default GNOME icon.\n" + icon="/usr/share/icons/gnome/scalable/status/nm-device-wireless.svg" + else + debug "Unable to locate any icon.\n" + icon="" + fi + fi + debug "Icon selected is: %s\n" "${icon}" + shortcuttitle="Sakis3G" + [ "a${DESKTOPICON}" = "aOPERATOR" ] && shortcuttitle="${statusproduct}" && [ "a${shortcuttitle}" = "a" ] && shortcuttitle="${statusname} Internet" + [ "a${shortcuttitle}" = "a" ] && shortcuttitle="Sakis3G" + commenttext=`format_text "Manages 3G internet connection and 3G USB modems"` + ${catbin} > "${desktopdestination}/sakis3g.desktop" < /dev/null > /dev/null + [ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -9 ${helperpid} 2> /dev/null > /dev/null + if [ "a${balloons}" != "a" ] && [ "a${BALOONIZERPID}" != "a" -o "a${BALOONIZER}" != "a" ]; then + [ "a${BALOONIZER}" != "a" ] && [ -f "${BALOONIZER}" ] && debug run_command "${rmbin} -f \"${BALOONIZER}\"" + [ "a${BALOONIZERPID}" != "a" ] && ! notrunning "${BALOONIZERPID}" && debug run_command "${killbin} -1 ${BALOONIZERPID}" + [ "a${BALOONIZERPID}" != "a" ] && ! notrunning "${BALOONIZERPID}" && debug run_command "${killbin} -9 ${BALOONIZERPID}" + find_binary "ps" && tailpid=`${psbin} -A -o pid,command | ${grepbin} "${tailbin} -f ${BALOONIZER}" | ${grepbin} -v "${grepbin}" | ${cutbin} -d\ -f1` + [ "a${tailpid}" != "a" ] && ! notrunning "${tailpid}" && debug run_command "${killbin} -1 ${tailpid}" + [ "a${tailpid}" != "a" ] && ! notrunning "${tailpid}" && debug run_command "${killbin} -9 ${tailpid}" + unset BALOONIZERPID; unset BALOONIZER + fi +} + +action_helper() { + if ! find_binary "zenity"; then + show_fmt_error "Unable to install tray icon to system notification area. You need to install %s.\n" "zenity" + return 0 + fi + need_binary "kill" + [ "a${PROVIDER}" = "a" ] && return 1 + [ ! -x "${PROVIDER}" ] && return 1 + if we_are_root_already && [ "a${MENU}" != "a" ]; then + debug "Calling menu since state variable MENU is set.\n" + action_menu "$@" + unset MENU + debug "MENU actor returned. Will now run as helper.\n" + fi + debug run_command "${rmbin} -f /tmp/sakis3g.helper.icon.red.$$.png /tmp/sakis3g.helper.icon.green.$$.png /tmp/sakis3g.helper.icon.yellow.$$.png" + addexittrap helper_cleaner + ${PROVIDER} getfile files/sakis3g.red.png > "/tmp/sakis3g.helper.icon.red.$$.png" 2> /dev/null + ${PROVIDER} getfile files/sakis3g.green.png > "/tmp/sakis3g.helper.icon.green.$$.png" 2> /dev/null + ${PROVIDER} getfile files/sakis3g.yellow.png > "/tmp/sakis3g.helper.icon.yellow.$$.png" 2> /dev/null + if [ ! -s "/tmp/sakis3g.helper.icon.green.$$.png" ]; then + debug "Failed to retrieve green/connected state icon.\n" + return 1 + elif [ ! -s "/tmp/sakis3g.helper.icon.red.$$.png" ]; then + debug "Failed to retrieve red/no hardware state icon.\n" + return 1 + elif [ ! -s "/tmp/sakis3g.helper.icon.yellow.$$.png" ]; then + debug "Failed to retrieve yellow/not connected state icon.\n" + return 1 + fi + debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.red.$$.png\"" + debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.green.$$.png\"" + debug run_command "${chmodbin} 644 \"/tmp/sakis3g.helper.icon.yellow.$$.png\"" + if [ "a${balloons}" != "a" ]; then + # Establish balloon helper now that will be accessible from root session later + if [ "a${BALOONIZER}" = "a" ]; then + BALOONIZER="/tmp/sakis3g.baloon.pipe.$$" + debug run_command "${rmbin} -f \"${BALOONIZER}\"" + debug run_command "${touchbin} -f \"${BALOONIZER}\"" + if [ -w "${BALOONIZER}" ]; then + ${printfbin} "\n\n\n\n\nvisible:false\n" >> "${BALOONIZER}" + export BALOONIZER + eval ${tailbin} -f "${BALOONIZER}" "2> /dev/null" | ${zenitybin} --notification --listen > /dev/null 2> /dev/null & + BALOONIZERPID=$!; eval "disown -a" > /dev/null 2> /dev/null + export BALOONIZERPID + ${printfbin} "visible:false\n" >> "${BALOONIZER}" + ${printfbin} "visible:false\nvisible:false\n" >> "${BALOONIZER}" + debug "Balloon pipe created. Location is \"%s\" and runs with PID %d.\n" "${BALOONIZER}" "${BALOONIZERPID}" + else + debug "Error while creating pipe for balloons.\n" + debug run_command "${rmbin} -f \"${BALOONIZER}\"" + unset BALOONIZER + + fi + elif [ -w "${BALOONIZER}" ]; then + debug "Will be using already existing balloon pipe: %s\n" "${BALOONIZER}" + elif [ ! -w "${BALOONIZER}" ]; then + debug "Balloons pipe \"%s\" exists but no write access granted.\n" "${BALOONIZER}" + fi + [ "a${BALOONIZER}" = "a" ] && debug "No balloons will be appearing.\n" + fi + debug "All set. Going into helper mode.\n" + while [ "1" = "1" ] + do + if ppp_slow_status && status_connected; then + helpertext="`translate_text "Connected"`" + [ "a${statusname}" != "a" ] && helpertext="${statusname}" + helperconnected=2 + else + usb_connected_modems + if [ "a${usb_modem_devices}" != "a" ]; then + helpertext="`translate_text "Not connected"`" + helperconnected=1 + helpermodems=`echo "${usb_modem_devices}" | ${cutbin} -d: -f3- | ${trbin} "\n" " "` + else + helpertext="`translate_text "No USB modem"`" + helperconnected=0 + fi + fi + # Check if something was changed not by us. Then balloon user. + if [ "a${balloons}" != "a" ]; then + if [ "a${BALOONIZER}" != "a" ] && [ "a${previousstatus}" != "a" -a "a${previousstatus}" != "a${helperconnected}" ]; then + debug "Status changed. Not by us.\n" + notificationtext=`translate_text "Notification"` + if [ "a${helperconnected}" = "a2" ]; then + iconpath="/tmp/sakis3g.helper.icon.green.$$.png" + elif [ "a${helperconnected}" = "a1" ]; then + iconpath="/tmp/sakis3g.helper.icon.yellow.$$.png" + elif [ "a${helperconnected}" = "a0" ]; then + iconpath="/tmp/sakis3g.helper.icon.red.$$.png" + else + iconpath="/tmp/sakis3g.helper.icon.yellow.$$.png" + fi + unset largetext; unset smalltext + if [ "a${previousstatus}" = "a0" -a "a${helperconnected}" = "a1" ]; then + largetext=`translate_text "USB Modem plugged"` + smalltext=`format_text "USB Modem %s is now plugged on computer." "${helpermodems}"` + elif [ "a${helperconnected}" = "a2" ]; then + largetext=`translate_text "Connected"` + if [ "a${MODEM_VARIANT}" != "a" -a "a${statusname}" != "a" ]; then + smalltext=`format_text "Modem %s is now connected to %s." "${MODEM_VARIANT}" "${statusname}"` + elif [ "a${MODEM_VARIANT}" != "a" ]; then + smalltext=`format_text "Modem %s is now connected." "${MODEM_VARIANT}"` + elif [ "a${statusname}" != "a" ]; then + smalltext=`format_text "You are now connected to %s." "${statusname}"` + else + smalltext=`translate_text "Computer is now connected.\n"` + fi + elif [ "a${previousstatus}" = "a1" -a "a${helperconnected}" = "a0" ]; then + largetext=`translate_text "USB Modem Unplugged"` + smalltext=`translate_text "No USB modem is anymore plugged on computer."` + elif [ "a${previousstatus}" = "a2" ]; then + largetext=`translate_text "Disconnected"` + if [ "a${helperconnected}" = "a0" ]; then + smalltext=`translate_text "You were disconnected due to modem being unplugged."` + elif [ "a${helperconnected}" = "a1" ]; then + smalltext=`translate_text "You are now disconnected from operator."` + fi + fi + debug "Will display baloon:\nIcon: %s\nTitle: %s\nMessage: %s\n" "${iconpath}" "${largetext}" "${smalltext}" + if [ "a${smalltext}" != "a" -a "a${largetext}" != "a" ]; then + ${printfbin} "icon:%s\n" "${iconpath}" >> "${BALOONIZER}" 2> /dev/null + ${printfbin} "tooltip:%s\n" "${notificationtext}" >> "${BALOONIZER}" 2> /dev/null + ${printfbin} "visible:true\n" >> "${BALOONIZER}" 2> /dev/null + ${printfbin} "message:%s\\\n%s\n" "${largetext}" "${smalltext}" >> "${BALOONIZER}" 2> /dev/null + ${printfbin} "visible:false\n" >> "${BALOONIZER}" 2> /dev/null + fi + unset iconpath; unset smalltext; unset largetext; unset notificationtext + fi + previousstatus="${helperconnected}" + fi + if [ "a${helpertext}" != "a${announcedtext}" -a "a${helperpid}" != "a" ] && ! notrunning "${helperpid}"; then + [ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -1 ${helperpid} 2> /dev/null > /dev/null + [ "a${helperpid}" != "a" ] && ! notrunning "${helperpid}" && ${killbin} -9 ${helperpid} 2> /dev/null > /dev/null + notrunning "${helperpid}" && unset helperpid + fi + if [ "a${helperpid}" = "a" ]; then + if [ "a${helperconnected}" = "a2" ]; then + ${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.green.$$.png --text="${helpertext}" > /dev/null 2> /dev/null & + elif [ "a${helperconnected}" = "a1" ]; then + ${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.yellow.$$.png --text="${helpertext}" > /dev/null 2> /dev/null & + elif [ "a${helperconnected}" = "a0" ]; then + ${zenitybin} --notification --window-icon=/tmp/sakis3g.helper.icon.red.$$.png --text="${helpertext}" > /dev/null 2> /dev/null & + else + ${zenitybin} --notification --text="${helpertext}" > /dev/null 2> /dev/null & + fi + helperpid=$!; + eval "disown -a" > /dev/null 2> /dev/null + announcedtext="${helpertext}" + export helperpid + elif notrunning "${helperpid}"; then + unset helperpid; unset previousstatus + debug "User clicked on icon.\n" + action_menu "$@"; ret=$? + if [ "${ret}" -eq "98" ]; then + if [ "a${forever}" != "a" ]; then + debug "User selected exit on MENU. However, \"forever\" is set.\n" + unset MENU; unset MOREMENU; + else + debug "User selected exit on MENU. Will ask for confirmation to exit.\n" + #${zenitybin} --question --title="`translate_text "Confirm exit"`" --text="`translate_text "Exiting will also remove tray icon. Are you sure you want to exit Sakis3G?"`" + #ret=$? + #if [ "a${ret}" = "a0" ]; then + if user_confirm "helperexit" "Confirm exit" "Exiting will also remove tray icon. Are you sure you want to exit Sakis3G?" "Yes" "No" "reset"; then + debug "User confirmed he wants to exit. Helper will die.\n" + break + else + debug "User did not confirm.\n" + unset MENU; unset MOREMENU + fi + fi + fi + debug "Resuming helper operation.\n" + else + debug "Helper is sleeping for a second.\n" + sleep 1 + fi + done + helper_cleaner + return 98 +} + +# Method called when called as a helper to hold HAL lock +action_holdlock() { + unset verbosecurrentcount + [ "a$2" != "a" ] && [ -f "$2" ] && checkfile="$2" && echo "$$" > "${checkfile}" + unset TRAPS + while [ "1" = "1" ] + do + if [ "a${PROVIDER}" = "a" ]; then + ppppp=`ps -p $$ -o ppid=` + else + ppppp=`ps -p $$ -o ppid=` + ppppp=`ps -p ${ppppp} -o ppid=` + fi + ppppp=`echo $ppppp` + [ "a${ppppp}" = "a1" ] && exit 0 + [ "a${ppppp}" = "a${PPID}" ] && exit 0 + [ "a${checkfile}" != "a" ] && [ ! -f "${checkfile}" ] && exit 0 + #echo $ppppp + sleep 1 + done +} + +action_state() { + unset verbosecurrentcount + state_variables "SGUI interactive stick_to_console DEBUG LOCALAUTHORITY BALOONIZER" + notify "To automatically repeat result of last action, use following command line:\n%s\n" "${ME} ${actors} ${statevariables}" + return 0 +} + +action_udevrule() { + unset verbosecurrentcount + state_variables "SGUI MODEM interactive stick_to_console USBMODEM OTHER DEBUG LOCALAUTHORITY BALOONIZER" +# statevariables=`echo "${statevariables}" | ${sedbin} -e "s/\"/\\\\\\\\\"/g"` + statevariables=`echo "${statevariables}" | ${sedbin} -e "s/\"//g"` + unset content + candidates="${MODEM}" + [ "a${candidates}" = "aOTHER" ] && unset candidates + [ "a${candidates}" = "aOTHER" -a "a${OTHER}" = "aUSBMODEM" -a "a${USBMODEM}" != "a" ] && candidates="${USBMODEM}" + localactors=`echo ${actors}` + for candidate in ${candidates} + do + modemvendor=`echo ${candidate} | ${cutbin} -d: -f1 -s` + modemproduct=`echo ${candidate} | ${cutbin} -d: -f2 -s` + if [ "a${modemvendor}" != "a" -a "a${modemproduct}" != "a" ]; then + content=`${printfbin} "%s\nACTION==\"add\", SUBSYSTEM==\"usb\", ATTRS{idVendor}==\"%s\", ATTRS{idProduct}==\"%s\", ATTRS{bInterfaceNumber}==\"00\", RUN+=\"%s %s %s MODEM=OTHER OTHER=USBMODEM USBMODEM=%s:%s\"\n\n" "${content}" "${modemvendor}" "${modemproduct}" "${ME}" "${localactors}" "${statevariables}" "${modemvendor}" "${modemproduct}"` + break; + fi + done + unset localactors; unset modemvendor; unset modemproduct; unset candidate; unset candidates; unset statevariables + term_clearline + if [ "a${content}" != "a" ]; then + format_text "To automatically repeat result of last action, immediately upon device connection, include following line within a %s file within \"%s\" directory:\n%s\n" ".rules" "/etc/udev/rules.d/" "${content}" + else + format_text "No USB modem was selected. No need for a udev example.\n" + fi + unset content + return 0 +} + +action_about() { + unset verbosecurrentcount + notify "%s\n" "`show_version`" + return 0 +} + +show_man() { + destination="$1" + case "a${destination}" in + ausb_modeswitch|ausb-modeswitch) + destination="dependencies/usb-modeswitch/usb_modeswitch.1" + ;; + asakis3g.conf) + destination="man/sakis3g.conf.5" + ;; + *) + destination="man/sakis3g.1" + ;; + esac + debug "Destination man page is: %s\n" "${destination}" + [ "a${PROVIDER}" = "a" ] && return 1 + [ ! -x "${PROVIDER}" ] && return 1 + need_binary "man" + need_binary "rm" + "${PROVIDER}" getfile "${destination}" > "/tmp/sakis3g.man.$$" + debug "Will now display man page %s.\n" "${destination}" + [ -s "/tmp/sakis3g.man.$$" ] && ${manbin} -l "/tmp/sakis3g.man.$$" + ${rmbin} -f "/tmp/sakis3g.man.$$" + return 0 +} + +action_report() { + unset verbosecurrentcount + flow_report "$@" + ret=$? + if [ "a${ret}" = "a0" ]; then + return 0 + else + return ${ret} + fi +} + +# Executes actor $1 with the arguments +run_action() { + actioncandidate=$1 + [ "$#" -gt "0" ] && shift + unset verbosecurrentcount + newactors="${actors} ${actioncandidate}" + case "${actioncandidate}" in + about) + action_about "$@" + actionresult=$? + ;; + desktop) + action_desktop "$@" + actionresult=$? + ;; + helper) + action_helper "$@" + actionresult=$? + ;; + status) + action_status "$@" + actionresult=$? + ;; + connected) + ppp_fast_status + actionresult=$? + ;; + disconnected) + if ppp_fast_status; then + actionresult=99 + else + actionresult=0 + fi + ;; + plugged) + if usb_connected_modems; then + actionresult=0 + else + actionresult=99 + fi + ;; + unplugged) + if usb_connected_modems; then + actionresult=99 + else + actionresult=0 + fi + ;; + switched) + if usb_connected_modems; then + if modeswitch_switchable_devices; then + actionresult=99 + else + actionresult=0 + fi + else + actionresult=0 + fi + ;; + switchable) + if modeswitch_switchable_devices; then + actionresult=0 + else + actionresult=99 + fi + ;; + wait|sleep) + debug "Sleeping for 1 second.\n" + sleep 1 + actionresult=0 + ;; + info) + action_info "$@" + actionresult=$? + ;; + clicked) + action_clicked "$@" + actionresult=$? + ;; + modem|select) + action_modem "$@" + actionresult=$? + ;; + switchonly) + action_switch "$@" + actionresult=$? + ;; + setup) + action_setup "$@" + actionresult=$? + ;; + prepare|init) + action_prepare "$@" + actionresult=$? + ;; + connect|start) + action_connect "$@" + actionresult=$? + ;; + toggle) + action_toggle "$@" + actionresult=$? + ;; + reconnect|restart) + action_reconnect "$@" + actionresult=$? + ;; + disconnect|stop) + action_disconnect "$@" + actionresult=$? + ;; + more|moremenu|menumore) + action_more "$@" + actionresult=$? + ;; + menu) + action_menu "$@" + actionresult=$? + ;; + state) + action_state "$@" + actionresult=$? + ;; + udevrule) + action_udevrule "$@" + actionresult=$? + ;; + compile|recompile) + action_compile "$@" + actionresult=$? + ;; + report) + action_report "$@" + actionresult=$? + ;; + *) + newactors="${actors}" + unset actioncandidate + actionresult=0 + ;; + esac + actors="${newactors}" + unset actioncandidate; unset newactors + [ "a${actionresult}" = "a" ] && actionresult=99 + return ${actionresult} +} + +# Executes actors in the order defined +action_command() { + unset actors + while [ "$#" -gt "0" ] + do + if [ "a${1}" = "anot" -o "a${1}" = "aNot" -o "a${1}" = "a!" ]; then + [ "$#" -gt "0" ] && shift + actors="${actors} not" + run_action "$@" + actionresult=$? + if [ "${actionresult}" -eq "0" ]; then + actionresult=99 + debug "Actor \"%s\" returned %d, \"not\" operator instructs to abort.\n" "${1}" "${actionresult}" + break + else + debug "Actor \"%s\" returned %d, but was inverted by \"not\" operator.\n" "${1}" "${actionresult}" + actionresult=0 + fi + elif [ "a${1}" = "aignore" -o "a${1}" = "aIgnore" -o "a${1}" = "aignoring" -o "a${1}" = "aIgnoring" -o "a${1}" = "a|" ]; then + [ "$#" -gt "0" ] && shift + actors="${actors} ignore" + run_action "$@" + actionresult=$? + if [ "${actionresult}" -ne "0" ]; then + debug "Actor \"%s\" returned %d, \"ignore\" operator instructs to continue.\n" "${1}" "${actionresult}" + actionresult=0 + fi + elif [ "a${1}" != "a" ] && ! run_action "$@"; then + debug "Aborting execution chain due to actor \"%s\" returning %d.\n" "${1}" "${actionresult}" + break + fi + [ "$#" -gt "0" ] && shift + done + unset arg + actors=`echo ${actors}` + if [ "a${actors}" = "a" ]; then + debug "No actors defined.\n" + unset actors + return 1 + else + debug "Following actors executed: %s\n" "${actors}" + unset actors + return 0 + fi +} + +# Checks if arguments defined a dummy action and aborts if it does +no_action_command() { + for arg in $@ + do + case "$arg" in + --help|help) + unset arg + if find_binary "fold"; then + if [ "a${COLUMNS}" != "a" ]; then + raw_help | ${foldbin} -s -w "${COLUMNS}" + else + raw_help | ${foldbin} -s -w "80" + fi + else + raw_help + fi + return 0 + ;; + --version|version) + unset arg + show_version + return 0 + ;; + --holdlock|holdlock) + unset arg + action_holdlock "$@" + return 0 + ;; + usb_modeswitch) + if [ "a${binaryfree}" != "a" ]; then + show_fmt_error "You are running a binary free version of Sakis3G. This action is not available.\n" + fi + return 0 + ;; + man) + if [ "a${stripped}" != "a" ]; then + show_fmt_error "You are running a stripped version of Sakis3G. This action is not available.\n" + else + shift + show_man "$@" + fi + unset arg + return 0 + ;; + esac + done + unset arg + return 1 +} + +# When no actor defined, executes default actor of GUI selected. +default_actor() { + debug "Executing default actor for \"%s\".\n" "${SGUI}" + if voodoo_mode; then + debug "Voodoo actions will happen.\n" + if action_connect "$@"; then + actors="connect" + action_state "$@" + return $? + else + return $? + fi + fi + case "${SGUI}" in + whiptail|dialog|Xdialog|zenity|kdialog) + action_menu "$@" + return $? + ;; + "9menu") + action_menu "$@" + return $? + ;; + "interactive terminal") + action_menu "$@" + return $? + ;; + "terminal") + show_help + return $? + ;; + *) + debug "No default actor for this GUI. Showing help.\n" + show_help + return $? + ;; + esac +} + +voodoo_mode() { + [ "a${voodoo}" != "a" ] && return 0 + return 1 +} + +guruplug_led() { + if [ "a$1" = "anoexecute" ]; then + noexecute=1 + shift + elif [ "a$1" = "aall" ]; then + shift + guruplug_leds "$@" + return 0 + else + noexecute=0 + fi + ledcolor=""; ledname=""; othercolor=""; otherled=""; ledblink=""; ledon=""; ledoff="" + for ledarg in "$@" + do + case "a${ledarg}" in + ared|aRED|aRed|aR|ar|"a${redcolor}") + ledcolor="${redcolor}" + othercolor="${othercolor} ${greencolor}" + ;; + agreen|aGREEN|aGreen|aG|ag|"a${greencolor}") + ledcolor="${greencolor}" + othercolor="${othercolor} ${redcolor}" + ;; + ablack|aBLACK|aBlack|aB|ab|anone|aNONE|aNone|aN|an|aNO|aNo|ano|aReset|aRESET|areset) + ledcolor="" + othercolor="${othercolor} ${redcolor} ${greencolor}" + ;; + aorange|aOrange|aORANGE|aO|ao|ayellow|aYellow|aYellow|aY|ay|aBOTH|aBoth|aboth) + ledcolor="${ledcolors}" + othercolor="" + ;; + aleft|aLEFT|aLeft|aL|al|"a${leftled}") + ledname="${leftled}" + otherled="${otherled}" + ;; + aright|aRIGHT|aRight|"a${rightled}") + ledname="${rightled}" + otherled="${otherled}" + ;; + ablink|aBlink|aBLINK) + ledblink=1; + ;; + anand|aNAND|assd|aSSD|adisk|aDISK|aDisk|aNand|aSsd|anand-disk|ananddisk|assddisk|assd-disk) + ledblink=2; + ;; + ammc|ammc0|aMMC|aMmc|aMMC0|acard|aCard|aCARD) + ledblink=3; + ;; + *) + ledcheck=`expr ${ledarg} + 1 - 1 2> /dev/null` + if [ "a${ledcheck}" = "a${ledarg}" ]; then + if [ "a${ledon}" = "a" ]; then + ledon="${ledarg}" + elif [ "a${ledoff}" = "a" ]; then + ledoff="${ledarg}" + fi + fi + ;; + esac + done + if [ "a${ledcolor}${othercolor}" = "a" -o "a${ledname}" = "a" ]; then + unset noexecute; unset ledarg; unset ledcolor; unset ledname; unset othercolor; unset otherled; + unset color; unset oled; unset ledcommand; unset ledblink; unset ledmode; unset ledon; unset ledoff; + return 1 + fi + ledcommand="" + for oled in ${otherled} + do + for color in ${ledcolors} + do + ledcommand="${ledcommand} echo \"none\" > \"${ledpath}/${color}:${oled}/trigger\";" + ledcommand="${ledcommand} echo \"0\" > \"${ledpath}/${color}:${oled}/brightness\";" + done + done + if [ "a${ledblink}" = "a1" ]; then + unset othercolor + ledmode="timer" + [ "a${ledon}" = "a" ] && ledon=500 + [ "a${ledoff}" = "a" ] && ledoff=500 + if [ "a${ledcolor}" = "a" ]; then + ttt="${ledon}"; ledon="${ledoff}"; ledoff="${ttt}"; unset ttt + ledcheck=`guruplug_led_getstate "${ledname}" | ${grepbin} "_brightness=1" | ${sedbin} -e "s/^${ledname}_\(.*\)_brightness=1$/\1/g" | tr "\n" " "` + ledcheck=`echo ${ledcheck}` + for color in ${ledcolors} + do + colorname=`echo "${color}" | ${sedbin} -e "s/:/_/g"` + if strinstr "${colorname}" "${ledcheck}" " "; then + ledcolor="${ledcolor} ${color}" + else + othercolor="${othercolor} ${color}" + fi + done + unset color; unset colorname; unset ledcheck + fi + [ "a${ledcolor}" = "a" ] && unset othercolor + elif [ "a${ledblink}" = "a2" ]; then + ledmode="nand-disk" + elif [ "a${ledblink}" = "a3" ]; then + ledmode="mmc0" + else + ledmode="none" + fi + for color in ${othercolor} + do + ledcommand="${ledcommand} echo \"none\" > \"${ledpath}/${color}:${ledname}/trigger\";" + ledcommand="${ledcommand} echo \"0\" > \"${ledpath}/${color}:${ledname}/brightness\";" + done + if [ "a${ledcolor}" != "a" ]; then + for color in ${ledcolor} + do + ledcommand="${ledcommand} echo \"${ledmode}\" > \"${ledpath}/${color}:${ledname}/trigger\";" + [ "a${ledmode}" = "anone" ] && ledcommand="${ledcommand} echo \"1\" > \"${ledpath}/${color}:${ledname}/brightness\";" + if [ "a${ledblink}" = "a1" ]; then + ledcommand="${ledcommand} echo \"${ledon}\" > \"${ledpath}/${color}:${ledname}/delay_on\";" + ledcommand="${ledcommand} echo \"${ledoff}\" > \"${ledpath}/${color}:${ledname}/delay_off\";" + fi + done + unset color + fi + if [ "a${noexecute}" = "a1" ]; then + echo "${ledcommand}" + else + unset LEDSCLEAN + eval ${ledcommand} + fi + unset noexecute; unset ledarg; unset ledcolor; unset ledname; unset othercolor; unset otherled; + unset color; unset oled; unset ledcommand; unset ledblink; unset ledmode; unset ledon; unset ledoff; + return 0 +} + +guruplug_leds() { + ledscommands="" + for ledi in ${allleds} + do + ledscommands="${ledscommands} `guruplug_led noexecute "${ledi}" "$@"`" + done + unset LEDSCLEAN + eval ${ledscommands} + unset ledscommands; unset ledi + return 0 +} + +guruplug_verbose() { + [ "a${guruplug}" = "a" ] && return 0 + if [ "a${gurucycle}" = "a" -o "a${gurucycle}" = "a0" ]; then + gurucycle="1" + led1="left" + led2="right" + elif [ "a${gurucycle}" = "a1" ]; then + gurucycle="0" + led1="right" + led2="left" + fi + export gurucycle + ledscommands="" + ledscommands="${ledscommands} `guruplug_led noexecute ${led1} reset`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led2} reset`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led1} green`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led2} blink green`" + eval ${ledscommands} + unset led1; unset led2; unset ledscommands + return 0 +} + +guruplug_verbose_same() { + [ "a${guruplug}" = "a" ] && return 0 + if [ "a${gurucycle}" = "a" -o "a${gurucycle}" = "a0" ]; then + led1="left" + led2="right" + elif [ "a${gurucycle}" = "a1" ]; then + led1="right" + led2="left" + fi + export gurucycle + ledscommands="" + ledscommands="${ledscommands} `guruplug_led noexecute ${led1} reset`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led2} reset`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led1} green`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led2} green`" + ledscommands="${ledscommands} `guruplug_led noexecute ${led2} blink red`" + eval ${ledscommands} + unset led1; unset led2; unset ledscommands + return 0 +} + +guruplug_notify() { + [ "a${guruplug}" = "a" ] && return 0 + guruplug_leds black + guruplug_leds blink green + [ "a${interactive}" = "a" ] && sleep 5 +} + +guruplug_error() { + [ "a${guruplug}" = "a" ] && return 0 + guruplug_leds black + guruplug_leds blink red + [ "a${interactive}" = "a" ] && sleep 5 +} + +guruplug_led_exists() { + [ "a${guruplug}" = "a" ] && return 1 + [ "a$1" = "a" ] && return 1 + for color in ${ledcolors} + do + [ ! -d "${ledpath}/${color}:$1" ] && return 1 + done + unset color + return 0 +} + +guruplug_led_getstate() { + [ "a${guruplug}" = "a" ] && return 0 + ! guruplug_led_exists "$@" && return 1 + for color in ${ledcolors} + do + colorname=`echo ${color} | ${sedbin} -e "s/:/_/g"` + for file in ${ledvariables} + do + if [ -r "${ledpath}/${color}:${1}/${file}" ]; then + value=`${catbin} "${ledpath}/${color}:$1/${file}"` + eval "$1_${colorname}_${file}=\"${value}\"" + eval "export $1_${colorname}_${file}" + else + eval "unset $1_${colorname}_${file}" + fi + done + value=`${catbin} "${ledpath}/${color}:$1/trigger" | ${sedbin} -e "s/^\(.*\)\[\(.*\)\]\(.*\)$/\2/g"` + eval "$1_${colorname}_trigger=\"${value}\"" + eval "export $1_${colorname}_trigger" + [ "a${value}" != "anone" ] && eval "unset $1_${colorname}_brightness" + done + unset colorname; unset color; unset value; unset file; + debug "Led $1 saved.\n" + set | ${grepbin} "^$1_" + return 0 +} + +guruplug_state() { + [ "a${guruplug}" = "a" ] && return 0 + for ledi in ${allleds} + do + ! guruplug_led_getstate ${ledi} && return 1 + done + unset ledi + debug "All leds are saved.\n" + return 0 +} + +guruplug_restore() { + [ "a${guruplug}" = "a" ] && return 0 + command="" + for ledi in ${allleds} + do + for color in ${ledcolors} + do + colorname=`echo ${color} | ${sedbin} -e "s/:/_/g"` + for file in trigger ${ledvariables} + do + value=`echo "$1" | ${grepbin} "^${ledi}_${colorname}_${file}=" | ${cutbin} -d= -f2- -s` + if [ "a${value}" != "a" ]; then + debug "echo \"${value}\" > \"${ledpath}/${color}:${ledi}/${file}\"\n" + command="${command} echo \"${value}\" > \"${ledpath}/${color}:${ledi}/${file}\";" + fi + done + done + done + unset LEDSCLEAN + eval ${command} + unset command + unset value; unset file; unset colorname; unset color; unset ledi; + return 0 +} + +guruplug_restore_state() { + [ "a${guruplug}" = "a" ] && return 0 + [ "a${guruplug_original_state}" != "a" ] && guruplug_restore "${guruplug_original_state}" && debug "Original state of GuruPlug leds is now restored.\n" && return 0 + debug "Failed to restore GuruPlug leds into original state.\n" + return 1 +} + +guruplug_save_state() { + [ "a${guruplug}" = "a" ] && return 0 + ! guruplug_state > /dev/null && return 1 + guruplug_original_state=`guruplug_state` + export guruplug_original_state + addexittrap guruplug_restore_state + debug "Original state of GuruPlug leds is saved.\n" + return 0 +} + +guruplug_probe() { + [ "a${guruplug}" = "a" ] && return 1 + [ ! -w "/sys/class/leds/guruplug:green:health/trigger" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:green:health/brightness" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:red:health/trigger" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:red:health/brightness" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:green:wmode/trigger" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:green:wmode/brightness" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:red:wmode/trigger" ] && unset guruplug + [ ! -w "/sys/class/leds/guruplug:red:wmode/brightness" ] && unset guruplug + if [ "a${guruplug}" = "a" ]; then + debug "GuruPlug leds not found, or not accessible.\n" + return 1 + else + ############################################## + export ledpath="/sys/class/leds" + ############################################## + export redcolor="guruplug:red" + export greencolor="guruplug:green" + export ledcolors="${redcolor} ${greencolor}" + ############################################## + export leftled="health" + export rightled="wmode" + export allleds="${leftled} ${rightled}" + ############################################## + export ledvariables="brightness delay_off delay_on" + ############################################## + debug "GuruPlug leds found.\n" + fi + if ! guruplug_save_state; then + unset guruplug + debug "Failed to retrieve state of leds.\n" + return 1 + fi +} + +config_args_read() { + for arg in "$@" + do + debug "Parsing configuration value: %s.\n" "${arg}" + parse_eval "readconfig" "${arg}" && continue + parse_switches "${arg}" + done + unset arg +} + +config_load() { + # If no PIN supplied from command line and $HOME/.3gnet exists, use PIN from there. + [ "a${SIM_PIN}" = "a" -a "a${runhome}" != "a" ] && [ -d "${runhome}" ] && [ -r "${runhome}/.3gpin" ] && SIM_PIN=`${headbin} -1 "${runhome}/.3gpin" 2> /dev/null | ${cutbin} -b1-4` && [ "a${SIM_PIN}" != "a" ] && export SIM_PIN && debug "Loaded PIN value from %s.\n" "${runhome}/.3gpin" && ! pin_valid "${SIM_PIN}" && unset SIM_PIN && debug "PIN supplied was not valid.\n" + # Load PIN from system-wide PIN suppliers + for pinsupplier in "/etc/default/3gpin" "/etc/sysconfig/3gpin" "/etc/3gpin" "/etc/default/sakis3g.3gpin" "/etc/sysconfig/sakis3g.3gpin" "/etc/sakis3g.3gpin" + do + [ -r "${pinsupplier}" ] && unset SIM_PIN && SIM_PIN=`${headbin} -1 "${pinsupplier}" 2> /dev/null | ${cutbin} -b1-4` && [ "a${SIM_PIN}" != "a" ] && export SIM_PIN && debug "Loaded PIN value from %s.\n" "${pinsupplier}" &&! pin_valid "${SIM_PIN}" && unset SIM_PIN && debug "PIN supplied was not valid.\n" + done + unset pinsupplier + # If system-wide configuration exists, load it overriding anything (user configuration/arguments/everything) + for configfile in "/etc/default/sakis3g" "/etc/sysconfig/sakis3g" "/etc/sakis3g.conf" + do + if [ -r "${configfile}" ]; then + debug "Loading system-wide configuration file %s.\n" "${configfile}" + debug show_file "${configfile}" + configargs=`${grepbin} -v "^#" "${configfile}" | ${grepbin} -v "^$" | ${sedbin} -e "s/^\(.*\)$/\"\1\"/g" | ${sedbin} -e "s/^\"\([A-Za-z_]*\)=\"\(.*\)\"\"$/\"\1=\2\"/g" | ${trbin} "\n" " "` + debug "Configuration arguments are: %s\n" "${configargs}" + eval config_args_read ${configargs} + unset configargs + debug "Finished loading file %s.\n" "${configfile}" + else + debug "Configuration file %s does not exist or is not readable.\n" "${configfile}" + fi + done + unset configfile + debug "Configuration file(s) loaded.\n" +} + +# Parses command line switch arguments +parse_switch() { + if [ "a$1" = "a$2" -o "a$1" = "a--$2" -o "a$1" = "a-$2" ]; then + debug "Command line switch defined: %s\n" "$1" + return 0 + fi + return 1 +} + +# Parses command line variable settings +parse_eval() { + ! find_binary "cut" && return 1 + ! find_binary "grep" && return 1 + if [ "a$1" = "areadconfig" ]; then + readconfig=1 + shift + [ "a$1" = "a" ] && unset readconfig && return 1 + else + readconfig=0 + fi + [ "a`echo "$1" | ${grepbin} "="`" = "a" ] && unset readconfig && return 1 + variable=`echo "${1}" | ${cutbin} -d= -f1` + [ "a${variable}" = "a" ] && unset variable && unset readconfig && return 1 + value=`echo "${1}" | ${cutbin} -d= -f2-` + [ "a${value}" = "a" ] && unset variable && unset value && unset readconfig && return 1 + case "${variable}" in + pppint|PPPINT) + export pppint="${value}" + ;; + CHAT_ABORT_STRINGS) + # Abort strings that chat program may encounter + export CHAT_ABORT_STRINGS="${value}" + ;; + BAUD) + # Baud rate + if [ "a${value}" = "aMAX" -o "a${value}" = "amax" ]; then + export BAUD="4000000" + elif [ "a${value}" = "aMIN" -o "a${value}" = "amin" ]; then + export BAUD="115200" + elif [ "a${value}" = "aDEFAULT" -o "a${value}" = "adefault" -o "a${value}" = "aNORMAL" -o "a${value}" = "anormal" ]; then + export BAUD="460800" + else + export BAUD="${value}" + fi + ;; + PPPD_OPTIONS) + # Options passed to pppd when called directly + export PPPD_OPTIONS="${value}" + ;; + PPPD_PEERS) + # Directory where pppd keeps its peers + export PPPD_PEERS="${value}" + ;; + XOSDFONT) + # Font that will be used when displaying messages through XOSD (osd_cat) + export XOSDFONT="${value}" + ;; + AOSDFONT) + # Font that will be used when displaying messages through XOSD (osd_cat) + export AOSDFONT="${value}" + ;; + MENUFONT|menufont) + # Font that will be used when using 9menu + export MENUFONT="${value}" + ;; + OSDFONT) + # Font that will be used when displaying messages through XOSD (osd_cat) + export AOSDFONT="${value}" + export XOSDFONT="${value}" + ;; + LOGPOSITION|logposition) + # Directory where pppd keeps its peers + export LOGPOSITION="${value}" + ;; + DESKTOPICON) + # Directory where pppd keeps its peers + export DESKTOPICON="${value}" + ;; + DCOPSERVER) + # Directory where pppd keeps its peers + export DCOPSERVER="${value}" + ;; + connection_hook|CONNECTION_HOOK|HOOK) + # Enabling this is a security issue. + # Users can pass argument to do whatever they want. + if [ "a${readconfig}" = "a1" ]; then + export CONNECTION_HOOK="${value}" + else + echo "Ignoring ${variable} variable for security reasons." > /dev/stderr + echo "This variable is only usable through global configuration." > /dev/stderr + echo "Consult documentation." > /dev/stderr + fi + ;; + DNS) + export DNS="${value}" + ;; + MODEM_PREPARE|PREPARE) + export MODEM_PREPARE="${value}" + INIT_STAGE0=`${printfbin} "%s\n" "${value}" | ${sedbin} -e "s/AT/\\nAT/g" | ${sedbin} -e "s/ *$//g" | ${grepbin} -v "^$" | ${grepbin} "^AT" | ${sedbin} -e "s/^\(.*\)$/\\\'\1\\\' OK/g" | ${trbin} "\n" " "` + export INIT_STAGE0 + ;; + MODEM_INIT|INIT) + export MODEM_INIT="${value}" + ;; + DIAL|CUSTOM_DIAL) + export CUSTOM_DIAL="${value}" + ;; + FORCE_APN) + export FORCE_APN="${value}" + ;; + CUSTOM_APN) + export CUSTOM_APN="${value}" + ;; + APN) + export APN="${value}" + ;; + APN_USER) + export APN_USER="${value}" + ;; + APN_PASS) + export APN_PASS="${value}" + ;; + FORCE_ISP) + export FORCE_ISP="${value}" + ;; + SIM_PIN) + export SIM_PIN="${value}" + ;; + RFCOMM_TTY) + export RFCOMM_TTY="${value}" + ;; + CUSTOM_TTY) + export CUSTOM_TTY="${value}" + ;; + RFSERVICE) + export RFSERVICE="${value}" + ;; + RFCHANNEL) + export RFCHANNEL="${value}" + ;; + UNDISCOVERABLE) + export UNDISCOVERABLE="${value}" + ;; + BLUETOOTH) + export BLUETOOTH="${value}" + ;; + USBINTERFACE) + export USBINTERFACE="${value}" + ;; + USBDRIVER) + export USBDRIVER="${value}" + ;; + USBMODEM) + export USBMODEM="${value}" + ;; + OTHER) + export OTHER="${value}" + ;; + MODEM) + export MODEM="${value}" + ;; + MOREMENU) + export MOREMENU="${value}" + ;; + MENU) + export MENU="${value}" + ;; + DISPLAY) + export DISPLAY="${value}" + ;; + XAUTHORITY|LOCALAUTHORITY) + export LOCALAUTHORITY="${value}" + ;; + BALOONIZER|BALLOONIZER) + export BALOONIZER="${value}" + ;; + DESKTOP) + export DESKTOP="${value}" + ;; + SGUI) + export SGUI="${value}" + ;; + TRANSLATION) + export TRANSLATION="${value}" + ;; + *) + debug "Unknown variable %s specified in command line.\n" "${variable}" + unset variable + ;; + esac + unset readconfig + if [ "a${variable}" != "a" ]; then + debug "Command line set variable %s to \"%s\".\n" "${variable}" "`eval echo \\\${${variable}}`" + unset variable; unset value; + return 0 + fi + unset variable; unset value + return 1 +} + +parse_switches() { + parse_switch "${1}" "balloons" && export balloons=yes + parse_switch "${1}" "balloon" && export balloons=yes + parse_switch "${1}" "baloons" && export balloons=yes + parse_switch "${1}" "baloon" && export balloons=yes + parse_switch "${1}" "ballons" && export balloons=yes + parse_switch "${1}" "ballon" && export balloons=yes + parse_switch "${1}" "balons" && export balloons=yes + parse_switch "${1}" "balon" && export balloons=yes + parse_switch "${1}" "b" && export balloons=yes + + parse_switch "${1}" "console" && export stick_to_console=yes + parse_switch "${1}" "stick_to_console" && export stick_to_console=yes + parse_switch "${1}" "c" && export stick_to_console=yes + + parse_switch "${1}" "debug" && export DEBUG=on + parse_switch "${1}" "DEBUG" && export DEBUG=on + parse_switch "${1}" "d" && export DEBUG=on + + parse_switch "${1}" "NOSMART" && export NOSMART=yes + parse_switch "${1}" "NOFIX" && export NOSMART=yes + parse_switch "${1}" "nosmart" && export NOSMART=yes + parse_switch "${1}" "nofix" && export NOSMART=yes + parse_switch "${1}" "smart" && export NOSMART=yes + parse_switch "${1}" "fix" && export NOSMART=yes + parse_switch "${1}" "f" && export NOSMART=yes + + parse_switch "${1}" "GOOGLEDNS" && export DNS="8.8.8.8 8.8.4.4" + parse_switch "${1}" "GOOGLE" && export DNS="8.8.8.8 8.8.4.4" + parse_switch "${1}" "googledns" && export DNS="8.8.8.8 8.8.4.4" + parse_switch "${1}" "google" && export DNS="8.8.8.8 8.8.4.4" + parse_switch "${1}" "g" && export DNS="8.8.8.8 8.8.4.4" + + parse_switch "${1}" "GURUPLUG" && export guruplug=yes + parse_switch "${1}" "guruplug" && export guruplug=yes + parse_switch "${1}" "GURU" && export guruplug=yes + parse_switch "${1}" "guru" && export guruplug=yes + parse_switch "${1}" "G" && export guruplug=yes + + parse_switch "${1}" "nohal" && export nohal=yes + parse_switch "${1}" "hal" && export nohal=yes + parse_switch "${1}" "h" && export nohal=yes + + parse_switch "${1}" "interactive" && export interactive=yes + parse_switch "${1}" "i" && export interactive=yes + + parse_switch "${1}" "killstorage" && export killstorage=yes + parse_switch "${1}" "nostorage" && export killstorage=yes + parse_switch "${1}" "storage" && export killstorage=yes + parse_switch "${1}" "k" && export killstorage=yes + + parse_switch "${1}" "nohalinform" && export nohalinform=yes + parse_switch "${1}" "noinform" && export nohalinform=yes + parse_switch "${1}" "l" && export nohalinform=yes + + parse_switch "${1}" "NOPROBE" && export NOPROBEGSM=yes + parse_switch "${1}" "NOPROBEGSM" && export NOPROBEGSM=yes + parse_switch "${1}" "noprobe" && export NOPROBEGSM=yes + parse_switch "${1}" "noprobegsm" && export NOPROBEGSM=yes + parse_switch "${1}" "GSM" && export NOPROBEGSM=yes + parse_switch "${1}" "gsm" && export NOPROBEGSM=yes + parse_switch "${1}" "n" && export NOPROBEGSM=yes + + parse_switch "${1}" "prefer_osd" && export prefer_osd=yes + parse_switch "${1}" "preferosd" && export prefer_osd=yes + parse_switch "${1}" "osd" && export prefer_osd=yes + parse_switch "${1}" "OSD" && export prefer_osd=yes + parse_switch "${1}" "o" && export prefer_osd=yes + + parse_switch "${1}" "forever" && export forever=yes + parse_switch "${1}" "persist" && export forever=yes + parse_switch "${1}" "P" && export forever=yes + + parse_switch "${1}" "directpppd" && export direct_pppd=yes + parse_switch "${1}" "direct_pppd" && export direct_pppd=yes + parse_switch "${1}" "ppp" && export direct_pppd=yes + parse_switch "${1}" "pppd" && export direct_pppd=yes + parse_switch "${1}" "p" && export direct_pppd=yes + + parse_switch "${1}" "noverbose" && export noverbose=yes + parse_switch "${1}" "noinformation" && export nonotify=yes + parse_switch "${1}" "nonotifications" && export nonotify=yes + parse_switch "${1}" "nonotify" && export nonotify=yes + parse_switch "${1}" "noerrors" && export noerror=yes + parse_switch "${1}" "noerror" && export noerror=yes + if parse_switch "${1}" "silent" || parse_switch "${1}" "quiet" || parse_switch "${1}" "q"; then + export noerror=yes + export nonotify=yes + export noverbose=yes + fi + + parse_switch "${1}" "sudo" && export alwayssudo=yes + parse_switch "${1}" "alwayssudo" && export alwayssudo=yes + parse_switch "${1}" "always_sudo" && export alwayssudo=yes + parse_switch "${1}" "s" && export alwayssudo=yes + + parse_switch "${1}" "showtext" && export showtext=yes + parse_switch "${1}" "T" && export showtext=yes + + parse_switch "${1}" "notranslate" && export notranslate=yes + parse_switch "${1}" "t" && export notranslate=yes + + parse_switch "${1}" "nosafety" && export nosafety=yes + parse_switch "${1}" "unsafe" && export nosafety=yes + parse_switch "${1}" "u" && export nosafety=yes + + parse_switch "${1}" "voodoo" && export voodoo=yes + parse_switch "${1}" "please" && export voodoo=yes + parse_switch "${1}" "magic" && export voodoo=yes + parse_switch "${1}" "Voodoo" && export voodoo=yes + parse_switch "${1}" "Please" && export voodoo=yes + parse_switch "${1}" "Magic" && export voodoo=yes + parse_switch "${1}" "v" && export voodoo=yes + + parse_switch "${1}" "whiptail" && export SGUI="whiptail" + parse_switch "${1}" "dialog" && export SGUI="dialog" + parse_switch "${1}" "Xdialog" && export SGUI="Xdialog" + parse_switch "${1}" "xdialog" && export SGUI="Xdialog" + parse_switch "${1}" "zenity" && export SGUI="zenity" + parse_switch "${1}" "kdialog" && export SGUI="kdialog" + parse_switch "${1}" "9menu" && export SGUI="9menu" + parse_switch "${1}" "xterm" && export SGUI="xterm" + parse_switch "${1}" "gnome-terminal" && export SGUI="gnome-terminal" + parse_switch "${1}" "konsole" && export SGUI="konsole" + parse_switch "${1}" "interactiveterminal" && export SGUI="interactive terminal" + parse_switch "${1}" "iterm" && export SGUI="interactive terminal" + parse_switch "${1}" "terminal" && export SGUI="terminal" + parse_switch "${1}" "term" && export SGUI="terminal" + if parse_switch "${1}" "legacy"; then + export SGUI="9menu" + export prefer_osd="yes" + fi + + parse_switch "${1}" "scanyes" && export scanyes="1" + parse_switch "${1}" "scanno" && export scanno="1" +} + +state_variables() { + unset statevariables + for flagvariable in stick_to_console:console interactive:interactive DEBUG:debug NOSMART:nofix killstorage:nostorage NOPROBEGSM:noprobegsm prefer_osd:osd direct_pppd:pppd alwayssudo:sudo forever:forever balloons:balloons + do + variablename=`echo "${flagvariable}" | cut -d: -f1` + strinstr "${variablename}" "${1}" " " && debug "Variable %s excluded from state variables.\n" "${variablename}" && continue + variablearg=`echo "${flagvariable}" | cut -d: -f2` + variablevalue=`eval echo \\\${${variablename}}` + [ "a${variablevalue}" != "a" ] && statevariables="${statevariables} --${variablearg}" + done + unset flagvariable; unset variablename; unset variablearg; unset variablevalue + [ "a${DNS}" = "a8.8.8.8 8.8.4.4" ] && statevariables="${statevariables} --googledns" + [ "a${DNS}" != "a8.8.8.8 8.8.4.4" -a "a${DNS}" != "a" ] && statevariables="${statevariables} DNS=\"${DNS}\"" + for valuevariable in MODEM_INIT FORCE_APN APN APN_USER APN_PASS FORCE_ISP SIM_PIN SGUI RFCOMM_TTY CUSTOM_TTY RFSERVICE RFCHANNEL UNDISCOVERABLE BLUETOOTH USBINTERFACE USBDRIVER USBMODEM OTHER MODEM MENU MOREMENU DISPLAY DESKTOP DCOPSERVER LOCALAUTHORITY BALOONIZER + do + strinstr "${valuevariable}" "${1}" " " && debug "Variable %s excluded from state variables.\n" "${valuevariable}" && continue + variablevalue=`eval echo \\\${${valuevariable}}` + [ "a${variablevalue}" != "a" ] && statevariables="${statevariables} ${valuevariable}=\"${variablevalue}\"" + done + unset valuevariable; unset variablevalue + statevariables=`echo ${statevariables}` + export statevariables + debug "State variables are: %s\n" "${statevariables}" + return 0 +} + +# Parses command line arguments +parse_arguments() { + need_binary "tr" + unset allargs + for arg in "$@" + do + varg=`sanitize "${arg}"` + allargs="${allargs} \"${varg}\"" + parse_eval "${varg}" && continue + parse_switches "${varg}" + unset varg + done + unset arg + allargs=`echo ${allargs}` + export allargs +} + +# Unsets binary variables if running as root. This eliminates the chance +# that a malicious user has succeed into setting a "trojan" binary helper +# that will be executed with root privileges. +secure_path() { + PATH="/bin:/sbin:/usr/bin:/usr/sbin" + export PATH + unset whichbin + unset grepbin + unset cutbin + need_binary "grep" + need_binary "cut" + for variable in `set | ${grepbin} "bin=" | ${cutbin} -d= -f1` + do + value=`eval echo \\${${variable}} 2> /dev/null` + if [ "a${value}" != "a" ] && [ -x "${value}" ]; then + eval "unset ${variable}" + debug "Unset variable %s for security reasons.\n" "${variable}" + fi + done + unset variable; unset value + return 0 +} + +# Removes \, ", ', ` from variables' contents +secure_variables() { + need_binary "sed" + need_binary "tr" + for variable in DISPLAY XAUTHORITY USERNAME HOME USER DESKTOP + do + debug "Sanitizing %s: %s\n" "${variable}" "`eval echo \"\\${${variable}}\"`" + value=`eval "echo \"\\${${variable}}\"" 2> /dev/null | ${trbin} "\\\\" " " 2> /dev/null | ${trbin} "\"" " " | ${trbin} "'" " " | ${trbin} "\\\`" " "` + debug "Sanitized value: %s\n" "${value}" + eval "${variable}=\"""${value}""\"" + eval "${variable}=\"`eval echo \"\\${${variable}}\"`\"" + eval "export ${variable}" + debug "Sanitized %s: %s\n" "${variable}" "`eval echo \"\\${${variable}}\"`" + done + unset value; unset variable + return 0 +} + +secure_capabilities() { + debug "Will check shell capabilities.\n" + set +o monitor > /dev/null 2> /dev/null + set +m > /dev/null 2> /dev/null + funcname=`set | grep "^FUNCNAME="` + if [ "a${funcname}" = "a" ]; then + debug "Shell does not provide FUNCNAME environment variable.\n" + debug "USB Safety will be disabled.\n" + export NOFUNCNAME="1" + unset YESFUNCNAME="" + else + debug "Shell provides FUNCNAME environment variable.\n" + unset NOFUNCNAME + export YESFUNCNAME="1" + fi + unset funcname + return 0 +} + +# Makes sure no danger exists when run as root +secure_environment() { + secure_capabilities + ! we_are_root_already && return 0 + secure_path + secure_variables + return 0 +} + +# Preparation or death +startup() { + # try to set shell as helpful as possible with background jobs + secure_environment + addexittrap cleanscreen + me=$1; [ "$#" -gt "0" ] && shift + # Draftly set allargs. Will better do it during parse_arguments + allargs="$@"; export allargs + no_action_command "$@" && stop_with 0 + verbose "Starting up" + parse_arguments "$@" + debug_header "$@" + resolv_binaries "${me}"; unset me + check_udevd "$@" + find_user + config_load + find_display + find_gui + translate_load + check_root_deps + modeswitch_load + guruplug_probe + debug "Finished starting up.\n" +} + +# Main program +sakis3g_main() { + # Initialization + startup "$@" + # Get action + action_command "$@" && stop_with ${actionresult} + default_actor + ret=$? + stop_with ${ret} +} + +# Execute main method +sakis3g_main $0 "$@" + +# In case all actors performed well +debug "Reached end of program.\n" +stop_with 0 + diff --git a/Software/3G Modem/Sakis3G/sakis3g.tar.gz b/Software/3G Modem/Sakis3G/sakis3g.tar.gz new file mode 100644 index 0000000..1794baa Binary files /dev/null and b/Software/3G Modem/Sakis3G/sakis3g.tar.gz differ diff --git a/Software/3G Modem/Speedtest.txt b/Software/3G Modem/Speedtest.txt new file mode 100644 index 0000000..dde183a --- /dev/null +++ b/Software/3G Modem/Speedtest.txt @@ -0,0 +1,3 @@ +Salmenkopf: Download: 4,52Mbit/s Upload: 3,10Mbit/s + +Kirchkopf: Download: 2,40Mbit/s Upload: 3,00Mbit/s diff --git a/Software/3G Modem/USB Modeswitcher/.Installation.txt.kate-swp b/Software/3G Modem/USB Modeswitcher/.Installation.txt.kate-swp new file mode 100644 index 0000000..7b2da70 Binary files /dev/null and b/Software/3G Modem/USB Modeswitcher/.Installation.txt.kate-swp differ diff --git a/Software/3G Modem/USB Modeswitcher/Installation.txt b/Software/3G Modem/USB Modeswitcher/Installation.txt new file mode 100644 index 0000000..573cd32 --- /dev/null +++ b/Software/3G Modem/USB Modeswitcher/Installation.txt @@ -0,0 +1,8 @@ +sudo apt-get install ppp usb-modeswitch + + +sudo usb_modeswitch -I -v 12d1 -p 1446 -V 12d1 -P 1446 -M '55534243123456780000000000000011062000000100000000000000000000' + + + +sudo usb_modeswitch -v 12d1 -p 14fe -M '55534243123456780000000000000011062000000100000000000000000000' diff --git a/Software/3G Modem/USB Modeswitcher/libusb-1.0.9.tar.bz2 b/Software/3G Modem/USB Modeswitcher/libusb-1.0.9.tar.bz2 new file mode 100644 index 0000000..0c5da32 Binary files /dev/null and b/Software/3G Modem/USB Modeswitcher/libusb-1.0.9.tar.bz2 differ diff --git a/Software/3G Modem/USB Modeswitcher/usb-modeswitch-2.5.0.tar.bz2 b/Software/3G Modem/USB Modeswitcher/usb-modeswitch-2.5.0.tar.bz2 new file mode 100644 index 0000000..10af9fa Binary files /dev/null and b/Software/3G Modem/USB Modeswitcher/usb-modeswitch-2.5.0.tar.bz2 differ diff --git a/Software/3G Modem/modem cron 6 Stunden.txt b/Software/3G Modem/modem cron 6 Stunden.txt new file mode 100644 index 0000000..71c11c2 --- /dev/null +++ b/Software/3G Modem/modem cron 6 Stunden.txt @@ -0,0 +1,4 @@ + + + +0 */6 * * * sudo /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' \ No newline at end of file diff --git a/Software/3G Modem/rc.local b/Software/3G Modem/rc.local new file mode 100644 index 0000000..7589511 --- /dev/null +++ b/Software/3G Modem/rc.local @@ -0,0 +1,25 @@ +#!/bin/sh -e +# V0.1 17.03.2017 +# rc.local +# +# This script is executed at the end of each multiuser runlevel. +# Make sure that the script will "exit 0" on success or any other +# value on error. +# +# In order to enable or disable this script just change the execution +# bits. +# +# By default this script does nothing. + +printf "%sStarting 3G Modem%s /n" + +sudo /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + +# Print the IP address +_IP=$(hostname -I) || true +if [ "$_IP" ]; then + printf "My IP address is %s\n" "$_IP" +fi + +exit 0 + diff --git a/Software/3G Modem/sakis reconnect stuff.txt b/Software/3G Modem/sakis reconnect stuff.txt new file mode 100644 index 0000000..0adeaed --- /dev/null +++ b/Software/3G Modem/sakis reconnect stuff.txt @@ -0,0 +1,60 @@ +try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + + + + + + + + + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') diff --git a/Software/3G Modem/sakis.txt b/Software/3G Modem/sakis.txt new file mode 100644 index 0000000..c260f8d --- /dev/null +++ b/Software/3G Modem/sakis.txt @@ -0,0 +1,16 @@ +/usr/bin/modem3g/sakis3g --interactive + + +/usr/bin/modem3g/sakis3g connect --console APN='internet.eplus.de' USBINTERFACE='0' USBMODEM='12d1:1436' + +/usr/bin/modem3g/sakis3g info + +/usr/bin/modem3g/sakis3g status + +/usr/bin/modem3g/sakis3g disconnect + + + +O2/WinSim/Drillisch/Handyvertag.de/AldiTalk APN: internet.eplus.de + +vodafone APN: web.vodafone.de diff --git a/Software/Backup_CMD.txt b/Software/Backup_CMD.txt new file mode 100644 index 0000000..eb392e0 --- /dev/null +++ b/Software/Backup_CMD.txt @@ -0,0 +1,12 @@ +ls | grep Jun | mv /home/hendrik/ftp/files/camera03/Position02/2018/06_June/ + + +ls | grep Jun -exec mv {} /home/hendrik/ftp/files/camera03/Position02/2018/06_June/ \; + + +find -maxdepth 1 -mtime +0 -type f -exec ls -l {} \; + + +/home/hendrik/ftp/files/camera01/latest/ + +find -maxdepth 1 -mtime +0 -type f -exec mv {} /home/hendrik/ftp/files/camera01/2018/06_June/ \; diff --git a/Software/Betriebsspannung einlesen/Betriebsspannung.py b/Software/Betriebsspannung einlesen/Betriebsspannung.py new file mode 100644 index 0000000..dec8691 --- /dev/null +++ b/Software/Betriebsspannung einlesen/Betriebsspannung.py @@ -0,0 +1,16 @@ +from spidev import SpiDev + +spi = SpiDev() +spi.open(0,0) + +def read(channel = 0): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +value = read(channel = 0) + +print("Anliegende Spannung: %.2f" % ((value / 1023.0 * 3.3)*6.62) ) + + + diff --git a/Software/Betriebsspannung einlesen/Spannungsteiler b/Software/Betriebsspannung einlesen/Spannungsteiler new file mode 100644 index 0000000..0f49b3b --- /dev/null +++ b/Software/Betriebsspannung einlesen/Spannungsteiler @@ -0,0 +1,4 @@ +[Desktop Entry] +Icon=text-html +Type=Link +URL[$e]=http://www.electronicsplanet.ch/Spannungsteiler/spannungsteiler-berechnen.php diff --git a/Software/Betriebsspannung einlesen/Thread-12v-batterieueberwachung b/Software/Betriebsspannung einlesen/Thread-12v-batterieueberwachung new file mode 100644 index 0000000..59b0c13 --- /dev/null +++ b/Software/Betriebsspannung einlesen/Thread-12v-batterieueberwachung @@ -0,0 +1,1650 @@ + + + +12V BatterieÃœberwachung + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ +
+ + + + +
+ +
+
+ +
+ + + + + + +
+ + + + + + + diff --git a/Software/Betriebsspannung einlesen/Widerstände b/Software/Betriebsspannung einlesen/Widerstände new file mode 100644 index 0000000..d9c1f20 --- /dev/null +++ b/Software/Betriebsspannung einlesen/Widerstände @@ -0,0 +1,4 @@ + +R1 = 1k +R2 = 186 +Vin = 21V diff --git a/Software/Betriebsspannung einlesen/spannungsteiler-mit-zwei-widerstaenden.png b/Software/Betriebsspannung einlesen/spannungsteiler-mit-zwei-widerstaenden.png new file mode 100644 index 0000000..1bb42de Binary files /dev/null and b/Software/Betriebsspannung einlesen/spannungsteiler-mit-zwei-widerstaenden.png differ diff --git a/Software/Datenvolumen.ods b/Software/Datenvolumen.ods new file mode 100644 index 0000000..9a934db Binary files /dev/null and b/Software/Datenvolumen.ods differ diff --git a/Software/FTP/FTP login.txt b/Software/FTP/FTP login.txt new file mode 100644 index 0000000..141e636 --- /dev/null +++ b/Software/FTP/FTP login.txt @@ -0,0 +1,5 @@ +User: uploader +pw: de8f57022a3909151bd1 + +User: brunner +pw: bb1753f214940e04b \ No newline at end of file diff --git a/Software/FTP/Samba.txt b/Software/FTP/Samba.txt new file mode 100644 index 0000000..f92d125 --- /dev/null +++ b/Software/FTP/Samba.txt @@ -0,0 +1,24 @@ + + + + +user: uploader + +pw: klausi7T1w + + +usermod -aG ftp-uploader www-data + + + +[ftp] + path = /home/hendrik/ftp/files + valid users = www-data + read list = www-data + read only = Yes + create mask = 0664 + directory mask = 0754 + + + + chown -R ftp-user:ftp-user /home/hendrik/ftp diff --git a/Software/FTP/Test_Verzeichnis.tar.zst b/Software/FTP/Test_Verzeichnis.tar.zst new file mode 100644 index 0000000..f2105dd Binary files /dev/null and b/Software/FTP/Test_Verzeichnis.tar.zst differ diff --git a/Software/FTP/ftp_setup.txt b/Software/FTP/ftp_setup.txt new file mode 100644 index 0000000..4ea549c --- /dev/null +++ b/Software/FTP/ftp_setup.txt @@ -0,0 +1,8 @@ +1) mkdir /home/ftp +2) sudo useradd -g ftp-uploader -d /home/ftp uploader + passwd uploader +3) sudo chown uploader:ftp-user /home/ftp +4) sudo useradd -g ftp-user -d /home/ftp client + passwd client +5) sudo chown -R uploader:ftp-user /home/ftp +6) sudo chmod -R 754 /home/ftp \ No newline at end of file diff --git a/Software/Postpoduktion/Server_TLC_PostSW.txt b/Software/Postpoduktion/Server_TLC_PostSW.txt new file mode 100644 index 0000000..13e2f1b --- /dev/null +++ b/Software/Postpoduktion/Server_TLC_PostSW.txt @@ -0,0 +1,30 @@ +nohup java -jar tlc_post.jar -log -m createDB -r /home/hendrik/ftp/files/camera01/ -p /home/hendrik/tlc_post/TLC01/ -i counter -n 140780 >> TLC01/log01.txt + +nohup java -jar tlc_post.jar -log -m createDB -r /home/hendrik/ftp/files/camera02/ -p /home/hendrik/tlc_post/TLC02/ -i counter -n 135414 >> TLC02/log02.txt + +java -jar tlc_post.jar -log -m createDB -r /home/hendrik/ftp/files/camera04/ -p /home/hendrik/tlc_post/TLC04/ -i counter -n 11935 & >> TLC04/log04.txt + + +printf "TLC01: " && tail -n 1 ./TLC01/log01.txt && printf "TLC02: " && tail -n 1 ./TLC02/log02.txt && printf "TLC04: " && tail -n 1 ./TLC04/log04.txt + + + + + + + + +while true; do + + clear + + printf "TLC01: " && tail -n 1 ./TLC01/log01.txt && printf "TLC02: " && tail -n 1 ./TLC02/log02.txt && printf "TLC04: " && tail -n 1 ./TLC04/log04.txt + + printf "\n" + + sleep 1 + +done + + + diff --git a/Software/Postpoduktion/brunner_cmd.txt b/Software/Postpoduktion/brunner_cmd.txt new file mode 100644 index 0000000..67a2281 --- /dev/null +++ b/Software/Postpoduktion/brunner_cmd.txt @@ -0,0 +1,7 @@ + + +-log -m createDB -r /home/hendrik/FTP/camera01/ -p /home/hendrik/Schreibtisch/TLC01/ -i counter -n 140780 + +-log -m createDB -r /home/hendrik/FTP/camera02/ -p /home/hendrik/Schreibtisch/TLC02/ -i counter -n 135414 + +-log -m createDB -r /home/hendrik/FTP/camera04/ -p /home/hendrik/Schreibtisch/TLC04/ -i counter -n 11935 diff --git a/Software/RTC/Installation.txt b/Software/RTC/Installation.txt new file mode 100644 index 0000000..fcf69e0 --- /dev/null +++ b/Software/RTC/Installation.txt @@ -0,0 +1,17 @@ +apt-get install i2c-tools + +i2cdetect -y 1 + +modprobe rtc-ds1307 + +bash + +echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device + +exit + +zeit mit internet syncroniseiren + +hwclock -w + +nano /etc/modules und rtc-ds1307 hinzufügen diff --git a/Software/RTC/RTC_Bug_fix.txt b/Software/RTC/RTC_Bug_fix.txt new file mode 100644 index 0000000..939f73a --- /dev/null +++ b/Software/RTC/RTC_Bug_fix.txt @@ -0,0 +1,32 @@ +apt-get install i2c-tools + +i2cdetect -y 1 + +modprobe rtc-ds1307 + +bash + +echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device + +exit + +zeit mit internet synchronisieren + +hwclock -w + +nano /etc/modules und rtc-ds1307 hinzufügen + + +nano /etc/rc.local +---------------------------------------------------- + +echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device +hwclock -s + +---------------------------------------------------- + + +Zusatz: + +date -s "29 AUG 1997 13:00:00" + diff --git a/Software/SchärfeTest/test.sh b/Software/SchärfeTest/test.sh new file mode 100644 index 0000000..222beb1 --- /dev/null +++ b/Software/SchärfeTest/test.sh @@ -0,0 +1 @@ +raspivid -t -0 \ No newline at end of file diff --git a/Software/SchärfeTest/zoom.sh b/Software/SchärfeTest/zoom.sh new file mode 100644 index 0000000..9da7568 --- /dev/null +++ b/Software/SchärfeTest/zoom.sh @@ -0,0 +1 @@ +raspivid -t -0 -roi 0.1,0.2,0.3,0.4 \ No newline at end of file diff --git a/Software/Speedtest API/Install.txt b/Software/Speedtest API/Install.txt new file mode 100644 index 0000000..8198eeb --- /dev/null +++ b/Software/Speedtest API/Install.txt @@ -0,0 +1,6 @@ +wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py + + +chmod +x speedtest-cli + +./speedtest-cli \ No newline at end of file diff --git a/Software/Speedtest API/speedtest.py b/Software/Speedtest API/speedtest.py new file mode 100644 index 0000000..1f0167a --- /dev/null +++ b/Software/Speedtest API/speedtest.py @@ -0,0 +1,1430 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# Copyright 2012-2016 Matt Martz +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import os +import re +import csv +import sys +import math +import errno +import signal +import socket +import timeit +import datetime +import platform +import threading +import xml.parsers.expat + +try: + import gzip + GZIP_BASE = gzip.GzipFile +except ImportError: + gzip = None + GZIP_BASE = object + +__version__ = '1.0.2' + + +class FakeShutdownEvent(object): + """Class to fake a threading.Event.isSet so that users of this module + are not required to register their own threading.Event() + """ + + @staticmethod + def isSet(): + "Dummy method to always return false""" + return False + + +# Some global variables we use +USER_AGENT = None +SOURCE = None +SHUTDOWN_EVENT = FakeShutdownEvent() +SCHEME = 'http' +DEBUG = False + +# Used for bound_interface +SOCKET_SOCKET = socket.socket + +# Begin import game to handle Python 2 and Python 3 +try: + import json +except ImportError: + try: + import simplejson as json + except ImportError: + json = None + +try: + import xml.etree.cElementTree as ET +except ImportError: + try: + import xml.etree.ElementTree as ET + except ImportError: + from xml.dom import minidom as DOM + ET = None + +try: + from urllib2 import urlopen, Request, HTTPError, URLError +except ImportError: + from urllib.request import urlopen, Request, HTTPError, URLError + +try: + from httplib import HTTPConnection +except ImportError: + from http.client import HTTPConnection + +try: + from httplib import HTTPSConnection +except ImportError: + try: + from http.client import HTTPSConnection + except ImportError: + HTTPSConnection = None + +try: + from Queue import Queue +except ImportError: + from queue import Queue + +try: + from urlparse import urlparse +except ImportError: + from urllib.parse import urlparse + +try: + from urlparse import parse_qs +except ImportError: + try: + from urllib.parse import parse_qs + except ImportError: + from cgi import parse_qs + +try: + from hashlib import md5 +except ImportError: + from md5 import md5 + +try: + from argparse import ArgumentParser as ArgParser + from argparse import SUPPRESS as ARG_SUPPRESS + PARSER_TYPE_INT = int + PARSER_TYPE_STR = str +except ImportError: + from optparse import OptionParser as ArgParser + from optparse import SUPPRESS_HELP as ARG_SUPPRESS + PARSER_TYPE_INT = 'int' + PARSER_TYPE_STR = 'string' + +try: + from cStringIO import StringIO + BytesIO = None +except ImportError: + try: + from io import StringIO, BytesIO + except ImportError: + from StringIO import StringIO + BytesIO = None + +try: + import builtins +except ImportError: + def print_(*args, **kwargs): + """The new-style print function for Python 2.4 and 2.5. + + Taken from https://pypi.python.org/pypi/six/ + + Modified to set encoding to UTF-8 if not set when stdout may not be + a tty such as when piping to head + """ + fp = kwargs.pop("file", sys.stdout) + if fp is None: + return + + def write(data): + if not isinstance(data, basestring): + data = str(data) + # If the file has an encoding, encode unicode with it. + encoding = fp.encoding or 'UTF-8' # Diverges for notty + if (isinstance(fp, file) and + isinstance(data, unicode) and + encoding is not None): + errors = getattr(fp, "errors", None) + if errors is None: + errors = "strict" + data = data.encode(encoding, errors) + fp.write(data) + want_unicode = False + sep = kwargs.pop("sep", None) + if sep is not None: + if isinstance(sep, unicode): + want_unicode = True + elif not isinstance(sep, str): + raise TypeError("sep must be None or a string") + end = kwargs.pop("end", None) + if end is not None: + if isinstance(end, unicode): + want_unicode = True + elif not isinstance(end, str): + raise TypeError("end must be None or a string") + if kwargs: + raise TypeError("invalid keyword arguments to print()") + if not want_unicode: + for arg in args: + if isinstance(arg, unicode): + want_unicode = True + break + if want_unicode: + newline = unicode("\n") + space = unicode(" ") + else: + newline = "\n" + space = " " + if sep is None: + sep = space + if end is None: + end = newline + for i, arg in enumerate(args): + if i: + write(sep) + write(arg) + write(end) +else: + print_ = getattr(builtins, 'print') + del builtins + +# Exception "constants" to support Python 2 through Python 3 +try: + import ssl + try: + CERT_ERROR = (ssl.CertificateError,) + except AttributeError: + CERT_ERROR = tuple() + + HTTP_ERRORS = ((HTTPError, URLError, socket.error, ssl.SSLError) + + CERT_ERROR) +except ImportError: + HTTP_ERRORS = (HTTPError, URLError, socket.error) + + +class SpeedtestException(Exception): + """Base exception for this module""" + + +class SpeedtestCLIError(SpeedtestException): + """Generic exception for raising errors during CLI operation""" + + +class SpeedtestHTTPError(SpeedtestException): + """Base HTTP exception for this module""" + + +class SpeedtestConfigError(SpeedtestException): + """Configuration provided is invalid""" + + +class ConfigRetrievalError(SpeedtestHTTPError): + """Could not retrieve config.php""" + + +class ServersRetrievalError(SpeedtestHTTPError): + """Could not retrieve speedtest-servers.php""" + + +class InvalidServerIDType(SpeedtestException): + """Server ID used for filtering was not an integer""" + + +class NoMatchedServers(SpeedtestException): + """No servers matched when filtering""" + + +class SpeedtestMiniConnectFailure(SpeedtestException): + """Could not connect to the provided speedtest mini server""" + + +class InvalidSpeedtestMiniServer(SpeedtestException): + """Server provided as a speedtest mini server does not actually appear + to be a speedtest mini server + """ + + +class ShareResultsConnectFailure(SpeedtestException): + """Could not connect to speedtest.net API to POST results""" + + +class ShareResultsSubmitFailure(SpeedtestException): + """Unable to successfully POST results to speedtest.net API after + connection + """ + + +class SpeedtestUploadTimeout(SpeedtestException): + """testlength configuration reached during upload + Used to ensure the upload halts when no additional data should be sent + """ + + +class SpeedtestBestServerFailure(SpeedtestException): + """Unable to determine best server""" + + +class GzipDecodedResponse(GZIP_BASE): + """A file-like object to decode a response encoded with the gzip + method, as described in RFC 1952. + + Largely copied from ``xmlrpclib``/``xmlrpc.client`` and modified + to work for py2.4-py3 + """ + def __init__(self, response): + # response doesn't support tell() and read(), required by + # GzipFile + if not gzip: + raise SpeedtestHTTPError('HTTP response body is gzip encoded, ' + 'but gzip support is not available') + IO = BytesIO or StringIO + self.io = IO() + while 1: + chunk = response.read(1024) + if len(chunk) == 0: + break + self.io.write(chunk) + self.io.seek(0) + gzip.GzipFile.__init__(self, mode='rb', fileobj=self.io) + + def close(self): + try: + gzip.GzipFile.close(self) + finally: + self.io.close() + + +def get_exception(): + """Helper function to work with py2.4-py3 for getting the current + exception in a try/except block + """ + return sys.exc_info()[1] + + +def bound_socket(*args, **kwargs): + """Bind socket to a specified source IP address""" + + sock = SOCKET_SOCKET(*args, **kwargs) + sock.bind((SOURCE, 0)) + return sock + + +def distance(origin, destination): + """Determine distance between 2 sets of [lat,lon] in km""" + + lat1, lon1 = origin + lat2, lon2 = destination + radius = 6371 # km + + dlat = math.radians(lat2 - lat1) + dlon = math.radians(lon2 - lon1) + a = (math.sin(dlat / 2) * math.sin(dlat / 2) + + math.cos(math.radians(lat1)) * + math.cos(math.radians(lat2)) * math.sin(dlon / 2) * + math.sin(dlon / 2)) + c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a)) + d = radius * c + + return d + + +def build_user_agent(): + """Build a Mozilla/5.0 compatible User-Agent string""" + + global USER_AGENT + if USER_AGENT: + return USER_AGENT + + ua_tuple = ( + 'Mozilla/5.0', + '(%s; U; %s; en-us)' % (platform.system(), platform.architecture()[0]), + 'Python/%s' % platform.python_version(), + '(KHTML, like Gecko)', + 'speedtest-cli/%s' % __version__ + ) + USER_AGENT = ' '.join(ua_tuple) + printer(USER_AGENT, debug=True) + return USER_AGENT + + +def build_request(url, data=None, headers=None, bump=''): + """Build a urllib2 request object + + This function automatically adds a User-Agent header to all requests + + """ + + if not USER_AGENT: + build_user_agent() + + if not headers: + headers = {} + + if url[0] == ':': + schemed_url = '%s%s' % (SCHEME, url) + else: + schemed_url = url + + if '?' in url: + delim = '&' + else: + delim = '?' + + # WHO YOU GONNA CALL? CACHE BUSTERS! + final_url = '%s%sx=%s.%s' % (schemed_url, delim, + int(timeit.time.time() * 1000), + bump) + + headers.update({ + 'User-Agent': USER_AGENT, + 'Cache-Control': 'no-cache', + }) + + printer('%s %s' % (('GET', 'POST')[bool(data)], final_url), + debug=True) + + return Request(final_url, data=data, headers=headers) + + +def catch_request(request): + """Helper function to catch common exceptions encountered when + establishing a connection with a HTTP/HTTPS request + + """ + + try: + uh = urlopen(request) + return uh, False + except HTTP_ERRORS: + e = get_exception() + return None, e + + +def get_response_stream(response): + """Helper function to return either a Gzip reader if + ``Content-Encoding`` is ``gzip`` otherwise the response itself + + """ + + try: + getheader = response.headers.getheader + except AttributeError: + getheader = response.getheader + + if getheader('content-encoding') == 'gzip': + return GzipDecodedResponse(response) + + return response + + +def get_attributes_by_tag_name(dom, tag_name): + """Retrieve an attribute from an XML document and return it in a + consistent format + + Only used with xml.dom.minidom, which is likely only to be used + with python versions older than 2.5 + """ + elem = dom.getElementsByTagName(tag_name)[0] + return dict(list(elem.attributes.items())) + + +def print_dots(current, total, start=False, end=False): + """Built in callback function used by Thread classes for printing + status + """ + + if SHUTDOWN_EVENT.isSet(): + return + + sys.stdout.write('.') + if current + 1 == total and end is True: + sys.stdout.write('\n') + sys.stdout.flush() + + +def do_nothing(*args, **kwargs): + pass + + +class HTTPDownloader(threading.Thread): + """Thread class for retrieving a URL""" + + def __init__(self, i, request, start, timeout): + threading.Thread.__init__(self) + self.request = request + self.result = [0] + self.starttime = start + self.timeout = timeout + self.i = i + + def run(self): + try: + if (timeit.default_timer() - self.starttime) <= self.timeout: + f = urlopen(self.request) + while (not SHUTDOWN_EVENT.isSet() and + (timeit.default_timer() - self.starttime) <= + self.timeout): + self.result.append(len(f.read(10240))) + if self.result[-1] == 0: + break + f.close() + except IOError: + pass + + +class HTTPUploaderData(object): + """File like object to improve cutting off the upload once the timeout + has been reached + """ + + def __init__(self, length, start, timeout): + self.length = length + self.start = start + self.timeout = timeout + + self._data = None + + self.total = [0] + + def _create_data(self): + chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ' + multiplier = int(round(int(self.length) / 36.0)) + IO = BytesIO or StringIO + self._data = IO( + ('content1=%s' % + (chars * multiplier)[0:int(self.length) - 9] + ).encode() + ) + + @property + def data(self): + if not self._data: + self._create_data() + return self._data + + def read(self, n=10240): + if ((timeit.default_timer() - self.start) <= self.timeout and + not SHUTDOWN_EVENT.isSet()): + chunk = self.data.read(n) + self.total.append(len(chunk)) + return chunk + else: + raise SpeedtestUploadTimeout + + def __len__(self): + return self.length + + +class HTTPUploader(threading.Thread): + """Thread class for putting a URL""" + + def __init__(self, i, request, start, size, timeout): + threading.Thread.__init__(self) + self.request = request + self.request.data.start = self.starttime = start + self.size = size + self.result = None + self.timeout = timeout + self.i = i + + def run(self): + request = self.request + try: + if ((timeit.default_timer() - self.starttime) <= self.timeout and + not SHUTDOWN_EVENT.isSet()): + try: + f = urlopen(request) + except TypeError: + # PY24 expects a string or buffer + # This also causes issues with Ctrl-C, but we will concede + # for the moment that Ctrl-C on PY24 isn't immediate + request = build_request(self.request.get_full_url(), + data=request.data.read(self.size)) + f = urlopen(request) + f.read(11) + f.close() + self.result = sum(self.request.data.total) + else: + self.result = 0 + except (IOError, SpeedtestUploadTimeout): + self.result = sum(self.request.data.total) + + +class SpeedtestResults(object): + """Class for holding the results of a speedtest, including: + + Download speed + Upload speed + Ping/Latency to test server + Data about server that the test was run against + + Additionally this class can return a result data as a dictionary or CSV, + as well as submit a POST of the result data to the speedtest.net API + to get a share results image link. + """ + + def __init__(self, download=0, upload=0, ping=0, server=None): + self.download = download + self.upload = upload + self.ping = ping + if server is None: + self.server = {} + else: + self.server = server + self._share = None + self.timestamp = datetime.datetime.utcnow().isoformat() + self.bytes_received = 0 + self.bytes_sent = 0 + + def __repr__(self): + return repr(self.dict()) + + def share(self): + """POST data to the speedtest.net API to obtain a share results + link + """ + + if self._share: + return self._share + + download = int(round(self.download / 1000.0, 0)) + ping = int(round(self.ping, 0)) + upload = int(round(self.upload / 1000.0, 0)) + + # Build the request to send results back to speedtest.net + # We use a list instead of a dict because the API expects parameters + # in a certain order + api_data = [ + 'recommendedserverid=%s' % self.server['id'], + 'ping=%s' % ping, + 'screenresolution=', + 'promo=', + 'download=%s' % download, + 'screendpi=', + 'upload=%s' % upload, + 'testmethod=http', + 'hash=%s' % md5(('%s-%s-%s-%s' % + (ping, upload, download, '297aae72')) + .encode()).hexdigest(), + 'touchscreen=none', + 'startmode=pingselect', + 'accuracy=1', + 'bytesreceived=%s' % self.bytes_received, + 'bytessent=%s' % self.bytes_sent, + 'serverid=%s' % self.server['id'], + ] + + headers = {'Referer': 'http://c.speedtest.net/flash/speedtest.swf'} + request = build_request('://www.speedtest.net/api/api.php', + data='&'.join(api_data).encode(), + headers=headers) + f, e = catch_request(request) + if e: + raise ShareResultsConnectFailure(e) + + response = f.read() + code = f.code + f.close() + + if int(code) != 200: + raise ShareResultsSubmitFailure('Could not submit results to ' + 'speedtest.net') + + qsargs = parse_qs(response.decode()) + resultid = qsargs.get('resultid') + if not resultid or len(resultid) != 1: + raise ShareResultsSubmitFailure('Could not submit results to ' + 'speedtest.net') + + self._share = 'http://www.speedtest.net/result/%s.png' % resultid[0] + + return self._share + + def dict(self): + """Return dictionary of result data""" + + return { + 'download': self.download, + 'upload': self.upload, + 'ping': self.ping, + 'server': self.server, + 'timestamp': self.timestamp + } + + def csv(self, delimiter=','): + """Return data in CSV format""" + + data = self.dict() + out = StringIO() + writer = csv.writer(out, delimiter=delimiter, lineterminator='') + writer.writerow([data['server']['id'], data['server']['sponsor'], + data['server']['name'], data['timestamp'], + data['server']['d'], data['ping'], data['download'], + data['upload']]) + return out.getvalue() + + def json(self, pretty=False): + """Return data in JSON format""" + + kwargs = {} + if pretty: + kwargs.update({ + 'indent': 4, + 'sort_keys': True + }) + return json.dumps(self.dict(), **kwargs) + + +class Speedtest(object): + """Class for performing standard speedtest.net testing operations""" + + def __init__(self, config=None): + self.config = {} + self.get_config() + if config is not None: + self.config.update(config) + + self.servers = {} + self.closest = [] + self.best = {} + + self.results = SpeedtestResults() + + def get_config(self): + """Download the speedtest.net configuration and return only the data + we are interested in + """ + + headers = {} + if gzip: + headers['Accept-Encoding'] = 'gzip' + request = build_request('://www.speedtest.net/speedtest-config.php', + headers=headers) + uh, e = catch_request(request) + if e: + raise ConfigRetrievalError(e) + configxml = [] + + stream = get_response_stream(uh) + + while 1: + configxml.append(stream.read(1024)) + if len(configxml[-1]) == 0: + break + stream.close() + uh.close() + + if int(uh.code) != 200: + return None + + printer(''.encode().join(configxml), debug=True) + + try: + root = ET.fromstring(''.encode().join(configxml)) + server_config = root.find('server-config').attrib + download = root.find('download').attrib + upload = root.find('upload').attrib + # times = root.find('times').attrib + client = root.find('client').attrib + + except AttributeError: + root = DOM.parseString(''.join(configxml)) + server_config = get_attributes_by_tag_name(root, 'server-config') + download = get_attributes_by_tag_name(root, 'download') + upload = get_attributes_by_tag_name(root, 'upload') + # times = get_attributes_by_tag_name(root, 'times') + client = get_attributes_by_tag_name(root, 'client') + + ignore_servers = list( + map(int, server_config['ignoreids'].split(',')) + ) + + ratio = int(upload['ratio']) + upload_max = int(upload['maxchunkcount']) + up_sizes = [32768, 65536, 131072, 262144, 524288, 1048576, 7340032] + sizes = { + 'upload': up_sizes[ratio - 1:], + 'download': [350, 500, 750, 1000, 1500, 2000, 2500, + 3000, 3500, 4000] + } + + counts = { + 'upload': int(upload_max * 2 / len(sizes['upload'])), + 'download': int(download['threadsperurl']) + } + + threads = { + 'upload': int(upload['threads']), + 'download': int(server_config['threadcount']) * 2 + } + + length = { + 'upload': int(upload['testlength']), + 'download': int(download['testlength']) + } + + self.config.update({ + 'client': client, + 'ignore_servers': ignore_servers, + 'sizes': sizes, + 'counts': counts, + 'threads': threads, + 'length': length, + 'upload_max': upload_max + }) + + self.lat_lon = (float(client['lat']), float(client['lon'])) + + return self.config + + def get_servers(self, servers=None): + """Retrieve a the list of speedtest.net servers, optionally filtered + to servers matching those specified in the ``servers`` argument + """ + if servers is None: + servers = [] + + self.servers.clear() + + for i, s in enumerate(servers): + try: + servers[i] = int(s) + except ValueError: + raise InvalidServerIDType('%s is an invalid server type, must ' + 'be int' % s) + + urls = [ + '://www.speedtest.net/speedtest-servers-static.php', + 'http://c.speedtest.net/speedtest-servers-static.php', + '://www.speedtest.net/speedtest-servers.php', + 'http://c.speedtest.net/speedtest-servers.php', + ] + + headers = {} + if gzip: + headers['Accept-Encoding'] = 'gzip' + + errors = [] + for url in urls: + try: + request = build_request('%s?threads=%s' % + (url, + self.config['threads']['download']), + headers=headers) + uh, e = catch_request(request) + if e: + errors.append('%s' % e) + raise ServersRetrievalError + + stream = get_response_stream(uh) + + serversxml = [] + while 1: + serversxml.append(stream.read(1024)) + if len(serversxml[-1]) == 0: + break + + stream.close() + uh.close() + + if int(uh.code) != 200: + raise ServersRetrievalError + + printer(''.encode().join(serversxml), debug=True) + + try: + try: + root = ET.fromstring(''.encode().join(serversxml)) + elements = root.getiterator('server') + except AttributeError: + root = DOM.parseString(''.join(serversxml)) + elements = root.getElementsByTagName('server') + except (SyntaxError, xml.parsers.expat.ExpatError): + raise ServersRetrievalError + + for server in elements: + try: + attrib = server.attrib + except AttributeError: + attrib = dict(list(server.attributes.items())) + + if servers and int(attrib.get('id')) not in servers: + continue + + if int(attrib.get('id')) in self.config['ignore_servers']: + continue + + try: + d = distance(self.lat_lon, + (float(attrib.get('lat')), + float(attrib.get('lon')))) + except: + continue + + attrib['d'] = d + + try: + self.servers[d].append(attrib) + except KeyError: + self.servers[d] = [attrib] + + printer(''.encode().join(serversxml), debug=True) + + break + + except ServersRetrievalError: + continue + + if servers and not self.servers: + raise NoMatchedServers + + return self.servers + + def set_mini_server(self, server): + """Instead of querying for a list of servers, set a link to a + speedtest mini server + """ + + urlparts = urlparse(server) + + name, ext = os.path.splitext(urlparts[2]) + if ext: + url = os.path.dirname(server) + else: + url = server + + request = build_request(url) + uh, e = catch_request(request) + if e: + raise SpeedtestMiniConnectFailure('Failed to connect to %s' % + server) + else: + text = uh.read() + uh.close() + + extension = re.findall('upload_?[Ee]xtension: "([^"]+)"', + text.decode()) + if not extension: + for ext in ['php', 'asp', 'aspx', 'jsp']: + try: + f = urlopen('%s/speedtest/upload.%s' % (url, ext)) + except: + pass + else: + data = f.read().strip().decode() + if (f.code == 200 and + len(data.splitlines()) == 1 and + re.match('size=[0-9]', data)): + extension = [ext] + break + if not urlparts or not extension: + raise InvalidSpeedtestMiniServer('Invalid Speedtest Mini Server: ' + '%s' % server) + + self.servers = [{ + 'sponsor': 'Speedtest Mini', + 'name': urlparts[1], + 'd': 0, + 'url': '%s/speedtest/upload.%s' % (url.rstrip('/'), extension[0]), + 'latency': 0, + 'id': 0 + }] + + return self.servers + + def get_closest_servers(self, limit=5): + """Limit servers to the closest speedtest.net servers based on + geographic distance + """ + + if not self.servers: + self.get_servers() + + for d in sorted(self.servers.keys()): + for s in self.servers[d]: + self.closest.append(s) + if len(self.closest) == limit: + break + else: + continue + break + + printer(self.closest, debug=True) + return self.closest + + def get_best_server(self, servers=None): + """Perform a speedtest.net "ping" to determine which speedtest.net + server has the lowest latency + """ + + if not servers: + if not self.closest: + servers = self.get_closest_servers() + servers = self.closest + + results = {} + for server in servers: + cum = [] + url = os.path.dirname(server['url']) + urlparts = urlparse('%s/latency.txt' % url) + printer('%s %s/latency.txt' % ('GET', url), debug=True) + for _ in range(0, 3): + try: + if urlparts[0] == 'https': + h = HTTPSConnection(urlparts[1]) + else: + h = HTTPConnection(urlparts[1]) + headers = {'User-Agent': USER_AGENT} + start = timeit.default_timer() + h.request("GET", urlparts[2], headers=headers) + r = h.getresponse() + total = (timeit.default_timer() - start) + except HTTP_ERRORS: + e = get_exception() + printer('%r' % e, debug=True) + cum.append(3600) + continue + + text = r.read(9) + if int(r.status) == 200 and text == 'test=test'.encode(): + cum.append(total) + else: + cum.append(3600) + h.close() + + avg = round((sum(cum) / 6) * 1000.0, 3) + results[avg] = server + + try: + fastest = sorted(results.keys())[0] + except IndexError: + raise SpeedtestBestServerFailure('Unable to connect to servers to ' + 'test latency.') + best = results[fastest] + best['latency'] = fastest + + self.results.ping = fastest + self.results.server = best + + self.best.update(best) + printer(best, debug=True) + return best + + def download(self, callback=do_nothing): + """Test download speed against speedtest.net""" + + urls = [] + for size in self.config['sizes']['download']: + for _ in range(0, self.config['counts']['download']): + urls.append('%s/random%sx%s.jpg' % + (os.path.dirname(self.best['url']), size, size)) + + request_count = len(urls) + requests = [] + for i, url in enumerate(urls): + requests.append(build_request(url, bump=i)) + + def producer(q, requests, request_count): + for i, request in enumerate(requests): + thread = HTTPDownloader(i, request, start, + self.config['length']['download']) + thread.start() + q.put(thread, True) + callback(i, request_count, start=True) + + finished = [] + + def consumer(q, request_count): + while len(finished) < request_count: + thread = q.get(True) + while thread.isAlive(): + thread.join(timeout=0.1) + finished.append(sum(thread.result)) + callback(thread.i, request_count, end=True) + + q = Queue(self.config['threads']['download']) + prod_thread = threading.Thread(target=producer, + args=(q, requests, request_count)) + cons_thread = threading.Thread(target=consumer, + args=(q, request_count)) + start = timeit.default_timer() + prod_thread.start() + cons_thread.start() + while prod_thread.isAlive(): + prod_thread.join(timeout=0.1) + while cons_thread.isAlive(): + cons_thread.join(timeout=0.1) + + stop = timeit.default_timer() + self.results.bytes_received = sum(finished) + self.results.download = ( + (self.results.bytes_received / (stop - start)) * 8.0 + ) + if self.results.download > 100000: + self.config['threads']['upload'] = 8 + return self.results.download + + def upload(self, callback=do_nothing): + """Test upload speed against speedtest.net""" + + sizes = [] + + for size in self.config['sizes']['upload']: + for _ in range(0, self.config['counts']['upload']): + sizes.append(size) + + # request_count = len(sizes) + request_count = self.config['upload_max'] + + requests = [] + for i, size in enumerate(sizes): + # We set ``0`` for ``start`` and handle setting the actual + # ``start`` in ``HTTPUploader`` to get better measurements + requests.append( + ( + build_request( + self.best['url'], + HTTPUploaderData(size, 0, + self.config['length']['upload']) + ), + size + ) + ) + + def producer(q, requests, request_count): + for i, request in enumerate(requests[:request_count]): + thread = HTTPUploader(i, request[0], start, request[1], + self.config['length']['upload']) + thread.start() + q.put(thread, True) + callback(i, request_count, start=True) + + finished = [] + + def consumer(q, request_count): + while len(finished) < request_count: + thread = q.get(True) + while thread.isAlive(): + thread.join(timeout=0.1) + finished.append(thread.result) + callback(thread.i, request_count, end=True) + + q = Queue(self.config['threads']['upload']) + prod_thread = threading.Thread(target=producer, + args=(q, requests, request_count)) + cons_thread = threading.Thread(target=consumer, + args=(q, request_count)) + start = timeit.default_timer() + prod_thread.start() + cons_thread.start() + while prod_thread.isAlive(): + prod_thread.join(timeout=0.1) + while cons_thread.isAlive(): + cons_thread.join(timeout=0.1) + + stop = timeit.default_timer() + self.results.bytes_sent = sum(finished) + self.results.upload = ( + (self.results.bytes_sent / (stop - start)) * 8.0 + ) + return self.results.upload + + +def ctrl_c(signum, frame): + """Catch Ctrl-C key sequence and set a SHUTDOWN_EVENT for our threaded + operations + """ + + SHUTDOWN_EVENT.set() + print_('\nCancelling...') + sys.exit(0) + + +def version(): + """Print the version""" + + print_(__version__) + sys.exit(0) + + +def csv_header(): + """Print the CSV Headers""" + + print_('Server ID,Sponsor,Server Name,Timestamp,Distance,Ping,Download,' + 'Upload') + sys.exit(0) + + +def parse_args(): + """Function to handle building and parsing of command line arguments""" + description = ( + 'Command line interface for testing internet bandwidth using ' + 'speedtest.net.\n' + '------------------------------------------------------------' + '--------------\n' + 'https://github.com/sivel/speedtest-cli') + + parser = ArgParser(description=description) + # Give optparse.OptionParser an `add_argument` method for + # compatibility with argparse.ArgumentParser + try: + parser.add_argument = parser.add_option + except AttributeError: + pass + parser.add_argument('--bytes', dest='units', action='store_const', + const=('byte', 8), default=('bit', 1), + help='Display values in bytes instead of bits. Does ' + 'not affect the image generated by --share, nor ' + 'output from --json or --csv') + parser.add_argument('--share', action='store_true', + help='Generate and provide a URL to the speedtest.net ' + 'share results image') + parser.add_argument('--simple', action='store_true', default=False, + help='Suppress verbose output, only show basic ' + 'information') + parser.add_argument('--csv', action='store_true', default=False, + help='Suppress verbose output, only show basic ' + 'information in CSV format. Speeds listed in ' + 'bit/s and not affected by --bytes') + parser.add_argument('--csv-delimiter', default=',', type=PARSER_TYPE_STR, + help='Single character delimiter to use in CSV ' + 'output. Default ","') + parser.add_argument('--csv-header', action='store_true', default=False, + help='Print CSV headers') + parser.add_argument('--json', action='store_true', default=False, + help='Suppress verbose output, only show basic ' + 'information in JSON format. Speeds listed in ' + 'bit/s and not affected by --bytes') + parser.add_argument('--list', action='store_true', + help='Display a list of speedtest.net servers ' + 'sorted by distance') + parser.add_argument('--server', help='Specify a server ID to test against', + type=PARSER_TYPE_INT) + parser.add_argument('--mini', help='URL of the Speedtest Mini server') + parser.add_argument('--source', help='Source IP address to bind to') + parser.add_argument('--timeout', default=10, type=PARSER_TYPE_INT, + help='HTTP timeout in seconds. Default 10') + parser.add_argument('--secure', action='store_true', + help='Use HTTPS instead of HTTP when communicating ' + 'with speedtest.net operated servers') + parser.add_argument('--version', action='store_true', + help='Show the version number and exit') + parser.add_argument('--debug', action='store_true', + help=ARG_SUPPRESS, default=ARG_SUPPRESS) + + options = parser.parse_args() + if isinstance(options, tuple): + args = options[0] + else: + args = options + return args + + +def validate_optional_args(args): + """Check if an argument was provided that depends on a module that may + not be part of the Python standard library. + + If such an argument is supplied, and the module does not exist, exit + with an error stating which module is missing. + """ + optional_args = { + 'json': ('json/simplejson python module', json), + 'secure': ('SSL support', HTTPSConnection), + } + + for arg, info in optional_args.items(): + if getattr(args, arg, False) and info[1] is None: + raise SystemExit('%s is not installed. --%s is ' + 'unavailable' % (info[0], arg)) + + +def printer(string, quiet=False, debug=False, **kwargs): + """Helper function to print a string only when not quiet""" + + if debug and not DEBUG: + return + + if debug: + out = '\033[1;30mDEBUG: %s\033[0m' % string + else: + out = string + + if not quiet: + print_(out, **kwargs) + + +def shell(): + """Run the full speedtest.net test""" + + global SHUTDOWN_EVENT, SOURCE, SCHEME, DEBUG + SHUTDOWN_EVENT = threading.Event() + + signal.signal(signal.SIGINT, ctrl_c) + + args = parse_args() + + # Print the version and exit + if args.version: + version() + + if args.csv_header: + csv_header() + + if len(args.csv_delimiter) != 1: + raise SystemExit('--csv-delimiter must be a single character') + + validate_optional_args(args) + + socket.setdefaulttimeout(args.timeout) + + # If specified bind to a specific IP address + if args.source: + SOURCE = args.source + socket.socket = bound_socket + + if args.secure: + SCHEME = 'https' + + debug = getattr(args, 'debug', False) + if debug == 'SUPPRESSHELP': + debug = False + if debug: + DEBUG = True + + # Pre-cache the user agent string + build_user_agent() + + if args.simple or args.csv or args.json: + quiet = True + else: + quiet = False + + # Don't set a callback if we are running quietly + if quiet or debug: + callback = do_nothing + else: + callback = print_dots + + printer('Retrieving speedtest.net configuration...', quiet) + try: + speedtest = Speedtest() + except (ConfigRetrievalError, HTTP_ERRORS): + printer('Cannot retrieve speedtest configuration') + raise SpeedtestCLIError(get_exception()) + + if args.list: + try: + speedtest.get_servers() + except (ServersRetrievalError, HTTP_ERRORS): + print_('Cannot retrieve speedtest server list') + raise SpeedtestCLIError(get_exception()) + + for _, servers in sorted(speedtest.servers.items()): + for server in servers: + line = ('%(id)5s) %(sponsor)s (%(name)s, %(country)s) ' + '[%(d)0.2f km]' % server) + try: + print_(line) + except IOError: + e = get_exception() + if e.errno != errno.EPIPE: + raise + sys.exit(0) + + # Set a filter of servers to retrieve + servers = [] + if args.server: + servers.append(args.server) + + printer('Testing from %(isp)s (%(ip)s)...' % speedtest.config['client'], + quiet) + + if not args.mini: + printer('Retrieving speedtest.net server list...', quiet) + try: + speedtest.get_servers(servers) + except NoMatchedServers: + raise SpeedtestCLIError('No matched servers: %s' % args.server) + except (ServersRetrievalError, HTTP_ERRORS): + print_('Cannot retrieve speedtest server list') + raise SpeedtestCLIError(get_exception()) + except InvalidServerIDType: + raise SpeedtestCLIError('%s is an invalid server type, must ' + 'be an int' % args.server) + + printer('Selecting best server based on ping...', quiet) + speedtest.get_best_server() + elif args.mini: + speedtest.get_best_server(speedtest.set_mini_server(args.mini)) + + results = speedtest.results + + printer('Hosted by %(sponsor)s (%(name)s) [%(d)0.2f km]: ' + '%(latency)s ms' % results.server, quiet) + + printer('Testing download speed', quiet, + end=('', '\n')[bool(debug)]) + speedtest.download(callback=callback) + printer('Download: %0.2f M%s/s' % + ((results.download / 1000.0 / 1000.0) / args.units[1], + args.units[0]), + quiet) + + printer('Testing upload speed', quiet, + end=('', '\n')[bool(debug)]) + speedtest.upload(callback=callback) + printer('Upload: %0.2f M%s/s' % + ((results.upload / 1000.0 / 1000.0) / args.units[1], + args.units[0]), + quiet) + + if args.simple: + print_('Ping: %s ms\nDownload: %0.2f M%s/s\nUpload: %0.2f M%s/s' % + (results.ping, + (results.download / 1000.0 / 1000.0) / args.units[1], + args.units[0], + (results.upload / 1000.0 / 1000.0) / args.units[1], + args.units[0])) + elif args.csv: + print_(results.csv(delimiter=args.csv_delimiter)) + elif args.json: + print_(results.json()) + + if args.share: + printer('Share results: %s' % results.share(), quiet) + + +def main(): + try: + shell() + except KeyboardInterrupt: + print_('\nCancelling...') + except (SpeedtestException, SystemExit): + e = get_exception() + if getattr(e, 'code', 1) != 0: + raise SystemExit('ERROR: %s' % e) + + +if __name__ == '__main__': + main() + +# vim:ts=4:sw=4:expandtab diff --git a/Software/Temperatur/TempGrenzwerte.txt b/Software/Temperatur/TempGrenzwerte.txt new file mode 100644 index 0000000..7b828df --- /dev/null +++ b/Software/Temperatur/TempGrenzwerte.txt @@ -0,0 +1,9 @@ + + +<= -5°C --> Critical Coold + +<= 5°C --> Warning Coold + +>= 45°C --> Warning Hot + +>= 50°C --> Critical Hot \ No newline at end of file diff --git a/Software/Temperatur/TempRead.txt b/Software/Temperatur/TempRead.txt new file mode 100644 index 0000000..022f143 --- /dev/null +++ b/Software/Temperatur/TempRead.txt @@ -0,0 +1,11 @@ + +vcgencmd measure_temp + + +import os + +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 \ No newline at end of file diff --git a/Software/Vorlagen/Dokumentation_Produce_V03.txt b/Software/Vorlagen/Dokumentation_Produce_V03.txt new file mode 100644 index 0000000..9380ef7 --- /dev/null +++ b/Software/Vorlagen/Dokumentation_Produce_V03.txt @@ -0,0 +1,84 @@ +Version 0.3 +Stand: 23.03.2017 +---------------------------------------------------------------------------- +User: pi PW: qaws +User: root PW: qaws +--------------------------------------------------------------------------- +1) neustes Rasbian Lite Image auf SD-Card schreiben + +2) per UART SSH aktivieren User: pi PW: raspberry + +3) per SSH einloggen mit User: pi PW: raspberry + 3.1) Root-Nutzer freigenen: + 3.1.1) --> PW: qaws + 3.1.2) sudo nano /etc/ssh/sshd_config <-- die Berechtigung für rootssh setzten, PermitRootLogin yes + 3.1.3) sudo reboot + +4) mit root einloggen: + 4.1) raspi-config + 4.1.1) Change User Password --> User: pi PW: qaws + 4.1.2) Boot Options --> CLI ohne auto loggin + 4.1.3) Localisation Options + 4.1.3.1) Change Locale --> DE@de-UTF8 + 4.1.3.2) Change Timezone --> Berlin + 4.1.4) Interfacing Options + 4.1.4.1) enable Camera + 4.1.5) reboot + +5) mit root einloggen + 5.1) hostname -b TLCXX + 5.2) apt-get update + 5.3) apt-get upgrade + 5.4) apt-get install watchdog ppp usb-modeswitch weavedconnectd python3-picamera usbmount screenfetch + 5.5) Sakis + 5.5.1) wget http://raspberry-at-home.com/files/sakis3g.tar.gz + 5.5.2) mkdir /usr/bin/modem3g + 5.5.3) chmod 777 /usr/bin/modem3g + 5.5.4) cp sakis3g.tar.gz /usr/bin/modem3g + 5.5.5) cd /usr/bin/modem3g + 5.5.6) tar -zxvf sakis3g.tar.gz + 5.5.7) chmod +x sakis3g + 5.5.8) cd /root + 5.6) Speedtest CLI + 5.6.1) wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py + 5.6.2) chmod +x speedtest-cli + 5.7) Swap deaktivieren + 5.7.1) dphys-swapfile swapoff + 5.7.2) systemctl disable dphys-swapfile + 5.7.3) apt-get purge dphys-swapfile + 5.8) Watchdog + 5.8.1) modprobe bcm2835_wdt + 5.8.2) echo "bcm2835_wdt" | tee -a /etc/modules + 5.8.3) nano /etc/watchdog.conf + 5.8.3.1) # entfernen bei: watchdog-device = /dev/watchdog UND max-load-1 = 24 + 5.8.4) nano /lib/systemd/system/watchdog.service + 5.8.4.1) ergänzen um WantedBy=multi-user.target + 5.8.5) systemctl enable watchdog.service + 5.9) USB Mount + 5.9.1) nano /etc/usbmount/usbmount.conf + 5.9.2) FS_MOUNTOPTIONS="-fstype=vfat,gid=users,dmask=0007,fmask=0117" einfügen + + Edit /lib/systemd/system/systemd-udevd.service and change the line +MountFlags=slave +to +MountFlags=shared +then reboot + +6) mit WinSCP als root einloggen + 6.1) zoom.sh und test.sh in /root kopieren + 6.2) chmod +x zoom.sh + 6.3) chmod +x test.sh + 6.4) camera.py und config.txt in /home/pi/ kopieren <-- gehört user pi + 6.5) /home/pi/picture_Number.txt erstellen und 0 eintragen + 6.6) camera_boot.log erstellen + +7) Auto Start + 7.1) crontab -e + 7.2) @reboot /usr/bin/python3 /home/pi/camera.py 2>&1 >> /home/pi/camera_boot.log 2>&1 einfügen + +8) Ordner anlegen + 9.1) mkdir /media/usb/pictures + 9.2) mkdir /media/usb/log + + + diff --git a/Software/Vorlagen/Dokumentation_Produce_V04.txt b/Software/Vorlagen/Dokumentation_Produce_V04.txt new file mode 100644 index 0000000..51a2fbf --- /dev/null +++ b/Software/Vorlagen/Dokumentation_Produce_V04.txt @@ -0,0 +1,115 @@ +Version 0.4 +Stand: 22.06.2018 +---------------------------------------------------------------------------- +User: pi PW: qaws +User: root PW: qaws +--------------------------------------------------------------------------- +1) neustes Rasbian Lite Image auf SD-Card schreiben + +2) per UART SSH aktivieren User: pi PW: raspberry + +3) per SSH einloggen mit User: pi PW: raspberry + 3.1) Root-Nutzer freigenen: + 3.1.1) --> PW: qaws + 3.1.2) sudo nano /etc/ssh/sshd_config <-- die Berechtigung für rootssh setzten, PermitRootLogin yes + 3.1.3) sudo nano /etc/ssh/sshd_config <-- Banner /home/pi/banner.txt + 3.1.3) sudo reboot + +4) mit root einloggen: + 4.1) raspi-config + 4.1.1) Change User Password --> User: pi PW: qaws + 4.1.2) Boot Options --> CLI ohne auto loggin + 4.1.3) Localisation Options + 4.1.3.1) Change Locale --> DE@de-UTF8 + 4.1.3.2) Change Timezone --> Berlin + 4.1.4) Interfacing Options + 4.1.4.1) enable Camera + 4.1.4.2) enable SPI + 4.1.4.3) enable I2C + 4.1.5) Expand Filesystem + 4.1.6) reboot + +5) mit root einloggen + 5.1) hostname -b TLCXX + 5.2) apt-get update + 5.3) apt-get upgrade + 5.4) apt-get install watchdog ppp usb-modeswitch weavedconnectd python3-picamera usbmount screenfetch python3-RPi.GPIO python3-dev i2c-tools + 5.5) Sakis + 5.5.1) wget http://raspberry-at-home.com/files/sakis3g.tar.gz + 5.5.2) mkdir /usr/bin/modem3g + 5.5.3) chmod 777 /usr/bin/modem3g + 5.5.4) cp sakis3g.tar.gz /usr/bin/modem3g + 5.5.5) cd /usr/bin/modem3g + 5.5.6) tar -zxvf sakis3g.tar.gz + 5.5.7) chmod +x sakis3g + 5.5.8) cd /root + 5.6) Speedtest CLI + 5.6.1) wget -O speedtest-cli https://raw.githubusercontent.com/sivel/speedtest-cli/master/speedtest.py + 5.6.2) chmod +x speedtest-cli + 5.7) Swap deaktivieren + 5.7.1) dphys-swapfile swapoff + 5.7.2) systemctl disable dphys-swapfile + 5.7.3) apt-get purge dphys-swapfile + 5.8) Watchdog + 5.8.1) modprobe bcm2835_wdt + 5.8.2) echo "bcm2835_wdt" | tee -a /etc/modules + 5.8.3) nano /etc/watchdog.conf + 5.8.3.1) # entfernen bei: watchdog-device = /dev/watchdog UND max-load-1 = 24 + 5.8.4) nano /lib/systemd/system/watchdog.service + 5.8.4.1) ergänzen um WantedBy=multi-user.target + 5.8.5) systemctl enable watchdog.service + 5.9) USB Mount + 5.9.1) nano /etc/usbmount/usbmount.conf + 5.9.2) FS_MOUNTOPTIONS="-fstype=vfat,gid=users,dmask=0007,fmask=0117" einfügen + 5.10) SPI + 5.10.1) wget https://github.com/doceme/py-spidev/archive/master.zip + 5.10.2) unzip master.zip + 5.10.3) cd py-spidev-master + 5.10.4) python3 setup.py install + 5.10.5) cd /root/ + +6) mit WinSCP als root einloggen + 6.1) camera.py und config.txt in /home/pi/ kopieren <-- gehört user pi + 6.2) /home/pi/picture_Number.txt erstellen und 0 eintragen + 6.4) /home/pi/banner.txt kopieren + +7) Auto Start +nano /etc/systemd/system/TLC.service + +############ INSERT BEGIN ################# + +[Unit] +Description=TLC +After=syslog.target + +[Service] +RestartSec=2s +Type=simple +User=root +Group=root +WorkingDirectory=/home/pi/ +ExecStart=/usr/bin/python3.4 /home/pi/camera.py +Restart=always +RestartSec=2s + +[Install] +WantedBy=multi-user.target + +############ INSERT END ################# + +systemctl enable TLC.service + +#debug + +journalctl -u TLC.service + + +8) Banner + 8.1) nano /root/.profile <-- /bin/cat /home/pi/banner.txt + + + + + + + diff --git a/Software/Vorlagen/Dokumentation_Replace_V02.txt b/Software/Vorlagen/Dokumentation_Replace_V02.txt new file mode 100644 index 0000000..b6d9f15 --- /dev/null +++ b/Software/Vorlagen/Dokumentation_Replace_V02.txt @@ -0,0 +1,54 @@ +Version 0.2 +Stand: 17.03.2017 +---------------------------------------------------------------------------- +User: pi PW: qaws +User: root PW: qaws +--------------------------------------------------------------------------- +1) Image XXXX.img auf SD-Card schreiben + +2) mit root einloggen per SSH + 2.1) hostname -b TLCXX + +3) remot3.it einrichten + 3.1) weavedinstaller + 3.2) 1 - Sign on to your ... + 3.3) TLCXX <-- Name des Gerätes + 3.4) 1 - Attach/reinstall ... + 3.5) 1 - SSH on port 22 + 3.6) yes + 3.7) SSH_TLCXX + 3.8) 4 - Exit + +4) mit WinSCP als root einloggen + 4.1) aktualisieren von camera.py und config.txt in /home/pi/ kopieren <-- gehört user pi + 4.2) /home/pi/picture_Number.txt die gewünschte Nummer eintragen + 4.3) config.txt anpassen + +5) Aufräumen + 5.1) in /root + 5.2) /media/usb + +6) Passwörter ändern + 6.1) passwd pi + 6.1.1) das pi-PW für TLCXX + 6.2) passwd root + 6.2.1) das root-PW für TLCXX + +7) Bei Modem-Version + 7.1) nano /etc/rc.local + 7.1.1) ergänzen um: + + printf "%sStarting 3G Modem%s /n" + sudo /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + + 7.2) Startverzögerung + 7.2.1) crontab -e + 7.2.2) @reboot /bin/sleep 120 ; /usr/bin/python3 /home/pi/camera.py 2>&1 >> /home/pi/camera_boot.log 2>&1 + + +8) reboot + + + + + \ No newline at end of file diff --git a/Software/Vorlagen/Dokumentation_Replace_V03.txt b/Software/Vorlagen/Dokumentation_Replace_V03.txt new file mode 100644 index 0000000..4e5fd49 --- /dev/null +++ b/Software/Vorlagen/Dokumentation_Replace_V03.txt @@ -0,0 +1,69 @@ +Version 0.3 +Stand: 22.06.2018 +---------------------------------------------------------------------------- +User: pi PW: qaws +User: root PW: qaws +--------------------------------------------------------------------------- +1) Image XXXX.img auf SD-Card schreiben + +2) mit root einloggen per SSH + 2.1) hostname -b TLCXX + 2.2) nano /home/pi/banner.txt <-- TLCXX ändern + +3) remot3.it einrichten + 3.1) weavedinstaller + 3.2) 1 - Sign on to your ... + 3.3) TLCXX <-- Name des Gerätes + 3.4) 1 - Attach/reinstall ... + 3.5) 1 - SSH on port 22 + 3.6) yes + 3.7) SSH_TLCXX + 3.8) 4 - Exit + +4) mit WinSCP als root einloggen + 4.1) aktualisieren von camera.py und config.txt in /home/pi/ kopieren <-- gehört user pi + 4.2) /home/pi/picture_Number.txt die gewünschte Nummer eintragen + 4.3) config.txt anpassen + +5) Aufräumen + 5.1) in /root + 5.2) /media/usb + +6) Passwörter ändern + 6.1) passwd pi + 6.1.1) das pi-PW für TLCXX + 6.2) passwd root + 6.2.1) das root-PW für TLCXX + +7) Bei Modem-Version + 7.1) nano /etc/rc.local + 7.1.1) ergänzen um: + + printf "%sStarting 3G Modem%s\n" + sudo /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + + 7.2) Startverzögerung + 7.2.1) crontab -e + 7.2.2) @reboot /bin/sleep 120 ; /usr/bin/python3 /home/pi/camera.py 2>&1 >> /home/pi/camera_boot.log 2>&1 + + +8) RTC bei I/O Board + 8.1) i2cdetect -y 1 + 8.2) modprobe rtc-ds1307 + 8.3) bash + 8.4) echo ds1307 0x68 > /sys/class/i2c-adapter/i2c-1/new_device + 8.5) exit + 8.6) zeit mit internet synchronisieren + 8.7) hwclock -w + 8.8) nano /etc/modules und rtc-ds1307 hinzufügen + +9) Ordner anlegen + 9.1) mkdir /media/usb/pictures + 9.2) mkdir /media/usb/log + +10) reboot + + + + + diff --git a/Software/Website/install.txt b/Software/Website/install.txt new file mode 100644 index 0000000..e3d8ca2 --- /dev/null +++ b/Software/Website/install.txt @@ -0,0 +1,53 @@ +mkdir -pv /home/timelapse + +latest_ftp_image.sh hinein kopieren + +nano /etc/systemd/system/TLCbackend.service + +############ INSERT BEGIN ################# + +[Unit] +Description=TLCbackend +After=syslog.target +After=network.target + +[Service] +RestartSec=2s +Type=oneshot +User=root +Group=root +WorkingDirectory=/home/timelapse/ +ExecStart=/bin/sh /home/timelapse/latest_ftp_image.sh + +[Install] +WantedBy=multi-user.target + +############ INSERT END ################# + +systemctl enable TLCbackend.service + +nano /etc/systemd/system/TLCbackend.timer + +############ INSERT BEGIN ################# + +[Unit] +Description=TLCbackend Timer + +[Timer] +OnActiveSec=30s +OnBootSec=10min +OnUnitActiveSec=5m + +[Install] +WantedBy=basic.target + +############ INSERT END ################# + +chmod 700 /home/timelapse/latest_ftp_image.sh + +systemctl enable --now TLCbackend.timer + + +#debug + +journalctl -u TLCbackend.service diff --git a/Software/Website/latest_ftp_image.sh b/Software/Website/latest_ftp_image.sh new file mode 100644 index 0000000..418af81 --- /dev/null +++ b/Software/Website/latest_ftp_image.sh @@ -0,0 +1,43 @@ +#! /bin/bash + +hostname=schuttercloud.com +username=uploader +password=XXXXXXXXXXXXXXXXXXXXXXXXXX +cameraDir=/camera03/latest/ +webDir=test +webFile=TLC03 +mask=mask.png + + +echo starting + +ftp -nv <> /home/pi/wifi_boot.log 2>&1 + +@reboot /bin/sleep 50 ; /usr/sbin/hostapd /etc/hostapd/hostapd.conf > /home/pi/wifi_boot.log & + + + + diff --git a/Software/ZK_python/Grenzwerte.txt b/Software/ZK_python/Grenzwerte.txt new file mode 100644 index 0000000..13bef3e --- /dev/null +++ b/Software/ZK_python/Grenzwerte.txt @@ -0,0 +1,40 @@ +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] + + +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] + + + +Monat Auf Unter (in Stunden) +_________________ +Jan 8 17 + +Feb 8 17.5 + +März 7 18 + +April 7 20 + +Mai 6 20.5 + +Juni 5.5 21.5 + +Juli 6 21.5 + +Aug 6.5 20.5 + +Sep 7.5 19.5 + +Okt 7.5 17.5 + +Nov 8 16.5 + +Dez 8 16.5 + + + +Auf = Wann geht die Sonne am spätesten im Monat auf. + +Unter = Wann geht die Sonne am frühsten im Monat unter. + +http://sunrisesunset.de/ \ No newline at end of file diff --git a/Software/ZK_python/Kameraeinstellungen.txt b/Software/ZK_python/Kameraeinstellungen.txt new file mode 100644 index 0000000..ed6e1f0 --- /dev/null +++ b/Software/ZK_python/Kameraeinstellungen.txt @@ -0,0 +1,9 @@ +Version 0.1 +Stand 16.03.2017 +---------------------------------------------------------------------------- + + +camera.iso = 50 +camera.resolution = (3280,2464) +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' \ No newline at end of file diff --git a/Software/ZK_python/Ordnerstruktur.txt b/Software/ZK_python/Ordnerstruktur.txt new file mode 100644 index 0000000..14171aa --- /dev/null +++ b/Software/ZK_python/Ordnerstruktur.txt @@ -0,0 +1,21 @@ +Bilder: +/camera01/session01/2018/01_January + + +Logs: +/logs/2018/01_January + +Monate: + +01_January +02_February +03_March +04_April +05_May +06_June +07_July +08_August +09_September +10_October +11_November +12_December diff --git a/Software/ZK_python/TempGrenzwerte.txt b/Software/ZK_python/TempGrenzwerte.txt new file mode 100644 index 0000000..7b828df --- /dev/null +++ b/Software/ZK_python/TempGrenzwerte.txt @@ -0,0 +1,9 @@ + + +<= -5°C --> Critical Coold + +<= 5°C --> Warning Coold + +>= 45°C --> Warning Hot + +>= 50°C --> Critical Hot \ No newline at end of file diff --git a/Software/ZK_python/camera_rc1_006.py b/Software/ZK_python/camera_rc1_006.py new file mode 100644 index 0000000..36d3f2e --- /dev/null +++ b/Software/ZK_python/camera_rc1_006.py @@ -0,0 +1,185 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_directory = configParser.get('config', 'ftp_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +while 1: + + time_next_unix = time.time() + 30 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + picture_number += 1 + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_007.py b/Software/ZK_python/camera_rc1_007.py new file mode 100644 index 0000000..c39749d --- /dev/null +++ b/Software/ZK_python/camera_rc1_007.py @@ -0,0 +1,193 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +while 1: + + time_next_unix = time.time() + 300 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + picture_number += 1 + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_008.py b/Software/ZK_python/camera_rc1_008.py new file mode 100644 index 0000000..b0872b3 --- /dev/null +++ b/Software/ZK_python/camera_rc1_008.py @@ -0,0 +1,199 @@ +#(c)2017 Jannik Seiler + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +while 1: + + time_next_unix = time.time() + 300 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + picture_number += 1 + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_009.py b/Software/ZK_python/camera_rc1_009.py new file mode 100644 index 0000000..3bf7c0c --- /dev/null +++ b/Software/ZK_python/camera_rc1_009.py @@ -0,0 +1,245 @@ +#(c)2017 Jannik Seiler +#009 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 009' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_010.py b/Software/ZK_python/camera_rc1_010.py new file mode 100644 index 0000000..752a7e8 --- /dev/null +++ b/Software/ZK_python/camera_rc1_010.py @@ -0,0 +1,248 @@ +#(c)2017 Jannik Seiler +#009 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 009' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month]*60*60 and seconds1 < bed_Time[datetime.now().month]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until'+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_011.py b/Software/ZK_python/camera_rc1_011.py new file mode 100644 index 0000000..860363f --- /dev/null +++ b/Software/ZK_python/camera_rc1_011.py @@ -0,0 +1,248 @@ +#(c)2017 Jannik Seiler +#011 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 011' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_012.py b/Software/ZK_python/camera_rc1_012.py new file mode 100644 index 0000000..613efcf --- /dev/null +++ b/Software/ZK_python/camera_rc1_012.py @@ -0,0 +1,266 @@ +#(c)2017 Jannik Seiler +#012 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 012' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_013.py b/Software/ZK_python/camera_rc1_013.py new file mode 100644 index 0000000..0861d18 --- /dev/null +++ b/Software/ZK_python/camera_rc1_013.py @@ -0,0 +1,268 @@ +#(c)2017 Jannik Seiler +#012 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess +import piexif + +configParser = configparser.RawConfigParser() +configFilePath = r'config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 012' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + piexif.remove(picture_path) + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc1_014.py b/Software/ZK_python/camera_rc1_014.py new file mode 100644 index 0000000..df436da --- /dev/null +++ b/Software/ZK_python/camera_rc1_014.py @@ -0,0 +1,267 @@ +#(c)2017 Jannik Seiler +#014 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess +import piexif + +configParser = configparser.RawConfigParser() +configParser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), 'config.txt')) + +version = 'starting camera version 014' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +print('done!') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + piexif.remove(picture_path) + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc2_015.py b/Software/ZK_python/camera_rc2_015.py new file mode 100644 index 0000000..92b8d16 --- /dev/null +++ b/Software/ZK_python/camera_rc2_015.py @@ -0,0 +1,277 @@ +#(c)2017 Jannik Seiler +#015 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess +import piexif + +configParser = configparser.RawConfigParser() +configParser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), '/home/pi/config.txt')) + +version = 'starting camera version 015' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enamble_modem = configParser.get('config', 'enamble_modem') +print('done!') + +if enamble_modem == 'true': + print('start modem connection ...') + logging.info('start modem connection ...') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('connection successful') + ogging.info(stdoutdata) + logging.info('connection successful') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("/home/pi/picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' and enamble_modem == 'true':in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + piexif.remove(picture_path) + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if 'nicht' and enamble_modem == 'true':in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc2_016.py b/Software/ZK_python/camera_rc2_016.py new file mode 100644 index 0000000..b2e2e09 --- /dev/null +++ b/Software/ZK_python/camera_rc2_016.py @@ -0,0 +1,279 @@ +#(c)2017 Jannik Seiler +#015 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess +import piexif + +configParser = configparser.RawConfigParser() +configParser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), '/home/pi/config.txt')) + +version = 'starting camera version 015' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enamble_modem = configParser.get('config', 'enamble_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +if enamble_modem == 'true': + print('start modem connection ...') + logging.info('start modem connection ...') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('connection successful') + ogging.info(stdoutdata) + logging.info('connection successful') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("/home/pi/picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enamble_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + piexif.remove(picture_path) + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enamble_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc2_019.py b/Software/ZK_python/camera_rc2_019.py new file mode 100644 index 0000000..c262cbe --- /dev/null +++ b/Software/ZK_python/camera_rc2_019.py @@ -0,0 +1,296 @@ +#(c)2017 Jannik Seiler +#019 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess +import piexif + +configParser = configparser.RawConfigParser() +configParser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), '/home/pi/config.txt')) + +version = 'starting camera version 019' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enamble_modem = configParser.get('config', 'enamble_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +if enamble_modem == 'true': + print('start modem connection ...') + logging.info('start modem connection ...') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('connection successful') + logging.info(stdoutdata) + logging.info('connection successful') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +f = open("/home/pi/picture_Number.txt",'r') +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +picture_number = int(f.read()) +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enamble_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + piexif.remove(picture_path) + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enamble_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc3_021.py b/Software/ZK_python/camera_rc3_021.py new file mode 100644 index 0000000..963d032 --- /dev/null +++ b/Software/ZK_python/camera_rc3_021.py @@ -0,0 +1,305 @@ +#(c)2017 Jannik Seiler +#021 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +#configParser = configparser.RawConfigParser() +#configParser.read(os.path.join(os.path.abspath(os.path.dirname(__file__)), '/home/pi/config.txt')) + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 021' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +if enable_modem == 'true': + print('start modem connection ...') + logging.info('start modem connection ...') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('connection successful') + logging.info(stdoutdata) + logging.info('connection successful') + +camera = PiCamera() +ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) +ftp.cwd(ftp_picture_directory) +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = '' + camera.exif_tags['IFD0.Model '] = '' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc3_022.py b/Software/ZK_python/camera_rc3_022.py new file mode 100644 index 0000000..73e3741 --- /dev/null +++ b/Software/ZK_python/camera_rc3_022.py @@ -0,0 +1,297 @@ +#(c)2017 Jannik Seiler +#022 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 022' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + logging.info('no internet connection on startup trying to reconnect later!') + logging.info(str(ea)) +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc3_023.py b/Software/ZK_python/camera_rc3_023.py new file mode 100644 index 0000000..92b6a40 --- /dev/null +++ b/Software/ZK_python/camera_rc3_023.py @@ -0,0 +1,297 @@ +#(c)2017 Jannik Seiler +#023 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 023' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + logging.info('no internet connection on startup trying to reconnect later!') + logging.info(str(ea)) +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + #os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + #os.remove(log_directory+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc3_024.py b/Software/ZK_python/camera_rc3_024.py new file mode 100644 index 0000000..aa3da34 --- /dev/null +++ b/Software/ZK_python/camera_rc3_024.py @@ -0,0 +1,293 @@ +#(c)2017 Jannik Seiler +#024 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 024' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc_001.py b/Software/ZK_python/camera_rc_001.py new file mode 100644 index 0000000..24516d0 --- /dev/null +++ b/Software/ZK_python/camera_rc_001.py @@ -0,0 +1,142 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging + +camera = PiCamera() +ftp = FTP('schuttercloud.com','uploader','1234') +ftp.cwd('/camera01') + +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +camera.shutter_speed = 500000 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +i=0 +camera_number = '01' +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successfull! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successfull! current dicertory is: '+ftp.pwd()) +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload succesful!') + logging.info('upload succesful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + + time_sleep_unix = time_next_unix - time.time() + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + return + +while 1: + + time_next_unix = time.time() + 3000 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(i).zfill(9)+'_'+time_name + '.jpg' + picture_path = '/home/pi/Pictures/' + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + i=i+1 + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('Time to wakeup! \n') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc_002.py b/Software/ZK_python/camera_rc_002.py new file mode 100644 index 0000000..985729c --- /dev/null +++ b/Software/ZK_python/camera_rc_002.py @@ -0,0 +1,156 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging + +camera = PiCamera() +ftp = FTP('schuttercloud.com','uploader','1234') +ftp.cwd('/camera01') + +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +camera.shutter_speed = 500000 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +i=0 +camera_number = '01' +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + + time_sleep_unix = time_next_unix - time.time() + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + return + +while 1: + + time_next_unix = time.time() + 3000 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(i).zfill(9)+'_'+time_name + '.jpg' + picture_path = '/home/pi/Pictures/' + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + i=i+1 + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('Time to wakeup! \n') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc_003.py b/Software/ZK_python/camera_rc_003.py new file mode 100644 index 0000000..8f02a08 --- /dev/null +++ b/Software/ZK_python/camera_rc_003.py @@ -0,0 +1,156 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging + +camera = PiCamera() +ftp = FTP('schuttercloud.com','uploader','1234') +ftp.cwd('/camera01') + +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +camera.shutter_speed = 500000 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +i=0 +camera_number = '01' +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + + time_sleep_unix = time_next_unix - time.time() + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + return + +while 1: + + time_next_unix = time.time() + 300 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(i).zfill(9)+'_'+time_name + '.jpg' + picture_path = '/home/pi/Pictures/' + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + i=i+1 + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('Time to wakeup! \n') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc_004.py b/Software/ZK_python/camera_rc_004.py new file mode 100644 index 0000000..7bfa8f3 --- /dev/null +++ b/Software/ZK_python/camera_rc_004.py @@ -0,0 +1,158 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging + +camera = PiCamera() +ftp = FTP('schuttercloud.com','uploader','1234') +ftp.cwd('/camera01') + +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +camera.shutter_speed = 500000 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +i=0 +camera_number = '01' +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + + time_sleep_unix = time_next_unix - time.time() + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + return + +while 1: + + time_next_unix = time.time() + 300 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(i).zfill(9)+'_'+time_name + '.jpg' + picture_path = '/home/pi/Pictures/' + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + i=i+1 + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_rc_005.py b/Software/ZK_python/camera_rc_005.py new file mode 100644 index 0000000..7133873 --- /dev/null +++ b/Software/ZK_python/camera_rc_005.py @@ -0,0 +1,166 @@ +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging + +camera = PiCamera() +ftp = FTP('schuttercloud.com','uploader','1234') +ftp.cwd('/camera01') +f = open("picture_Number.txt",'r') +wakeup_Time = [7,7,6,5,5,4,4,5,5,6,6,6] +picture_number = int(f.read()) +camera_number = '01' +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) #TODO fallback test + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + + time_sleep_unix = time_next_unix - time.time() + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + return + +while 1: + + time_next_unix = time.time() + 20 + time_name = time.asctime(time.localtime(time.time())) + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = '01_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = '/home/pi/Pictures/' + picture_name + + print ("Zeit Name:", time_name) + + try: + camera.capture(picture_path) #nimmt bild 'image.jpg' auf + picture_number += 1 + print('picture_number:',str(picture_number)) + f = open("picture_Number.txt",'w') + f.write(str(picture_number)) + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: + print ('it seems to be night!') + logging.info('it seems to be night!') + if datetime.now().hour > wakeup_Time[datetime.now().month] and datetime.now().hour < 17: + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + #uploading log file + print ('skipping picture upload!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect('schuttercloud.com') + ftp.login('uploader','1234') + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + log_name, open('/home/pi/'+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #maybe needed! needs to be tested +# ftp.connect('schuttercloud.com') +# ftp.login('uploader','1234') + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_test_025.py b/Software/ZK_python/camera_test_025.py new file mode 100644 index 0000000..65d68bc --- /dev/null +++ b/Software/ZK_python/camera_test_025.py @@ -0,0 +1,294 @@ +#(c)2017 Jannik Seiler +#025 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 025' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_test_026.py b/Software/ZK_python/camera_test_026.py new file mode 100644 index 0000000..e580166 --- /dev/null +++ b/Software/ZK_python/camera_test_026.py @@ -0,0 +1,299 @@ +#(c)2017 Jannik Seiler +#026 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 026' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < 1800000: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_name) + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_test_027.py b/Software/ZK_python/camera_test_027.py new file mode 100644 index 0000000..ec70378 --- /dev/null +++ b/Software/ZK_python/camera_test_027.py @@ -0,0 +1,300 @@ +#(c)2017 Jannik Seiler +#027 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 027' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger().handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger().handlers = [] + logging.basicConfig(filename=log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_028.py b/Software/ZK_python/camera_v2_028.py new file mode 100644 index 0000000..cb9d146 --- /dev/null +++ b/Software/ZK_python/camera_v2_028.py @@ -0,0 +1,300 @@ +#(c)2017 Jannik Seiler +#028 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 028' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('re-connecting successful!') + logging.info('re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e9: + print('re-connecting failed!') + print(e9) + logging.error('re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('Network Status: ' + stdoutdata) + logging.info('Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('not connected, trying to reconnect') + logging.info('not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('reconnection successful') + logging.info(stdoutdata) + logging.info('reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('connected!') + logging.info('connected!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_029.py b/Software/ZK_python/camera_v2_029.py new file mode 100644 index 0000000..9d80cd0 --- /dev/null +++ b/Software/ZK_python/camera_v2_029.py @@ -0,0 +1,301 @@ +#(c)2017 Jannik Seiler +#029 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 029' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print([sakis3g]'not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('trying to reconnect ...') + logging.info('trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('re-connecting failed!') + print(e8) + logging.error('re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_030.py b/Software/ZK_python/camera_v2_030.py new file mode 100644 index 0000000..0f872eb --- /dev/null +++ b/Software/ZK_python/camera_v2_030.py @@ -0,0 +1,301 @@ +#(c)2017 Jannik Seiler +#030 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 030' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + ftp.cwd(ftp_picture_directory) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_031.py b/Software/ZK_python/camera_v2_031.py new file mode 100644 index 0000000..65adee0 --- /dev/null +++ b/Software/ZK_python/camera_v2_031.py @@ -0,0 +1,308 @@ +#(c)2017 Jannik Seiler +#031 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 031' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_032.py b/Software/ZK_python/camera_v2_032.py new file mode 100644 index 0000000..db4ce4a --- /dev/null +++ b/Software/ZK_python/camera_v2_032.py @@ -0,0 +1,308 @@ +#(c)2017 Jannik Seiler +#032 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 032' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +print('reading picture number ...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + +logging.info(version) +print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) +logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --sudo --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v2_033.py b/Software/ZK_python/camera_v2_033.py new file mode 100644 index 0000000..91016d4 --- /dev/null +++ b/Software/ZK_python/camera_v2_033.py @@ -0,0 +1,310 @@ +#(c)2017 Jannik Seiler +#033 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 033' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +print('done!') + +print('reading picture number...') +f = open("/home/pi/picture_Number.txt",'r') +picture_number = int(f.read()) +print('done, picture number is:',str(picture_number)) +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +print('done') +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() + +logging.info(version) +try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + uploadToFTP() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('uploading todays log befor going to sleep!') + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g connect --sudo --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + uploadToFTP() diff --git a/Software/ZK_python/camera_v3_034.py b/Software/ZK_python/camera_v3_034.py new file mode 100644 index 0000000..46f783d --- /dev/null +++ b/Software/ZK_python/camera_v3_034.py @@ -0,0 +1,353 @@ +#(c)2017 Jannik Seiler & Hendrik Schutter + +#034 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 034' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') + +print('done!') + +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:',str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() + +if internet == 'true': + print('Running in Online mode, internet connection is required') + try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +else: + print('Running in Offline mode, no internet connection is required') + +logging.info(version) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + return + +def checkCpuTemperature(): + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + return + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + 300 #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Zeit:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + if internet == 'true': uploadToFTP() + checkCpuTemperature() + sleepToNextPicture() + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': logging.info('uploading todays log befor going to sleep!') + if internet == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + if internet == 'true': uploadToFTP() + checkCpuTemperature() + sleepToNextPicture() + diff --git a/Software/ZK_python/camera_v3_035.py b/Software/ZK_python/camera_v3_035.py new file mode 100644 index 0000000..009acb3 --- /dev/null +++ b/Software/ZK_python/camera_v3_035.py @@ -0,0 +1,387 @@ +#(c)2017 Jannik Seiler & Hendrik Schutter + +#035 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +from collections import namedtuple +import logging +import configparser +import subprocess + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 035' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) + +print('done!') + +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:',str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +upload_every = upload_only + +if internet == 'true': + print('Running in Online mode, internet connection is required') + try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +else: + print('Running in Offline mode, no internet connection is required') + +logging.info(version) + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + return +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize)/(st.f_blocks * st.f_frsize))*100) + logging.info('Free disk space ' +str(freePercentaged)+' %') + print('Free disk space ',str(freePercentaged),' %') + if freePercentaged < 20: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + + return + +def checkCpuTemperature(): + + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + + return + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + interval #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Time:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + checkDiskSpace() + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer",upload_every) + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',(upload_every),'pictures') + checkCpuTemperature() + sleepToNextPicture() + + + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': logging.info('uploading todays log befor going to sleep!') + if internet == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',upload_every,'pictures') + + checkCpuTemperature() + sleepToNextPicture() + diff --git a/Software/ZK_python/camera_v3_036.py b/Software/ZK_python/camera_v3_036.py new file mode 100644 index 0000000..9fad64b --- /dev/null +++ b/Software/ZK_python/camera_v3_036.py @@ -0,0 +1,407 @@ +#(c)2017 Jannik Seiler & Hendrik Schutter + +#036 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 036' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') + +print('done!') + +wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:',str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +upload_every = upload_only + +if ioBoard =="true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0,0) +else: + print('Running without the nice IO board!') + +if internet == 'true': + print('Running in Online mode, internet connection is required') + try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +else: + print('Running in Offline mode, no internet connection is required') + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + return + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize)/(st.f_blocks * st.f_frsize))*100) + logging.info('Free disk space ' +str(freePercentaged)+' %') + print('Free disk space ',str(freePercentaged),' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + return + +def checkCpuTemperature(): + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + return + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3)*6.62)*0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: logging.warning('Low System Input Voltage! Maybe bad power supply or no sun.') + if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + interval #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Time:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + checkDiskSpace() + if ioBoard =="true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer",upload_every) + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',(upload_every),'pictures') + checkCpuTemperature() + sleepToNextPicture() + + + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': logging.info('uploading todays log befor going to sleep!') + if internet == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',upload_every,'pictures') + + checkCpuTemperature() + sleepToNextPicture() + diff --git a/Software/ZK_python/camera_v3_037.py b/Software/ZK_python/camera_v3_037.py new file mode 100644 index 0000000..c478565 --- /dev/null +++ b/Software/ZK_python/camera_v3_037.py @@ -0,0 +1,409 @@ +#(c)2017 Jannik Seiler & Hendrik Schutter + +#037 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +version = 'starting camera version 037' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') + +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +print('done!') + +#wakeup_Time = [8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8] +#bed_Time = [17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5] +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:',str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +upload_every = upload_only + +if ioBoard =="true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0,0) +else: + print('Running without the nice IO board!') + +if internet == 'true': + print('Running in Online mode, internet connection is required') + try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +else: + print('Running in Offline mode, no internet connection is required') + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464 +camera.awb_mode = 'auto' +camera.exposure_mode = 'auto' +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + return + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize)/(st.f_blocks * st.f_frsize))*100) + logging.info('Free disk space ' +str(freePercentaged)+' %') + print('Free disk space ',str(freePercentaged),' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + return + +def checkCpuTemperature(): + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + return + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3)*6.62)*0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: logging.warning('Low System Input Voltage! Maybe bad power supply or no sun.') + if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + interval #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Time:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + checkDiskSpace() + if ioBoard =="true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > wakeup_Time[datetime.now().month-1]*60*60 and seconds1 < bed_Time[datetime.now().month-1]*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer",upload_every) + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',(upload_every),'pictures') + checkCpuTemperature() + sleepToNextPicture() + + + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': logging.info('uploading todays log befor going to sleep!') + if internet == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (wakeup_Time[datetime.now().month-1]*60*60): #if time between 0am and wakeup_Time + sleep_time = (wakeup_Time[datetime.now().month-1]*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(wakeup_Time[datetime.now().month-1]*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (wakeup_Time[datetime.now().month-1]*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',upload_every,'pictures') + + checkCpuTemperature() + sleepToNextPicture() + diff --git a/Software/ZK_python/camera_v3_038.py b/Software/ZK_python/camera_v3_038.py new file mode 100644 index 0000000..2281ce5 --- /dev/null +++ b/Software/ZK_python/camera_v3_038.py @@ -0,0 +1,443 @@ +#(c)2017 Jannik Seiler & Hendrik Schutter + +#038 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep +import RPi.GPIO as GPIO + + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +#ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 038' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +print('done!') + + +print('initializing logger...') +log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' +log_name = log_name.replace(" ","-") +reconnect_counter = 0 +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt",'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:',str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') +sleep(15) + +camera = PiCamera() +upload_every = upload_only + +if ioBoard =="true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0,0) + GPIO.setmode(GPIO.BCM) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464s + camera.start_preview() + #camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if internet == 'true': + print('Running in Online mode, internet connection is required') + try: + ftp = FTP(ftp_url,ftp_user,ftp_pw,timeout=20) + ftp.cwd(ftp_picture_directory) + except Exception as ea: + print('no internet connection on startup trying to reconnect later!') + print ('New ftp connection successful! current dicertory is: '+ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: '+ftp.pwd()) +else: + print('Running in Offline mode, no internet connection is required') + +#camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +#camera.shutter_speed = 500000 +camera.resolution = (3280,2464) #aufloesung der bilder maximal 3280,2464s +camera.exposure_mode = 'auto' +camera.crop = (0, 0, 0, 0) +#camera.brightness = 50 #0 bis 100; default 50 +#camera.contrast = 0 #-100 bis 100; default 0 +#camera.iso = 0 #0 bis 1600; default 0(auto) +#camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +#camera.sharpness = 0 #-100 bis 100; default 0 + +#get cpu temperature +def getCpuTemperature(): + tempFile = open( "/sys/class/thermal/thermal_zone0/temp" ) + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp)/1000 + +#uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP]re-connecting successful!') + logging.info('[FTP]re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+picture_name) + os.remove(picture_path) + print('[FTP]upload successful!') + logging.info('[FTP]upload successful!') + except ftplib.all_errors as e9: + print('[FTP]re-connecting failed!') + print(e9) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e9)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + return + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize)/(st.f_blocks * st.f_frsize))*100) + logging.info('Free disk space ' +str(freePercentaged)+' %') + print('Free disk space ',str(freePercentaged),' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + return + +def checkCpuTemperature(): + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature())+ ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature())+ ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature())+ ' C') + return + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix>0: + print("sleeping now",time_sleep_unix,"seconds"+'\n') + logging.info('sleeping now '+str(time_sleep_unix)+' seconds'+'\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3)*6.62)*0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: logging.warning('Low System Input Voltage! Maybe bad power supply or no sun.') + if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') + return + +#main programm (endless loop) +while 1: + + time_next_unix = time.time() + interval #time for next picture + time_name = time.asctime(time.localtime(time.time())) #get time for picture_name + time_name = time_name.replace(" ","_") + time_name = time_name.replace(":","-") + picture_name = camera_number+'_'+str(picture_number).zfill(6)+'_'+time_name + '.jpg' + picture_path = picture_directory + picture_name + + print ("Time:", time_name) + + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = '5 minute interval' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + camera.capture(picture_path) #capture image and save to picture_path (picture_directory + picture_name) + if mute == "false": GPIO.output(piezo, GPIO.LOW) + + picture_number += 1 #increase picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print ('Picture size:',os.path.getsize(picture_path),"Byte") + logging.info('Picture size: '+str(os.path.getsize(picture_path))+' Byte') + checkDiskSpace() + if ioBoard =="true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: #if picture size is under 1800000 Byte we could sleep + print ('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds #seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month-1])*60*60 and seconds1 < float(bed_Time[datetime.now().month-1])*60*60: #if it is before 5pm, it cann't be night -> not going to sleep + print ('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer",upload_every) + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',(upload_every),'pictures') + checkCpuTemperature() + sleepToNextPicture() + + + else: + os.remove(picture_path) #deleting picture because it's night! + picture_number -= 1 #decrease picture_number + print('picture_number:',str(picture_number)) + f = open("/home/pi/picture_Number.txt",'w') + f.write(str(picture_number)) #save picture_number to a text file + f.close() + #uploading log file + print ('skipping picture upload!') + print('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until '+str(wakeup_Time[datetime.now().month-1])+'am!') + if internet == 'true': logging.info('uploading todays log befor going to sleep!') + if internet == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e: + print ('upload failed!') + print (e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP]trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('[FTP]re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except ftplib.all_errors as e8: + print('[FTP]re-connecting failed!') + print(e8) + logging.error('[FTP]re-connecting failed!') + logging.error(str(e8)) + try: + stdoutdata = subprocess.getoutput('/usr/bin/modem3g/sakis3g status') + print('[sakis3g]Network Status: ' + stdoutdata) + logging.info('[sakis3g]Network Status: ' + stdoutdata) + if enable_modem == 'true' and 'Nicht' in stdoutdata: + print('[sakis3g]not connected, trying to reconnect') + print('[sakis3g]not connected, trying to reconnect') + logging.info('[sakis3g]not connected, trying to reconnect') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[sakis3g] disconnected') + stdoutdata = subprocess.getoutput("/usr/bin/modem3g/sakis3g --sudo disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[sakis3g]reconnection successful') + logging.info(stdoutdata) + logging.info('[sakis3g]reconnection hopefully successful') + try: + ftp.connect(ftp_url) + ftp.login(ftp_user,ftp_pw) + print('re-connecting ftp successful!') + logging.info('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory+log_name,'rb'),1024) + ftp.sendcmd('SITE CHMOD 754 '+log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print(str(e4)) + logging.error(str(e4)) + else: + print('[sakis3g]if this appears you are connected or there is a bug!') + logging.info('[sakis3g]if this appears you are connected or there is a bug!') + except Exception as e3: + print(str(e3)) + logging.error(str(e3)) + + #try? check inet connection -> /usr/bin/modem3g/sakis3g status + # if nicht dann neu verbinden -> /usr/bin/modem3g/sakis3g connect --console APN='web.vodafone.de' USBINTERFACE='0' USBMODEM='12d1:1436' + # danach nochmal status if dann status = nicht dann reboot + + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + #sleep until next morning + print ('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds #seconds since midnight + if seconds < (float(wakeup_Time[datetime.now().month-1])*60*60): #if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month-1])*60*60)-seconds + else: #if time between wakeup_Time and 12pm + sleep_time = 86400-seconds+(float(wakeup_Time[datetime.now().month-1])*60*60) + print ('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + logging.info('sleeping now '+str(sleep_time)+' seconds or until '+str(wakeup_Time[datetime.now().month-1])+'am!') + sleep(sleep_time-10) + + #wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds)+' < '+str((wakeup_Time[datetime.now().month-1]*60*60))) + while(datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month-1])*60*60): + sleep(0.5) + log_name = camera_number+'_'+str(datetime.now().strftime("%A %d. %B %Y"))+'.log' + log_name = log_name.replace(" ","-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory+log_name,format='%(asctime)s [%(levelname)s] %(message)s',level=logging.DEBUG,datefmt='%d/%m/%Y %H:%M:%S') + print('slept for '+str(sleep_time)+' seconds') + print('Time to wakeup! \n') + logging.info('slept for '+str(sleep_time)+' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internet == 'true')and(upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + logging.info('Skipping upload. Next upload in '+str(upload_every)+' pictures') + print('Skipping upload. Next upload in',upload_every,'pictures') + + checkCpuTemperature() + sleepToNextPicture() + diff --git a/Software/ZK_python/camera_v4_039.py b/Software/ZK_python/camera_v4_039.py new file mode 100644 index 0000000..09312ec --- /dev/null +++ b/Software/ZK_python/camera_v4_039.py @@ -0,0 +1,533 @@ +# (c)2017 Jannik Seiler & Hendrik Schutter + +# 039 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep +import RPi.GPIO as GPIO + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('Free disk space ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + return + + +def checkCpuTemperature(): + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature()) + ' C') + return + + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: logging.warning( + 'Low System Input Voltage! Maybe bad power supply or no sun.') + if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is not online!') + logging.info('Internet connection established') + logging.error('Server is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + except Exception as ea: + print('no internet or ftp connection trying to reconnect later!') + logging.error('no internet or ftp connection trying to reconnect later!') + print('Server connection established') + logging.info('Server connection established') + except Exception as e5: + conn.close() + print('Server connection not established') + logging.info('Server connection not established') + reconnectToInternet() + + return + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 039' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +camera = PiCamera() +upload_every = upload_only +internetTmp = internet + + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 +camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s +camera.exposure_mode = 'auto' +camera.crop = (0, 0, 0, 0) + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + + + +# main programm (endless loop) +while 1: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + if mute == "false": GPIO.output(piezo, GPIO.LOW) + + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + checkCpuTemperature() + sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpuTemperature() + sleepToNextPicture() + + + diff --git a/Software/ZK_python/camera_v4_040.py b/Software/ZK_python/camera_v4_040.py new file mode 100644 index 0000000..206e259 --- /dev/null +++ b/Software/ZK_python/camera_v4_040.py @@ -0,0 +1,535 @@ +# (c)2017 Jannik Seiler & Hendrik Schutter + +# 040 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep +import RPi.GPIO as GPIO + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('upload successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('Free disk space ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('Storage Drive full, Backup Space in use!') + return + + +def checkCpuTemperature(): + if getCpuTemperature() <= -5.0: + logging.critical('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('Temperature: ' + str(getCpuTemperature()) + ' C') + return + + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('System Input Voltage: ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: logging.warning( + 'Low System Input Voltage! Maybe bad power supply or no sun.') + if systemVoltage < 9: logging.critical('Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + except Exception as ea: + print('no internet or ftp connection trying to reconnect later!') + logging.error('no internet or ftp connection trying to reconnect later!') + print('Server connection established') + logging.info('Server connection established') + except Exception as e5: + conn.close() + print('Server connection not established') + logging.info('Server connection not established') + reconnectToInternet() + + return + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 040' +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +camera = PiCamera() +upload_every = upload_only +internetTmp = internet + + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 +camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s +camera.exposure_mode = 'auto' +camera.crop = (0, 0, 0, 0) + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + + + +# main programm (endless loop) +while 1: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + if mute == "false": GPIO.output(piezo, GPIO.LOW) + + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + checkCpuTemperature() + sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('could not change ftp directory !') + logging.error('could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpuTemperature() + sleepToNextPicture() + + + diff --git a/Software/ZK_python/camera_v4_041.py b/Software/ZK_python/camera_v4_041.py new file mode 100644 index 0000000..07a793a --- /dev/null +++ b/Software/ZK_python/camera_v4_041.py @@ -0,0 +1,557 @@ +# (c)2017 Jannik Seiler & Hendrik Schutter + +# 041 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +from time import sleep +import RPi.GPIO as GPIO + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('[Upload] successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('[Upload] failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('[Disk] Free space: ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!') + return + + +def checkCpu(): + cpuUsage = (os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()) + cpuUsage = (float(cpuUsage.replace(',', '.')))*25 + print('[CPU] Usage: ',str("%.2f" % cpuUsage),' %') + logging.info('[CPU] Usage: '+ str("%.2f" % cpuUsage) + ' %') + if getCpuTemperature() <= -5.0: + logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('[CPU] Temperature: ' + str(getCpuTemperature()) + ' C') + return + + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: + logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.') + if tvOut == 'auto': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + except Exception as ea: + print('[FTP] no internet or ftp connection trying to reconnect later!') + logging.error('[FTP] no internet or ftp connection trying to reconnect later!') + print('[FTP] Server connection established') + logging.info('[FTP] Server connection established') + except Exception as e5: + conn.close() + print('[FTP] Server connection not established') + logging.info('[FTP] Server connection not established') + reconnectToInternet() + + return + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + + +version = 'starting camera version 041' +print('Copyright CopterSicht - info@coptersicht.de 2015-2017') +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +tvOut = configParser.get('config', 'TV_Output') +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +#camera = PiCamera() +upload_every = upload_only +internetTmp = internet + + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + camera.close() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + + +if tvOut == 'false': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 + + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + + + +# main programm (endless loop) +while 1: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.exposure_mode = 'auto' + camera.crop = (0, 0, 0, 0) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) 2017 CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + camera.close() + if mute == "false": GPIO.output(piezo, GPIO.LOW) + + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + checkCpu() + sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e: + print('[FTP] upload failed!') + print(e) + logging.error('[FTP] upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('[FTP] could not change ftp directory !') + logging.error('[FTP] could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpu() + sleepToNextPicture() + + + diff --git a/Software/ZK_python/camera_v4_042.py b/Software/ZK_python/camera_v4_042.py new file mode 100644 index 0000000..c03de30 --- /dev/null +++ b/Software/ZK_python/camera_v4_042.py @@ -0,0 +1,595 @@ +# (c)2017-2018 Jannik Seiler & Hendrik Schutter + +# 042 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +import RPi.GPIO as GPIO +import re +import fcntl + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('[Upload] successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('[Upload] failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('[Disk] Free space: ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!') + return + + +def checkCpu(): + try: + cpuUsage = (os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()) + cpuUsage = (float(cpuUsage.replace(',', '.'))) * 25 + print('[CPU] Usage: ', str("%.2f" % cpuUsage), ' %') + logging.info('[CPU] Usage: ' + str("%.2f" % cpuUsage) + ' %') + if getCpuTemperature() <= -5.0: + logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('[CPU] Temperature: ' + str(getCpuTemperature()) + ' C') + return + except Exception as e2: + print('[CPU] ' + str(e2)) + logging.warning('[CPU] ' + str(e2)) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: + logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.') + if tvOut == 'auto': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + resetModem() + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + except Exception as ea: + print('[FTP] no internet or ftp connection trying to reconnect later!') + logging.error('[FTP] no internet or ftp connection trying to reconnect later!') + print('[FTP] Server connection established') + logging.info('[FTP] Server connection established') + except Exception as e5: + conn.close() + print('[FTP] Server connection not established') + logging.info('[FTP] Server connection not established') + reconnectToInternet() + + return + +def resetModem(): + try: + lsusb_cmd = 'lsusb | grep {}'.format('Huawei') + lsusb_out = subprocess.check_output(lsusb_cmd, shell=True) + parts = re.search(r'Bus (?P\d+) Device (?P\d+): ID [:\d\w]+ (?P.*)$', str(lsusb_out)) + bus = parts.group('bus') + dev = parts.group('dev') + desc = parts.group('desc').strip() + print('[Modem] Found device {} on bus {} for "{}"'.format(bus, dev, desc)) + f = open('/dev/bus/usb/{}/{}'.format(bus, dev), 'w', os.O_WRONLY) + fcntl.ioctl(f, 21780, 0) + sleep(15) + print('[Modem] Reset successfully attempt') + except Exception as ea: + print('[Modem] Reset Error: ' + str(ea)) + + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 042' +print('Copyright CopterSicht - info@coptersicht.de 2015-' + str(datetime.now().year)) +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +tvOut = configParser.get('config', 'TV_Output') +width = configParser.get('config', 'Width') +height = configParser.get('config', 'Height') +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +try: + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +except Exception as er: + print('[Logger] Could not create .log' + str(er)) + print('[USB] Could not find USB storage!') + while 1: + checkConnectionToFTPServer() + print('[Timlapse Core] Waiting for maintenance!') + sleep(3600) +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +#camera = PiCamera() +upload_every = upload_only +internetTmp = internet + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.awb_mode = 'auto' + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + camera.close() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + + +if tvOut == 'false': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 + + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + +print('[Camera] Resolution: ' + width + 'x' + height) +logging.info('[Camera] Resolution: ' + width + 'x' + height) + + +# main programm (endless loop) +while 1: + try: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + camera = PiCamera() + camera.resolution = (int(width), int(height)) # aufloesung der bilder maximal 3280,2464s + camera.exposure_mode = 'auto' + camera.awb_mode = 'auto' + camera.crop = (0, 0, 0, 0) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) ' + str(datetime.now().year) + ' CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + camera.close() + if mute == "false": GPIO.output(piezo, GPIO.LOW) + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + checkCpu() + sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e: + print('[FTP] upload failed!') + print(e) + logging.error('[FTP] upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('[FTP] could not change ftp directory !') + logging.error('[FTP] could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpu() + sleepToNextPicture() + + except Exception as loopError: + print('[Timlapse Core] ' + str(loopError)) + try: + logging.error('[FTP] could not change ftp directory !') + except Exception as er: + print('[Timlapse Core] Could not log: ' + str(er)) + + diff --git a/Software/ZK_python/camera_v4_043.py b/Software/ZK_python/camera_v4_043.py new file mode 100644 index 0000000..ca3c75d --- /dev/null +++ b/Software/ZK_python/camera_v4_043.py @@ -0,0 +1,611 @@ +# (c)2017-2018 Jannik Seiler & Hendrik Schutter + +# 043 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +import RPi.GPIO as GPIO +import re +import fcntl + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('[Upload] successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('[Upload] failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('[Disk] Free space: ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!') + return + + +def checkCpu(): + try: + cpuUsage = (os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()) + cpuUsage = (float(cpuUsage.replace(',', '.'))) * 25 + print('[CPU] Usage: ', str("%.2f" % cpuUsage), ' %') + logging.info('[CPU] Usage: ' + str("%.2f" % cpuUsage) + ' %') + if getCpuTemperature() <= -5.0: + logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('[CPU] Temperature: ' + str(getCpuTemperature()) + ' C') + return + except Exception as e2: + print('[CPU] ' + str(e2)) + logging.warning('[CPU] ' + str(e2)) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: + logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.') + if tvOut == 'auto': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + resetModem() + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + print('[FTP] Server connection established') + logging.info('[FTP] Server connection established') + except Exception as ea: + internetTmp = 'false' + print('[FTP] no internet or ftp connection trying to reconnect later!') + logging.error('[FTP] no internet or ftp connection trying to reconnect later!') + except Exception as e5: + conn.close() + print('[FTP] Server connection not established') + logging.info('[FTP] Server connection not established') + reconnectToInternet() + + return + +def resetModem(): + try: + lsusb_cmd = 'lsusb | grep {}'.format('Huawei') + lsusb_out = subprocess.check_output(lsusb_cmd, shell=True) + parts = re.search(r'Bus (?P\d+) Device (?P\d+): ID [:\d\w]+ (?P.*)$', str(lsusb_out)) + bus = parts.group('bus') + dev = parts.group('dev') + desc = parts.group('desc').strip() + print('[Modem] Found device {} on bus {} for "{}"'.format(bus, dev, desc)) + f = open('/dev/bus/usb/{}/{}'.format(bus, dev), 'w', os.O_WRONLY) + fcntl.ioctl(f, 21780, 0) + sleep(15) + print('[Modem] Reset successfully attempt') + except Exception as ea: + print('[Modem] Reset Error: ' + str(ea)) + + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 043' +print('Copyright CopterSicht - info@coptersicht.de 2015-' + str(datetime.now().year)) +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +tvOut = configParser.get('config', 'TV_Output') +width = configParser.get('config', 'Width') +height = configParser.get('config', 'Height') +rebootCMD = configParser.get('config', 'Reboot') +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +try: + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +except Exception as er: + print('[Logger] Could not create .log' + str(er)) + print('[USB] Could not find USB storage!') + while 1: + checkConnectionToFTPServer() + print('[Timlapse Core] Waiting for maintenance!') + sleep(3600) +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +camera = PiCamera() +upload_every = upload_only +internetTmp = internet +rebootFlag = 'false' + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.awb_mode = 'auto' + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + camera.close() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if rebootCMD == 'true': + print('Automatic reboot is allowed while wake up!') + logging.info('Automatic reboot is allowed while wakeup!') + +if tvOut == 'false': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 + + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + +print('[Camera] Resolution: ' + width + 'x' + height) +logging.info('[Camera] Resolution: ' + width + 'x' + height) + + +# main programm (endless loop) +while 1: + try: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + #camera = PiCamera() + camera.resolution = (int(width), int(height)) # aufloesung der bilder maximal 3280,2464s + camera.exposure_mode = 'auto' + camera.awb_mode = 'auto' + camera.crop = (0, 0, 0, 0) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) ' + str(datetime.now().year) + ' CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + #camera.close() + if mute == "false": GPIO.output(piezo, GPIO.LOW) + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + checkCpu() + sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e: + print('[FTP] upload failed!') + print(e) + logging.error('[FTP] upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('[FTP] could not change ftp directory !') + logging.error('[FTP] could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + if internetTmp == 'false': + rebootFlag = 'true' + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + if rebootFlag == 'true': + rebootFlag = 'false' + stdoutdata = subprocess.getoutput('shutdown -r now') + print('[Timelapse Core] Reboot: ' + stdoutdata) + logging.info('[Timelapse Core] Reboot: ' + stdoutdata) + sleep(70) + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpu() + sleepToNextPicture() + + except Exception as loopError: + print('[Timlapse Core] ' + str(loopError)) + try: + logging.error('[FTP] could not change ftp directory !') + except Exception as er: + print('[Timlapse Core] Could not log: ' + str(er)) + + diff --git a/Software/ZK_python/camera_v4_044.py b/Software/ZK_python/camera_v4_044.py new file mode 100644 index 0000000..2eaef56 --- /dev/null +++ b/Software/ZK_python/camera_v4_044.py @@ -0,0 +1,653 @@ +# (c)2017-2018 Jannik Seiler & Hendrik Schutter + +# 044 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +import RPi.GPIO as GPIO +import re +import fcntl + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('[Upload] successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('[Upload] failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs('/media/usb0') + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('[Disk] Free space: ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!') + return + + +def checkCpu(): + try: + cpuUsage = (os.popen("top -n1 | awk '/Cpu\(s\):/ {print $2}'").readline().strip()) + cpuUsage = (float(cpuUsage.replace(',', '.'))) * 25 + cpuUsageStr = str(cpuUsage) + ' %' + print('[CPU] Usage: ', cpuUsageStr) + logging.info('[CPU] Usage: ' + str("%.2f" % cpuUsage) + ' %') + if getCpuTemperature() <= -5.0: + logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 5.0: + logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('[CPU] Temperature: ' + str(getCpuTemperature()) + ' C') + return + except Exception as e2: + print('[CPU] ' + str(e2)) + logging.warning('[CPU] ' + str(e2)) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.3 and systemVoltage > 9: + logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.') + if tvOut == 'auto': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + resetModem() + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + print('[FTP] Server connection established') + logging.info('[FTP] Server connection established') + except Exception as ea: + internetTmp = 'false' + print('[FTP] no internet or ftp connection trying to reconnect later!') + logging.error('[FTP] no internet or ftp connection trying to reconnect later!') + except Exception as e5: + conn.close() + print('[FTP] Server connection not established') + logging.info('[FTP] Server connection not established') + reconnectToInternet() + + return + +def resetModem(): + try: + lsusb_cmd = 'lsusb | grep {}'.format('Huawei') + lsusb_out = subprocess.check_output(lsusb_cmd, shell=True) + parts = re.search(r'Bus (?P\d+) Device (?P\d+): ID [:\d\w]+ (?P.*)$', str(lsusb_out)) + bus = parts.group('bus') + dev = parts.group('dev') + desc = parts.group('desc').strip() + print('[Modem] Found device {} on bus {} for "{}"'.format(bus, dev, desc)) + f = open('/dev/bus/usb/{}/{}'.format(bus, dev), 'w', os.O_WRONLY) + fcntl.ioctl(f, 21780, 0) + sleep(15) + print('[Modem] Reset successfully attempt') + except Exception as ea: + print('[Modem] Reset Error: ' + str(ea)) + +def rebootSystem(): + rebootFlag = 'false' + os.system('sudo shutdown -r now') + print('[Timelapse Core] Reboot') + logging.info('[Timelapse Core] Reboot') + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) + sleep(1) + GPIO.output(piezo, GPIO.HIGH) + sleep(2) + GPIO.output(piezo, GPIO.LOW) + sleep(2) + sleep(70) + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = 'starting camera version 044' +print('Copyright CopterSicht - info@coptersicht.de 2015-' + str(datetime.now().year)) +print(version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +tvOut = configParser.get('config', 'TV_Output') +width = configParser.get('config', 'Width') +height = configParser.get('config', 'Height') +rebootCMD = configParser.get('config', 'Reboot') + +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +try: + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +except Exception as er: + print('[Logger] Could not create .log' + str(er)) + print('[USB] Could not find USB storage!') + while 1: + checkConnectionToFTPServer() + if internet == 'true' and internetTmp == 'false': + if internetTmp == 'false': + rebootFlag = 'true' + print('[Timelapse Core] Reboot Flag set') + if rebootFlag == 'true': + rebootSystem() + print('[Timlapse Core] Waiting for maintenance!') + sleep(3600) +logging.info(version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +camera = PiCamera() +upload_every = upload_only +internetTmp = internet +rebootFlag = 'false' + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + + if GPIO.input(bootSwitch) == 0: + camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.awb_mode = 'auto' + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + camera.close() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if rebootCMD == 'true': + print('Automatic reboot is allowed while wake up!') + logging.info('Automatic reboot is allowed while wakeup!') + +if tvOut == 'false': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 + + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + +print('[Camera] Resolution: ' + width + 'x' + height) +logging.info('[Camera] Resolution: ' + width + 'x' + height) + + +# main programm (endless loop) +while 1: + try: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + #camera = PiCamera() + camera.resolution = (int(width), int(height)) # aufloesung der bilder maximal 3280,2464s + camera.exposure_mode = 'auto' + camera.awb_mode = 'auto' + camera.crop = (0, 0, 0, 0) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) ' + str(datetime.now().year) + ' CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + #camera.close() + if mute == "false": GPIO.output(piezo, GPIO.LOW) + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + #checkCpu() + #sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e: + print('[FTP] upload failed!') + print(e) + logging.error('[FTP] upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('[FTP] could not change ftp directory !') + logging.error('[FTP] could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + if internet == 'true' and internetTmp == 'false': + print('[Timelapse Core] Checking again Internet Connection before sleep') + logging.info('[Timelapse Core] Checking again Internet Connection before sleep') + checkConnectionToFTPServer() + if internetTmp == 'false': + rebootFlag = 'true' + print('[Timelapse Core] Reboot Flag set') + logging.info('[Timelapse Core] Reboot Flag set') + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info(version) + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + if rebootFlag == 'true': + rebootSystem() + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpu() + sleepToNextPicture() + + except Exception as loopError: + print('[Timlapse Core] ' + str(loopError)) + try: + logging.error('[FTP] could not change ftp directory !') + except Exception as er: + print('[Timlapse Core] Could not log: ' + str(er)) + + diff --git a/Software/ZK_python/camera_v4_045.py b/Software/ZK_python/camera_v4_045.py new file mode 100644 index 0000000..2b9ca86 --- /dev/null +++ b/Software/ZK_python/camera_v4_045.py @@ -0,0 +1,650 @@ +# (c)2017-2018 Jannik Seiler & Hendrik Schutter + +# 045 + +from picamera import PiCamera +from time import sleep +from ftplib import FTP +from fractions import Fraction +from datetime import datetime +import ftplib +import time +import os +import http.client as httplib +from collections import namedtuple +import logging +import configparser +import subprocess +from spidev import SpiDev +import RPi.GPIO as GPIO +import re +import fcntl + +# get cpu temperature +def getCpuTemperature(): + tempFile = open("/sys/class/thermal/thermal_zone0/temp") + cpu_temp = tempFile.read() + tempFile.close() + return float(cpu_temp) / 1000 + + +# uploading picture to ftp and make chmod 754 when done sleep until sleeping time is over +def uploadToFTP(): + print('trying to upload file ...') + logging.info('trying to upload file ...') + try: + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('upload successful!') + logging.info('[Upload] successful!') + except Exception as e: + print('upload failed!') + print(e) + logging.error('[Upload] failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP] trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + ftp.cwd(ftp_picture_directory) + print('[FTP] re-connecting successful!') + logging.info('[FTP] re-connecting successful!') + ftp.storbinary('STOR ' + picture_name, open(picture_path, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + picture_name) + os.remove(picture_path) + print('[FTP] upload successful!') + logging.info('[FTP]upload successful!') + except Exception as e9: + print('[FTP] re-connecting failed!') + print(e9) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e9)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + return + + +def checkDiskSpace(): + st = os.statvfs(picture_directory) + free = st.f_bavail * st.f_frsize + total = st.f_blocks * st.f_frsize + + freePercentaged = int(((st.f_bavail * st.f_frsize) / (st.f_blocks * st.f_frsize)) * 100) + logging.info('[Disk] Free space: ' + str(freePercentaged) + ' %') + print('Free disk space ', str(freePercentaged), ' %') + if freePercentaged < 20 and freePercentaged > 10: logging.warning('[Disk] Storage Drive nearly full!') + if freePercentaged < 10: logging.critical('[Disk] Storage Drive full, Backup Space in use!') + return + + +def checkCpu(): + try: + if getCpuTemperature() <= -5.0: + logging.critical('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() <= 7.0: + logging.warning('[CPU] Coold: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 45.0: + logging.warning('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + elif getCpuTemperature() >= 50.0: + logging.critical('[CPU] Hot: ' + str(getCpuTemperature()) + ' C') + else: + logging.info('[CPU] Temperature: ' + str(getCpuTemperature()) + ' C') + return + except Exception as e2: + print('[CPU] ' + str(e2)) + logging.warning('[CPU] ' + str(e2)) + +def readMPC(channel): + adc = spi.xfer2([1, (8 + channel) << 4, 0]) + data = ((adc[1] & 3) << 8) + adc[2] + return data + +def sleepToNextPicture(): + time_sleep_unix = time_next_unix - time.time() + if time_sleep_unix > 0: + print("sleeping now", time_sleep_unix, "seconds" + '\n') + logging.info('sleeping now ' + str(time_sleep_unix) + ' seconds' + '\n') + sleep(time_sleep_unix) + else: + print('no sleep needed, behind schedule!') + logging.warning('no sleep needed, behind schedule!') + return + +def checkSystemVoltage(): + systemVoltage = (((readMPC(0) / 1023.0 * 3.3) * 6.62) * 0.95) + print("System Input Voltage: %.2f" % systemVoltage, "Volt") + logging.info('[Voltage] ' + str("%.2f" % systemVoltage) + ' Volt') + if systemVoltage < 11.2 and systemVoltage > 9: + logging.warning('[Voltage] Low System Input Voltage! Maybe bad power supply or no sun.') + if tvOut == 'auto': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + if systemVoltage < 9: logging.critical('[Voltage] Very low System Input Voltage! Bad power supply or no sun.') + return + + +def reconnectToInternet(): + try: + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + print('Server is maybe not online!') + logging.info('Internet connection established') + logging.error('Server maybe is not online!') + global interntTmp + interntTmp = 'true' + #checkConnectionToFTPServer() + return 'true' + except Exception as e2: + conn.close() + print('no Internet connection') + print('trying to reconnect to internet') + logging.error('no Internet connection!') + logging.info('trying to reconnect to internet') + if enable_modem == 'true': + print('[MODEM] no UMTS connection') + logging.error('[MODEM] no UMTS connection') + try: + stdoutdata = subprocess.getoutput('sudo /usr/bin/modem3g/sakis3g status') + print('[MODEM] Network Status: ' + stdoutdata) + logging.info('[MODEM] Network Status: ' + stdoutdata) + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g disconnect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + logging.info(stdoutdata) + logging.info('[MODEM] disconnected') + sleep(20) + resetModem() + stdoutdata = subprocess.getoutput( + "sudo /usr/bin/modem3g/sakis3g connect --console APN='" + modem_apn + "' USBINTERFACE='0' USBMODEM='12d1:1436'") + print(stdoutdata) + print('[MODEM] reconnection successful attempt') + logging.info('[MODEM] reconnection successful attempt') + logging.info(stdoutdata) + sleep(10) + try: + conn = httplib.HTTPConnection("www.google.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + print('Internet connection established') + logging.info('Internet connection established') + return 'true' + except Exception as e5: + conn.close() + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e5)) + logging.error(str(e5)) + return 'false' + except Exception as e4: + print('[MODEM] UMTS connection failed') + logging.error('[MODEM] UMTS connection failed') + print(str(e4)) + logging.error(str(e4)) + return 'false' + else: + print('LAN or WLAN not connected!') + logging.error('LAN or WLAN not connected!') + return 'false' + +def checkConnectionToFTPServer(): + try: + # ping ftp url instead something else + conn = httplib.HTTPConnection("www.coptersicht.de", timeout=5) + conn.request("HEAD", "/") + conn.close() + try: + global ftp + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('[FTP] New ftp connection successful! current dicertory is: ' + ftp.pwd()) + global internetTmp + internetTmp = 'true' + global upload_every + upload_every = upload_only + print('[FTP] Server connection established') + logging.info('[FTP] Server connection established') + except Exception as ea: + internetTmp = 'false' + print('[FTP] no internet or ftp connection trying to reconnect later!') + logging.error('[FTP] no internet or ftp connection trying to reconnect later!') + except Exception as e5: + conn.close() + print('[FTP] Server connection not established') + logging.info('[FTP] Server connection not established') + reconnectToInternet() + + return + +def resetModem(): + try: + lsusb_cmd = 'lsusb | grep {}'.format('Huawei') + lsusb_out = subprocess.check_output(lsusb_cmd, shell=True) + parts = re.search(r'Bus (?P\d+) Device (?P\d+): ID [:\d\w]+ (?P.*)$', str(lsusb_out)) + bus = parts.group('bus') + dev = parts.group('dev') + desc = parts.group('desc').strip() + print('[Modem] Found device {} on bus {} for "{}"'.format(bus, dev, desc)) + f = open('/dev/bus/usb/{}/{}'.format(bus, dev), 'w', os.O_WRONLY) + fcntl.ioctl(f, 21780, 0) + sleep(15) + print('[Modem] Reset successfully attempt') + except Exception as ea: + print('[Modem] Reset Error: ' + str(ea)) + +def rebootSystem(): + rebootFlag = 'false' + os.system('sudo shutdown -r now') + print('[Timelapse Core] Reboot') + logging.info('[Timelapse Core] Reboot') + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) + sleep(1) + GPIO.output(piezo, GPIO.HIGH) + sleep(2) + GPIO.output(piezo, GPIO.LOW) + sleep(2) + sleep(70) + +configParser = configparser.RawConfigParser() +configFilePath = r'/home/pi/config.txt' +configParser.read(configFilePath) + +# ioBoard +piezo = 25 +bootSwitch = 17 + +version = '045' +print('Copyright CopterSicht - info@coptersicht.de 2015-' + str(datetime.now().year)) +print('starting camera version: ' + version) +print('reading config...') +ftp_url = configParser.get('config', 'ftp_url') +ftp_picture_directory = configParser.get('config', 'ftp_picture_directory') +ftp_log_directory = configParser.get('config', 'ftp_log_directory') +ftp_user = configParser.get('config', 'ftp_user') +ftp_pw = configParser.get('config', 'ftp_pw') +picture_directory = configParser.get('config', 'picture_directory') +log_directory = configParser.get('config', 'log_directory') +camera_number = configParser.get('config', 'camera_number') +enable_modem = configParser.get('config', 'enable_modem') +picture_size = int(configParser.get('config', 'picture_size')) +internet = configParser.get('config', 'internet') +modem_apn = configParser.get('config', 'modem_apn') +upload_only = int(configParser.get('config', 'upload_only')) +interval = int(configParser.get('config', 'interval')) +ioBoard = configParser.get('config', 'I/O_Board') +mute = configParser.get('config', 'mute') +wakeup_Time = str(configParser.get('config', 'wakeup_Time')).split(',') +bed_Time = str(configParser.get('config', 'bed_Time')).split(',') +tvOut = configParser.get('config', 'TV_Output') +width = configParser.get('config', 'Width') +height = configParser.get('config', 'Height') +rebootCMD = configParser.get('config', 'Reboot') + +print('done!') + +print('initializing logger...') +log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' +log_name = log_name.replace(" ", "-") +logging.getLogger('').handlers = [] +try: + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') +except Exception as er: + print('[Logger] Could not create .log' + str(er)) + print('[USB] Could not find USB storage!') + while 1: + checkConnectionToFTPServer() + if internet == 'true' and internetTmp == 'false': + if internetTmp == 'false': + rebootFlag = 'true' + print('[Timelapse Core] Reboot Flag set') + if rebootFlag == 'true': + rebootSystem() + print('[Timlapse Core] Waiting for maintenance!') + sleep(3600) +logging.info('starting camera version: ' + version) +print('done') +print('reading picture number...') +try: + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() +except Exception as ea: + print('No picture_Number.txt found. Creating new .. ') + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(0)) + f.close() + f = open("/home/pi/picture_Number.txt", 'r') + picture_number = int(f.read()) + f.close() + logging.info('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') + print('Maybe a fatal error occourd! New picture_Number was created. Risk of redundancy!') +print('done, picture number is:', str(picture_number)) +print('sleeping for 15 seconds until boot is finished!') + +sleep(15) + +camera = PiCamera() +upload_every = upload_only +internetTmp = internet +rebootFlag = 'false' + +if ioBoard == "true": + print('Running with the nice IO board!') + spi = SpiDev() + spi.open(0, 0) + spi.max_speed_hz = 5000 + GPIO.setmode(GPIO.BCM) + GPIO.setwarnings(False) + GPIO.setup(piezo, GPIO.OUT) + GPIO.setup(bootSwitch, GPIO.IN) + GPIO.output(piezo, GPIO.LOW) + + if GPIO.input(bootSwitch) == 0: + #camera = PiCamera() + camera.resolution = (3280, 2464) # aufloesung der bilder maximal 3280,2464s + camera.awb_mode = 'auto' + camera.start_preview() + # camera.start_preview(fullscreen=False, window = (100, 20, 960, 720)) + print('---starting sharpness tool---') + print('--------normal output--------') + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + sleep(5) + if GPIO.input(bootSwitch) == 0: + camera.stop_preview() + print('---------zoom output---------') + camera.crop = (0.5, 0.5, 0.3, 0.4) + camera.start_preview() + while GPIO.input(bootSwitch) == 0: sleep(1) + camera.stop_preview() + else: + camera.stop_preview() + camera.close() + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(1) + GPIO.output(piezo, GPIO.LOW) +else: + print('Running without the nice IO board!') + +if rebootCMD == 'true': + print('Automatic reboot is allowed while wake up!') + logging.info('Automatic reboot is allowed while wakeup!') + +if tvOut == 'false': + stdoutdata = subprocess.getoutput('sudo /usr/bin/tvservice -o ') + print('[TV Out] Status: ' + stdoutdata) + logging.info('[TV Out] Status: ' + stdoutdata) + +if internetTmp == 'true': + print('Running in Online mode, internet connection is required') + if enable_modem == 'true': reconnectToInternet() + try: + ftp = FTP(ftp_url, ftp_user, ftp_pw, timeout=20) + ftp.cwd(ftp_picture_directory) + print('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + logging.info('New ftp connection successful! current dicertory is: ' + ftp.pwd()) + except Exception as ea: + print('no internet or ftp connection on startup trying to reconnect later!') + logging.error('no internet or ftp connection on startup trying to reconnect later!') + internetTmp = 'false' +else: + print('Running in Offline mode, no internet connection is required') + +# camera.framerate = 15 #Fraction(2,6) #framrate 15 bei video und 2592x1944 +# camera.shutter_speed = 500000 + + +# camera.brightness = 50 #0 bis 100; default 50 +# camera.contrast = 0 #-100 bis 100; default 0 +# camera.iso = 0 #0 bis 1600; default 0(auto) +# camera.zoom = (0, 0, 1.0, 1.0) #0.0 bis 1.0 (x, y, w, h) +# camera.sharpness = 0 #-100 bis 100; default 0 + +print('[Camera] Resolution: ' + width + 'x' + height) +logging.info('[Camera] Resolution: ' + width + 'x' + height) + + +# main programm (endless loop) +while 1: + try: + time_next_unix = time.time() + interval # time for next picture + time_name = time.asctime(time.localtime(time.time())) # get time for picture_name + time_name = time_name.replace(" ", "_") + time_name = time_name.replace(":", "-") + picture_name = camera_number + '_' + str(picture_number).zfill(6) + '_' + time_name + '.jpg' + picture_path = picture_directory + picture_name + + print("Time:", time_name) + #camera = PiCamera() + camera.resolution = (int(width), int(height)) # aufloesung der bilder maximal 3280,2464s + camera.exposure_mode = 'auto' + camera.awb_mode = 'auto' + camera.crop = (0, 0, 0, 0) + try: + camera.exif_tags['IFD0.Make'] = 'CopterSicht' + camera.exif_tags['IFD0.Model'] = 'Long Term Timelapse Camera' + camera.exif_tags['IFD0.ShutterSpeedValue '] = '' + camera.exif_tags['IFD0.ISOSpeedRatings '] = '' + camera.exif_tags['IFD0.WhiteBalance '] = '' + camera.exif_tags['IFD0.Copyright'] = 'Copyright (c) ' + str(datetime.now().year) + ' CopterSicht' + camera.exif_tags['IFD0.ImageDescription'] = 'interval capture' + + if mute == "false": GPIO.output(piezo, GPIO.HIGH) + print('Capturing image') + logging.info('[Camera] Capturing image') + camera.capture(picture_path) # capture image and save to picture_path (picture_directory + picture_name) + #camera.close() + if mute == "false": GPIO.output(piezo, GPIO.LOW) + picture_number += 1 # increase picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + except Exception as e2: + logging.error(str(e2)) + + print('Picture size:', os.path.getsize(picture_path), "Byte") + logging.info('[Camera] Picture size: ' + str(os.path.getsize(picture_path)) + ' Byte') + checkDiskSpace() + if ioBoard == "true": checkSystemVoltage() + if os.path.getsize(picture_path) < picture_size: + print('it seems to be night!') + logging.info('it seems to be night!') + midnight1 = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds1 = (datetime.now() - midnight1).seconds # seconds since midnight + if seconds1 > float(wakeup_Time[datetime.now().month - 1]) * 60 * 60 and seconds1 < float(bed_Time[ + datetime.now().month - 1]) * 60 * 60: # if it is before 5pm, it cann't be night -> not going to sleep + print('cannot be night!') + logging.warning('cannot be night!') + print("uploadTimer", upload_every) + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + #checkCpu() + #sleepToNextPicture() + else: + os.remove(picture_path) # deleting picture because it's night! + picture_number -= 1 # decrease picture_number + print('picture_number:', str(picture_number)) + f = open("/home/pi/picture_Number.txt", 'w') + f.write(str(picture_number)) # save picture_number to a text file + f.close() + # uploading log file + print('skipping picture upload!') + print('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': print('uploading todays log befor going to sleep!') + logging.info('skipping picture upload!') + logging.info('sleeping until ' + str(wakeup_Time[datetime.now().month - 1]) + 'am!') + if internetTmp == 'true': logging.info('uploading todays log befor going to sleep!') + if internetTmp == 'true': + try: + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e: + print('[FTP] upload failed!') + print(e) + logging.error('[FTP] upload failed!') + logging.error(str(e)) + try: + print('[FTP] trying to reconnect ...') + logging.info('[FTP]trying to reconnect ...') + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('[FTP] re-connecting ftp successful!') + logging.info('[FTP]re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('uploaded log-file successful!') + logging.info('uploaded log-file successful!') + except Exception as e8: + print('[FTP] re-connecting failed!') + print(e8) + logging.error('[FTP] re-connecting failed!') + logging.error(str(e8)) + if reconnectToInternet() == 'true': + print('Reconnect successful') + logging.info('[Internet] Reconnect successful!') + try: + print() + ftp.connect(ftp_url) + ftp.login(ftp_user, ftp_pw) + print('re-connecting ftp successful!') + ftp.cwd(ftp_log_directory) + ftp.storbinary('STOR ' + log_name, open(log_directory + log_name, 'rb'), 1024) + ftp.sendcmd('SITE CHMOD 754 ' + log_name) + print('[FTP] uploaded log-file successful!') + logging.info('[FTP] uploaded log-file successful!') + except Exception as e4: + print('[FTP] re-connecting failed!') + logging.error('[FTP] re-connecting failed!') + print(str(e4)) + logging.error(str(e4)) + else: + print('Reconnect failed') + logging.error('[Internet] Reconnect failed!') + try: + ftp.cwd(ftp_picture_directory) + except Exception as er: + print('[FTP] could not change ftp directory !') + logging.error('[FTP] could not change ftp directory !') + print(str(er)) + logging.error(str(er)) + + if internet == 'true' and internetTmp == 'false': + print('[Timelapse Core] Checking again Internet Connection before sleep') + logging.info('[Timelapse Core] Checking again Internet Connection before sleep') + checkConnectionToFTPServer() + if internetTmp == 'false': + rebootFlag = 'true' + print('[Timelapse Core] Reboot Flag set') + logging.info('[Timelapse Core] Reboot Flag set') + if mute == "false": + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + GPIO.output(piezo, GPIO.HIGH) + sleep(0.5) + GPIO.output(piezo, GPIO.LOW) + sleep(0.5) + + # sleep until next morning + print('going to sleep for a while ...') + logging.info('going to sleep for a while ...') + midnight = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) + seconds = (datetime.now() - midnight).seconds # seconds since midnight + if seconds < ( + float(wakeup_Time[ + datetime.now().month - 1]) * 60 * 60): # if time between 0am and wakeup_Time + sleep_time = (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) - seconds + else: # if time between wakeup_Time and 12pm + sleep_time = 86400 - seconds + (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60) + print('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + logging.info('sleeping now ' + str(sleep_time) + ' seconds or until ' + str( + wakeup_Time[datetime.now().month - 1]) + 'am!') + sleep(sleep_time - 10) + + # wake up 10 seconds before we should for exact start + print(str((datetime.now() - midnight).seconds) + ' < ' + str( + (wakeup_Time[datetime.now().month - 1] * 60 * 60))) + while (datetime.now() - midnight).seconds < (float(wakeup_Time[datetime.now().month - 1]) * 60 * 60): + sleep(0.5) + log_name = camera_number + '_' + str(datetime.now().strftime("%A %d. %B %Y")) + '.log' + log_name = log_name.replace(" ", "-") + logging.getLogger('').handlers = [] + logging.basicConfig(filename=log_directory + log_name, format='%(asctime)s [%(levelname)s] %(message)s', + level=logging.DEBUG, datefmt='%d/%m/%Y %H:%M:%S') + print('slept for ' + str(sleep_time) + ' seconds') + print('Time to wakeup! \n') + logging.info('Camera versiom: ' + version) + logging.info('slept for ' + str(sleep_time) + ' seconds') + logging.info('Time to wakeup! \n') + if rebootFlag == 'true': + rebootSystem() + else: + + if (internetTmp == 'true') and (upload_every == 1): + uploadToFTP() + upload_every = upload_only + else: + upload_every -= 1 + if upload_every < 0: + upload_every = 0 + if upload_every == 0: + logging.info('Skipping upload. Next picture will be uploaded') + print('Skipping upload. Next picture will be uploaded') + else: + logging.info('Skipping upload. Next upload in ' + str(upload_every) + ' pictures') + print('Skipping upload. Next upload in', (upload_every), 'pictures') + + if internet == 'true' and internetTmp == 'false': + checkConnectionToFTPServer() + + checkCpu() + sleepToNextPicture() + + except Exception as loopError: + print('[Timlapse Core] ' + str(loopError)) + try: + logging.error('[FTP] could not change ftp directory !') + except Exception as er: + print('[Timlapse Core] Could not log: ' + str(er)) + + diff --git a/Software/ZK_python/config.txt b/Software/ZK_python/config.txt new file mode 100644 index 0000000..7ac3c54 --- /dev/null +++ b/Software/ZK_python/config.txt @@ -0,0 +1,23 @@ +[config] +ftp_url = schuttercloud.com +ftp_picture_directory = /camera03/Position02 +ftp_log_directory = /logs +ftp_user = uploader +ftp_pw = XXXXXXXXXXXXXXXXXXXXXXXXX +enable_modem = true +picture_directory = /media/usb/pictures/ +log_directory = /media/usb/log/ +picture_size = 2300000 +camera_number = 03 +internet = true +modem_apn = web.vodafone.de +upload_only = 1 +interval = 300 +I/O_Board = false +mute = true +wakeup_Time: 8,8,7,7,6,5.5,6,6.5,7.5,7.5,8,8 +bed_Time: 17,17.5,18,20,20.5,21.5,21.5,20.5,19.5,17.5,16.5,16.5 +TV_Output: false +Width: 3280 +Height: 2464 +Reboot: false diff --git a/Software/banner.txt b/Software/banner.txt new file mode 100644 index 0000000..6561e37 --- /dev/null +++ b/Software/banner.txt @@ -0,0 +1,49 @@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@(.@@@@@@@@@@@@@ .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@%@@@@@@@@@@@@ +@@@@@@@@@@ .@@@@@@@@% %@ @# ./. .% . & & . .@@@@@@@@@@ +@@@@@@@@@ @@@@@@@@@@@@@@@ @@@@ @@@@@@@ @@@@& @@@@@@@@@@@ % @@@@@@@@@ @@@@@@@@@@@ +@@@@@@@@@# @ .@@@ @@@ ,@ @@@@@/ @@@@ @ @@@@@@@@@@@ +@@@@@@@# *@ @@@&&&& , @@@,*@@ @@@@@@@@@ +@@@@@@@ @@@@@@@@@ +@@@@@@@@@(@@@@@@@@@@@@@@@ @@@@@@.@ /@@@@@@@ @@@@@@@@@@*@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@(@ @@@@@@ @@@@@& @@@@@@@@@ @@@@@@@@@@@@@ *@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@( @@@@@@@@@@@ @ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@# @@, %.@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ %@@ @@%@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@ @@@ @ @%@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@ @@@ @ @@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ * *@@@@ @@@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@, @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ %@@@ @@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ /@@@( %@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@ @@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@ @@ @ ,@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ +@ ______ __ ______ __ __ __ @ +@ / \ / | / \ / | / | / | @ +@ /$$$$$$ | ______ ______ _$$ |_ ______ ______ /$$$$$$ |$$/ _______ $$ |____ _$$ |_ @ +@ $$ | $$/ / \ / \ / $$ | / \ / \ $$ \__$$/ / | / |$$ \ / $$ | @ +@ $$ | /$$$$$$ |/$$$$$$ |$$$$$$/ /$$$$$$ |/$$$$$$ |$$ \ $$ |/$$$$$$$/ $$$$$$$ |$$$$$$/ @ +@ $$ | __ $$ | $$ |$$ | $$ | $$ | __ $$ $$ |$$ | $$/ $$$$$$ |$$ |$$ | $$ | $$ | $$ | __ @ +@ $$ \__/ |$$ \__$$ |$$ |__$$ | $$ |/ |$$$$$$$$/ $$ | / \__$$ |$$ |$$ \_____ $$ | $$ | $$ |/ | @ +@ $$ $$/ $$ $$/ $$ $$/ $$ $$/ $$ |$$ | $$ $$/ $$ |$$ |$$ | $$ | $$ $$/ @ +@ $$$$$$/ $$$$$$/ $$$$$$$/ $$$$/ $$$$$$$/ $$/ $$$$$$/ $$/ $$$$$$$/ $$/ $$/ $$$$/ @ +@ $$ | @ +@ $$ | https://coptersicht.de @ +@ $$/ @ +X-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-X +@ @ +@ Basic Image: basic04.img Camera: TLCXX Creation date: XX.XX.20XX @ +@ @ +X-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-X diff --git a/Software/createMonthFolder.sh b/Software/createMonthFolder.sh new file mode 100644 index 0000000..d7b6891 --- /dev/null +++ b/Software/createMonthFolder.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +for D in `find . -type d` +do + echo $D + mkdir $D/01_January + mkdir $D/02_February + mkdir $D/03_March + mkdir $D/04_April + mkdir $D/05_May + mkdir $D/06_June + mkdir $D/07_July + mkdir $D/08_August + mkdir $D/09_September + mkdir $D/10_October + mkdir $D/11_November + mkdir $D/12_December + + +done