tag:blogger.com,1999:blog-91470062096729545972024-03-19T06:08:08.176+02:00Ιστορίες για... ανοικτό λογισμικό, ηλεκτρονικά και άλλαΣε αυτό το Blog περιγράφονται οι προσωπικές μου εμπειρίες με το ανοικτό λογισμικό, οι εμπειρίες μου με την ηλεκτρονική τεχνολογία, κάποια "πιστέυω" μου και ότι άλλο μου έρθει στο κεφάλι!eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.comBlogger43125tag:blogger.com,1999:blog-9147006209672954597.post-43677473311367683922020-09-20T21:44:00.545+03:002020-11-16T15:20:52.615+02:00DeepSeaRobotix - coYaght<p class="el">Το σχολικό έτος 2019-2020 είχα την τιμή να βρίσκομαι σε τρία πολύ καλά σχολειά. Γυμνάσια και τα τρία, αλλά πολύ ενεργά σε εξωσχολικές δραστηριότητες. Ένα από αυτά ήταν και το <i>1ο Γυμνάσιο Γέρακα</i> που ανήκει στη <i>Δ.Δ.Ε Ανατολικής Αττικής</i>. Στο συγκεκριμμένο σχολείο υπήρξε παλαιότερα ένα project που με τη βοήθεια του <i><a href="http://www.eugenfound.edu.gr">Ευγενιδίου Ιδρύματος</a></i> είχαν φτιάξει ένα <i><a href="http://www.hydrobots.gr">Hydrobot</a></i>. Κάποια στιγμή ένας συνάδελφος, μαζί με το Διευθυντή του σχολείου, με ρώτησαν αν ήθελα να τους βοηθήσω να το εξελίξουν. Φυσικά η απάντηση ήταν θετική.
</p><p class="el">Το σχολείο ξεκίνησε τη συμμετοχή του στο διαγωνισμό <b>European Junior Achievement 2019-2020</b>, όπου κάθε σχολείο που συμμετέχει δημιουργεί μια εικονική επιχείριση και προωθεί το προϊόν της. Η διαδικασία περιέχει όλα τα καλά, όπως τη δημιουργία ενός Επιχειρισιακού Πλάνου, τη Διοίκηση της Επιχείρισης, κλπ. Ο διαγωνισμός, τελικά, έγινε μέσω διαδικτύου λόγω της πανδημίας του COVID-19.
</p><p class="el">Το όνομα της επιχείρησής μας; <b>DeepSeaRobotix Α.Β.Ε.Ε</b>. και το προϊόν μας είχε την ονομασία <b>coYaght</b>, μιας κι επρόκειτο για ένα Drone Θαλάσσης που θα ήταν η εξέλιξη του Hydrobot. Στο διαγωνισμό η επιχείρισή μας βαθμολογήθηκε με <b>91/100</b> καταλαμβάνοντας τη <b>12η θέση</b>, ενώ κέρδισε το <b>Ειδικό Βραβείο Αξιοποίησης Νέων Τεχνολογιών</b>. Στο άρθρο αυτό, θα δούμε τον τρόπο κατασκευής και λειτουργίας του coYaght, αλλά πρώτα από όλα θα ήθελα να ευχαριστήσουμε το <b>Ευγενίδιο Ίδρυμα</b> για την προσφορά του που μας διέθεσε δωρεάν το κιτ του <i>Hydrobot</i> αλλά και του συστήματος <i>HydroSensors V2</i> που περιείχε ένα Arduino Uno, ένα shield με δυνατότητα χρήσης κάρτας SD για εγγραφή δεδομένων, Real Time Clock για να κρατάει την ώρα με τη βοήθεια μπαταρίας και τρεις αισθητήρες, ένα θερμοκρασίας, έναν πίεσης κι ένα φωτισμού.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs88Qtfqxrf0Z2KTbxwwFp3xCbSLl-4iXzWDRenHINEXzlOgDWlK6cJE3cLE7LRmF1b2El1TIRy9q_gr9G548yV-a2fW50FEWsVd0aKdOabVtcKDax2PTMk49o0eSjKCk3AAx-HOughEjN/s640/coYaght.jpg" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" data-original-height="387" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs88Qtfqxrf0Z2KTbxwwFp3xCbSLl-4iXzWDRenHINEXzlOgDWlK6cJE3cLE7LRmF1b2El1TIRy9q_gr9G548yV-a2fW50FEWsVd0aKdOabVtcKDax2PTMk49o0eSjKCk3AAx-HOughEjN/s600/coYaght.jpg" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" /></a></div>
<h2 align="center" class="el">Τι θα δούμε σε αυτό το άρθρο</h2>
<ul>
<li class="el">Τι είναι το coYaght</li>
<ul>
<li class="el">Μονάδα τροφοδοσίας</li>
<li class="el">Οδηγοί κινητήρων</li>
<li class="el">Arduino Uno και Υποκυκλώματά του</li>
<li class="el">Raspberry Pi - Ο "Εγκέφαλος" του συστήματος</li>
</ul>
<li class="el">Έλεγχος του coYaght</li>
<ul>
<li class="el">Εγκατάσταση Λειτουργικού</li>
<li class="el">Πρώτες παραμετροποιήσεις Hardware</li>
<li class="el">Προετοιμασία δικτύωσης</li>
<li class="el">Σύνδεση σε δικό μας τοπικό δίκτυο</li>
<li class="el">Εγκατάσταση Arduino Software</li>
<li class="el">Arduino Firmware</li>
<li class="el">Προετοιμασία βάσης δεδομένων MySQL</li>
<li class="el">Προετοιμασία Python</li>
<li class="el">coYaght Server</li>
<li class="el">Αυτόματη εκκίνηση του server με την εκκίνηση του Raspberry Pi</li>
</ul>
<li class="el">Χρήση του coYaght</li>
<li class="el">Συμπεράσματα</li>
</ul>
<h2 align="center" class="el">Τι είναι το coYaght</h2>
<p class="el">Το coYaght είναι ένα drone θαλάσσης. Έχει τη δυνατότητα να μπαίνει μέσα στο νερό και με τη βοήθεια τριών μοτέρ να μπορεί να κατευθυνθεί όπου ο χρήστης επιθυμεί. Το κέλυφός του είναι ελαφρύ και κατασκευασμένο από πλαστικούς σωλήνες, εκτός από το τμήμα που περιέχει τα ηλεκτρονικά συστήματα που είναι κατασκευασμένο από plexiglass. Τα τοιχώματα από plexiglass είναι κολλημένα με εποξική κόλλα έτσι ώστε να είναι στεγανά και να μη μπαίνει νερό μέσα τους.</p>
<p class="el">Τα ηλεκτρονικά συστήματα που προστατεύει το κουτί από plexiglass είναι:</p>
<ul>
<li class="el">Ένα Raspberry Pi 3B+</li>
<li class="el">Ένα Arduino Uno</li>
<li class="el">Ένα SD Card + Real Time Clock Shield για το Arduino</li>
<li class="el">Έναν αισθητήρα θερμοκρασίας</li>
<li class="el">Έναν αισθητήρα πίεσης</li>
<li class="el">Έναν αισθητήρα φωτεινότητας περιβάλλοντος</li>
<li class="el">Μία κάμερα συνδεδεμένη στο Raspberry Pi</li>
<li class="el">Δύο προβολείς λευκού φωτός για την κάμερα</li>
<li class="el">Ένα κόκκινο κι ένα πράσινο φως που συμφωνούν με τα πρώτυπα της ναυσιπλοΐας (το κόκκινο αριστερά και το πράσινο δεξιά)</li>
<li class="el">Τρεις οδηγούς για τα μοτέρ</li>
<li class="el">Μια διάταξη τροφοδοσίας για τα ηλεκτρονικά χαμηλής τάσης (Raspberry και Arduino + Shield)</li>
</ul>
<p class="el">Ας γνωρίσουμε ένα-ένα τα κομμάτια του συστήματος και τη λειτουργία τους</p>
<h3 class="el">Μονάδα τροφοδοσίας</h3>
<p class="el">Το coYaght τροφοδοτείται μέσω του καλωδίου δικτύου που περιέχει (Power Over Ethernet - PoE). Η τάση που δίδεται είναι μεγάλη, για να μπορέσει να κινήσει τα μοτερ της πλοήγησης και τους προβολείς. Αυτό σημαίνει πως δε μπορεί να συνδεθεί απευθείας στις ηλεκτρονικές πλακέτες του Raspberry Pi και του Arduino Uno. Επίσης, άλλο ένα πρόβλημα που υπάρχει είναι πως η τελική τάση που φτάνει στα κυκλώματα του coYaght δεν είναι καθόλου σταθερή· Εξαρτάται από την εξωτερική τροφοδοσία, τη ζήτηση σε ρεύμα την κάθε χρονική στιγμή κλπ. Η ζήτηση ρεύματος διαφέρει, διότι εξαρτάται πολύ από τον αριθμό των μοτέρ που είναι ενεργοποιημένα, αλλά και την επεξεργασία που κάνει το ίδιο το Raspberry Pi.</p>
<p class="el">Για να μπορέσουμε να ξεπεράσουμε τα προβλήματα αυτά, είναι επιτακτική η ανάγκη χρήσης μιας τροφοδοτικής διάταξης που θα κατεβάζει την τάση που φτάνει στο coYaght μέσω του καλωδίου, στην τάση που μπορούν να δεχθούν τα ηλεκτρονικά κυκλώματα. Η μονάδα αυτή θα πρέπει επίσης να έχει αντοχή μεγάλη σε ριπές ρεύματος, λόγω του Raspberry Pi. Παρότι οι ασύρματες συνδέσεις BLE και WiFi δεν είναι ενεργοποιημένες, μιας και δεν είναι χρήσιμες, όπως και το γραφικό περιβάλλον χρήστη, το Raspberry Pi ζητάει ακανόνιστες ριπές ρεύματος, ανάλογα με τις λειτουργίες που εκτελεί κάθε στιγμή. Είναι, λοιπόν, ανάγκη η τροφοδοτική διάταξη να έχει αντοχές σε τέτοιες ριπές ρεύματος.</p>
<p class="el">Κάτι επίσης σημαντικό, είναι πως η τροφοδοτική διάταξη θα πρέπει να έχει μεγάλη απόδοση για να θερμένεται όσο το δυνατόν λιγότερο και να μη δαπανάται ενέργεια επάνω στη λειτουργία της άσκοπα.</p>
<p class="el">Η μονάδα τροφοδοσίας που χρησιμοποιήθηκε βασίστηκε στον ολοκληρωμένο σταθεροποιητή τάσης LM2596S-5.0. Είναι ένας σταθεροποιητής τύπου παλμοτροφοδοτικού για να επιτύχει μεγάλη απόδοση και μικρή αύξηση θερμοκρασίας. Το σχηματικό διάγραμμα του κυκλώματος φαίνεται στην ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx39_c3AJvqbazUQGUah-SGUgsMSeRo4AhvXRmWw095n_asSsSiqWp12be-FpRIJBTsOTLcUvfV5P_NIb2gHp4Cbpwg-A-Uojs6VNUKHpjULqOJUe3JL-7DveYjWY9mUghEgoH33kV5j_k/s767/5V+Regulator.jpg" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" data-original-height="202" data-original-width="767" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgx39_c3AJvqbazUQGUah-SGUgsMSeRo4AhvXRmWw095n_asSsSiqWp12be-FpRIJBTsOTLcUvfV5P_NIb2gHp4Cbpwg-A-Uojs6VNUKHpjULqOJUe3JL-7DveYjWY9mUghEgoH33kV5j_k/s600/5V+Regulator.jpg" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" /></a></div>
<p class="el">Το κύκλωμα έχει δημιουργηθεί επάνω σε ένα κομμάτι διάτρητης πλακέτας, ενώ χρησιμοποιείται κι ένα κομμάτι φύλλου χαλκού για να λειτουργήσει ως ψύκτρα του σταθεροποιητή.</p>
<h3 class="el">Οδηγοί κινητήρων</h3>
<p class="el">Το CoYaght διαθέτει τρεις κινητήρες (μοτέρ) για την πλοήγησή του μέσα στη θάλασσα, ένα για την κατακόρυφη κίνηση (βύθιση ή ανάδυση), ένα για την κίνηση του δεξιού του μέρους κι ένα για την κίνηση του αριστερού. Η κίνηση των δύο τελευταίων μπορεί να είναι και προς τις δύο κατευθύνσεις (πρόσω και όπισθεν). Οι κινητήρες λειτουργούν με τάση 12V ενώ οδηγούνται από τη μονάδα Arduino Uno. Συνεπώς, πρέπει να μπορούν να κινηθούν είτε δεξιόστροφα, είτε αριστερόστροφα με τάση οδήγησης αρκετά μεγαλύτερη από αυτή του κυκλώματος που δίνει τις εντολές.</p>
<p class="el">Για να μπορέσει το Arduino να οδηγήσει τους κινητήρες θα πρέπει να παρεμβληθεί ένα κύκλωμα που να έχει τη δυνατότητα να οδηγεί τους κινητήρες με μεγάλη τάση (σε σύγκριση με αυτή του Arduino) ενώ ταυτόχρονα για πρέπει να μπορεί να επιλεχθεί και η πολικότητά της. Το κύκλωμα βασίζεται στην αρχή λειτουργείας της γέφυρας με MOSFET. Η γέφυρα οδηγείται από ειδικό ολοκληρωμένο κύκλωμα για να αποφευχθούν συμπεριφορές βραχυκυκλώματος της τροφοδοσίας και κατά συνέπεια την καταστροφή των κυκλωμάτων. Τα MOSFET λειτουργούν ως διακόπτες που συνδέουν το κάθε άκρο του μοτέρ που οδηγούν, είτε στα +12V, είτε στο 0. Το ποιο άκρο θα συνδεθεί πού, εξαρτάται από την εντολή που δίνει το Arduino.</p>
<p class="el">Το σχηματικό διάγραμμα του κυκλώματος οδήγησης ενός κινητήρα φαίνεται στην ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicFWIChqt0CqpxEMUUwPAw_gPJRX5FseB-QXOZQkhfcWFRvRGNXDQKH3JX_vvzio6SAiPV2EEXwhWXvUHLSF7KLhjORFkC1f_Go2WPkh8t3s4PjRyVR7dLU0xOWMA9yiG_r8vpr7CB9qnD/s488/Motor+Driver.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" data-original-height="251" data-original-width="488" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicFWIChqt0CqpxEMUUwPAw_gPJRX5FseB-QXOZQkhfcWFRvRGNXDQKH3JX_vvzio6SAiPV2EEXwhWXvUHLSF7KLhjORFkC1f_Go2WPkh8t3s4PjRyVR7dLU0xOWMA9yiG_r8vpr7CB9qnD/s600/Motor+Driver.png" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" /></a></div>
<h3 class="el">Arduino Uno και Υποκυκλώματά του</h3>
<p class="el">Το όλο σύστημα του coYaght περιέχει ένα μικρό προγραμματιζόμενο υπολογιστή, μικρών δυνατοτήτων, το Arduino Uno. Αυτό δομείται από ένα μικροελεγκτή τύπου AVR atmega328P της Atmel (πλέον κομμάτι της Microchip, Inc.). Το κύκλωμα είναι open source. Έχει ένα απλό περιβάλλον προγραμματισμού που μπορούμε να γράψουμε κώδικα και να προγραμματίσουμε το Arduino με γλώσσα που μοιάζει αρκετά με τη C. Επιπλέον, περιέχει πολλές έτοιμες βιβλιοθήκες που μας γλυτώνουν από τον κόπο του προγραμματισμού χαμηλού επιπέδου και κάνουν τη ζωή μας πιο εύκολη. Με αυτό τον τρόπο, ο χρόνος που χρειαζόμαστε για να φτιάξουμε μια πλήρη εφαρμογή είναι αρκετά μικρότερος σε σύγκριση με περιπτώσεις χρήσης μικροελεγκτών άλλων εταιριών. Καθίσταται ιδανικό, λοιπόν, για ένα σχολικό περιβάλλον και μαθητές με όρεξη να γευτούν τον κόσμο των ψηφιακών ηλεκτρονικών και του προγραμματισμού.</p>
<p class="el">Οι δυνατότητες που παρέχει το Arduino είναι η οδήγηση ή το διάβασμα ψηφιακών σημάτων, το διάβασμα αναλογικών σημάτων (ο μικροελεγκτής περιέχει μετατροπέα αναλογικού σήματος σε ψηφιακό), η επικοινωνία μέσω σειριακής θύρας, η οποία δρομολογείται σε υπολογιστή μέσω συνδέσμου USB. Υπάρχουν, επίσης, στο εμπόριο αρκετά κυκλώματα που εφαρμόζουν στους συνδέσμους του, δίνοντάς του επιπλέον δυνατότητες. Αυτά τα ονομάζουμε shields.</p>
<p class="el">Στην περίπτωση του coYaght, το Arduino είναι το σύστημα που παίρνει μετρήσεις από τους αισθητήρες που είναι συνδεδεμένοι σε αυτό. Τις μετρήσεις τις δίνει στη σειριακή του έξοδο, η οποία οδηγείται στο σύνδεσμο USB. Αυτό σημαίνει πως ένας υπολογιστής συνδεδεμένος στο USB του, μπορεί να διαβάσει τις μετρήσεις που δίνει κάθε δευτερόλεπτο, το Arduino.</p>
<p class="el">Κάτι ακόμα που κάνει το Arduino για το coYaght, είναι το να οδηγεί τους τρεις κινητήρες πλοήγησης. Ο τρόπος που θα πλοηγηθεί το coYaght μέσα στη θάλασσα περιγράφεται από εντολές που δίνει ο χρήστης, πού αλλού; στη σειριακή του πόρτα.</p>
<p class="el">Τέλος, χρησιμοποιείται ένα shield που περιέχει ένα ολοκληρωμένο Real Time Clock (RTC) και μια θέση κάρτας SD. Η δουλειά του RTC είναι να μετράει το χρόνο, κρατώντας την ημερομηνία και την τρέχουσα ώρα. Τροφοδοτείται από μια μπαταρία, έτσι ώστε ακόμα κι αν το σύστημα δεν τροφοδοτείται, το RTC να συνεχίζει να μετράει το χρόνο χωρίς να χάνει ούτε δευτερόλεπτο. Το τμήμα της κάρτας SD δε χρησιμοποιείται στο coYaght.</p>
<p class="el">Το μπλοκ διάγραμμα του υποσυστήματος φαίνεται στο ακόλουθο σχήμα:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-bPWv7ekjPy5zjuy7dTRIf-ziVz0xnpN4M-e5gAzcICR0x8w5IMJ50Rh02sVAs1ZJ1-CJdvwLeJM0HpPNklBVc9nln3vgTdE8Gdm5WNCKEQ1p9IKFAobSRg3gCLwKFkCgXIOU3Wc3CnJU/s1255/Arduino+Subsystem.png" style="display: block; padding: 1em 0px; text-align: center;"><img alt="" data-original-height="739" data-original-width="1255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-bPWv7ekjPy5zjuy7dTRIf-ziVz0xnpN4M-e5gAzcICR0x8w5IMJ50Rh02sVAs1ZJ1-CJdvwLeJM0HpPNklBVc9nln3vgTdE8Gdm5WNCKEQ1p9IKFAobSRg3gCLwKFkCgXIOU3Wc3CnJU/s600/Arduino+Subsystem.png" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" /></a></div>
<p class="el">Στο διάγραμμα, τα τμήματα που φαίνονται ως κινητήρες, εννοείται πως είναι μαζί και τα αντίστοιχα κυκλώματα οδήγησης.</p>
<h3 class="el">Raspberry Pi - Ο "Εγκέφαλος" του συστήματος</h3>
<p class="el">Στο σύστημα του coYaght πρέπει να υπάρχει κι ένα υπολογιστικό σύστημα ικανό να μπορεί να συνδέεται με μια κάμερα και να δίνει το βίντεό της διαμέσου δικτύου σε real time streaming. Μια καλή λύση είναι ο υπολογιστής μιας πλακέτας Raspberry Pi και συγκεκριμμένα η έκδοση 3B+. Ο υπολογιστής αυτός διαθέτει όλα τα χαρακτηριστικά που χρειάζονται: Δικτύωση ethernet, σύνδεση για κάμερα, σύνδεση USB για να συνδεθεί το Arduino κλπ.</p>
<p class="el">Το Raspberry τρέχει λειτουργικό Linux. Αυτό λύνει τα χέρια, τόσο στα θέματα της δικτύωσης και το χειρισμό περιφερειακών συσκευών, όπως η κάμερα και το Arduino, όσο και στην ανάπτυξη του κώδικα που χρειάζεται για να μπορέσει να λειτουργήσει σαν εξυπηρετητής web και να παρέχει ένα αρκετα φιλικό περιβάλλον χρήστη για το χειρισμό του συστήματος coYaght. Εύκολα δίνεται η δυνατότητα σύνδεσης σε κάποιο φορητό υπολογιστή, ο προγραμματισμός σε γλώσσα προγραμματισμού Python, ακόμα και η αναβάθμιση του firmware του Arduino. Η σύνδεση για τις ανάγκες προγραμματισμού γίνεται μέσω SSH ενώ μπορούν να τρέχουν ταυτόχρονα κι άλλοι servers για τις ανάγκες της δικτύωσης, όπως DHCP. Στη συνέχεια θα δούμε το στήσιμό του για να μπορέσει το coYaght να αποτελέσει ένα ολοκληρωμένο σύστημα υποβρύχιου drone.</p>
<h2 align="center" class="el">Έλεγχος του coYaght</h2>
<p class="el">Όλος ο έλεγχος του coYaght γίνεται διαμέσου του Raspbery Pi. Ας δούμε, αρχικά, τον τρόπο με τον οποίο επιθυμούμε να λειτουργεί και με βάση αυτή τη λογική θα στήσουμε σιγά-σιγά το Raspberry για την επίτευξη του τελικού μας στόχου.</p>
<p class="el">Κατ' αρχήν, η χρήση του συστήματος θα πρέπει να γίνεται από ένα απλό φυλλομετρητή (browser) σε ένα υπολογιστή ανεξαρτήτου λειτουργικού συστήματος. Αυτό σημαίνει πως θα πρέπει να υπάρχει μια σύνδεση δικτύου μεταξύ ενός υπολογιστή και του coYaght. Η σύνδεση με την οποία λειτουργεί το coYaght είναι μέσω καλωδίου ethernet το οποίο μεταφέρει και την ισχύ τροφοδοσίας του (Power over Ethernet - PoE).</p>
<p class="el">Όταν το coYaght συνδεθεί, με τη βοήθεια καλωδίου, στον υπολογιστή, θα πρέπει ο χρήστης να μπορεί να ανοίξει όποιο φυλλομετρητή επιθυμεί και να μπει στην ιστοσελίδα του coYaght. Εκεί θα πρέπει να υπάρχουν όλα τα διαθέσιμα χειριστήρια αλλά και ενδείξεις που να δείχνουν την κατάσταση των αισθητήρων και το βίντεο της κάμερας. Τα χειριστήρια θα πρέπει να δίνουν τη δυνατότητα πλοήγησής του με ευκολία.</p>
<p class="el">Όλα αυτά, παρότι φαίνονται εύκολα σαν ιδέα, κρύβουν πολλές λεπτομέρειες που θα πρέπει να υλοποιηθούν για να μπορέσουμε να έχουμε το επιθυμητό αποτέλεσμα. Ας δούμε, λοιπόν, το στήσιμο κομμάτι-κομμάτι.</p>
<h3 class="el">Εγκατάσταση Λειτουργικού</h3>
<p class="el">Το Raspberry Pi είναι, όπως λέμε, υπολογιστής μιας πλακέτας (Single Board Computer - SBC). Για να γίνει χρήσιμο πρέπει να του φορτώσουμε ένα λειτουργικό σύστημα, όπως και στους υπολογιστές μας. Η εγκατάσταση γίνεται σε μια κάρτα μνήμης microSD. Η εγκατάσταση του λειτουργικού συστήματος γίνεται όπως περιγράφεται στο site του <a href="https://projects.raspberrypi.org/en/projects/raspberry-pi-setting-up/2">Raspberry.org</a>. Στη σελίδα περιγράφεται η εγκατάσταση διαφόρων λειτουργικών. Εμείς χρησιμοποιήσαμε το προκαθορισμένο Raspberry Pi OS που είναι βασισμένο στο Ubuntu.</p>
<p class="el">Μετά την εγκατάσταση του λειτουργικού στη διαθέσιμη microSD κάρτα, τποθετούμε την κάρτα στο Raspberry Pi, του συνδέουμε ένα πληκτρολόγιο, ένα ποντίκι μια οθόνη και δίκτυο. Λίγα δευτερόλεπτα μετά την ενεργοποίησή του βλέπουμε την αρχική οθόνη του γραφικού περιβάλλοντος Ubuntu.</p>
<h3 class="el">Πρώτες παραμετροποιήσεις Hardware</h3>
<p class="el">Η παραμετροποίηση του Raspberry γίνεται από το εργαλείο <code>raspi-config</code>. Μιας και μιλάμε για παραμετροποίηση συστήματος, φυσικά, το <code>raspi-config</code> πρέπει να τρέξει κάτω από τον χρήστη <code>root</code>. Για να το τρέξουμε, ανοίγουμε μια κονσόλα και γράφουμε:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo raspi-config</pre>
</div><br />
<p class="el">Το ακόλουθο παράθυρο ανοίγει:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijLgHeqmS5zYr9MLa9XkGWwiGmgOMNPNv4EckGs0nb5v6kZyTvPKhR4bZBAKXOpXrsoYQ41Ux7s8AtOdoy-peJmXv-bGARRSS38U-nIY7WjKNHTTYypWwOHMaPGaqPzbommjsWWRK5QTxf/s689/raspi-config.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" data-original-height="404" data-original-width="689" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijLgHeqmS5zYr9MLa9XkGWwiGmgOMNPNv4EckGs0nb5v6kZyTvPKhR4bZBAKXOpXrsoYQ41Ux7s8AtOdoy-peJmXv-bGARRSS38U-nIY7WjKNHTTYypWwOHMaPGaqPzbommjsWWRK5QTxf/s600/raspi-config.png"/></a></div>
<p class="el">Με το πληκτρολόγιο μπορούμε να πλοηγηθούμε μέσα στα μενού και τις επιλογές του παραθύρου. Κάνουμε τις ακόλουθες επιλογές:</p>
<ul>
<li>Network Options -> Hostname -> OK -> coyaght: Ρυθμίζουμε την ονομασία του coYaght. Πρέπει να χρησιμοποιήσουμε πεζούς χαρακτήρες σε όλα τα γράμματα</li>
<li>Boot Options -> Desktop / CLI -> Console: Απενεργοποιούμε το γραφικό περιβάλλον για να μη χρησιμοποιεί πόρους του συστήματος, αφού δεν πρόκειται να το συνδέσουμε σε μια οθόνη</li>
<li>Localization Options -> Change Time Zone -> Europe -> Athens: Ρυθμίζουμε τη ζώνη ώρας του συστήματος, να είναι σύμφωνη με τα πρότυπα της Ελλάδας</li>
<li>Interfacing Options -> Camera -> Yes: Ενεργοποιούμε το δίαυλο επικοινωνίας του επεξεργαστή με την κάμερα</li>
<li>Interfacing Options -> SSH -> Yes: Ενεργοποιούμε την πρόσβαση μέσω SSH</li>
</ul>
<h3 class="el">Προετοιμασία δικτύωσης</h3>
<p class="el">Συνέχεια έχει η προετοιμασία του δικτύου. Όταν το coYaght συνδέεται σε ένα laptop, στο χώρο στον οποίο θα χρησιμοποιηθεί, πρέπει να μην υπάρχει η ανάγκη ενός router ή άλλης δικτυακής συσκευής. Αυτό σημαίνει πως το σύστημα θα πρέπει να έχει μια στατική διεύθυνση δικτύου IP και να μπορεί να στείλει χαρακτηριστικά δικτύωσης και στο εν λόγω laptop. Χρειάζεται, δηλαδή, να τρέχει ένας DHCP server στο Raspberry Pi για να μπορέσει να γίνει η επικοινωνία σωστά. Άλλο ένα σημαντικό πράγμα που θα πρέπει να προσέξουμε, είναι πως αν το laptop έχει και ασύρματη σύνδεση, επειδή υπάρχουν πιθανότητες να είναι και αυτή συνδεδεμένη σε κάποιο ασύρματο δίκτυο, τα δύο υποδίκτυα να μην είναι κοινά. Με βάση όλες αυτές τις παραμέτρους, θα ορίσουμε τη διεύθυνση του Raspberry να είναι η 192.168.111.10/24. Ας δούμε πως γίνεται αυτή η διαδικασία.</p>
<p class="el">Για να ρυθμίσουμε τη στατική IP θα πρέπει να ανοίξουμε το αρχείο <code>/etc/dhcpcd.conf</code>. Εκεί μέσα βάζουμε τις κατάλληλες ρυθμίσεις για το interface <code>eth0</code>. Φυσικά αν υπάρχουν προηγούμενες ρυθμίσεις θα πρέπει να τις σβήσουμε. Με τον επιθυμητό editor ανοίγουμε το αρχείο πάντα ως <code>root</code> και το τροποποιούμε:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo vi /etc/dhcpcd.conf</pre>
</div><br />
<div class="code">
<pre>
interface eth0
static ip_address=192.168.111.10/24
static routers=192.168.111.1
static domain_name_servers=8.8.8.8</pre>
</div><br />
<p class="el">Το επόμενο βήμα είναι να κάνουμε το Raspberry Pi να λειτουργεί και ως DHCP server. Το πρωτο πράγμα που πρέπει να κάνουμε είναι να εγκαταστήσουμε το κατάλληλο πακέτο:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get install isc-dhcp-server</pre>
</div><br />
<p class="el">Στη συνέχεια πρέπει να παραμετροποιήσουμε τον εξυπηρετητή. Το πρώτο πράγμα που πρέπει να κάνουμε είναι να του πούμε ποιον δικτυακό σύνδεσμο θα χρησιμοποιεί:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo vi /etc/default/isc-dhcp-server</pre>
</div><br />
<p class="el">Προς το τέλος του αρχείου θα βρούμε κάπου τη γραμμή <code>INTERFACESv4</code>. Θα πρέπει να σιγουρευτούμε πως περιέχει μέσα το σύνδεσμο <code>eth0</code>. Με αυτό τον τρόπο λέμε στο server πως θα εξυπηρετεί το σύνδεσμο <code>eth0</code> στον οποίο θα συνδέεται ο υπολογιστής:</p>
<div class="code">
<pre>
INTERFACESv4="eth0"
INTERFACESv6=""</pre>
</div><br />
<p class="el">Τώρα πρέπει να του πούμε τι παραμέτρους θα στέλνει στους clients. Αυτές βρίσκονται στο αρχείο <code>/etc/dhcp/dhcpd.conf</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo vi /etc/dhcp/dhcpd.conf</pre>
</div><br />
<p class="el">Στην αρχή του αρχείου βρίσκουμε τις γραμμές για options του domain-name και του domain-name-servers. Δίνουμε τις ακόλουθες τιμές:</p>
<div class="code">
<pre># option definitions common to all supported networks...
option domain-name "coyaght_home";
option domain-name-servers 192.168.111.1;</pre>
</div><br />
<p class="el">Ο server αυτός είναι ο κυρίαρχος server του δικτύου, μιας και θα είναι ο μοναδικός μεταξύ του coYaght και του laptop που θα το χειρίζεται. Πρέπει να ενεργοποιήσουμε το <code>authoritative</code>. Ψάχνουμε μέσα στο αρχείο και το ενεργοποιούμε:</p>
<div class="code">
<pre># If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.
authoritative;</pre>
</div><br />
<p class="el">Τέλος προσθέτουμε γραμμές για τη δημιουργία του υποδικτύου που χρειάζεται να εξυπηρετεί αυτός ο DHCP:</p>
<div class="code">
<pre>subnet 192.168.111.0 netmask 255.255.255.0 {
range 192.168.111.11 192.168.111.249; #//Available address range to clients
option domain-name-servers 192.168.111.1; #//DNS requests are sent to router (Though there won't be any :)
option domain-name "coyaght_home"; #//The domain name. Here we set the same as earlier
option routers 192.168.111.1; #//The router is the gateway to other networks
option broadcast-address 192.168.111.255; #//Broadcast address for this subnet
default-lease-time 600;
max-lease-time 7200;
}</pre>
</div><br />
<p class="el">Τώρα μένει να ενεργοποιήσουμε την υπηρεσία, ώστε να τρέχει αυτόματα στην εκκίνηση του συστήματος:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo update-rc.d isc-dhcp-server start
pi@coyaght:~ $ sudo service isc-dhcp-server start</pre>
</div><br />
<p class="el">Η τελευταία εντολή τρέχει την υπηρεσία αυτή τη στιγμή. Τώρα αν συνδέσουμε το καλώδιο δικτύου του coYaght σε έναν υπολογιστή, αυτός πρέπει να πάρει αυτόματα μια διεύθυνση IP στο υποδίκτυο 192.168.111.x</p>
<p class="el">Τέλος, (για την ώρα), μιας και μέχρι να τελειώσουμε με την όλη εγκατάσταση ώστε να έχουμε ένα λειτουργικό coYaght, η σύνδεσή του θα γίνεται στο δικό μας τοπικό δίκτυο, καλό είναι να φτιάξουμε ένα μικρό script που να προσθέτει ρυθμίσεις ώστε να λειτουργεί σωστά ΚΑΙ στο δικό μας δίκτυο. Φτιάχνουμε ένα αρχείο που το ονομάζουμε <code>bin/initnet.sh</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ vi bin/initnet.sh</pre>
</div><br />
<p class="el">Στο αρχείο βάζουμε τις ακόλουθες γραμμές:</p>
<div class="code">
<pre>#!/bin/bash
# Must be run using sudo!
service isc-dhcp-server stop
ip address add 192.168.1.16/24 dev eth0
ip route del default
route add default gw 192.168.1.1 dev eth0
echo "The network is ready."</pre>
</div><br />
<p class="el">Το script αυτό κάνει τις εξής εργασίες:</p>
<ul>
<li class="el">Απενεργοποιεί προσωρινά τον DHCP server. Το δίκτυό μας σίγουρα έχει το δικό του από το router μας και δεν είναι καλό αυτά τα δύο να λειτουργούν ταυτόχρονα. Κάποια δικτυακή συσκευή θα μπορούσε να πάρει τις ρυθμίσεις που στέλνει το coYaght και να μην έχει πρόσβαση στο διαδίκτυο.</li>
<li class="el"><b>Προσθέτει</b> μια IP διεύθυνση στον σύνδεσμο ethernet. Τώρα το coYaght <i>ακούει</i> και στις δύο διευθύνσεις (192.168.111.10 και 192.168.1.16).</li>
<li class="el">Σβήνει το default route μιας και δεν υπάρχει σύνδεση internet σε αυτή</li>
<li class="el">Προσθέτει ως default route το router του δικτύου μας, ώστε να έχει το coYaght πρόσβαση στο διαδίκτυο για updates και εγκαταστάσεις άλλων προγραμμάτων</li>
</ul>
<p class="el">Τώρα πρέπει να δηλωθεί ως εκτελέσιμο:</p>
<div class="code">
<pre>pi@coyaght:~ $ chmmod +x bin/initnet.sh</pre>
</div><br />
<p class="el">Τώρα, όταν συνδέουμε το coYaght στο δικό μας δίκτυο μπορούμε να μπαίνουμε με <code>ssh</code> και να τρέχουμε το script που μόλις φτιάξαμε με:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo bin/initnet.sh</pre>
</div><br />
<p class="el">Είναι, πλέον ώρα, να αρχίσουμε να λειτουργούμε το Raspberry Pi μέσω δικτύου. Το απενεργοποιούμε και μπορουμε να το συνδέσουμε στ δίκτυό μας με ένα καλώδιο:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo shutdown -h now</pre>
</div><br />
<h3 class="el">Σύνδεση σε δικό μας τοπικό δίκτυο</h3>
<p class="el">Στην κατάσταση που βρίσκεται αυτή τη στιγμή το Raspberry Pi δεν έχει πρόβλημα να συνδεθεί στο δικό μας τοπικό δίκτυο, όσο το προετοιμάζουμε για το coYaght. Αν θέλετε, πλέον μπορείτε να του αποσυνδέσετε το πληκτρολόγιο, το ποντίκι και την οθόνη. Είναι ρυθμισμένο για να μπορούμε να το χρησιμοποιούμε μέσω δικτύου.</p>
<p class="el">Αυτό που θα πρέπει να προσέξουμε είναι πως όταν το συνδέσουμε στο δίκτυό μας, το Raspberry Pi ήδη τρέχει ένα DHCP server. Αν τον αφήσουμε έτσι, τότε αν προσπαθήσει να συνδεθεί κάποια άλλη συσκευή, δύο DHCP servers, ένας από το router του δικτύου μας κι ένας από το Raspberry Pi, θα στείλουν ρυθμίσεις. Η συσκευή έχει πιθανότητες να πάρει τις ρυθμίσεις του τελευταίου και να μη μπορεί να επικοινωνήσει σωστά ούτε με τις συσκευές του δικτύου, ούτε με το internet. Έτσι, θα πρέπει με το που ενεργοποιηθεί να συνδεθούμε και να τρέξουμε το script που φτιάξαμε τελευταίο.</p>
<p class="el">Για να μπορέσουμε να συνδεθούμε θα πρέπει οι ρυθμίσεις της κάρτας δικτύου μας να είναι για το ίδιο υποδίκτυο που θεωρεί το Raspberry, δηλάδη το 192.168.111.0/24. Ανάλογα, λοιπόν, με το λειτουργικό που τρέχει ο υπολογιστής μας θα πρέπει να κάνουμε τις κατάλληλες ρυθμίσεις στην κάρτα δικτύου. Στην περίπτωση που και ο υπολογιστής μας τρέχει κάποια διανομή Linux μπορούμε να δώσουμε τις ακόλουθες εντολές σε μια κονσόλα:</p>
<div class="code">
<pre>eliaschr@pluto:~> su
Password:
pluto:/home/eliaschr # ip address add 192.168.111.11/24 dev eth0
pluto:/home/eliaschr # exit</pre>
</div><br />
<p class="el">Σε διανομές βασισμένες σε Ubuntu, αρκεί να δώσουμε, αντί για τις παραπάνω, μόνο την ακόλουθη:</p>
<div class="code">
<pre>eliaschr@pluto:~> sudo ip address add 192.168.111.11/24 dev eth0</pre>
</div><br />
<p class="el">Θα έχει το ίδιο αποτέλεσμα. Τώρα, μπορούμε πολύ εύκολα να μπούμε στο Raspberry Pi και να εκτελέσουμε το Script <code>bin/initnet.sh</code></p>
<div class="code">
<pre>eliaschr@pluto:~> ssh pi@192.168.111.10
pi@192.168.111.10's password:
Linux coyaght 5.4.72-v7+ #1356 SMP Thu Oct 22 13:56:54 BST 2020 armv7l
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Mon Nov 9 18:35:46 2020 from 192.168.111.11
SSH is enabled and the default password for the 'pi' user has not been changed.
This is a security risk - please login as the 'pi' user and type 'passwd' to set a new password.
pi@coyaght:~ $ sudo bin/initnet.sh
The network is ready.
pi@coyaght:~ $ </pre>
</div><br />
<p class="el">Πλέον το σύστημα είναι εναρμονισμένο με το δικό μας δίκτυο και μπορούμε να κάνουμε όλους τους υπόλοιπους χειρισμούς για να το ολοκληρώσουμε.</p>
<h3 class="el">Εγκατάσταση Arduino Software</h3>
<p class="el">Είναι ώρα να εγκαταστήσουμε προγράμματα. Μιας και το Raspberry Pi θα συνδεθεί με ένα Arduino μέσω USB θύρας, καλό είναι να έχουμε μέσα τα προγράμματα που μας χρειάζονται για να μπορούμε να κάνουμε και τον προγραμματισμό του τελευταίου. Αυτό θα μας βοηθήσει να μπορούμε να πειράζουμε το Firmware του ακόμα κι όταν τα ηλεκτρονικά κυκλώματα είναι αεροστεγώς κλεισμένα μέσα στο κουτί από plexiglass. Το βασικό πρόγραμμα που χρειαζόμαστε είναι το <code>arduino-cli</code>, αλλά για λόγους πληρότητας θα εγκαταστήσουμε και το περιβάλλον του Arduino IDE. Από τις ακόλουθες εντολές, οι δύο πρώτες είναι για να αναβαθμιστούν τα ήδη εγκαταστημένα πακέτα. Είναι μια διαδικασία που μας βοηθάει να έχουμε τις πιο πρόσφατες ενημερώσεις του λογισμικού μας:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get update
.
.
.
pi@coyaght:~ $ sudo apt-get upgrade
.
.
.
pi@coyaght:~ $ sudo apt-get install arduino
.
.
.
pi@coyaght:~ $ sudo apt-get install avrdude
.
.
.
pi@coyaght:~ $ sudo apt-get install avrdude-doc
.
.
.
pi@coyaght:~ $ mkdir Downloads
pi@coyaght:~ $ cd Downloads/
pi@coyaght:~ $ curl -fsSL https://raw.githubusercontent.com/arduino/arduino-cli/master/install.sh | sh
.
.
.
pi@coyaght:~ $ mv bin/ ..
pi@coyaght:~ $ cd ..
</pre>
</div><br />
<p class="el">Τώρα θα πρέπει να ρυθμίσουμε το <code>arduino-cli</code> για να μπορεί να δει το Arduino μας:</p>
<div class="code">
<pre>pi@coyaght:~ $ arduino-cli config init
.
.
pi@coyaght:~ $ arduino-cli core update-index
.
.
pi@coyaght:~ $ arduino-cli core install arduino:avr</pre>
</div><br />
<p class="el">Μετά από αυτές τις εντολές, το <code>arduino-cli</code> θα μπορεί να δει κανονικά το Arduino μας και να το προγραμματίσει. Πώς, όμως, μπορεί να γίνει αυτό; Η δύναμη του <code>arduino-cli</code> είναι πως μπορεί να φορτώσει στο Arduino οποιδήποτε <code>.hex</code> αρχείο θελήσουμε. Για να δημιουργήσουμε το αρχείο <code>.hex</code> της εφαρμογής μας, μπορούμε να το κάνουμε στον υπολογιστή, στον οποίο κάνουμε και την ανάπτυξή του. Έχοντας την εφαρμογή του Arduino ανοιχτή στο Arduino IDE, πατάμε το πλήκτρο <i>Verify</i>. Στο κάτω τμήμα του παραθύρου βλέπουμε τα μηνύματα της μεταγλώτισσης. Στο τέλος, μπορούμε να δούμε σε ποιο κατάλογο καταχωρεί το τελικό εκτελέσιμο αρχείο που δημιουργήθηκε. Στη δικιά μας περίπτωση το αρχείο λέγεται <code>/tmp/arduino_build_361228/hydrosensor_shield.ino.elf</code>. Κάθε φορά που τρέχουμε το περιβάλλον ανάπτυξης, αυτός ο κατάλογος αλλάζει, γι' αυτό και πρέπει να το κοιτάζουμε κάθε φορά. Στον ίδιο κατάλογο βρίσκεται και το αρχείο που θα πούμε στο <code>arduino-cli</code> να στείλει στο arduino του coYaght.</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpTbQaJ4lKG-sc2s1IkUCNthoK2KX-rHbE_CsIYzRzZJW6uX6120K4CmR0vDob2veEsGLFPcI2LSQKOodX_U9C4PzghRoPKgDqNmGz9-KrjqyMzFyTtJUESv8c0115oWDZrtoMAs5Hkuv0/s691/Arduino+Compilation.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" data-original-height="591" data-original-width="691" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjpTbQaJ4lKG-sc2s1IkUCNthoK2KX-rHbE_CsIYzRzZJW6uX6120K4CmR0vDob2veEsGLFPcI2LSQKOodX_U9C4PzghRoPKgDqNmGz9-KrjqyMzFyTtJUESv8c0115oWDZrtoMAs5Hkuv0/s600/Arduino+Compilation.png"/></a></div>
<p class="el">Αρχικά θε πρέπει να αντιγράψουμε το <code>.hex</code> αρχείο στο Raspberry Pi για να προγραμματίσουμε το Arduino. Η εντολή που μας χρειάζεται είναι:</p>
<div class="code">
<pre>eliaschr@pluto:~> scp /tmp/arduino_build_361228/hydrosensor_shield.ino.hex pi@192.168.111.10:/home/pi/Dow
nloads/
pi@192.168.111.10's password:
hydrosensor_shield.ino.hex 100% 29KB 29.0KB/s 00:00
</pre>
</div><br />
<p class="el">Αν συνδέσουμε το Arduino στο Raspberry Pi, τότε στο τελευταίο δημιουργείται μια σειριακή πόρτα με την ονομασία <code>/dev/ttyACM0</code>. Μέσω αυτής είναι που γίνεται η επικοινωνία μεταξύ των δύο. Για να γίνει ο προγραμματισμός, πρέπει να μπούμε στον κατάλογο που γράψαμε το <code>.hex</code> αρχείο και να χρησιμοποιήσουμε το <code>arduino-cli</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ cd Downloads/
pi@coyaght:~/Downloads $ arduino-cli upload -b arduino:avr:uno -p /dev/ttyACM0 -t -v -i hydrosensor_shiel
d.ino.hex
.
.
</pre>
</div><br />
<p class="el">Μόλις τελειώσει η διαδικασία, το arduino θα τρέχει τον κώδικα που του στείλαμε.</p>
<h3 class="el">Arduino Firmware</h3>
<p class="el">Τον τελικό κώδικα του firmware μπορεί κανείς να τον κατεβάσει από το <a href="https://github.com/eliaschr/coYaght/tree/master/HydroSensors">GitHub</a>. Θα πρέπει να κατεβάσετε τα τέσσερα αρχεία <code>.ino</code> και να τα τοποθετήσετε μέσα σε ένα κατάλογο με το όνομα <code>hydrosensor_shield</code>. Από εκεί μπορείτε να ανοίξετε το <code>hydrosensor_shield.ino</code> με το περιβάλλον προγραμματισμού Arduino IDE, να το παραλάξετε και να το λειτουργήσετε όπως επιθυμείτε. Μπορείτε να το κάνετε compile με το πλήκτρο <i>Verify</i> και να το στείλετε στο Arduino σας.</p>
<p class="el">Ο κώδικας του firmware είναι βασισμένος στον κώδικα που δίνει το <i><a href="http://www.eugenfound.edu.gr">Ευγενίδιο Ίδρυμα</a></i> στο αντίστοιχο project <i><a href="http://www.hydrobots.gr">Hydrobot</a></i>. Φυσικά έχουν γίνει αρκετές τροποποιήσεις για να μπορέσει να έρθει στα "μέτρα" του coYaght. Έχει απενεργοποιηθεί το τμήμα που ασχολείται με την SD κάρτα μνήμης, έχουν προστεθεί εντολές και παραμετροποιήσεις κι έχει παραλλαχθεί το μήνυμα των μετρήσεων που δίνει στη σειριακή θύρα, έτσι ώστε να ταιριάζει καλύτερα στο δικό μας σύστημα.</p>
<p class="el">Στη σελιδα του <a href="https://github.com/eliaschr/coYaght/tree/master/HydroSensors">GitHub</a> υπάρχουν διαθέσιμες πληροφορίες για τον κώδικα του firmware. Τα ίδια τα αρχεία περιέχουν αρκετές πληροφορίες μέσα. Έτσι, μπορείτε να δείτε με λεπτομέρειες τον τρόπο με τον οποίο λειτουργεί όλο το firmware.</p>
<h3 class="el">Προετοιμασία βάσης δεδομένων MySQL</h3>
<p class="el">Το σύστημά μας χρησιμοποιεί μια βάση δεδομένων για να καταχωρεί τις μετρήσεις έτσι ώστε όταν χρειαστεί να μπορέσουμε να τις ξαναδούμε. Η επιλεγμένη βάση δεδομένων είναι η <b>MySQL</b> (ή σε νεότερες εκδόσεις, <i>mariaDB</i>). Για να την εγκαταστήσουμε αρκεί η εντολή:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get install mariadb-server</pre>
</div><br />
<p class="el">Αρχικά η MySQL είναι ρυθμισμένη με ανοικτό το χρήστη <code>root</code>, τη σύνδεση νέσω δικτύου κλπ. Καλό είναι να γίνουν οι απαραίτητες ρυθμίσεις για τη θωράκιση του συστήματος:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo mysql_secure_installation</pre>
</div><br />
<p class="el">Με αυτή την εντολή μπορούμε να ρυθμίσουμε ένα password της αρεσκείας μας για το χρήστη <code>root</code>, να σβήσουμε τους ανώνυμους χρήστες, να απαγορέψουμε την πρόσβαση στη βάση δεδομένων από τον χρήστη <code>root</code> απομακρυσμένα και να σβήσουε την πρoτοποθετημένη βάση δεδομένων <code>test</code>. Φυσικά δεν ξεχνάμε να πούμε να επαναφορτωθούν τα δικαιώματα των χρηστών του εξυπηρετητή.</p>
<p class="el">Το σύστημα του coYaght χρειάζεται ένα δικό του χρήστη και μια δικιά του βάση με τους δικούς της πίνακες. Ας δούμε πως θα γίνουν όλες αυτές οι ρυθμίσεις. Πρώτα θα δημιουργήσουμε τη βάση δεδομένων και τον χρήστη της:</p>
<div class="code">
<pre>pi@coyaght:~ $ mysql -u root -p
Enter password:
.
.
</pre>
</div><br />
<p class="el">Στο σημείο αυτό έχουμε μπει στον server της MySQL. Ας δημιουργήσουμε τη βάση δεδομένων και τον χρήστη της:</p>
<div class="code">
<pre>MariaDB [(none)]> CREATE DATABASE coYaght;
CREATE USER 'coyaght'@localhost IDENTIFIED BY 'coYaght_Gerakas';
GRANT ALL PRIVILEGES ON coYaght.* TO 'coyaght'@localhost;
FLUSH PRIVILEGES;
EXIT;</pre>
</div><br />
<p class="el">Σειρά έχει το να φτιάξουμε τον πίνακα που θε κρατάει τις μετρήσεις από τους αισθητήρες. Ο πίνακας θα πρέπει να έχει επτά στήλες. Ο τρόπος δημιουργίας του φαίνεται ακολούθως:</p>
<div class="code">
<pre>pi@coyaght:~ $ mysql -u coyaght -p
Enter password:
.
.
MariaDB [(none)]> USE coYaght;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
MariaDB [coYaght]> CREATE TABLBE `measurements` (
-> `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
-> `DateStamp` DATETIME NOT NULL,
-> `Temp` DECIMAL(5,2) NOT NULL,
-> `Press` DECIMAL(8,2) NOT NULL,
-> `Depth` DECIMAL(7,3) NOT NULL,
-> `Lux` DECIMAL(7,2) NOT NULL,
-> `Batt` DECIMAL(4,2) NOT NULL,
-> PRIMARY KEY (`id`),
-> UNIQUE KEY `DateStamp` (`DateStamp`)
-> ) ENGINE=InnoDB DEFAULT CHARSET=utf8;</pre>
</div><br />
<p class="el">Τώρα η βάση δεδομένων του coYaght είναι έτοιμη να δεχθεί δεδομένα.</p>
<h3 class="el">Προετοιμασία Python</h3>
<p class="el">Για να λειτουργήσει το σύστημα, ο server που δημιουργούμε έχει γραφτεί σε python 3. Αυτό σημαίνει πως χρειάζονται τα κατάλληλα modules για να μπορέσει να γίνει χρήση της βάσης δεδομένων, της κάμερας και της σειριακής πόρτας. Το σύστημα πρέπει να έχει τη δυνατότητα να χρησιμοποιεί <i>νήματα</i> για να μπορεί να στέλνει δεδομένα από την κάμερα, να ελέγχει τα δεδομένα από τη σειριακή πόρτα και να στέλνει σε αυτήν εντολές. Όλα αυτά είναι ασύγχρονα κι έτσι δε θα μπορούσε ποτέ να γίνει με άλλο τρόπο.</p>
<p class="el">Για να εγκαταστήσουμε τη βιβλιοθήκη που μας δίνει πρόσβαση στην κάμερα, εκτελούμε την εντολή:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get install python3-picamera ffmpeg python3-ws4py</pre>
</div><br />
<p class="el">Η βιβλιοθήκη χρήσης της κάμερας από την python είναι η picamera. Η βιβλιοθήκη <code>ffmpeg</code> είναι για επεξεργασία της εικόνας της κάμερας. Κανονικά δεν είναι απαραίτητη, αλλά μπορεί να μας φανεί χρήσιμη σε κάποιες περιπτώσεις test. Τέλος η βιβλιοθήκη <code>ws4py</code> δίνει τη δυνατότητα στην python να χρησιμοποιεί web sockets. Είναι χρήσιμη για το video streaming που θέλουμε να πετύχουμε. Οι δύο τελευταίες βιβλιοθήκες μας χρειάστηκαν κατά τη διάρκεια ανάπτυξης του κώδικα του συστήματος για διάφορα test. Δεν είναι απαραίτητες για την τελική λειτουργία του coYaght.</p>
<p class="el">Για να εγκαταστήσουμε την κατάλληλη βιβλιοθήκη χρήσης της σειριακής πόρτας θα πρέπει πρώτα να εγαταστήσουμε το <code>pip3</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get install python3-pip</pre>
</div><br />
<p class="el">Τώρα είμαστε σε θέση να εγκαταστήσουμε τη βιβλιοθήκη χρήσης της σειριακής θύρας, <code>pyserial</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo pip3 install pyserial</pre>
</div><br />
<p class="el">Αν δε χρησιμοποιηθεί η εντολή <code>sudo</code> πριν την <code>pip3</code>, τότε η βιβλιοθήκη θα εγκατασταθεί, αλλά τοπικά στο χρήστη και όχι καθολικά στο σύστημα. Παρόλα αυτά θα συνεχίσει να είναι λειτουργική, αλλά πριν τη χρησιμοποιήσουμε ως <code>root</code> θα πρέπει να προσθέσουμε τον κατάλογο <code>/home/pi/.local/lib/python3.7/site-packages</code> στη μεταβλητή συστήματος <code>PYTHONPATH</code>.</p>
<p class="el">Τέλος, θα πρέπει να εγκαταστήσουμε τη βιβλιοθήκη που δίνει τη συνατότητα στην python να έχει πρόσβαση στη MySQL:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo apt-get install python3-pymysql</pre>
</div><br />
<p class="el">Πλέον είναι έτοιμη η python να επικοινωνήσει με όλα τα τμήματα που μας ενδιαφέρουν. Είναι ώρα να στήσουμε τον server μας.</p>
<h3 class="el">coYaght Server</h3>
<p class="el">Στο σύστημα coYaght θα πρέπει να υπάρχει πρόσβαση μέσω ενός web browser ώστε να μην υπάρχει η ανάγκη για εγκατάσταση κάποιας στοχευμένης εφαρμογής. Η ιστοσελίδα που θα εμφανίζεται πρέπει να περιέχει όλα τα απαραίτητα στοιχεία για να μπορούμε να:</p>
<ul>
<li class="el">παρακολουθούμε την κάμερά του</li>
<li class="el">μπορούμε να κάνουμε <i>παύση</i> στο βίντεο που μας δείχνει και να το ξαναεκκινούμε</li>
<li class="el">παρακολουθούμε τις μετρήσεις των αισθητήρων ως γραφικές παραστάσεις</li>
<li class="el">να σταματάμε και ξαναεκκινούμε τις μετρήσεις των αισθητήρων</li>
<li class="el">πλοηγούμε το coYaght μέσα στη θάλασσα</li>
</ul>
<p clas="el">Ο κώδικας του server έχει γραφτεί, όπως προείπαμε, σε python 3. Σαν εναρκτήριος κώδικας υπήρξε αυτός που βρίσκεται στη σελίδα <a href="https://picamera.readthedocs.io/en/latest/recipes2.html#web-streaming">4. Advanced Recipes - Picamera 1.13 documentation</a>. Πάνω σε αυτό τον κώδικα βασίστηκε η ομάδα μας για τη δημιουργία του server.</p>
<p class="el">Φυσικά, το τμήμα της ιστοσελίδας πλοήγησης του coYaght κάνει χρήση τεχνολογιών διαδικυου, HTML, CSS και JavaScript. Το κομμάτι εμφάνισης γραφικών παραστάσεων προέρχεται από τη <a href="https://developers.google.com/chart/">Google - Google Charts</a>.</p>
<p class="el">Τον πλήρη κώδικα μπορείτε να τον δείτε και να τον κατεβάσετε από το <a href="https://github.com/eliaschr/coYaght">GitHub</a>. Εκεί θα βρείτε και αρκετή τεκμηρίωση για τον τρόπο που λειτουργεί ο κώδικας. Επίσης, μέσα στα αρχεία υπάρχει επιπλέον τεκμηρίωση, ώστε κάποιος να μπορέσει να έχει μια καλύτερη καταννόηση της λειτουργίας του κάθε τμήματος κώδικα. Ας δούμε κι εδώ λίγα βασικά πράγματα.</p>
<p class="el">Ο βασικός κώδικας του server (python) αποτελείται από τρία αρχεία:</p>
<ul>
<li class="el"><b>database.py</b>: Δημιουργεί την κλάση με την οποία μπορούμε πολύ εύκολα να έχουμε πρόσβαση στη βάση δεδομένων coYaght της MySQL</li>
<li class="el"><b>serial_arduino.py</b>: Δημιουργεί την κλάση με την οποία μπορούμε να έχουμε πρόσβαση στη σειραική θύρα του arduino. Κάνει χρήση νημάτων για να μπορεί να διαχειριστεί τόσο την αποστολή εντολών προς αυτό, όσο και τη λήψη των μηνυμάτων που στέλνει το arduino. Κάθε γραμμή εισόδου ελέγχεται, τόσο για να πιστοποιηθεί η κατάσταση του συστήματος του arduino, όσο και για να φιλτραριστούν οι πληροφορίες της κάθε γραμμής και αν πρόκειται για πληροφορίες των αισθητήρων, να καταχωρηθούν στη βάση δεδομένων</li>
<li class="el"><b>controller.py</b>: Είναι το κεντρικό πρόγραμμα του server. Κάνει χρήση των άλλων δύο τμημάτων που προαναφέρθηκαν. Εδώ δημιουργείται ο εξυπηρετητής web και φιλτράρονται όλα τα ερωτήματα που αποστέλλονται μέσω δικτύου.</li>
</ul>
<p class="el">Τα αρχεία της ιστοσελίδας που μεταφέρονται στους πελάτες βρίσκονται στον κατάλογο <code>web</code>. Κι εκεί η δομή που χρησιμοποιείται είναι απλή:</p>
<ul>
<li class="el"><b>index.html</b>: Είναι το βασικό αρχείου που δίνει το οπτικό τμήμα της ιστοσελίδας. Το πρώτο αρχείο που διαβάζεται από ένα φυλλομετρητή</li>
<li class="el"><b>images</b>: Ο κατάλογος περιέχει όλες τις εικόνες που συμπληρώνουν το οπτικό κομμάτι της ιστοσελίδας</li>
<li class="el"><b>styles</b>: Περιέχει όλα τα αρχεία <code>.css</code> για την εφαρμογή οπτικών στυλ επάνω στα στοιχεία της ιστοσελίδας</li>
<li class="el"><b>scripts</b>: Περιέχει τα αρχεία της JavaScript που χρησιμοποιούνται για τις λειτουργίες της σελίδας, αλλά και την υπόλοιπη επικοινωνία με τον εξυπηρετητή</li>
</ul>
<p class="el">Η εν λόγω δενδρική δομή βρίσκεται μέσα σε ένα κατάλογο coYaght που φτιάχνουμε μέσα στον κατάλογο του χρήστη. Για να τον δημιουργήσουμε, αρκεί να εκτελέσουμε την ακόλουθη εντολή:</p>
<div class="code">
<pre>pi@coyaght:~ $ mkdir coYaght</pre>
</div><br />
<p class="el">Όταν όλη η δενδρική δομή των αρχείων του server εγγραφεί μεσα στον κατάλογο που μόλις δημιουργήσαμε, τότε μπορούμε να τρέξουμε τον server με την εντολή:</p>
<div class="code">
<pre>pi@coyaght:~ $ cd coYaght
pi@coyaght:~ $ sudo python3 controller.py</pre>
</div><br />
<p class="el">Αν όλα έχουν πάει σωστά, τότε από τον υπολογιστή μας θα μπορούμε να μπούμε στο περιβάλλον του coYaght με τη χρήση του φυλλομετρητή μας (πχ. Firefox). Εκεί θα χρησιμοποιήσουμε τη διεύθυνση IP του coYaght, 192.168.111.10, όπως φαίνεται και στην ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMVNo54lBhQ2dMHdb5S5_WtUYrlEuxXPCcPGe_h0ZKqVe7DZugFD1FvY5qe9wYijXKgQ6RWAo_bghvGxqeNu6Iu-G0aIWwBGFG98IkiGTdW9nYcSqoITUYfiqkQwS_-tHhKioAsEqTW_Pj/s1920/coYaght+Web+Page.png" style="display: block; padding: 1em 0; text-align: center; "><img alt="" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" data-original-height="1034" data-original-width="1920" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhMVNo54lBhQ2dMHdb5S5_WtUYrlEuxXPCcPGe_h0ZKqVe7DZugFD1FvY5qe9wYijXKgQ6RWAo_bghvGxqeNu6Iu-G0aIWwBGFG98IkiGTdW9nYcSqoITUYfiqkQwS_-tHhKioAsEqTW_Pj/s600/coYaght+Web+Page.png"/></a></div>
<p class="gr">Ο λόγος που πρέπει να μπει το <code>sudo</code> μπροστά, είναι πως ο εξυπηρετητής μας <i>ακούει</i> στην πόρτα 80 στην οποία έχει πρόσβαση μόνο ο χρήστης <code>root</code> του συστήματος.</p>
<h3 class="el">Αυτόματη εκκίνηση του server με την εκκίνηση του Raspberry Pi</h3>
<p class="el">Το να έχουμε κατασευάσει τον server δεν αρκεί. Θα πρέπει κάθε φορά που ενεργοποιούμε το coYaght να μπαίνουμε με <code>ssh</code> και να τρέχουμε με τις προηγούμενες εντολές το πρόγραμμα. Αυτό δεν είναι καθόλου βολικό. Θα πρέπει ο εξυπηρετητής να ενεργοποιείται αυτόματα όταν εκκινεί το Raspberry Pi. Αυτό σημαίνει πως πρέπει να μετατραπεί σε υπηρεσία.</p>
<p class="el">Το λειτουργικό Linux που τρέχει το Raspberry Pi χρησιμοποιεί τον <code>systemd</code> ώς κύριο τρόπο διαχείρισής του. Αυτός είναι υπεύθυνος, εκτός των άλλων, για τις υπηρεσίες που θα ενεργοποιηθούν. Θα πρέπει, λοιπόν να τον καθοδηγήσουμε να δει το <code>controller.py</code> ως υπηρεσία και να το "σηκωσει" όταν εκκινήσει το λειτουργικό. Το πρώτο πράγμα που κάνουμε είναι να δημιουργήσουμε το αρχείο <code>.service</code>:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo vi /lib/systemd/system/coYaght.service</pre>
</div><br />
<p class="el">Μέσα σε αυτό θα πρέπει να βάλουμε τις ακόλουθες πληροφορίες:</p>
<div class="code">
<pre>[Unit]
Description=coYaght control service. Serves HTTP at port 80
After=multi-user.target
[Service]
Type=simple
ExecStart=/usr/bin/python3 /home/pi/coYaght/controller.py
Restart=on-abort
[Install]
WantedBy=multi-user.target
</pre>
</div><br />
<p class="el">Στη συνέχεια θα πρέπει να γίνει εκτελέσιμο:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo chmod 644 /lib/systemd/system/coYaght.service</pre>
</div><br />
<p class="el">Τέλος, θα πρέπει να πούμε στον <code>systemd</code> να ξαναδιαβάσει τις εγκαταστημένες υπηρεσίες και να ενεργοποιήσει την καινούργια:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo systemctl daemon-reload
pi@coyaght:~ $ sudo systemctl enable coYaght.service
pi@coyaght:~ $ sudo systemctl status coYaght.service
</pre>
</div><br />
<p class="el">Η τελευταία εντολή μας δείχνει την κατάσταση της υπηρεσίας, πλέον, <code>coYaght</code>. Για να την εκκινήσουμε εμείς αρχεί η εντολή:</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo systemctl start coYaght.service</pre>
</div><br />
<p class="el">Σε αυτό το σημείο αν κάνουμε μια επανεκκίνηση στο Raspberry Pi θα πρέπει να λειτουργήσει κανονικά ο server μας χωρίς άλλη παρέμβαση.</p>
<div class="code">
<pre>pi@coyaght:~ $ sudo shutdown -r now</pre>
</div><br />
<h2 class="el" align="center">Χρήση του coYaght</h2>
<div class="separator" style="clear: both;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe-Kjf-SjCeCsxkULoZEHK5a72uY5c93kFIt-EBhBh6hlqbphn5TQZt1lZussEUjH_H1Ao_0zDFZcRTT_emWGLbAEQWvSqVRhN3FfY6JtwGohXFqOwb_qESunv04kJApl9yFRgUNdLXtHZ/s1920/coYaghtUI.gif" style="display: block; padding: 1em 0; text-align: center; "><img alt="" style="-moz-border-radius: 8px; border-radius: 8px; border: 1px solid rgb(255, 255, 170);" width="600" data-original-height="998" data-original-width="1920" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhe-Kjf-SjCeCsxkULoZEHK5a72uY5c93kFIt-EBhBh6hlqbphn5TQZt1lZussEUjH_H1Ao_0zDFZcRTT_emWGLbAEQWvSqVRhN3FfY6JtwGohXFqOwb_qESunv04kJApl9yFRgUNdLXtHZ/s600/coYaghtUI.gif"/></a></div>
<p class="el">Για τη χρήση του coYaght, το πρώτο βασικό πράγμα είναι να συνδεθεί με ένα καλώδιο δικτύου σε έναν υπολογιστή. Αφού το ενεργοποιήσουμε, ο υπολογιστής θα πάρει μια διεύθυνση IP σύμφωνα με όσα προαναφέραμε. Από εκείνη τη στιγμή και μετά, με τη βοήθεια ενός φυλλομετρητή μπορούμε να μπούμε στην ιστοσελίδα του και να το χρησιμοποιήσουμε. Ένα βασικό σημείο είναι πως η αρχική ενεργοποίηση του coYaght πρέπει να γίνει στο επίπεδο της θάλασσας. Δεν εννοούμε πως θα πρέπει να βρίσκεται μέσα στη θάλασσα, αλλά στο επίπεδο 0. Αυτό είναι απαραίτητο γιατί το πρώτο πράγμα που κάνει το arduino είναι να μετρήσει την πίεση που δέχεται ο αντίστοιχος αισθητήρας και να κρατήσει την τιμή ως τιμή επιπέδου της θάλασσας.</p>
<p class="el">Στην είσοδο της σελίδας του συστήματος, βλέπουμε το λογότυπο της DeepSeaRobotix, το οποίο καταλαμβάνει όλη την οθόνη. Στο κάτω μέρος βλέπουμε μια μπάρα κατάστασης που δείχνει πως ο server περιμένει να επικοινωνήσει με το arduino. Όταν αυτό ολοκληρωθεί και υπάρχει κανονική επικοινωνία μεταξύ Raspberry Pi και Arduino, τότε το λογότυπο φεύγει και τοποθετείται στο επάνω αριστερά μέρος, αφήνοντας όλη την υπόλοιπη οθόνη για το περιβάλλον χειρισμού.</p>
<p class="el">Η οθόνη χωρίζεται σε τέσσερα μέρη:</p>
<ul>
<li class="el">Άνω δεξιά τμήμα: Live streaming της κάμερας</li>
<li class="el">Άνω αριστερά τμήμα: Γραφήματα των αισθητήρων</li>
<li class="el">Κάτω δεξιά τμήμα: Πλήκτρα πλοήγησης του coYaght στο οριζόντιο επίπεδο</li>
<li class="el">Κάτω αριστερά τμήμα: Πλήκτρα πλοήγησης του coYaght στο κατακόρυφο επίπεδο</li>
</ul>
<p class="el">Το βίντεο που προέρχεται από την κάμερα του Raspberry Pi είναι ενεργοποιημένο. Κάτω από αυτό υπάρχει ένα πλήκτρο με το οποίο μπορούμε να κάνουμε παύση στο βίντεο ή αν είναι σε παύση να το εκκινήσουμε και πάλι.</p>
<p class="el">Οι γραφικές παραστάσεις των αισθητήρων αρχικά είναι άδειες, ενώ δεν τοποθετούνται μετρήσεις μεσα σε αυτές. Αυτό συμβαίνει γιατί όσο το arduino στέλνει δεδομένα αισθητήρων, αυτά καταγράφονται και στη βάση δεδομένων. Ο ρυθμός των δεδομένων είναι ένα πακέτο ανά δευτερόλεπτο. Αν ξεχαστούμε μπορεί πολύ εύκολα η κάρτα μνήμης να γεμίσει με δεδομένα που στην πραγματικότητα δε χρειαζόμαστε. Έτσι, ο χρήστης θα πρέπει να ενεργοποιήσει τις μετρήσεις όταν χρειάζεται να τις κρατήσει. Για να γίνει αυτό, όπως και στην περιοχή της κάμερας, κάτω από τις γραφικές παραστάσεις των μετρήσεων υπάρχει ένα πλήκτρο που τις εκκινεί όταν είναι σταματημένες ή τις σταματάει όταν οι μετρήσεις καταγράφονται.</p>
<p class="el">Κάτι ακόμα που πρέπει να αναφέρουμε για τις γραφικές παραστάσεις, είναι πως βλέπουμε δύο πίνακες. Ο επάνω περιέχει τα γραφήματα της <b>Πίεσης</b> και της <b>Θερμοκρασίας</b>, ενώ ο κάτω δείχνει τα γραφήματα <b>Φωτεινότητας</b> και <b>Τάσης Τροφοδοσίας</b>. Η μέτρηση της πίεσης ανάγεται και στο βάθος στο οποίο βρίσκεται το coYaght, σε μέτρα. Έχουμε την επιλογή στο επάνω γράφημα να μας δείχνει είτε την πίεση που μετράει ο αισθητήρας σε KPa είτε το βάθος σε μέτρα. Η επιλογή γίνεται με το να επιλέξουμε την κατάλληλη μονάδα μέτρησης κάτω από το γράφημα Πίεσης και Θερμοκρασίας.</p>
<p class="el">Η κίνηση του coYaght γίνεται με τα πλήκτρα που εμφανίζονται στο κάτω μέρος της οθόνης. Επειδή δεν είναι δυνατόν να μπορέσουμε να το χειριστούμε απλά με το ποντίκι μας, παρότι υπάρχει η δυνατότητα, η ομάδα μας σκέφτηκε πως θα είναι ιδιαίτερα πιο χρήσιμο να μπορούμε να χρησιμοποιήσουμε το πληκτρολόγιο ώστε να μπορούμε να το κινούμε ταυτόχρονα τόσο στον κατακόρυφο, όσο και στον οριζόντιο άξονα. Τα πλάτρα που χρησιμοποιούμε είναι τα ακόλουθα:</p>
<ul>
<li class="el"><b>Q</b>: Κίνηση άνω, προς την επιφάνεια της θάλασας</li>
<li class="el"><b>A</b>: Κίνηση κάτω, προς το βυθό</li>
<li class="el"><b>NumPad 8</b>: Κίνηση εμπρός</li>
<li class="el"><b>NumPad 2</b>: Κίνηση πίσω</li>
<li class="el"><b>NumPad 6</b>: Δεξιόστροφη περιστροφή γύρω από τον κάθετο άξονα του coYaght</li>
<li class="el"><b>NumPad 4</b>: Αριστερόστροφη περιστροφή γύρω από τον κάθετο άξονα του coYaght</li>
<li class="el"><b>NumPad 9</b>: Στροφή δεξιά με κίνηση εμπρός</li>
<li class="el"><b>NumPad 3</b>: Στροφή δεξιά με κίνηση πίσω</li>
<li class="el"><b>NumPad 7</b>: Στροφή αριστερά με κίνηση εμπρός</li>
<li class="el"><b>NumPad 1</b>: Στροφή αριστερά με κίνηση πίσω.</li>
</ul>
<h2 class="el">Συμπεράσματα</h2>
<p class="el">Σαν σχολικό project, το coYaght ήταν ένα δυνατό μάθημα. Με τη βοήθειά του η ομάδα τρίφτηκε αρκετά με τις νέες τεχνολογίες και ήρθαν σε επαφή με τον τρόπο που γίνοτναι οι μετρήσεις στο περιβάλλον. Βρέθηκαν αντιμέτωποι με τον τρόπο που λειτουργούν τα υπολογιστικά συστήματα, τον προγραμματισμό, τον τρόπο με τον οποίο λειτουργούν τα δίκτυα επικοινωνιών κλπ.</p>
<p class="el">Ως κατασκευή, το coYaght είναι ένα drone που έχει κάποια μειονεκτήματα, πράγματα που μας δίνουν ιδέες να προχωρήσουμε ακόμα και στην κατασκευή μιας άλλης έκδοσής του, αρκετά καλύτερης από αυτή. Μέσα σε όλα όσα αναφέρθηκαν σε brainstorming με την ομάδα, είναι η λειτουργία με περισσότερους κινητήρες για βελτίωση της σταθερότητας, χρήση επικλινόμετρου για βελτίωση της πλοήγησης, σασί που να είναι 3D εκτυπωμένο, για να μπορεί να αποσυναρμολογείται, κ.α.</p>
<p class="el">Όσον αφορά την εφαρμογή χειρισμού, θα μπορούσε να προστεθεί κώδικας που να συγχρονίζει το RTC με την ημερομηνία και την ώρα του υπολογιστή (μιας και το Raspberry δεν έχει πρόσβαση στο internet για να πάρει την ώρα από εκεί), δημιουργία sessions με ονομασία και στίγμα GPS για το σημείο στο οποίο πρόκειται να γίνουν οι μετρήσεις, ρύθμιση της ταχύτητας των κινητήρων ώστε να έχουμε απόλυτο έλεγχο και στην ταχύτητα με την οποία θα κινείται προς κάθε κατεύθυνση μέσα στο νερό, καταγραφή του βίντεο σε αρχείο στον υπολογιστή μας, επαναφορά μετρήσεων ενός session, ακόμα και την απενεργοποίηση του συστήματος.</p>
<p class="el">Ο σκοπός που δημιουργήθηκε το project αυτό ήταν περισσότερο η τριβή των μαθητών με την τεχνολογία ώστε να γνωρίσουν μονοπάτια της, που με τη βοήθεια του "στεγνού" μαθήματος θα ήταν αδύνατο να συμβεί. Πραγματικά θέλω να ευχαριστήσω τον Διευθυντή του <b>1ου Γυμνασίου Γέρακα</b>, <b>κ. Κουρτέση Θεόδωρο</b>, που με ένταξε στο πρόγραμμα του <b>Junior Achievement</b>, όσο και τα παιδιά της ομάδας που με έκαναν να αισθανθώ και να θαυμάσω τη δύναμη του μυαλού που έχουν αυτές οι ηλικίες:</p>
<ul>
<li class="el">Αδαμαντιάδης Παναγιώτης</li>
<li class="el">Αμερκάνος Ευστράτιος</li>
<li class="el">Δροσάκης Γιάννης</li>
<li class="el">Ζωγράφου Ελένη</li>
<li class="el">Καλαβρού Ελευθερία</li>
<li class="el">Λέκκας Αντώνιος</li>
<li class="el">Μπούκη Αντιγόνη</li>
</ul>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-40159535766163934852015-05-22T00:22:00.000+03:002015-05-26T01:07:35.433+03:00Παιδεία κι Ελληνική Πραγματικότητα<div dir="ltr" style="text-align: left;" trbidi="on">
<p>Το παρόν άρθρο δεν ανήκει ούτε στα ηλεκτρονικά, αλλά ούτε στους υπολογιστές. Ανήκει στο "... και άλλα!". Πιο συγκεκριμένα είναι ο προβληματισμός μου για το ποιόν της Ελλάδας, το τι κουβαλάμε οι Έλληνες μέσα στο κεφάλι μας αλλά και ο προβληματισμός μου σχετικά με το τι τελικά είναι αυτό που εμείς οι Έλληνες θέλουμε. Βαρύ ε;</p>
<p>Θα διηγηθώ μια ιστορία, προσωπική. Η ιστορία εξελίσσεται την ημέρα των πανελλαδικών εξετάσεων του παρόντος έτους (2015). Το νούμερο του έτους το θεωρώ σημαντικό διότι έχουμε ξεφύγει από την αρχαιότητα και τη στενομυαλιά και βαδίζουμε σε σύγχρονα μονοπάτια (πανάθεμά μας), με περισσότερη γνώση (πανάθεμά μας δεύτερη φορά!).</p>
<p>Είναι γνωστό πως εργάζομαι ως εκπαιδευτικός σε δημόσιο τεχνικό λύκειο (ΕΠΑ.Λ.) της χώρας. Αυτό σημαίνει πως κάθε χρόνο η συμμετοχή μου στις πανελλαδικές εξετάσεις ως επιτηρητής είναι δεδομένη. Φέτος βρέθηκα να είμαι επιτηρητής σε ένα γενικό λύκειο, κάπου στο νομό Χανίων.</p>
<p>Πρώτα απ' όλα θα πρέπει να αναφέρω λίγα "γνωστά" πράγματα σχετικά με τις εξετάσεις. Το σύστημα των εξετάσεων είναι πολύ ακριβές και πολύ ευαίσθητο με το θέμα της δολίευσης. Απαγορεύονται ρητά κινητά (τόσο στους μαθητές όσο και στους εκπαιδευτικούς) μέσα στην αίθουσα την ώρα της εξέτασης. Απαγορεύονται τα σκονάκια και οποιοσδήποτε τρόπος αντιγραφής γνώσεων και πληροφοριών. Απαγορεύεται να μιλήσεις σε κάποιον συμμαθητή σου, είτε για να σου πει, είτε για να του πεις. Απαγορεύεται να δημιουργείς φασαρία ενοχλώντας τους συμμαθητές σου. Απαγορεύεται να μεταφέρεις θέματα εκτός τάξης. Και πολλά άλλα. Γι αυτό οι επιτηρητές σε κάθε σχολείο προέρχονται από άλλα σχολεία και άλλες περιοχές, ώστε να μην υπάρχει κάποια περίπτωση γνωριμίας επιτηρητή με εξεταζόμενο. Ότι στραβό συμβεί έχει μόνο ένα αντίκτυπο: τον μηδενισμό του τετραδίου θεμάτων του μαθητή ή των μαθητών οι οποίοι δεν συμμορφώνονται με τους κανόνες.</p>
<p>Στις 20 Μαΐου, λοιπόν, επιτηρώ σε ένα σχολείο, κανονικά στη θέση μου, μαζί με κάποια άλλη συνάδελφο. Κάποια στιγμή μια μαθήτρια βάζει ένα σκονάκι στο χέρι της, προσπαθώντας, φυσικά, να το κρατήσει κρυφό. Έλα όμως που την είδαμε, τόσο η συνάδελφος όσο κι εγώ. Τελικά της παίρνω το σκονάκι, το παραδίδω στη Λυκειακή Επιτροπή, η οποία είναι υπεύθυνη για περαιτέρω διερεύνηση του θέματος και το λογικό αποτέλεσμα του μηδενισμού του τετραδίου της εξεταζομένης.</p>
<p>Μετά τη λήξη της εξέτασης, μίλησα με τη Λυκειακή Επιτροπή για τη μαθήτρια, η οποία, όπως ακριβώς μου είπαν, είναι μια μαθήτρια άριστη, η οποία δεν είναι τύπος που γενικά κάνει σκονάκια, φιλότιμη και γενικά τη στόλισαν με τα καλύτερα λόγια, κυριολεκτικά! Εδώ θα προσθέσω και το (όχι μόνο) δικό μου σχόλιο πως πίσω από ένα καλό μαθητή κρύβεται και μια οικογένεια επίσης καλή. Γιατί μια τέτοια μαθήτρια να έχει την ανάγκη να κάνει σκονάκι για να βοηθηθεί στις εξετάσεις; Στην πραγματικότητα δεν υπάρχει λόγος, πέρα από το άγχος της να γράψει καλά σε ένα μάθημα με αυξημένη για εκείνη βαρύτητα. Η κοπέλα είχε λύσει το θέμα και στη συνέχεια έβγαλε το σκονάκι για να σιγουρέψει πως λειτούργησε με το σωστό τρόπο στην απάντησή της. Παρόλα αυτά, το σύστημα είναι αυστηρό και αυτό της βγήκε... ξινό με το να χάσει παντελώς το μάθημα.</p>
<p>Ως εδώ, καλά (αν μπορεί πραγματικά να το πει κανείς έτσι). Το πρόβλημα "ξεκινάει" από εδώ και πέρα (και μιλάω για το πραγματικό πρόβλημα της νοοτροπίας των Ελλήνων).</p>
<p>Το απόγευμα κάποιος μου χτύπησε την πόρτα ΤΟΥ ΣΠΙΤΙΟΥ ΜΟΥ! Όταν άνοιξα, είδα έναν αγχωμένο-τσαντισμένο άντρα ο οποίος έβγαλε την πρώτη του κουβέντα: "Ο κύριος Χρυσοχέρης;". Φυσικά αποκρίθηκα θετικά. Και συνεχίζει "Δεν ήρθα εδώ για να δημιουργήσω κανένα πρόβλημα!". Εκεί, προφανώς η απορία στο πρόσωπό μου ήταν εμφανής. "Γιατί να δημιουργήσετε πρόβλημα;" του απάντησα. Και παίρνω το κεραμίδι στο κεφάλι: "Είμαι ο πατέρας της κοπελιάς από το πρωί". Εκεί, νομίζω πως η φάτσα μου θύμιζε λίγο τις φάτσες που ζωγραφίζει ο Αρκάς στα κόμικς του!</p>
<p>Ο κύριος, πατέρας της κοπελιάς που είχε γίνει το πρωινό επεισόδιο, ήρθε να με ρωτήσει, επικριτικά πάντα, γιατί έκανα σωστά τη δουλειά μου! Έπρεπε, σύμφωνα με τα δικά του λόγια, να πετάξω το σκονάκι και να αφήσω την κοπελιά να γράψει σα να μην συνέβαινε τίποτα. Το γεγονός βέβαια πως το σκονάκι το είδαν και όλοι οι υπόλοιποι εξεταζόμενοι δεν παίζει κανένα ρόλο, έτσι; Και φυσικά σαν ισχυρό συστατικό της στήριξης της γνώμης του ήταν το "έπρεπε να πάτε με το γράμμα του νόμου; Δηλαδή εσείς είστε καθόλα νόμιμος;". Δε νομίζω πως του άρεσε η απάντηση πως οι παρανομίες μου περιορίζονται στην μη τήρηση των ορίων ταχύτητας σε κάποιους δρόμους κι αυτό όταν είμαι μόνος, χωρίς άλλους οδηγούς! Μετά από λίγη, ας το πούμε συζήτηση (γιατί όπως είναι φυσικό ένας άνθρωπος σε μια τέτοια ψυχολογική κατάσταση δεν ακούει ποτέ τον αντίλογο και δεν κάθεται ποτέ να συζητήσει με ψυχραιμία) έλαβα και το ωραίο σχόλιο: "Νομίζω πάντως πως με αυτή τη στάση σας θα έχετε γενικότερα προβλήματα!". Για να είμαι ειλικρινής το εξέλαβα λίγο ως απειλή!</p>
<p>Πέρα από τα στενά όρια του συμβάντος και των απειλών και των δικαιολογιών κ.λ.π, κ.λ.π. εμένα τριγυρίζει στο μυαλό μου κάτι γενικότερο στον Έλληνα (καλά, δεν πιστεύω πως είναι μόνο στον Έλληνα, αλλά αυτή τη στιγμή αυτόν θα κοιτάξω). Το κομμάτι που κρατάω είναι το: Βρίσκω ποιος είναι αυτός που (θεωρώ πως) μου δημιούργησε πρόβλημα, μαθαίνω που μένει και πάω κατάμουτρα να τον "βρίσω"-απειλήσω γιατί έκανε τη δουλειά του όπως έπρεπε να την κάνει! Για μένα φυσικά αυτός δεν ανήκει στο οικογενειακό μου περιβάλλον (κοινώς δεν φταίει η κοπελιά που έβγαλε σκονάκι κατά τη διάρκεια της εξέτασης, αλλά ο επιτηρητής που την έπιασε!). Με την ίδια λογική, αν εμένα με σταματήσει ένας τροχονόμος και μου κόψει κλήση (θα έλεγα τι άλλο θα μου κόψει κανονικά, αλλά τέλος πάντων) για υπερβολική ταχύτητα, εγώ θα πάω ΣΠΙΤΙ ΤΟΥ να του ζητήσω τα ρέστα! Αντί να κοιτάξουμε πως η παιδεία (και πιστεύω στοχευμένα) έχει καταλήξει να είναι μια φαντασίωση στην Ελλάδα, κοιτάμε πάντα να πετύχουμε το στόχο μας με τον πλάγιο τρόπο. Αν κάποιος κάνει τη δουλειά του σωστά και με εμποδίσει να πετύχω το στόχο μου, τότε τον απειλώ. Αν ο ίδιος δεν κάνει τη δουλειά του σωστά αμέσως θα του κολλήσω τη ρετσινιά. Και για να το φέρω στο επάγγελμά μου, αν κάνω σωστά τη δουλειά μου και αποτρέψω τη δολιοφθορά των εξετάσεων, έχω πρόβλημα με τη στάση μου! Αν αφήσω τους μαθητές να αντιγράψουν και κάτσω απλά σε μια γωνία και σφυρίζω αδιάφορα για να μπορέσει να γίνει κάτι τέτοιο, είμαι αυτό το κάθαρμα που έριξα την Ελλάδα έξω με το να πληρώνομαι και να μην κάνω τίποτα! Το γεγονός όμως πως αν κάποιος αντιγράψει και βρεθεί στη σχολή που ήθελε να μπει η κόρη σου φίλε συμπατριώτη, πετώντας την έξω από τη σχολή, αυτό δε θα σε έκανε έξω φρενών; Γιατί αυτό πιθανόν θα είχε συμβεί αν δεν έκανα καλά τη δουλειά μου (εγώ ΚΑΙ οι συνάδελφοί μου)</p>
<p>Ο Έλληνας το μόνο που θέλει είναι να πετυχαίνει χωρίς να κοπιάζει. Είναι παρτάκιας και το μόνο που τον ενδιαφέρει είναι ο εαυτός του! Μήπως τελικά αυτό που έχει αδειάσει την Ελλάδα από τα δυνατά μυαλά και τους σοβαρούς επιστήμονες που διαπρέπουν στο εξωτερικό, είναι αυτή ακριβώς η νοοτροπία; Μήπως όλοι αυτοί που φεύγουν από αυτό τον "ευλογημένο" (να ξαναπώ το "πανάθεμά μας";) είναι αυτοί που δε μπορούν να συμβαδίσουν με τη νοοτροπία του πλάγιου δρόμου, αυτοί που πασχίζουν και πετυχαίνουν και τους αρέσει να αμείβονται γι' αυτό που καταφέρνουν; Μήπως τελικά τα καλά κεφάλια φεύγουν από την Ελλάδα γιατί δε γουστάρουν να τους καπελώνουν κάποιοι που σκαρφαλώνουν πάνω από αυτούς επειδή έχουν κάποιο γνωστό; Αυτό το αποτέλεσμα κρατάω, όπως επίσης και την καταγγελία του συμβάντος στην αστυνομία γιατί το να έρθει κάποιος στο σπίτι μου και να μου χτυπήσει την πόρτα για να μου κάνει με αυτό τον τρόπο την "παρατήρησή" του δε μου φαίνεται καθόλου... "φιλικό".</p>
<p>Όλα τα παραπάνω, νομίζω πως είναι πολύ καλή τροφή για σκέψη!</p>
<p class="authorname">Ηλίας Χρυσοχέρης</p>
<br /></div>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-6922819640488459982014-06-04T13:48:00.000+03:002014-06-04T13:48:25.181+03:00Σεμινάριο Δικτύων Υπολογιστών για Εκπαιδευτικούς<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6j8mMPIcza-2vdycOC1_3-CRax9hq4l1jh3O4OxXU5nNnRNzBBC6OE40UPtreq4UlUpwlKqzsXAnQFZ5yb3KVNr60bFvyF47tGnHGnJzXxF3v0qdaePs4WJbHfi3k1DXR3LQagv-Ana5P/s1600/20140307_122237.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img style="border:1px solid #FFA;border-radius:8px;-moz-border-radius:8px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6j8mMPIcza-2vdycOC1_3-CRax9hq4l1jh3O4OxXU5nNnRNzBBC6OE40UPtreq4UlUpwlKqzsXAnQFZ5yb3KVNr60bFvyF47tGnHGnJzXxF3v0qdaePs4WJbHfi3k1DXR3LQagv-Ana5P/s320/20140307_122237.jpg" /></a></div>
<p>Στις 6 Μαρτίου 2014, στο Ηράκλειο Κρήτης, οργανώθηκε ένα σεμινάριο δικτύων υπολογιστών για εκπαιδευτικούς του Ηλεκτρονικού Τομέα. Η οργάνωση έγινε από το <b>1ο Εργαστηριακό Κέντρο Ηρακλείου Κρήτης</b> και πιο συγκεκριμένα από τον κ. <b>Μανατάκη Γεώργιο</b>, Διευθυντή του 1ου ΕΚ Ηρακλείου και τον κ. <b>Καζγκούτη Γεώργιο</b>, Υπεύθυνο Τομέα Ηλεκτρονικών του Εργαστηριακού Κέντρου σε συνεργασία με τη Σχολικό Σύμβουλο κ. <b>Σαλωνίδου Αθηνά</b> και το Σχολικό Σύμβουλο Γενικής Παιδαγωγικής Ευθύνης, κ. <b>Τζωρτζάκη Ιωάννη</b>. Το σεμινάριο διεξήχθη στους χώρους του Εργαστηρίου Υπολογιστικών Συστημάτων και Δικτύων του Τομέα Ηλεκτρονικών στο Εργαστηριακό Κέντρο.</p>
<p>Στόχος του σεμιναρίου ήταν η επιμόρφωση των εκπαιδευτικών για την υποστήριξη των μαθημάτων του Τομέα Ηλεκτρονικής, αλλά και του μαθήματος της Ειδικής Θεματικής Δραστηριότητας, όσο και των Ερευνητικών Εργασιών και των υπολοίπων εκπαιδευτικών προγραμμάτων των σχολείων. Το σεμινάριο ξεκίνησε στις 16:00 και διήρκεσε περίπου 6:30 ώρες!...</p>
<p>Το περιεχόμενο κρατήθηκε στα πρώτα βήματα των δικτύων ώστε να μπορέσουν να καλυφθούν και όσοι δεν έχουν ασχοληθεί ποτέ με τη δικτύωση των υπολογιστών και τις δυνατότητές τους. Πιο συγκεκριμένα, η δομή του σεμιναρίου περιέχει:</p>
<ol>
<li>Εισαγωγή</li>
<ul>
<li>Τι είναι δίκτυο</li>
<li>Βασικοί τρόποι λειτουργίας</li>
<li>Δυνατότητες δικτύων - Πλεονεκτήματα / Μειονεκτήματα</li>
<li>Επιπεδοποίηση της επικοινωνίας</li>
<li>Βασικά συστατικά δικτύου (Συσκευές δικτύωσης)</li>
</ul>
<li>TCP/IP - Το βασικό πρωτόκολλο δικτύωσης</li>
<ul>
<li>Επίπεδα TCP/IP</li>
<li>Διευθυνσιοδότηση</li>
<ul>
<li>IPv4</li>
<li>IPv6</li>
</ul>
<li>Servers και Clients / Ports</li>
</ul>
<li>Δρομολόγηση</li>
<ul>
<li>Routing</li>
<li>NAT</li>
<li>Port forwarding</li>
<li>DHCP</li>
</ul>
<li>Ασφάλεια</li>
<ul>
<li>Γενικά περί ασφάλειας</li>
<li>Προστασία του υπολογιστή μας</li>
<li>Κρυπτογράφηση</li>
</ul>
</ol>
<p>Όπως θα είναι κατανοητό, ειδικά το τμήμα της ασφάλειας δε θα μπορούσε ποτέ να είναι ολοκληρωμένο, μιας και το εν λόγω θέμα είναι τόσο ευρύ που ακόμα κι ένα αποκλειστικό σεμινάριο δε θα μπορούσε να είναι αρκετό. Σκοπός είναι απλά οι συμμετέχοντες να κατανοήσουν την ανάγκη της προστασίας των υπολογιστών και του δικτύου από κακόβουλες επιθέσεις</p>
<p>Το εργαστηριακό κομμάτι αφορά στο στήσιμο ενός σχολικού εργαστηρίου με την κατάλληλη δομή, τους servers, δυναμικό DNS για απομακρυσμένη διαχείριση και επίδειξη εγκατάστασης ενός CMS προγράμματος όπως Joomla/Drupal/Wordpress.</p>
<p>Η βιντεοσκόπηση χρειάζεται ακόμα δουλειά για να μπορέσει να αναρτηθεί, αλλά οι διαφάνειες της παρουσίασης βρίσκονται εδώ:</p>
<ul>
<li><a href="https://docs.google.com/uc?id=0B7ISTrXcHVjMS0xFOWpuVFFOMGs">Θεωρητικό κομμάτι (Φυλλάδιο Παρουσίασης)</a></li>
<li><a href="https://docs.google.com/uc?id=0B7ISTrXcHVjMM1dYU1M3VVlGUHc">Θεωρητικό κομμάτι (Διαφάνειες)</a></li>
<li><a href="https://docs.google.com/uc?id=0B7ISTrXcHVjMX2hUTkRBUFJha1E">Εργαστηριακό κομμάτι (Φυλλάδιο Παρουσίασης)</a></li>
<li><a href="https://docs.google.com/uc?id=0B7ISTrXcHVjMOEs5REdWMV9iNHc">Εργαστηριακό κομμάτι (Διαφάνειες)</a></li>
</ul>
<p>Τα φυλλάδια παρουσίασης είναι οι συνολικές διαφάνειες της παρουσίασης, χωρίς τις μεταβάσεις των κειμένων. Όλα τα αρχεία είναι σε μορφή pdf.</p>
<p>Θα ήθελα να ευχαριστήσω θερμά τους κυρίου <b>Τομαδάκη Ιωάννη</b> και <b>Καζγκούτη Γεώργιο</b> που μου έδωσαν την ευκαιρία να βρεθώ εισηγητής του σεμιναρίου.</p>
<br />
<p class="authorname">Ηλίας Χρυσοχέρης</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-90369574802986022642014-05-13T10:51:00.000+03:002014-05-13T10:52:34.804+03:00Ελληνικός Οδηγός Εγκατάστασης openSUSE 13.1<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMacemCpPFQlhHaRInQcZ7xGyP-e3PWGcDRGHpF4dyH-vXV3iKvaAizKCaOiE0ElONk2UCi-HNZKE0wOw9ythy5mJuuIPQWERz5bpUdero1h1CgfufO8fOAQnwbhnZ4ukVlVWi3wwRUxrv/s1600/opensuse.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMacemCpPFQlhHaRInQcZ7xGyP-e3PWGcDRGHpF4dyH-vXV3iKvaAizKCaOiE0ElONk2UCi-HNZKE0wOw9ythy5mJuuIPQWERz5bpUdero1h1CgfufO8fOAQnwbhnZ4ukVlVWi3wwRUxrv/s320/opensuse.png" /></a>
</div>
<p>Για άλλη μια φορά ο οδηγός άργησε να βγει. Λίγο ο φόρτος εργασίας, λίγο κάποια προβληματάκια με το Virtual Box και λίγο το... τεμπέλιασμά μου (ας το πούμε κι έτσι...) έκαναν τον οδηγό να αργήσει. Η προσπάθεια ξεκίνησε τον Ιανουάριο, αλλά τελείωσε τώρα, το Μάιο. Αυτό γιατί ήθελα ταυτόχρονα να τελειώσω και το artwork για τα CD/DVD και τη θήκη τους. Τέλος πάντων, όλα καλά για άλλη μια φορά.</p>
<p>Ο οδηγός εγκατάστασης <a href="http://www.opensuse.org/">openSUSE 13.1</a> βρίσκεται στο <a href="http://wiki.chania-lug.gr/">wiki</a> του ιστότοπου του <a href="http://www.chania-lug.gr/">Συλλόγου Φίλων Ανοικτού Λογισμικού Χανίων</a>. Κάτω από το τμήμα "<a href="http://wiki.chania-lug.gr/index.php/%CE%94%CE%B7%CE%BC%CE%B9%CE%BF%CF%85%CF%81%CE%B3%CE%AF%CE%B1_%CE%A4%CE%B5%CE%BA%CE%BC%CE%B7%CF%81%CE%AF%CF%89%CF%83%CE%B7%CF%82">Τεκμηρίωση</a>" έχει αναρτηθεί και ο εν λόγω οδηγός.</p>
<p>Ο <a href="https://docs.google.com/uc?authuser=0&id=0B7ISTrXcHVjMQ1JFeTBJNmFRU0E&export=download">οδηγός</a> είναι γραμμένος και πάλι με τον τρόπο που να πηγαίνει τον αναγνώστη ένα βήμα παραπάνω από την απλή εγκατάσταση του λειτουργικού. Βοηθάει αρκετά στο να γνωρίσει κάποιος από λίγο κοντύτερα τη βασική παραμετροποίηση του συστήματος και τον τρόπο με τον οποίο μπορεί να το διαχειριστεί· απλά μια ιδέα επάνω σε αυτά χωρίς να γίνεται System Adminitrator...</p>
<p>Ελπίζω, όπως πάντα άλλωστε, να σας φανεί χρήσιμος</p>
<br />
<p class="authorname">Ηλίας Χρυσοχέρης</p>
<br />
</div>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-40031775588009120772014-03-03T00:31:00.000+02:002014-06-04T13:49:04.654+03:00Σειρά Σεμιναρίων Για Εκπαιδευτικούς από το 1ο ΕΚ Ηρακλείου<div dir="ltr" style="text-align: left;" trbidi="on">
<p>Το 1ο ΕΚ Ηρακλείου είναι από το πιο ολοκληρωμένο Εργαστηριακό Κέντρο δευτεροβάθμιας εκπαίδευσης που έχω δεί. Κάθε χρόνο οργανώνουν επιμορφωτικά σεμινάρια για εκπαιδευτικούς. Φέτος η σειρά των σεμιναρίων ξεκινάει με διάλεξη και εργαστήριο δικτύων υπολογιστών:</p>
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKapjm2gHO-rN7bwZyQq4Ci-YCaHNpt-F7HJx3b_h45rDz67lhXhdYQQZPi6Jpaced17VnMR7Vj4xbF0pAU4niXqs3gouEcZqhRZmDi1SAZgYp05UqUfk_ALqHY2hBeveyMz-NHX_0lfz3/s1600/Seminar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKapjm2gHO-rN7bwZyQq4Ci-YCaHNpt-F7HJx3b_h45rDz67lhXhdYQQZPi6Jpaced17VnMR7Vj4xbF0pAU4niXqs3gouEcZqhRZmDi1SAZgYp05UqUfk_ALqHY2hBeveyMz-NHX_0lfz3/s400/Seminar.png" /></a></div>
<p>Για περισσότερες πληροφορίες σχετικά με τα σεμινάρια που διεξάγωνται, καθώς και αίτηση αν επιθυμείτε να παρακολουθήσετε κάποια από αυτά, θα βρείτε στο <a href="http://semisek2014.weebly.com/">http://semisek2014.weebly.com/</a>.</p>
<p>Ελπίζω το παράδειγμά τους να εφαρμοστεί και σε άλλες περιοχές της Ελλάδας.</p>
<p class="authorname">Ηλίας Χρυσοχέρης</p>
<br /></div>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-78229592804938242482013-09-21T16:49:00.001+03:002014-03-11T10:07:40.738+02:00Πολυγλωσσικές αναρτήσεις στο blogger.comMultilingual posts on blogger.com<p class="el">Ξεκίνησα το <a href="http://eliaschr.blogspot.gr/">blog μου</a> στο <a href="http://www.blogger.com/">blogger</a> τον Αύγουστο του 2009. Όταν ξεκίνησα αγνοούσα τη δυνατότητα του να έχω πολυγλωσσικές αναρτήσεις. Πίστευα πως όταν χρειαζόταν να κάνω μια ανάρτηση σε άλλη γλώσσα από τη μητρική μου, απλά θα την έκανα. Η έννοια του να έχω μια ανάρτηση σε δύο γλώσσες δεν ήταν κάτι που με απασχολούσε. Λάθος μου!</p>
<p class="en">I started <a href="http://eliaschr.blogspot.gr/">my blog</a> in <a href="http://www.blogger.com/">blogger</a> on August 2009. In the beginning I totally ignored the ability to make multilingual posts. I believed that when I needed to write something in a different language than my native one, I would just use that language. The thought of having a post written in two different languages was something that didn't even pass through my mind. I was wrong!</p>
<p class="el">Όταν άρχισαν να διαβάζουν τις αναρτήσεις μου ακόμα και τα ανήψια μου, εκεί κατάλαβα πόσο σημαντικό είναι οι αναρτήσεις μου να είναι στα Ελληνικά. Ταυτόχρονα, οι αναρτήσεις θα έπρεπε να είναι και στα Αγγλικά (δυστυχώς δε γνωρίζω άλλη γλώσσα) διότι αφορούν τεχνολογικό περιεχόμενο. Συνεπώς, καλό είναι να μπορούν να το καταλάβουν και άλλοι αναγνώστες οι οποίοι ενδιαφέρονται για το αντικείμενο που περιγράφεται, εκτός Ελλάδας. Παράδειγμα υπήρξε ακόμα και στις λίστες του <a href="http://www.freebsd.org/">FreeBSD</a> όπου έκανα αναφορά σε ένα how-to που έχω γράψει, το οποίο όμως είναι γραμμένο στα Ελληνικά. Ο ενδιαφερόμενος φυσικά και δυσκολεύτηκε να πετύχει αυτά που περιέγραφε το άρθρο γιατί ήταν χωμένος μέσα σε εντολές κονσόλας και σε... μεταφραστικό...</p>
<p class="en">When even my siblings started to read my posts, I understood the importance of my posts to be written in Greek. At the same time some posts should be also in English (unfortunately I don't speak any other language than these two) because they are on technological aspects. So, it is a good thing for other readers, others than Greek, that are interested in the subject of the post, to be able to understand it. An example was on <a href="http://www.freebsd.org/">FreeBSD</a> lists when I referenced an article of mine (a how-to) that it was, unfortunately, written in Greek. It was hard for the guy that was interested in the topic to achieve the goal of the post because he fell into terminal commands and... a translator...</p>
<p class="el">Η απόφαση του να προσπαθήσω να κάνω το blog μου δίγλωσσο δεν άργησε (αντίθετα με την υλοποίησή του...).</p>
<p class="en">The decision to convert my blog to multilingual was not that far (as opposed to its implementation...).</p>
<h4 class="el">Τι θα δούμε σε αυτό το άρθρο</h4>
<h4 class="en">What's in this article</h4>
<p class="el">Σε αυτό το άρθρο θα παρουσιαστούν τα ακόλουθα κομμάτια:</p>
<p class="en">In this article the following parts will be presented:</p>
<ul>
<li><a href="#MuLing_BasicNeeds"><span class="el">Πολυγλωσσική λειτουργία - βασικές ανάγκες</span><span class="en">Multilingual Function - Basic Functionality</span></a></li>
<li><a href="#MuLing_LangSel"><span class="el">Επιλογή Γλώσσας</span><span class="en">Language Selection</span></a></li>
<li><a href="#MuLing_Template"><span class="el">Εφαρμογή Προτύπου</span><span class="en">Apply Template</span></a></li>
<li><a href="#MuLing_Struct"><span class="el">Δομικά Στοιχεία</span><span class="en">Structural Components</span></a></li>
<li><a href="#MuLing_CSS"><span class="el">Προσθήκη κανόνων στο CSS</span><span class="en">Adding CSS Rules</span></a></li>
<li><a href="#MuLing_BasicSteps"><span class="el">Βασική Λειτουργία του Κώδικα JavaScript</span><span class="en">Basic Functionality of JavaScript Program</span></a></li>
<li><a href="#MuLing_StepByStep"><span class="el">Ο Κώδικας Βήμα Βήμα</span><span class="en">The Code Step By Step</span></a></li>
<ul style="list-style-type:circle">
<li><a href="#MuLing_SBS_Intro"><span class="el">Ορισμοί Γενικών Μεταβλητών</span><span class="en">Global Variables</span></a></li>
<li><a href="#MuLing_SBS_Flags"><span class="el">Προσθήκη Εικονιδίων Σημαίων Επιλογής Γλώσσας στον Τίτλο</span><span class="en">Adding Small Selection Flags On Post Title</span></a></li>
<li><a href="#MuLing_SBS_URLParam"><span class="el">Ανάγνωση Παραμέτρου από τη URL</span><span class="en">Read URL Parameters</span></a></li>
<li><a href="#MuLing_SBS_Cookies"><span class="el">Διαχείριση Cookies</span><span class="en">Cookies Manipulation</span></a></li>
<li><a href="#MuLing_SBS_LangGet"><span class="el">Απόφαση Γλώσσας Αναγνώστη</span><span class="en">Readers Language Decision</span></a></li>
<li><a href="#MuLing_SBS_LangApply"><span class="el">Εφαρμογή Γλώσσας Στις Αναρτήσεις</span><span class="en">Apply Language Selection On Posts</span></a></li>
<li><a href="#MuLing_SBS_Last"><span class="el">Τελευταίες Πινελιές στον Κώδικα</span><span class="en">Some Code's Finishing Touches</span></a></li>
</ul>
<li><a href="#MuLing_Program"><span class="el">Το Συνολικό Πρόγραμμα της JavaScript</span><span class="en">The Whole JavaScript Program</span></a></li>
<li><a href="#MuLing_Example"><span class="el">Παράδειγμα Χρήσης</span><span class="en">An Example Of Usage</span></a></li>
<li><a href="#MuLing_Conclusion"><span class="el">Συμπεράσματα</span><span class="en">Conclusions</span></a></li>
</ul>
<a name="MuLing_BasicNeeds"></a>
<h4 class="el">Πολυγλωσσική λειτουργία - βασικές ανάγκες</h4>
<h4 class="en">Multilingual Function - Basic Functionality</h4>
<p class="el">Για να μπορέσει να γίνει σωστά η λειτουργία της πολυγλωσσικής μορφής ενός άρθρου θα πρέπει το σύστημα τα ακολουθεί κάποιους κανόνες:</p>
<p class="en">For the multilingual form of a post to be correct the system should follow some rules:</p>
<ul>
<li class="el">Όταν κάποιος επισκέπτεται τη σελίδα για πρώτη φορά, το σύστημα θα πρέπει να αποφασίζει σε ποια γλώσσα θα δείξει τα άρθρα.</li>
<li class="en">When somebody visits the web page of the blog for the first time the system should decide what will be the presentation language.</li>
<li class="el">Θα πρέπει ο αναγνώστης να μπορεί να αλλάξει γλώσσα εύκολα.</li>
<li class="en">The reader must be able to change the language presented, easily.</li>
<li class="el">Θα πρέπει να μπορεί το σύστημα να καταλάβει σε ποιες γλώσσες είναι γραμμένο το άρθρο, ώστε να δίνονται οι αντίστοιχες επιλογές στον αναγνώστη.</li>
<li class="en">The system should be able to understand what are the available languages of the post, so only them should be presented to the reader as options.</li>
<li class="el">Όταν ο αναγνώστης κάνει μια επιλογή μιας γλώσσας, το σύστημα θα πρέπει να τη θυμάται.</li>
<li class="en">When the reader makes a language choice, the system should remember it.</li>
<li class="el">Όταν ο αναγνώστης επιστρέψει μια άλλη μέρα στο blog θα πρέπει η πρώτη επιλεγμένη γλώσσα να είναι αυτή που χρησιμοποιήθηκε τελευταία φορά.</li>
<li class="en">When the reader returns to the blog another day, the presentation language should be the one he last used.</li>
<li class="el">Το σύστημα να μπορεί να διαχειριστεί άρθρα τα οποία είναι γραμμένα μόνο σε μια γλώσσα.</li>
<li class="en">The system should be able to handle posts that are written in only one language.</li>
<li class="el">Θα πρέπει να υπάρχει link parameter που να υποχρεώνει την εμφάνιση ενός άρθρου/άρθρων σε συγκεκριμμένη γλώσσα.</li>
<li class="en">There must be a URL link parameter that should force the presentation of a post/article in a specific language.</li>
</ul>
<p class="el">Οι δύο βασικοί τρόποι για να συμβεί κάτι τέτοιο είναι:</p>
<p class="en">The two basic ways of implementing such functionality are:</p>
<ol>
<li class="el">Συγγραφή ξεχωριστού άρθρου για κάθε γλώσσα και χρήση links που να οδηγούν από τη μια γλώσσα στην άλλη</li>
<li class="en">Write of a new post for every language and usage of links to move from one language to the other</li>
<li class="el">Χρήση JavaScript η οποία να εμφανίζει τα στοιχεία HTML της επιλεγμένης γλώσσας και να εξαφανίζει αυτά που ανήκουν στις άλλες.</li>
<li class="en">JavaScript usage to display HTML elements that belong to the selected language and hide the others that belong to others.</li>
</ol>
<p class="el">Ο κάθε τρόπος έχει τα υπέρ και τα κατά του. Ο τρόπος που προτιμάει να χρησιμοποιήσει ο καθένας είναι καθαρά αντικειμενικός. Σε αυτό το blog χρησιμοποιείται ο δεύτερο· χρήση JavaScript.</p>
<p class="en">Each way has its own pros and cons. The choise of the implementation way is just a matter of preference. In that blog we use and describe the latter; JavaScript usage.</p>
<a name="MuLing_LangSel"></a>
<h4 class="el">Επιλογή Γλώσσας</h4>
<h4 class="en">Language Selection</h4>
<p class="el">Για να υλοποιηθεί η διαδικασία της πολυγλωσσικότητας πρώτα απ' όλα θα πρέπει να υπάρχει ο κατάλληλος τρόπος για την επιλογή μιας από τις διαθέσιμες γλώσσας από τον χρήστη. Η εμφάνιση μιας σημαίας για κάθε διαθέσιμη γλώσσα είναι κάτι βολικό για μια τέτοια λειτουργία. Το σημείο και ο τρόπος με τον οποίο θα εμφανίζεται η εν λόγω επιλογή είναι καθαρά θέμα του συγγραφέα του blog στο οποίο θα εφαρμοστεί η πολυγλωσσικότητα. Άλλη μια ιδέα για την επιλογή είναι η εμφάνιση μιας λίστας με τις διαθέσιμες γλώσσες μέσα από την οποία ο χρήστης θα επιλέγει αυτή που επιθυμεί.</p>
<p class="en">For the multilanguage process to be implemented, first of all, there must be a propper way of reader selecting one of the available languages for the post. The presentation of a small flag for each available language option is very convenient for that purpose. The layout, the way of presentation and the part of the page that will host the language selection is only a matter of preference of the blog's writer. Another idea is to present a dropdown list of the available languages through which the user can apply his/her language choise.</p>
<p class="el">Στο παρόν blog κρίθηκε κατάλληλο το να εμφανίζονται όλες οι διαθέσιμες επιλογές επάνω στον τίτλο του κάθε άρθρου, έτσι ώστε ο αναγνώστης να βλέπει αμέσως τις διαθέσιμες επιλογές. Κρίθηκε, επίσης, σκόπιμο η γλώσσα στην οποία εμφανίζεται το άρθρο να μην υπάρχει στις διαθέσιμες επιλογές (μιας και δεν υπάρχει νόημα στο να επιλέξει κανείς μια γλώσσα την οποία ήδη χρησιμοποιεί).</p>
<p class="en">At the current blog the decision was to present all the available language options at the right of the post title, so every reader can see at once what are the options he/she has. Also, the flag of the currently presented language not to be presented (as there is no meaning to select a language that is already in use).</p>
<p class="el">Και πως μπορεί να ελέγχεται ποια κομμάτια θα εμφανίζονται, ώστε κάθε φορά με την επιλογή μιας γλώσσας να εμφανίζονται μόνο τα επιθυμητά; Η λύση βρίσκεται στη δυνατότητα της HTML να μπορεί να περιέχει κρυφά και φανερά κομμάτια. Αν με κάποιο τρόπο σηματοδοτήσουμε ότι μια παράγραφος ανηκει στο Ελληνικό κείμενο και μια άλλη ανήκει σε κείμενο μιας άλλης γλώσσας, τότε σαρώνωντας τα δομικά στοιχεία της σελίδας θα μπορούν να αποκρύπτωνται τα στοιχεία που ανήκουν σε γλώσσα εκτός της επιλεγμένης και να εμφανίζονται μόνο αυτά που ανήκουν στην επιλεγμένη. Τα στοιχεία τα οποία δεν έχουν τέτοια σηματοδότηση θα εμφανίζονται πάντα. Ο τρόπος κατά τον οποίο γίνεται εύκολη αυτή η διεργασία της σηματοδότησης είναι, ποιος άλλος, η εφαρμογή μιας κλάσης με το όνομα της γλώσσας στην οποία ανήκει το δομικό στοιχείο. Έτσι, μια παράγραφος που ανήκει στην κλάση "el" ανήκει στο Ελληνικό κείμενο, ενώ μια άλλη που ανήκει στην κλάση "en" θα ανήκει στο Αγγλικό κείμενο.</p>
<p class="en">And how is it possible to control which parts of the post will be visible, so each time a language selection is made, only the propper parts will be presented? The solution lies in the HTML ability of containing non visible elements in a page. If, somehow, there is a kind of note in a paragraph element that it belongs to the Greek text and another note in another pragraph that it belongs to some other language's text, then by scanning all the page's elements the ones that belong to some other language could be forced invisible, and leave visible only the ones of the reader's choice. Every other elements that do not contain such a note will be always visible. The way to apply such a note in every wanted element is, which else, the application of a class with the name of the valid language descriptor. So, if one paragraph belongs to the HTML class "el", it belongs to Greek text, while anothe that belongs to HTML class "en", belongs to English text.</p>
<p class="el">Και πως γίνεται να προσθέσουμε τα δομικά στοιχεία και τον κώδικα που θα εκτελεί όλες τις λειτουργίες; Πρώτα θα πρέπει να δούμε τι εργαλεία υπάρχουν για εφαρμογή θέματος στη σελίδα του blog μας.</p>
<p class="en">And how can we add the bulding code blocks that will perform such functionality? First, we have to see what kind of tools we have for applying a template to our blog.</p>
<a name="MuLing_Template"></a>
<h4 class="el">Εφαρμογή Προτύπου</h4>
<h4 class="en">Apply Template</h4>
<p class="el">Το blogger.com μας δίνει τη δυνατότητα εφαρμογής προτύπων στη σελίδα μας. Δε θα μπορούσε να είναι σελίδα κατασκευής blogs αν δεν υπήρχε αυτή η δυνατότητα. Φυσικά, κάθε πρότυπο έχει και τη δική του δομή. Σε γενικές γραμμές, ο τρόπος που περιγράφεται εδώ είναι ίδιος με αυτόν που μπορείτε να ακολουθήσετε και σε blog με το δικό σας πρότυπο. Λίγο ο κώδικας του προτύπου, λίγο ο <a href="https://getfirebug.com/">firebug</a>, μπορούμε να βρούμε τα δομικά στοιχεία και τον τρόπο με τον οποίο θα κάνουμε τη παρέμβασή μας.</p>
<p class="en">blogger.com offeres the ability to apply templates on our blog page. It would not be a blog spot if it didn't. Of course, every template has its own structure. In general the way described here is the same as the one you have to follow for your blog page with a different template. Well, some template code understanding, some <a href="https://getfirebug.com/">firebug</a> usage, we can hack around and find the bulding blocks of the template and the way to make our intervention in order to achieve our goal.</p>
<p class="el">Ξεκινάμε από την εφαρμογή του προτύπου που μας ενδιαφέρει. Κάνουμε login στο blog μας και εκεί έχουμε τη δυνατότητα να επιλέξουμε πρότυπο εμφάνισης.</p>
<p class="en">Lets start from the application of the template we are interested in. Lets log into our blog; there we have the option to select a template.</p>
<div class="el separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiT9dqOFgMAkns9h32z7Ym1okoai8AWleGcYPmD_B2LruzgYXkurzxnKx32LpuUNvZ57kZNSPc6oob3ZS_f5Yraq9KCsx1t_kt1R9AYZe_60UxFYZcNB5OI7YIrX9lJZldu0Mp6G3aikUj/s1600/BlogTemplate-el.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img class="bordered" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiT9dqOFgMAkns9h32z7Ym1okoai8AWleGcYPmD_B2LruzgYXkurzxnKx32LpuUNvZ57kZNSPc6oob3ZS_f5Yraq9KCsx1t_kt1R9AYZe_60UxFYZcNB5OI7YIrX9lJZldu0Mp6G3aikUj/s400/BlogTemplate-el.png" /></a></div>
<div class="en separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2fXr0UaWIRGbxWLmUtJDqpFDZeuzRZE-7ulOnkTO5JTJxrzwKchzI3ZiZ5yQ5SLE8FbEZg48m-5jm8Iy4Vhi7OwXNJWFS25Gb4EXg6EVrhc_9zqvFdnt013EjT6kFQ8viCxNLkz6YGxtZ/s1600/BlogTemplate.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img class="bordered" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2fXr0UaWIRGbxWLmUtJDqpFDZeuzRZE-7ulOnkTO5JTJxrzwKchzI3ZiZ5yQ5SLE8FbEZg48m-5jm8Iy4Vhi7OwXNJWFS25Gb4EXg6EVrhc_9zqvFdnt013EjT6kFQ8viCxNLkz6YGxtZ/s400/BlogTemplate.png" /></a></div>
<p class="el">Εδώ μπορούμε να κάνουμε επιλογή του προτύπου που μας ενδιαφέρει. Το βασικό, όμως, είναι πως έχουμε τη δυνατότητα να επέμβουμε στον κώδικά του με τη χρήση του πλήκτρου "<i>Επεξεργασία HTML</i>". Με τη χρήση αυτού του πλήκτρου εμφανίζεται μπροστά μας όλος ο κώδικας που φτιάχνει την εμφάνιση της σελίδας μας.</p>
<p class="en">Here is the place to choose the template we like. But, the most important thing is the access to the template's code, using the "<i>Edit HTML</i>" button. Using that we are able to alter the code that forms the visual part of our blog page at will.</p>
<a name="MuLing_Struct"></a>
<h4 class="el">Δομικά Στοιχεία</h4>
<h4 class="en">Structural Components</h4>
<p class="el">Κοιτάζοντας λίγο τον κώδικα του προτύπου μας, μπορούμε να δούμε όλα τα gadgets της σελίδας μας. Εκεί, μπορούμε να δούμε ότι η λίστα με τις αναρτήσεις αποτελείται από:</p>
<p class="en">Looking around at our template's code we can find all the gadgets that are included in our page. Ther we can also find the structure of our posts. It is formed as described:</p>
<ul>
<li class="el">Στοιχείο HTML <tt><div></tt> που ανήκει στην κλάση <tt>blog-posts</tt>. Αυτό περιέχει όλες τις αναρτήσεις που εμφανίζονται στην ιστοσελίδα.</li>
<li class="en">A <tt><div></tt> HTML element that belongs to <tt>blog-posts</tt> class. It contains all the posts that appear on the HTML page.</li>
<li class="el">Μέσα σε αυτό περιέχειται ένα <tt><div></tt> που ανήκει στην κλάση <tt>date-outer</tt>. Αυτό φιλοξενεί τις αναρτήσεις μιας ημέρας.</li>
<li class="en">In there, there is another <tt><div></tt> that belongs to <tt>date-outer</tt> class. It hosts all the posts of the same day.</li>
<li class="el">Το τμήμα των αναρτήσεων μιας ημέρας αποτελείται από μια επικεφαλίδα (στη δικιά μας περίπτωση <tt><h2></tt> που ανήκει στην κλάση <tt>date-header</tt>) που δηλώνει την ημερομηνία που έγιναν οι ακόλουθες αναρτήσεις και ένα <tt><div></tt> που ανήκει στην κλάση <tt>date-posts</tt>. Εκεί μέσα είναι που θα φιλοξενηθούν οι αναρτήσεις της ίδιας ημέρας.</li>
<li class="en">The part of a day's posts is formed by a heading element (in our case it is a <tt><h2></tt> tag tha belongs to <tt>date-header</tt> class) presenting the date of the posts and a <tt><div></tt> element that belongs to <tt>date-posts</tt> class. The latter hosts all the posts of that day.</li>
<li class="el">Κάθε ανάρτηση είναι από μόνη της ένα <tt><div></tt> που ανήκει στην κλάση <tt>post-outer</tt> και περιέχει δύο <tt><div></tt> στοιχεία, ένα που περιέχει την ανάρτησή μας (ανήκει στην κλάση <tt>post</tt>) κι ένα που περιέχει τα σχόλια και τη φόρμα ανάρτησης σχολίων από τους αναγνώστες (ανήκει στην κλάση <tt>comments</tt>). Αυτό που μας ενδιαφέρει, φυσικα, είναι το πρώτο από τα δύο.</li>
<li class="en">Each post is a single <tt><div></tt> that belongs to <tt>post-outer</tt> class and contains two other <tt><div></tt> elements, one for the post's text (it belongs to <tt>post</tt> class) and one containing the comments of the readers and a form for comments posting (it belongs to <tt>comments</tt> class). We are intrested on the first of these two, of course.</li>
<li class="el">Κάθε ανάρτησή μας αποτελείται από τέσσερα βασικά τμήματα. Το πρώτο είναι ο τίτλος, το δεύτερο είναι κάποιου είδους επικεφαλίδα (στη δικιά μας περίπτωση είναι πάντα κενό), το τρίτο είναι το κείμενο της ανάρτησης και το τελευταίο είναι το τέλος της ανάρτησης που περιέχει κοινά στοιχεία σε όλες τις αναρτήσεις, όπως ονομα του συγγραφέα, εικονίδια για διαμοιρασμό της ανάρτησης σε facebook, google+, κ.λ.π.</li>
<li class="en">Each post is formed by four parts. The first is the title, the second is the post's header (in our case it is always empty), the third part is the text of our post and the last one is the post's footer that contains common things to all the posts, like the author of the post, some post sharing buttons to social networks like facebook, google+, etc.</li>
<li class="el">Ο τίτλος της ανάρτησης είναι κάτι που μας ενδιαφέρει. Είναι ένα HTML στοιχείο τύπου <tt><h3></tt> που ανήκει στην κλάση <tt>post-title</tt>. Μας ενδιαφέρει γιατί εκεί θα ενσωματωθούν οι ενδείξεις για τις διαθέσιμες γλώσσες. Επίσης, από τον τίτλο θα μπορεί να καταλάβει ο κώδικας JavaScript και ποιες είναι αυτές οι διαθέσιμες γλώσσες στις οποίες έχει γραφτεί η ανάρτηση.</li>
<li class="en">The title of the post is something we are interested in very much. It is an HTML <tt><h3></tt> element that belongs to <tt>post-title</tt> class. In there will be inserted the necessary indications of the available languages. At the same time, the JavaScript code can understand what are the available languages of the post from the languages that are included in this title.</li>
<li class="el">Το επόμενο κομμάτι της ανάρτησης που μας ενδιαφέρει είναι το HTML στοιχείο <tt><div></tt> που περιέχει το κυρίως κείμενο. Αυτό μας ενδιαφέρει, γιατί εκεί είναι που θα γίνεται η παρέμβαση της JavaScript για να εμφανίσει μόνο τα στοιχεία που ανήκουν στην επιλεγμένη γλώσσα. Το εν λόγω <tt><div></tt> ανήκει στην κλάση <tt>post-body</tt>.</li>
<li class="en">The next part of the post that we are interested in, is the <tt><div></tt> HTML element that contains the main text. There is the most JavaScript code's intervention for showing only the elements that belong to the chosen language. The <tt><div></tt> in question belongs to <tt>post-body</tt> class.</li>
</ul>
<a name="MuLing_CSS"></a>
<h4 class="el">Προσθήκη Κανόνων στο CSS</h4>
<h4 class="en">Adding CSS Rules</h4>
<p class="el">Η πρώτη προσθήκη που έχουμε να κάνουμε στον κώδικα είναι να προσθέσουμε κάποιους κανόνες στο CSS κομμάτι που δηλώνεται μέσα στο πρότυπο που χρησιμοποιούμε για την εμφάνιση της ιστοσελίδας μας. Όταν πατήσουμε το πλήκτρο "<i>Επεξεργασία HTML</i>" που φαίνεται και στο προηγούμενο στιγμιότυπο, κάτω από την προεπισκόπιση της σελίδας μας, μεταφερόμαστε στον κειμενογράφο όπου μπορούμε να "πειράξουμε" τον κώδικα του προτύπου.</p>
<p class="en">The first addition we have to make to the template code is to add some rules in its CSS part. By pressing the "<i>Edit HTML</i>" button that we can see on the previous snapshot, under the template preview, we are transfered to an editor that we can alter the template's code.</p>
<p class="el">Εκεί μπορούμε να βρούμε το σημείο στο οποίο βρίσκονται οι κανόνες CSS που στέλνονται για τη μορφοποίηση της σελίδας. Μια μικρή παρέμβαση που κάνουμε είναι η ακόλουθη:</p>
<p class="en">We can find the part that there are a lot of CSS rules, already, formating our blog's page. A small addition we must make is the following:</p>
<a name="MuLing_CSSCode"></a>
<div class="code"><pre class="prettyprint lang-css">
...<i>Some template code</i>...
<b:skin>
...<i>Some CSS code</i>...
<b>
/*Added for multilingual support*/
.flag {
height:24px;
width:24px;
margin-top:-3px;
background-size:24px;
float:right;
cursor:pointer;
}
.flgen {
background-image:url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhevngcbkeTVwuM79NIvECzw-c8ZDzPx1ueBR_uMxZT79MzzsyOCfd_XnzsChqU2F0sGclwpb5NMTite-y16niyB37Py5plX-SDq7hwsFOWEHkhvds6pdLgrzoIQVKSgtYfXluB47JVymTb/s320/United-Kingdom-flag-icon.png);
}
.flgel {
background-image:url(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMMfgCwXuktRQ6cQlLeCD76uvA_2aHdNmdTrHW-HnsspX4fccXA03KUanP8eI72HyzWk8gMrKp_Y9UntV45F2GGTiQSkfYUSeqSd-MeW_WTjU0xGMQEmH3nt0bJpQ0tkhyw315gEBFbFyZ/s1600/Greece-Flag2.png);
}
en {
display:none;
}
//End of multilingual support edditions
</b>
...<i>Some more CSS code</i>...
</b:skin>
...<i>Some more template code</i>...
</pre></div>
<p class="el">Εδώ χρειάζονται λίγες διευκρινήσεις σχετικά με το τμήμα του κώδικα που προσθέσαμε. Κάθε ένα σημαιάκι που θα εμφανίζεται για την επιλογή γλώσσας θα ανήκει στην κλάση <tt>flag</tt> η οποία ορίζει τα οπτικά χαρακτηριστικά, όπως το μέγεθος και το ότι θα εμφανίζεται στα δεξιά του τμήματος στο οποίο προστίθεται· κοινώς, στα δεξιά στον τίτλο του άρθρου. Για κάθε μια γλώσσα που χρησιμοποιούμε, δημιουργούμε από μια κλάση που έχει όνομα <tt>flg</tt> και το όνομα της γλώσσας. Για την Ελληνική γλώσσα, δηλαδή, η ονομασία της κλάσης είναι η <tt>flgel</tt>, ενώ για την Αγγλική (γενικά) θα είναι <tt>flgen</tt>. Αν υποστηρίζαμε και άλλη μια γλώσσα π.χ. την Ισπανική, τότε θα δημιουργούσαμε ακόμα μια κλάση με όνομα <tt>flges</tt>, μιας και το <tt><i>es</i></tt> είναι το χαρακτηριστικό της Iσπανικής γλώσσας. Κάθε μια από αυτές τις κλάσεις θα εφαρμόζεται στο αντίστοιχο ενδεικτικό σημαιάκι επιλογής γλώσσας, μαζί με την προηγούμενη κλάση που περιγράφηκε και ο μόνος κανόνας που περιλαμβάνεται είναι αυτός που θέτει ως υπόβαθρο την εικόνα της σημαίας που μας ενδιαφέρει να απεικονίζεται. Εδώ μπορείτε να αλλάξετε το URL της εικόνας που χρησιμοποιώ και να θέσετε το δικό σας. Τέλος, για κάθε άλλη γλώσσα, εκτός από αυτή που θέλουμε να είναι προεπιλεγμένη, δημιουργούμε μια κλάση με το όνομα της γλώσσας, όπου κάνουμε το συστατικό που ανήκει σε αυτή να μην εμφανίζεται στην οθόνη μας. Γι' αυτό το λόγο υπάρχει η κλάση <tt>en</tt>, μιας και η προεπιλεγμένη γλώσσα για το παρόν blog θεωρείται η Ελληνική· η Αγγλική αποκρύπτεται. Αν υποστηρίζαμε και την Ισπανική γλώσσα, μιας και δεν είναι η προεπιλεγμένη, θα έπρεπε να δημιουργήσουμε άλλη μια κλάση με το όνομα <tt>es</tt> που να περιέχει τον κανόνα απόκρυψης, δηλαδή το <tt>display:none</tt>.</p>
<p class="en">Here we have to give some clarifications according to the part of the code we just added. Every little flag indicator for language selection will belong to <tt>flag</tt> class. This class sets the common optical characteristics of these flags, like the size, to be presented at the right side of the element that it is added to, meaning the right side of the title, cause that's were we are going to add it, etc. For each language we use, we create a class with name comprised of <tt>flg</tt> and the characteristic name of the language in question. Thus, for the Greek language the name of this class will be <tt>flgel</tt>, and for the English (general) will be <tt>flgen</tt>. If we support another language, lets say the Spanish, we should also create another class named <tt>flges</tt>, since <tt><i>es</i></tt> is the characteristic of this language. Each of these described classes will be applied to the corresponding indicator flag for this language selection, together with the previous one (<tt>flag</tt> class). The only rule they include is the one that sets the background image to the indication we like, meaning the flag image. Here you can set your URL instead of the one I use. Finally, for each other language we use except for the default one, we create a class with its characteristic name, were we make the elements belonging to that class, invisible. That is why there is a CSS rule for <tt>en</tt> class, since the default language in this blog is the Greek one; the English becomes invisible. If we also supported the Spanish language here, then we should create one more rule for <tt>es</tt> class making it invisible, also (having <tt>display:none</tt>).</p>
<a name="MuLing_BasicSteps"></a>
<h4 class="el">Βασική Λειτουργία του Κώδικα JavaScript</h4>
<h4 class="en">Basic Functionality Of JavaScript Program</h4>
<p class="el">Ήρθε η ώρα να δούμε τι λειτουργίες και με ποια σειρά θα πρέπει να κάνει ο κώδικας της JavaScript. Εν συντομία έχουμε τα ακόλουθα βήματα:</p>
<p class="en">Now it's time for the functionality of the JavaScript code we add, and in which order it must perform its functions. In short there are the following steps:</p>
<ul>
<li class="el">Ο κώδικας θα πρέπει να εκτελείται αμέσως μόλις φορτωθεί η σελίδα (HTML τμήμα· δε μας ενδιαφέρει να έχουν φορτωθεί και οι εικόνες, αλλά μόνο το DOM). Συνεπώς, ο κώδικας προστίθεται στο τέλος της σελίδας, πριν κλείσει το <tt></body></tt>.</li>
<li class="en">The program must start its execution just after the page is loaded (HTML part· we don't care about extra files, like images etc., but only the DOM). That means that we have to add the code just before the closing <tt></body></tt> tag.</li>
<li class="el">Το πρώτο πράγμα που πρέπει να γίνει στην εμφάνιση της σελίδας είναι η προσθήκη των διαθέσιμων γλωσσών στον τίτλο κάθε άρθρου. Για να μπορέσει να βρει ο κώδικας τις διαθέσιμες γλώσσες του ενός άρθρου, αρκεί να κοιτάξει τον τίτλο του και να δει σε ποιες γλώσσες είναι γραμμένος.</li>
<li class="en">First thing the code must do is to add the language selection flags at the presentation of the page, just at the title of each post. For the code to be able to understand in which languages the post is available, it must look at the title and find out in which languages it is written.</li>
<li class="el">Αν υπάρχει μόνο μια γλώσσα στον τίτλο του άρθρου, τότε ενεργοποιεί μόνο αυτή τη γλώσσα και στο κείμενό του. Χρήσιμο κυρίως για τα άρθρα που έχουν γραφτεί παλιότερα και γίνεται τώρα η μετάφρασή τους. Κατά τη διάρκεια της μετάφρασης, το μεταφρασμένο κείμενο δεν εμφανίζεται, αν δε προστεθεί και ο τίτλος στη δεύτερη γλώσσα.</li>
<li class="en">If there is only one available language in the title, then, for this post only, it must make it active. That is useful for the older posts that are not translated and they are in a translation phase. During this phase we do not want the partial translated text to be presented. We add the second language only when the translation phase is complete.</li>
<li class="el">Αν δε βρεθεί καμιά γλώσσα στον τίτλο του άρθρου, τότε δε γίνεται καμιά επεξεργασία στο κείμενο.</li>
<li class="en">If there is no language specified in thte title of the post, then the text is presented as is; without any processing.</li>
<li class="el">Θα πρέπει να μπορεί να διαβαστεί μια παράμετρος GET (δηλαδή από τη γραμμή διεύθυνσης) για την επιθυμητή γλώσσα. Με αυτό τον τρόπο, αν κάποιος θέλει να στείλει ένα link σε κάποιον άλλο γι διαμοιρασμό του άρθρου που διαβάζει, μπορεί να προσθέσει την εν λόγω παράμετρο έτσι ώστε ο αποδέκτης να ενεργοποιήσει τη προτοποθετημένη γλώσσα αυτόματα. Αυτό βοηθάει και στην προεπισκόπιση του άρθρου κατά τη διάρκεια της συγγραφής του. Με τη προσθήκη της παραμέτρου στη URL της προεπισκόπισης μπορούμε να δουμε την προεπισκόπιση του άρθρου σε μια άλλη γλώσσα.</li>
<li class="en">There must be a GET parameter (in the URL address of the post) to force the presentation in a specific language. In that way, if someone wants to share a link of the post with a friend, he/she can add the parameter in question so the receiver will read the article in that language automatically. This is also helpful in the post preview during a post editing. By adding the parameter in the preview URL you can preview the post in the willing language.</li>
<li class="el">Για να μπορεί να θυμάται το σύστημα την επιλογή γλώσσας του αναγνώστη θα πρέπει να γίνει χρήση Cookies.</li>
<li class="en">For the system to be able to remember the language choice of the reader, it must use Cookies.</li>
<li class="el">Θα πρέπει να μπορεί να διαβαστεί η επιλογή γλώσσας που έχει γίνει από τον φυλλομετρητή του αναγνώστη.</li>
<li class="en">Also, there must be the ability to read the language settings of the reader's browser.</li>
<li class="el">Αν από η γλώσσα που αποφασίστηκε να ακολουθηθεί δεν υπάρχει στο παρόν άρθρο τότε θα πρέπει να εμφανιστεί η προεπιλεγμένη. Το σύστημα θα πρέπει να λαμβάνει υπόψη του και την κοντινότερη γλώσσα επιλογής. Δηλαδή, αν η γλώσσα επιλογής είναι τα Αγγλικά Ηνωμένων Πολιτειών (με χαρακτηριστικό <i>en_US</i>), όταν αυτή δε βρεθεί, πρώτα θα πρέπει να ελέγχεται η ύπαρξη της κοντινότερης γλώσσας, δηλαδή η Αγγλική γενικότερα (με χαρακτηριστικό <i>en</i>).</li>
<li class="en">If the reader's language decision ends to a language that is not used for the currently presented post, then the presented language must be the default one. But first, the system must take into account the existence of a closest language. To be more specific, if the user's choice is the United States English (with <i>en_US</i> literal characteristic), if this is not one of the post's languages, it must first check for the existence of the closest one, meaning the General English (with <i>en</i> literal characteristic).</li>
<li class="el">Από τις σημαίες επιλογής γλώσσας πρέπει να αποκρύπτεται η γλώσσα στην οποία εμφανίζεται το άρθρο.</li>
<li class="en">From the language selector indications, the post's currently presented one must become hidden.</li>
<li class="el">Όταν ο χρήστης επιλέγει κάποια σημαία για αλλαγή γλώσσας εμφάνισης ενός άρθρου, θα πρέπει να ενημερώνεται το Cookie, να αποκρύπτεται η σημαία επιλογής, να εμφανίζεται η σημαία της προηγούμενης επιλογής, ενώ από το κείμενο να αποκρύπτονται όλα τα στοιχεία το οποία ανήκουν μόνο σε άλλες γλώσσες από την επιλεγμένη.</li>
<li class="en">When the user makes a language choice, the cookie must be updated, the older hidden selector must become visible and the new one that becomes current must become hidden and, of cource, the post must become visible in the newlly selected language.</li>
</ul>
<p class="el">Κάτι που θα πρέπει να προσεχθεί είναι η χρήση της παραμέτρου <tt>display</tt> στα στοιχεία της ιστοσελίδας. Για κανονική εμφάνιση δεν αρκεί να πάρει την τιμή <tt>block</tt>. Κάποια στοιχεία για να εμφανιστούν σωστά πρέπει να έχουν άλλη τιμή, όπως τα στοιχεία <tt><span></tt> και τα στοιχεία <tt><li></tt></p>
<p class="en">Something that must be taken care of is the <tt>display</tt> CSS parameter of the page's elements. For normal appearance, not all of them must have the <tt>block</tt> value. Some, to be normally presented, must have a different value as happens for <tt><span></tt> and <tt><li></tt> elements.</p>
<a name="MuLing_StepByStep"></a>
<h4 class="el">Ο Κώδικας Βήμα Βήμα</h4>
<h4 class="en">The Code Step By Step</h4>
<p class="el">Ας δούμε τον κώδικα βήμα προς βήμα.</p>
<p class="en">Lets walk through the code and examine it step by step.</p>
<a name="MuLing_SBS_Intro"></a>
<h5 class="el">Ορισμοί Γενικών Μεταβλητών</h5>
<h5 class="en">Global Variables</h5>
<p class="el">Ο κώδικας όπως προαναφέραμε προστίθεται ακριβώς πριν το κλείσιμο του tag <tt></body></tt>. Ας δούμε βήμα βήμα τον κώδικα. Ξεκινάμε απο τα "προκαταρκτικά"</p>
<p class="en">As we mentioned earlier, the code we add lies just before the closing <tt></body></tt> tag of the page. Lets see this code step by step. We start from the "preliminary" part</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous Template Code...</i>
<b>
<script type='text/javascript'>
//Script for making the blog multilingual.
var PREFEREDLANGS = &quot;el en&quot;;
var LANGCOOKIENAME = &quot;echlang&quot;;
var EXPIREDAYS = 7;
var TITLES = {};
TITLES[&quot;el&quot;] = &quot;Δείτε το άρθρο στα Ελληνικά&quot;;
TITLES[&quot;en&quot;] = &quot;View the article in English&quot;;
</b>
<i>...More code, will be presented later...</i>
</pre></div>
<p class="el">Πρώτα ορίζουμε μερικές μεταβλητές. Αυτές είναι που θα πειράξετε για να προσθέσετε γλώσσες και να παραμετροποιήσετε το πολυγλωσσικό σύστημα. Θα παρατηρήσατε, βέβαια, πως κάποιοι χαρακτήρες γράφονται με την HTML κωδικοποίηση, όπως π.χ. τα εισαγωγικά γράφονται με την έκφραση <tt>&quot;</tt>. Αυτό συμβαίνει γιατί στην ουσία πειράζουμε ένα αρχείο <tt>xml</tt> και αυτό θα πρέπει να μπορεί να το χειριστεί χωρίς προβλήματα ο xml parser του blogger.com. Για τα εισαγωγικά δεν τίθεται θέμα, μιας και από μόνο του το σύστημα τα μετατρέπει. Το πρόβλημα βρίσκεται σε άλλους χαρακτήρες, όπως π.χ. το '<' και το '>'. Αν αυτούς τους χαρακτήρες τους γράψουμε κανονικά και όχι με τη μορφή HTML, δηλαδή <tt>&lt;</tt> και <tt>&gt;</tt> αντίστοιχα, τότε το σύστημα θα παραπονεθεί.</p>
<p class="en">First we define some variables. These are the ones you will have to alter to add some languages and use this multilingual system. I believe you noticed that some of the characters are written in their HTML notation, for example the quote characters are written as <tt>&quot;</tt>. This happens because what we alter here is the <tt>xml</tt> file of the template and the xml parser of blogger.com must be able to handle it without confusion. For the quotes there is no problem to write them without this notation, but for other characters as '<' and '>' this becomes a problem. If we use these characters not with their HTML notation (<tt>&lt;</tt> and <tt>&gt;</tt>, respectively) but straight then the system will thing it has a new tag and will complain.</p>
<p class="el">Ας επανέλθουμε στο τμήμα του κώδικα που δώθηκε και ας δούμε μια προς μια τις μεταβλητές που ορίστηκαν:</p>
<p class="en">Lets come back to the presented part of the code and see the global variables defined, one by one:</p>
<ul>
<li><b>PREFEREDLANGS:</b> <span class="el">Λίστα από τις υποστηριζόμενες γλώσσες. Η πρώτη είναι η βασική. Οι γλώσσες διαχωρίζονται από κενό</span><span class="en">Supported languages list. The first one is the default. The language literals are separated by a space character.</span>.</li>
<li><b>LANGCOOKIENAME:</b> <span class="el">Το όνομα του Cookie που θα δημιουργείται. Αυτό θα περιέχει και τη προτίμιση της γλώσσας του χρήστη</span><span class="en">The name of the Cookie to be created. It is going to store the reader's language choice</span>.</li>
<li><b>EXPIREDAYS:</b> <span class="el">Ο χρόνος διάρκειας του Cookie που δημιουργείται. Όταν ο αναγνώστης επισκέπτεται και πάλι τη σελίδα, το Cookie θα ανανεώνεται για άλλο τόσο χρονικό διάστημα</span><span class="en">The duration time of the cookie. When the reader returnes to our blog some time after, its expiration time will be updated for as much time as it is defined here</span>.</li>
<li><b>TITLES:</b> <span class="el">Πρόκειται για ένα map. Ο λόγος ύπαρξής του είναι για το μικρό tooltip που θα εμφανίζεται όταν ο αναγνώστης αφήσει για λίγη ώρα τον κέρσορα του ποντικιού στο σημαιάκι επιλογής της αντίστοιχης γλώσσας</span><span class="en">It is a map type variable. The reason of its existence is for the text that appears in the small tooltip when the reader leaves his/her mouse pointer over the small indicator flag</span>.</li>
</ul>
<a name="MuLing_SBS_Flags"></a>
<h5 class="el">Προσθήκη Εικονιδίων Σημαίων Επιλογής Γλώσσας στον Τίτλο</h5>
<h5 class="en">Adding Small Selection Flags On Post Title</h5>
<p class="el">Ας δούμε το κομμάτι του κώδικα που προσθέτει τις σημαίες επιλογής γλώσσας:</p>
<p class="en">The following is the part of the code that adds the small language selection flags:</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
function setupFlags() {
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
var headings = document.getElementsByClassName(&quot;post-title&quot;);
var usedLangs = new Array();
for(i=0; i&lt;headings.length; i++) {
var tempHead = headings[i];
usedLangs.length = 0;
if(tempHead != undefined) {
for(j=0; j&lt;availLangs.length; j++) {
var tempElems = tempHead.getElementsByClassName(availLangs[j]);
if(tempElems.length&gt;0) {
usedLangs.push(availLangs[j]);
}
}
if(usedLangs.length&gt;0) {
for(j=0; j&lt;usedLangs.length; j++) {
newDiv = document.createElement(&quot;div&quot;);
newDiv.className = &quot;flag flg&quot; + usedLangs[j];
newDiv.setAttribute(&quot;onclick&quot;, &quot;applyLang(&#39;&quot; +usedLangs[j]+ &quot;&#39;)&quot;);
newDiv.title = TITLES[usedLangs[j]];
tempHead.appendChild(newDiv);
}
}
}
}
}
</b>
<i>...More JavaScript code...</i>
</pre></div>
<p class="el">Στη γραμμή 4 φτιάχνεται ένας πίνακας με τις υποστηριζόμενες γλώσσες. Στη γραμμή 5 διαβάζονται όλοι οι διαθέσιμοι τίτλοι αναρτήσεων που υπάρχουν στη σελίδα που εμφανίζεται. Μια σελίδα μπορεί να προβάλει περισσότερες από μία αναρτήσεις. Αρκεί να θυμηθούμε ότι κάθε τίτλος ανάρτησης ανήκει στην κλάση <tt>post-title</tt>. Το επόμενο βήμα είναι να βρούμε σε πόσες και ποιες γλώσσες είναι διαθέσιμη κάθε ανάρτηση. Αυτό κάνει το <tt>for</tt> loop. Για κάθε τίτλο που έχει βρεθεί, μηδενίζει αρχικά τον πίνακα των χρησιμοποιούμενων γλωσσών (<tt>usedLangs</tt> - γραμμή 9) και αν πραγματικά έχει βρεθεί κάποιος τίτλος ανάρτησης, τότε μέσα σε αυτόν ελέγχει ποιες από τις διαθέσιμες γλώσσες χρησιμοποιούνται (εσωτερικό <tt>for</tt> loop - γραμμές 11 έως 16). Οι γλώσσες που βρίσκονται προστίθενται στη μεταβλητή <tt>usedLangs</tt>.</p>
<p class="en">On line 4 an array is built containing all the supported languages. On line 5 the code reads all the available titles of the posts that appear on page. There can be more than one post. Just remember that every title belongs to <tt>post-title</tt> class. The next step is to find how many and which languages each post is available. This is the <tt>for</tt> loop's job. For each title found, it first clears the aray of used languages (<tt>usedLangs</tt> - line 9) and if there is a title found, it checks which of the available languages are used (nested <tt>for</tt> loop - lines 11 to 16). Each language found it is added to <tt>usedLangs</tt>.</p>
<p class="el">Ας θυμηθούμε λίγο μια προΥπόθεση που έχουμε θέσει προτύτερα· αν κάποιο άρθρο δεν έχει καθόλου μετάφραση, τότε ο τίτλος δεν περιέχει καμιά κλάση γλώσσας ενώ αν ο τίτλος περιέχει μόνο μια γλώσσα, τότε βρισκόμαστε σε κατάσταση μεταγλώτισης η οποία δεν έχει τελειώσει κι έτσι ο κώδικας θα πρέπει να αποκρύπτει τα τμήματα των μη δηλωμένων γλωσσών. Η σημαία επιλογής της τρέχουσας γλώσσας πρέπει να μην εμφανίζεται. Για περισσότερες δηλωμένες γλώσσες στον τίτλο της ανάρτησης, δε νομίζω πως θα πρέπει να πούμε κάτι παραπάνω.</p>
<p class="en">At this point we have to remember one condition we set earlier; If a post is not translated at all then there is no element with language class in the title; If there is only one language class defined then the post is in a translation phase so the code must hide the partial translated part, meaning the elements that belong to other than the specified in the title one, languages. The selection flag must also be hidden. I don't thing we have to say any more on that.</p>
<p class="el">Αν λοιπόν βρέθηκαν δηλωμένες γλώσσες στον τίτλο, τότε θα πρέπει να δημιουργηθούν οι σημαίες επιλογής για κάθε μία. Αυτό κάνει και ο κώδικας των γραμμών 17 έως 25.</p>
<p class="en">So, if there is any language defined in the title, then for each one there must be one selection flag. That is what lines 17 to 25 do.</p>
<a name="MuLing_SBS_URLParam"></a>
<h5 class="el">Ανάγνωση Παραμέτρου από τη URL</h5>
<h5 class="en">Read URL Parameters</h5>
<p class="el">Το τμήμα που θα δούμε ακολούθως είναι αυτό που διαβάζει τις παραμέτρους τύπου GET από το URL του φυλλομετρητή μας. Πρόκειται για μια υπορουτίνα που δέχεται σαν παράμετρο εισόδου τη παράμετρο που αναζητάμε. Αν Αυτή βρεθεί, τότε επιστρέφει την τιμή της. Αν δε βρεθεί επιστρέφεται η τιμή <tt>null</tt>:</p>
<p class="en">The part that follows is the one that reads GET type parameters from the URL of our browser. It is a funcition that takes the name of the wanted parameter as input. If it is found in URL then it returns the found value, else it returns <tt>null</tt>:</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
function getParam(p_name) {
pArray = location.search.substring(1).split(&quot;&amp;&quot;);
retVal = null;
pLength = pArray.length;
for(i=0; i &lt; pLength; i++) {
keys = pArray[i].split(&quot;=&quot;);
if(decodeURIComponent(keys[0]) == p_name) {
retVal = decodeURIComponent(keys[1]);
break;
}
}
return retVal
}
</b>
<i>...More JavaScript code...</i>
</pre></div>
<p class="el">Στη γραμμή 4 διαβάζεται το τμήμα της URL που περιέχει τις παραμέτρους. Ο πρώτος χαρακτήρας είναι ο "<tt>?</tt>" και γι' αυτό αποκόπτεται (<tt>substring(1)</tt>) ενώ το υπόλοιπο δημιουργεί ένα πίνακα που περιέχει τις παραμέτρους που δηλώνωνται. Η μια παράμετρος από την επόμενη χωρίζονται από τον χαρακτήρα "<tt>&</tt>". Αν βρεθούν παράμετροι, τότε εξετάζονται μια προς μία για να βρούμε αυτή που δηλώθηκε κατά την κλήση της υπορουτίνας. Προσέξτε ότι χρησιμοποιείται η <tt>decodeURIComponent</tt> για να αποκωδικοποιηθούν σωστά οι ειδικοί χαρακτήρες που μπορεί να περιέχονται στο URL. Αν η παράμετρος βρεθεί τότε σταματάει το ψάξιμο και επιστρέφεται η τιμή της, ενώ αν δε βρεθεί επιστρέφεται η προτοποθετημένη τιμή <tt>null</tt>.</p>
<p class="en">In line 4 the parameters part of the URL is fetched. The first character is always "<tt>?</tt>" so it is omitted (<tt>substring(1)</tt>) and the rest forms an array containing the parameters read and their values. Each parameter is separated from the next by the "<tt>&</tt>" character. If there is any parameter found, they are checked one by one to match the one specified by the caller of the function. Mind that <tt>decodeURIComponent</tt> is used to decode the HTML characters used in URLs correctly. If the parameter needed is found in the list then the searching stops and its value is returned, else the returned value is the predefined <tt>null</tt>.</p>
<p class="el">Θα μπορούσε κάποιος να παρατηρήσει πως η συγκεκριμμένη ρουτίνα δεν ξέρει να ασχοληθεί με παραμέτρους που μπορούν να πάρουν πολλές τιμές ταυτόχρονα (όπως επιλογές από checkboxes με το ίδιο όνομα). Αυτό δεν είναι κάτι που μας ενδιαφέρει γιατί η μόνη παράμετρος που διαχειριζόμαστε είναι η <tt>lang</tt>. Θα ήταν, λοιπόν, άσκοπο να προσθέσουμε κάτι παραπάνω σε αυτή τη ρουτίνα για κάτι που δε χρειαζόμαστε.</p>
<p class="en">Someone could notice that this function does not know how to handle parameters that can take many values at the same time; a list of values (like from checkboxes with the same name). This is not of our concern because the only parameter we need to handle is <tt>lang</tt> and this takes only one value. So, it would be useless to try to handle something more complicated than that.</p>
<a name="MuLing_SBS_Cookies"></a>
<h5 class="el">Διαχείριση Cookies</h5>
<h5 class="en">Cookies Manipulation</h5>
<p class="el">Ο κώδικας πρέπει να θυμάται την επιλογή της γλώσσας του αναγνώστη. Είναι αρκετά άβολο, κάθε φορά που ένας αναγνώστης επιλέγει να δει μια καινούργια ανάρτηση να πρέπει να ξαναεπιλέξει και τη γλώσσα που τον ενδιαφέρει να διαβάζει το άρθρο. Για να μπορεί να θυμάται το σύστημα την επιλογή της γλώσσας για τον κάθε ένα αναγνώστη ξεχωριστά, ο μόνος τρόπος είναι η χρήση ενός Cookie. Ας δούμε τις ρουτίνες που τα διαχειρίζονται.</p>
<p class="en">The code must be able to remember reader's language choice. It is very inconvenient each time the reader visits our page, or changes post in our blog, to have to select again and again the same language. For the system to be able to remember each reader's choice, the only way is to use Cookies. Lets see the functions that manipulate them.</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
function setCookie(c_name, c_inval, exdays) {
if (exdays) {
var exdate = new Date();
exdate.setTime(exdate.getTime()+(exdays*24*60*60*1000));
var expires = &quot;; expires=&quot; + exdate.toGMTString();
} else {
var expires = &quot;&quot;;
}
var c_value = escape(c_inval);
document.cookie = c_name + &quot;=&quot; + c_value + expires + &quot;; path=/&quot;;
}
function getCookie(c_name) {
var nameEQ = c_name + &quot;=&quot;;
var ca = document.cookie.split(&quot;;&quot;);
var caLength = ca.length;
for(var i=0; i &lt; caLength; i++) {
var c = ca[i];
while (c.charAt(0)==&quot; &quot;) c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function updCookie(c_name, c_newval) {
var c_val = c_newval || getCookie(c_name);
if (c_val) {
setCookie(c_name, c_val, EXPIREDAYS)
}
}
</b>
<i>...More JavaScript code...</i>
</pre></div>
<p class="el">Σε αυτό το τμήμα του κώδικα βλέπουμε τρεις υπορουτίνες. Η πρώτη (<tt>setCookie</tt>) δημιουργεί ένα Cookie με όνομα που δηλώνεται στην παράμετρο <tt>c_name</tt>, η τιμή του καθορίζεται από τη παράμετρο <tt>c_inval</tt> ενώ ο χρόνος εγκυρότητάς του δηλώνεται από τη παράμετρο <tt>exdays</tt>.</p>
<p class="en">In this part of the code we can see three functions. The first one, (<tt>setCookie</tt>), creates a Cookie with the name set at <tt>c_name</tt> calling parameter, its value is set according to <tt>c_inval</tt> and the time to live is set by <tt>exdays</tt>.</p>
<p class="el">Η δεύτερη υπορουτίνα διαβάζει το Cookie με όνομα που δηλώνεται στη παράμετρο εισόδου <tt>c_name</tt> κι επιστρέφει την τιμή του. Αν δε το βρει επιστρέφει <tt>null</tt>.</p>
<p class="en">The second function reads a Cookie named according to <tt>c_name</tt> input parameter and returns its value. If the cookie is not found then <tt>null</tt> is returned.</p>
<p class="el">Η τρίτη κι τελευταία υπορουτίνα χρησιμοποιεί τη <tt>setCookie</tt> για να κάνει τη δουλειά της. Αν υπάρχει το Cookie που δηλώνεται στην παράμετρο <tt>c_name</tt> τότε το ενημερώνει με μια πιθανά καινούργια τιμή, αν αυτή έχει δηλωθεί στη παράμετρο <tt>c_newval</tt> και μια ημερομηνία που ορίζεται από τις αρχικές μεταβλητές που δηλώσαμε στην αρχή, την <tt>EXPIREDAYS</tt>.</p>
<p class="en">The third and last function uses the previously mentioned <tt>setCookie</tt> to do its job. If there is already a Cookie named as the input parameter <tt>c_name</tt> specifies, it possibly updates its value to the new one specified by <tt>c_newval</tt>. If the parameter is omited then it does not change the cookie's value. Also, the expiration date is updated according to the global variable we saw in the beginning of the code, <tt>EXPIREDAYS</tt>.</p>
<a name="MuLing_SBS_LangGet"></a>
<h5 class="el">Απόφαση Γλώσσας Αναγνώστη</h5>
<h5 class="en">Readers Language Decision</h5>
<p class="el">Ήρθε η ώρα να αποφασίσουμε τελικά σε ποια από τις διαθέσιμες γλώσσες θα εμφανίσουμε το άρθρο. Η απόφαση πρέπει να γίνει με βάση τα εξής κριτήρια:</p>
<p class="en">Time to decide, finaly, which one of the available languages will be the one that the post will be displayed. The decision is made according to the following criteria:</p>
<ol>
<li><span class="el">Αν υπάρχει παράμετρος με όνομα <tt>lang</tt> στη URL του φυλλομετρητή, τότε η απόφαση ορίζεται από αυτή την τιμή</span><span class="en">If there is a parameter named <tt>lang</tt> in the URL of the browser, then the language to be used is the one specified there</span>.</li>
<li><span class="el">Αν δεν υπάρχει η παράμετρος τότε εξετάζεται το ενδεχόμενο να έχει ξαναεπισκευτεί τη σελίδα ο αναγνώστης, δηλαδή το να υπάρχει αποθηκευμένο Cookie με το όνομα που δηλώνει η αρχική μεταβλητή <tt>LANGCOOKIENAME</tt>. Αν υπάρχει τότε η γλώσσα επιλέγεται από αυτό</span><span class="en">If that parameter si not found then we have to check if the reader has visited our page before, by checking the existance of a Cookie with the name specified by global variable <tt>LANGCOOKIENAME</tt>. If it is true, then the language to be used is set by the Cookie's value</span>.</li>
<li><span class="el">Αν ο αναγνώστης επισκέπτεται για πρώτη φορά τη σελίδα μας, ή έχει καιρό να την επισκευτεί έτσι ώστε να έχει λήξει η προθεσμία του Cookie, τότε η απόφαση θα παρθεί από τις ρυθμίσεις του φυλλομετρητή</span><span class="en">If this is the first time the reader visits our page, or he/she has a long time to visit it so the Cookie in question has expired, then the decision must be made by the browser settings</span>.</li>
<li><span class="el">Τέλος, αν όλες οι προηγούμενες προσπάθειες αποτύχουν, ορίζεται ως γλώσσα η πρώτη από τη λίστα που ορίζει η αρχική μεταβλητή <tt>PREFEREDLANGS</tt></span><span class="en">Finally, when all the previous attempts fail, the default language is used and this is the first one in the global list in <tt>PREFEREDLANGS</tt></span>.</li>
</ol>
<p class="el">Όλα τα παραπάνω φαίνονται στο ακόλουθο κομμάτι κώδικα:</p>
<p class="en">All the previously mentioned are performed by the following code:</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
function getLang() {
var langParam = getParam(&quot;lang&quot;);
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
var browserLang = langParam || getCookie(LANGCOOKIENAME) || window.navigator.userLanguage || window.navigator.language || availLangs[0];
var langCnt = availLangs.length;
retVal = 0;
for(i=0; i &lt; langCnt; i++) {
if(browserLang == availLangs[i]) {
retVal = i;
break;
} else if(browserLang.substring(0, browserLang.indexOf(&quot;_&quot;)) == availLangs[i]) {
retVal = i;
break;
}
}
return availLangs[retVal];
}
</b>
<i>...More JavaScript code...</i>
</pre></div>
<p class="el">Στη γραμμή 6, εξετάζονται μια προς μια οι παράμετροι, με τη σειρά που εξηγήσαμε. Όποια βρεθεί πρώτη είναι και αυτή που θα δώσει την τιμή της στη μεταβλητή <tt>browserLang</tt>. Για να μπορέσουμε, όμως, να εξασφαλίσουμε ότι η γλώσσα που θα επιστραφεί είναι μια από τις αποδεκτές που ορίζονται στην αρχή του όλου κώδικα, με τη μεταβλητή <tt>PREFEREDLANGS</tt>, θα πρέπει να γίνει μια αντιπαράθεση με μια προς μια τις διαθέσιμες γλώσσες. Αυτό κάνει και το <tt>for</tt> loop στις γραμμές 9 έως 17. Μια μικρή λεπτομέρεια είναι πως η γλώσσα μπορεί να αποτελείται από το γενικό κομμάτι της (π.χ. "en" για την Αγγλική) αλλά μπορεί να περιέχει και το χαρακτηριστικό της περιοχής (όπως π.χ. "en_US" για την Αγγλική γλώσσα των Ηνωμένων Πολιτειών). Αυτό ο κώδικας το λαμβάνει υπόψη του.</p>
<p class="eν">In line 6, the parameters are checked ony by one in the described order. The first found one sets the value of <tt>browserLang</tt>. To be able to secure that the returned language value to be used is one of the available ones, set by <tt>PREFEREDLANGS</tt> global variable, we should compare their values. This is done by the <tt>for</tt> loop in lines 9 to 17. One small detail is that a language literal characteristic may contain only the general part of the language (ie. "en" for English) or may include the country literal (as in "en_US" for United States English). The code takes it into account, also.</p>
<a name="MuLing_SBS_LangApply"></a>
<h5 class="el">Εφαρμογή Γλώσσας Στις Αναρτήσεις</h5>
<h5 class="en">Apply Language Selection On Posts</h5>
<p class="el">Γνωρίζωντας, πλέον, τη γλώσσα στην οποία θα πρέπει να εμφανιστεί το άρθρο, το μόνο που μένει είναι να εφαρμόσουμε αυτή την επιλογή. Η εφαρμογή γίνεται από την ίδια ρουτίνα που χρησιμοποιείται και από τις σημαίες επιλογής γλώσσας που εμφανίσαμε στον τίτλο της ανάρτησης. Αν γυρίσουμε, για μια στιγμή μόνο, πίσω στο κομμάτι του κώδικα που πρόσθεσε <a href="#MuLing_SBS_Flags">τα ενδεικτικά σημαιάκια στον τίτλο</a>. Βλέπουμε στη γραμμή 21 εκείνου του κώδικα να ορίζεται το event <tt>onclick</tt> να καλεί μια υπορουτίνα με όνομα <tt>applyLang</tt> και παράμετρο τη γλώσσα που αντιπροσωπεύει το αντίστοιχο ενδεικτικό σημαιάκι. Ας δούμε τον κώδικα της υπορουτίνας:</p>
<p class="en">Knowing the language that the post should be presented, the only thing left is to apply this decision. The same function that applies the language choice when selecting one of the title's flags, is the one that does the same job here, also. If we go back to the part of code that added <a href="#MuLing_SBS_Flags">the small language selection flags in the title</a>, we can see in line 21 of that code part that it sets the <tt>onclick</tt> event to call a function named <tt>applyLang</tt> having as calling parameter the language that coresponds to the selected flag. Lets see now the code of this function:</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
function applyLang(inLang) {
var posts = document.getElementsByClassName(&quot;post&quot;);
setCookie(LANGCOOKIENAME, inLang, EXPIREDAYS);
if(posts[0] == undefined)
return;
for(k=0; k&lt;posts.length; k++) {
var flags = posts[k].getElementsByClassName(&quot;flag&quot;);
var langExist = (posts[k].getElementsByClassName(&quot;flag flg&quot; + inLang) != undefined);
var flagsCnt = flags.length;
if(flagsCnt==0) continue;
var tempLang = inLang;
if((flagsCnt==1) || !langExist) {
tempLang = flags[0].className.indexOf(&quot;flg&quot;);
tempLang = flags[0].className.substring(tempLang+3);
}
for(i=0; i&lt;flagsCnt; i++){
curI = flags[i].className.indexOf(&quot;flg&quot;+tempLang);
if(curI &gt;= 0) {
flags[i].style.display = &quot;none&quot;;
} else {
flags[i].style.display = &quot;inline&quot;;
}
}
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
for(i=0; i&lt;availLangs.length; i++){
var currLang = availLangs[i];
if(currLang == tempLang)
continue;
var divs = document.getElementsByClassName(currLang);
var divsCnt = divs.length;
for(j=0; j&lt;divsCnt; j++) {
divs[j].style.display = &quot;none&quot;;
}
}
var divs = document.getElementsByClassName(tempLang);
var divsCnt = divs.length;
for(j=0; j&lt;divsCnt; j++) {
elemType = divs[j].tagName.toLowerCase();
divDisplay = &quot;block&quot;;
switch(elemType) {
case &quot;a&quot;:
case &quot;span&quot;:
divDisplay = &quot;inline&quot;;
break;
case &quot;li&quot;:
divDisplay = &quot;list-item&quot;;
break;
}
divs[j].style.display = divDisplay;
}
}
}
</b>
<i>...More JavaScript code...</i>
</pre></div>
<p class="el">Πιθανόν κάποιος να αναρωτηθεί για τον τρόπο με τον οποίο είναι γραμμένη αυτή η υπορουτίνα. Ας δούμε λίγο τι κάνει.</p>
<p class="en">Well, perhaps someone will ask for the way this function is written. Lets see how it operates.</p>
<p class="el">Αρχικά ανανεώνει το Cookie για τη γλώσσα που πρόκειται να παρουσιαστεί και φυσικά το χρόνο λήξης της ισχύος του (γραμμή 5). Στη συνέχεια αν δεν υπάρχει κάποια διαθέσιμη ανάρτηση, τότε δεν υπάρχει κάτι να κάνει, οπότε και τερματίζεται (γραμμές 6 και 7).</p>
<p class="en">In the beginning it updates the Cookie with the language value to be used and, of course, its expiration time (line 5). Next, if there is no post on screen it has nothing to do so it returns (lines 6 and 7).</p>
<p class="el">Για κάθε ανάρτηση που βρίσκει αναγνωρίζει ποιες είναι οι διαθέσιμες γλώσσες και αν η ανάρτηση περιέχεται στη γλώσσα που επιλέχθηκε. Αν δε βρεθεί κάποια γλώσσα για την ανάρτηση την οποία ελέγχει τότε προχωράει στην επόμενη (γραμμή 12).</p>
<p class="en">For every post it finds it checks its available languages and if the selected one appears in the list. If this is not true it continues to the next post (line 12).</p>
<p class="el">Το τμήμα που αποτελείται από τις γραμμές 13 έως 17, αποφασίζει ποια γλώσσα από τις διαθέσιμες του άρθρου είναι αυτή στην οποία θα εμφανιστεί. Ο λόγος που γίνεται αυτό, είναι γιατί ένα άρθρο μπορεί να είναι ολοκληρωμένο μόνο σε μια γλώσσα, η οποία να είναι διαφορετική από την επιλεγμένη, οπότε και θα εμφανιστεί στη γλώσσα στην οποία είναι γραμμένο, ή να μην έχει γραφτεί καθόλου στην επιλεγμένη γλώσσα, συνεπώς εμφανίζεται στην προεπιλεγμένη. Μην ξεχνάμε πως ο λόγος να έχει δηλωθεί μόνο μια γλώσσα στον τίτλο ενός άρθρου, είναι κατά τη διάρκεια της μεταγλώτισής του ενώ αυτό έχει αναρτηθεί, έτσι ώστε να αποκρύπτεται η ημιτελής μετάφραση.</p>
<p class="en">The part that is formed by lines 13 to 17, decides which of the post's available language will be used, finaly.The reason for this is that a post may be in a translation phase and the completed language be different from the one specified. Thus, the completed language is the one that should be used. The post may also be written only in a different language, so it is presented in the default one. Don't forget the reason of specifying only one language in the post's title. It means the article is in a translation phase and the non completed language should not be presented.</p>
<p class="el">Από τη γραμμή 18 έως την 25 ενημερώνεται η εμφάνιση των σημαιών επιλογής γλώσσας. Εμφανίζονται, δηλαδή, οι σημαίες των γλωσσών που δεν είναι επιλεγμένες και αποκρύπτεται αυτή στην οποία εμφανίζεται η παρούσα ανάρτηση.</p>
<p class="en">Form line 18 to line 25 the avalable selection flags are updated; the languages that are not used become visible and the one that represents the current selection becomes hidden.</p>
<p class="el">Τα επόμενο βήμα είναι να εμφανιστούν τα HTML στοιχεία που ανήκουν στη γλώσσα που έχει αποφασιστεί να προβληθεί η ανάρτηση. Αυτό γίνεται σε δύο κομμάτια. Το πρώτο αποτελείται από τις γραμμές 27 έως 36, το οποίο αποκρύπτει όλες τις παραγράφους που έχουν επισήμανση γλώσσας. Το δεύτερο κομμάτι αποτελείται από τις γραμμές 37 έως και 52. Αυτό εμφανίζει τα στοιχεία τα οποία ανήκουν στη γλώσσα προβολής του άρθρου. Εδώ δίνεται και η δυνατότητα να μπορέσουν τα διαφορετικά στοιχεία να πάρουν διαφορετική τιμή στη παράμετρο <tt>display</tt>.</p>
<p class="en">The next step is for the HTML elements that belong to the selected language to be displayed. It is done in two phases. The first is the code in lines 27 to 36, that hides all the elements that belong to another language. The second phase, code lines 37 to 52, displays the elements that belong to the currently selected language. Here every element can take a different <tt>display</tt> value for their correct appearance.</p>
<p class="el">Ο λόγος για τον οποίο η εμφάνιση γίνεται με διπλό πέρασμα των στοιχείων της ανάρτησης είναι γιατί ένα στοιχείο μπορεί να ανήκει σε δύο γλώσσες. Παραδείγματος χάρην, αν το άρθρο έχει γραφτεί σε Ελληνικά, Αγγλικά και Κινέζικα, τότε ένα στοιχείο που εμφανίζεται και στα Ελληνικά, αλλά και στα Αγγλικά θα πρέπει να ανήκει και στις δύο κλάσεις γλώσσας (<tt>class="el en"</tt>). Αν δεν περνούσαμε την εμφάνιση σε δύο βήματα, τότε η λειτουργία της εμφάνισης δε θα γινόταν σωστά· ναι μεν στην επιλογή της εμφάνισης του άρθρου σε Κινέζικα δε θα εμφανιζόταν το εν λόγω στοιχείο, αλλά αναλόγως με τη θέση της γλώσσας των Ελληνικών και των Αγγλικών στη λίστα των διαθέσιμων γλωσσών δε θα είχαμε εμφάνιση και στις δύο γλώσσες...</p>
<p class="en">The reason of the two phases insted of one, is that an element can belong to two or more languages. In example, if an article is written in Greek, English and Chinese, there is the posibility for an element to be presented for both Greek and English languages and be hidden in Chinese. For this to become true, the element must belong to both <tt>el</tt> and <tt>en</tt> classes (<tt>class="el en"</tt>). If there were not two phases the presentation of the article would be broken; in the Chinese post everything would be fine, but in the other two languages the correct representation would be only in the one that appears first in the global list of languages. We would not see the element in question in both specified ones...</p>
<a name="MuLing_SBS_Last"></a>
<h5 class="el">Τελευταίες Πινελιές στον Κώδικα</h5>
<h5 class="en">Some Code's Finishing Touches</h5>
<p class="el">Τι δεν έχουμε δει ακόμα; Το κομμάτι του κώδικα που ξεκινάει την αυτόματη εκτέλεσή του. Μιας και δεν έχουμε τον πλήρη έλεγχο όλου του κώδικα που τρέχει στη σελίδα, παρά μόνο στο δικό μας κομμάτι, δε μπορούμε να χρησιμοποιήσουμε την <tt>onload</tt>. Μπορεί ήδη να τη χρησιμοποιεί κάποιο άλλο κομμάτι κώδικα από όλα αυτά που φορτώνονται για την επιβολή των στατιστικών κ.λ.π. που μας παρέχει το blogger.com. Κατα συνέπεια, ο μόνος διαθέσιμος τρόπος είναι οι αυτόματα εκτελέσιμες υπορουτίνες της JavaScript:</p>
<p class="en">What we haven't seen yet? The part of the code that automatically starts its execution. Since we don't have the complete control of the whole code that runs in our page, but only in our part of code, we cannot use <tt>onload</tt>. It may be in use from another part of the code that the page loads for google statistics etc. and for the gadjets that blogger.com offeres. The only safe way is the autorun JavaScript functions:</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<i>...Previous JavaScript code...</i>
<b>
(function(){
setupFlags();
setupLang();
})();
function setupLang() {
currLang = getLang();
applyLang(currLang);
}
</script>
</b>
</body>
</html>
</pre></div>
<p class="el">Οι γραμμές 8 έως 11 δεν κάνουν τίποτα άλλο από το να διαβάσουν τη γλώσσα που θα πρέπει να χρησιμοποιηθεί, την πρώτη φορά που φορτώνεται η σελίδα, ενώ οι γραμμές 3 έως και 6 είναι αυτές που εκτελούνται αυτόματα με το που φορτώνεται η σελίδα μας. Αυτές είναι που ξεκινάνε την εμφάνιση των σημαιών επιλογής γλώσσας κι εμφανίζουν τα άρθρα που υπάρχουν στη σελίδα στη γλώσσα που είναι πιο κοντά στον χρήστη, όπως περιγράφτηκε στην παράγραφο "<a href="#MuLing_SBS_LangGet">Απόφαση Γλώσσας Αναγνώστη</a>". Σε αυτό το σημείο ολοκληρώνεται και ο κώδικας που περιέχεται σε αυτό εδώ το blog για την πολυγλωσσική εμφάνιση των αναρτήσεών του.</p>
<p class="en">Lines from 8 to 11 do nothing more than finding the propper language the first time the page is loaded. Lines 3 to 6 are those that take advantage of the autorun feature of JavaScript. When the page is loaded they are automatically executed. These are the ones that start adding the language selection flags and present the posts on the page in the correct languages, the ones closer to the reader, just as described in "<a href="#MuLing_SBS_LangGet">Readers Language Decision</a>". And in that point the code we present is complete and is the code that this blog uses to offer nultilanguage capabilities in our posts.</p>
<a name="MuLing_Program"></a>
<h4 class="el">Το Συνολικό Πρόγραμμα της JavaScript</h4>
<h4 class="en">The Whole JavaScript Program</h4>
<p class="el">Μιας και ο κώδικας περιγράφτηκε σε τμήματα, για να είναι πιο εύκολο για τον αναγνώστη να μπορέσει να τον αντιγράψει και να τον χρησιμοποιήσει/παραλλάξει σύμφωνα με τις ανάγκες του, ο κώδικας παρατίθεται ολόκληρος σε αυτό το σημείο. Μπορείτε να τον χρησιμοποιήσετε ελεύθερα.</p>
<p class="en">Since the code was described part to part, for the reader to be easier to copy and use/alter it according to his/her needs, the whole code will be presented here. You can copy and use it freely.</p>
<div class="code"><pre class="prettyprint lang-js linenums">
<script type='text/javascript'>
//Script for making the blog multilingual.
//Written by Elias Chrysocheris
/*THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
var PREFEREDLANGS = &quot;el en&quot;;
var LANGCOOKIENAME = &quot;echlang&quot;;
var EXPIREDAYS = 7;
var TITLES = {};
TITLES[&quot;el&quot;] = &quot;Δείτε το άρθρο στα Ελληνικά&quot;;
TITLES[&quot;en&quot;] = &quot;View the article in English&quot;;
(function(){
setupFlags();
setupLang();
})();
function setCookie(c_name, c_inval, exdays) {
if (exdays) {
var exdate = new Date();
exdate.setTime(exdate.getTime()+(exdays*24*60*60*1000));
var expires = &quot;; expires=&quot; + exdate.toGMTString();
} else {
var expires = &quot;&quot;;
}
var c_value = escape(c_inval);
document.cookie = c_name + &quot;=&quot; + c_value + expires + &quot;; path=/&quot;;
}
function getCookie(c_name) {
var nameEQ = c_name + &quot;=&quot;;
var ca = document.cookie.split(&quot;;&quot;);
var caLength = ca.length;
for(var i=0; i &lt; caLength; i++) {
var c = ca[i];
while (c.charAt(0)==&quot; &quot;) c = c.substring(1,c.length);
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
}
return null;
}
function updCookie(c_name, c_newval) {
var c_val = c_newval || getCookie(c_name);
if (c_val) {
setCookie(c_name, c_val, EXPIREDAYS)
}
}
function getParam(p_name) {
pArray = location.search.substring(1).split(&quot;&amp;&quot;);
retVal = null;
pLength = pArray.length;
for(i=0; i &lt; pLength; i++) {
keys = pArray[i].split(&quot;=&quot;);
if(decodeURIComponent(keys[0]) == p_name) {
retVal = decodeURIComponent(keys[1]);
break;
}
}
return retVal
}
function getLang() {
var langParam = getParam(&quot;lang&quot;);
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
var browserLang = langParam || getCookie(LANGCOOKIENAME) || window.navigator.userLanguage || window.navigator.language || availLangs[0];
var langCnt = availLangs.length;
retVal = 0;
for(i=0; i &lt; langCnt; i++) {
if(browserLang == availLangs[i]) {
retVal = i;
break;
} else if(browserLang.substring(0, browserLang.indexOf(&quot;_&quot;)) == availLangs[i]) {
retVal = i;
break;
}
}
return availLangs[retVal];
}
function setupLang() {
currLang = getLang();
applyLang(currLang);
}
function applyLang(inLang) {
var posts = document.getElementsByClassName(&quot;post&quot;);
setCookie(LANGCOOKIENAME, inLang, EXPIREDAYS);
if(posts[0] == undefined)
return;
for(k=0; k&lt;posts.length; k++) {
var flags = posts[k].getElementsByClassName(&quot;flag&quot;);
var langExist = (posts[k].getElementsByClassName(&quot;flag flg&quot; + inLang) != undefined);
var flagsCnt = flags.length;
if(flagsCnt==0) continue;
var tempLang = inLang;
if((flagsCnt==1) || !langExist) {
tempLang = flags[0].className.indexOf(&quot;flg&quot;);
tempLang = flags[0].className.substring(tempLang+3);
}
for(i=0; i&lt;flagsCnt; i++){
curI = flags[i].className.indexOf(&quot;flg&quot;+tempLang);
if(curI &gt;= 0) {
flags[i].style.display = &quot;none&quot;;
} else {
flags[i].style.display = &quot;inline&quot;;
}
}
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
for(i=0; i&lt;availLangs.length; i++){
var currLang = availLangs[i];
if(currLang == tempLang)
continue;
var divs = document.getElementsByClassName(currLang);
var divsCnt = divs.length;
for(j=0; j&lt;divsCnt; j++) {
divs[j].style.display = &quot;none&quot;;
}
}
var divs = document.getElementsByClassName(tempLang);
var divsCnt = divs.length;
for(j=0; j&lt;divsCnt; j++) {
elemType = divs[j].tagName.toLowerCase();
divDisplay = &quot;block&quot;;
switch(elemType) {
case &quot;a&quot;:
case &quot;span&quot;:
divDisplay = &quot;inline&quot;;
break;
case &quot;li&quot;:
divDisplay = &quot;list-item&quot;;
break;
}
divs[j].style.display = divDisplay;
}
}
}
function setupFlags() {
var availLangs = PREFEREDLANGS.split(&quot; &quot;);
var headings = document.getElementsByClassName(&quot;post-title&quot;);
var usedLangs = new Array();
for(i=0; i&lt;headings.length; i++) {
var tempHead = headings[i];
usedLangs.length = 0;
if(tempHead != undefined) {
for(j=0; j&lt;availLangs.length; j++) {
var tempElems = tempHead.getElementsByClassName(availLangs[j]);
if(tempElems.length&gt;0) {
usedLangs.push(availLangs[j]);
}
}
if(usedLangs.length&gt;0) {
for(j=0; j&lt;usedLangs.length; j++) {
newDiv = document.createElement(&quot;div&quot;);
newDiv.className = &quot;flag flg&quot; + usedLangs[j];
newDiv.setAttribute(&quot;onclick&quot;, &quot;applyLang(&#39;&quot; +usedLangs[j]+ &quot;&#39;)&quot;);
newDiv.title = TITLES[usedLangs[j]];
tempHead.appendChild(newDiv);
}
}
}
}
}
</script>
</body>
</html>
</pre></div>
<p class="el">Απλά θυμηθείτε πως υπάρχει και το <a href="#MuLing_CSSCode">τμήμα του CSS</a> καθώς επίσης θα πρέπει να παραλλάξετε τις global μεταβλητές σύμφωνα με τις δικές σας ανάγκες.</p>
<p class="en">Just keep in mind that there is also the <a href="#MuLing_CSSCode">CSS part</a> of the code and that you may have to alter the global variables for your needs.</p>
<a name="MuLing_Example"></a>
<h4 class="el">Παράδειγμα Χρήσης</h4>
<h4 class="en">An Example Of Usage</h4>
<p class="el">Για να δούμε πώς μπορούμε να φτιάξουμε ένα πολυγλωσσικό κείμενο. Μιας και στο παρόν blog χρησιμοποιούμε Ελληνική και Αγγλική γλώσσα, το παράδειγμα που θα δοθεί είναι γι' αυτές. Ας δούμε ένα κομμάτι κειμένου που αναρτούμε σε ένα άρθρο μας. Να σημειωθεί ότι το κέιμενο είναι γραμμένο σε καθαρή HTML:</p>
<p class="en">Lets see how we can create a multilingual text. Since in our blog we use only Greek and English languages, the example will be given for these two. Lets see a part of text that will be presented in our post. Notice that it is written in pure HTML:</p>
<div class="code"><pre class="prettyprint lang-html">
<p class="el">Αυτό είναι το κείμενο της παραγράφου στα Ελληνικά. Εφόσον η κλάση που δηλώνεται
στο tag της παραγράφου είναι <tt>el</tt>, η παράγραφος αυτή θα εμφανίζεται όταν βλέπετε το
Ελληνικό κείμενο!</p>
<p class="en">This is the English text of the paragraph. Since the &lt;p&gt; tag belongs to
<tt>en</tt> class, this paragraph will be visible only when the English text is displayed!</p>
</pre></div>
<p class="el">Το αποτέλεσμα είναι η ακόλουθη παράγραφος στο γκρι πλαίσιο. Η ενδεικτική σημαία δεν προστίθεται με αυτό τον HTML κώδικα, αλλά την έχουμε προσθέσει εμείς για την ευκολία της παρατήρησης του αναγνώστη. Δοκιμάστε να επιλέξετε άλλη γλώσσα από τον τίτλο του κειμένου (ή από τη σημαία στα δεξιά) και παρατηρείστε τι εμφανίζεται σε αυτή την παράγραφο:</p>
<p class="en">The result is the following paragraph in the gray box. The selector flag at the right is not added by this HTML code, but we have added it for the reader's convenience to observe the results. Try to select another language from the post's tilte (or the indicator flag at the right) and observe the appeared paragraph:</p>
<div class="grayed">
<table>
<tr>
<td>
<p class="el">Αυτό είναι το κείμενο της παραγράφου στα Ελληνικά. Εφόσον η κλάση που δηλώνεται
στο tag της παραγράφου είναι <tt>el</tt>, η παράγραφος αυτή θα εμφανίζεται όταν βλέπετε το
Ελληνικό κείμενο!</p>
<p class="en">This is the English text of the paragraph. Since the <p> tag belongs to
<tt>en</tt> class, this paragraph will be visible only when the English text is displayed!</p>
</td>
<td width="34px">
<div class="post-title"><span class="en el"></span></div>
</td>
</tr>
</table>
</div>
<p class="el">Κάτι ακόμα που θα πρέπει να αναφερθεί, είναι πως κατά τη διάρκεια της προεπισκόπισης ενός άρθρου που ακόμα συντάσεται, χωρίς να έχει αναρτηθεί, επειδή το blogger κόβει κάποιες από τις λειτουργίες, ένας απλός τρόπος για να γίνει προεπισκόπιση σε άλλη γλώσσα, είναι η χρήση της παραμέτρου <tt>lang</tt> στο URL του παραθύρου της προεπισκόπισης. Δηλαδή, όταν πατήσουμε το πλήκτρο προεπισκόπιση κατά τη διάρκεια της συγγραφής ενός άρθρου, ανοίγει μια καινούργια καρτέλα (ή καινούργιο παράθυρο, ανάλογα με τις ρυθμίσεις του φυλλομετρητή) και μας δειχνει πως θα φαίνεται το άρθρο όταν αναρτηθεί. Αν στο URL προσθέσουμε το "<tt>&lang=en</tt>", τότε υποχρεώνουμε το σύστημα να μας εμφανίσει το άρθρο στην Αγγλική γλώσσα.</p>
<p class="en">One more thing must be reported is that during the preview of a post that is still editted without being published, because blogger.com uses a "click trap", a simple way of previewing the post in a different language is to use the <tt>lang</tt> parameter in the URL of the preview page. Meaning, when we use the <i>Preview</i> button during the editing of a post, a new tab (o a new window, depending on your browser's settings) opens and it presents us how the post will appear when it is published. If we add "<tt>&lang=en</tt>" in the preview URL, then we force the system to present the article in English.</p>
<a name="MuLing_Conclusion"></a>
<h4 class="el">Συμπεράσματα</h4>
<h4 class="en">Conclusions</h4>
<p class="el">Το να μπορεί κάποιος να διαβάσει ένα κείμενο που τον ενδιαφέρει στη μητρική του γλώσσα, είναι κάτι πολύ σημαντικό. Σκεφτείτε πόσες φορές έχετε βρει ένα κείμενο σε μια γλώσσα που δεν καταλαβαίνετε· είτε δεν το προσπαθήσατε καθόλου, είτε χωθήκατε μέσα σε ένα μεταφραστικό και... ότι βγάλατε βγάλατε. Μην ξεχνάμε ότι παντού γίνονται προσπάθειες μετάφρασης. Από κλειστά λογισμικά μέχρι ανοικτά, ιστοσελίδες και ό,τι μπορεί να περιέχει κείμενο, κρύβουν μια ομάδα, μεγάλη ή μικρή που δουλειά της είναι να μεταφράζει τα κείμενα σε διάφορες γλώσσες. Όσοι ασχολείστε με το ανοικτό λογισμικό πιστεύω πως θα ασχοληθήκατε, ή έστω θα διαπιστώσατε τη μεγάλη προσπάθεια που γίνεται για τη μετάφραση των προγραμμάτων, τόσο του γραφικού περιβάλλοντός τους όσο και του κειμένου βοήθειας.</p>
<p class="en">For somebody to be able to read a text in his/her native language is something very important. Just think of the times that you have found an interesting article in a language that you cannot understand. Either you didn't try to read it at all, or you fell into a translating site (or dictionary) and... whatever came out of this. Lets not forget that everywhere there are translation tries. From closed source programs to opensource ones, web pages and whatever may include text, everything hides a translating team behind the scenes, big or small to translate documents into different languages. Whoever of you uses open source programs and operating systems I believe that you have tried to do something like that, or at least you have seen the big effort made for translation of all programs, graphical environment and help files.</p>
<p class="el">Το blogger.com δυστυχώς δε μας δίνει τη δυνατότητα να έχουμε μεταφράσεις του κειμένου μιας ανάρτησής μας. Αυτό το εμπόδιο, με λίγη προσπάθεια, το προσπερνάμε και έχουμε μεταφρασμένες αναρτήσεις. Με αυτό τον τρόπο η απήχηση του blog μας αυξάνει.</p>
<p class="en">Unfortunately, blogger.com doesnot offer the ability to have multilingual posts. That barrier is oversteped with little effort, and now we can have what we need. In that way the audience of our blog grows.</p>
<p class="el">Μια μικρή ματιά σε ιστότοπους, όπως αυτό της <a href="http://www.transifex.com/">Transifex</a>, νομίζω πως μπορεί να σας πείσει για την αναγκαιότητα της μετάφρασης.</p>
<p class="en">Just a small search arround, to web pages and companies like <a href="http://www.transifex.com/">Transifex</a>, can show you the necessity of translation, I believe.</p>
<p class="el authorname">Ηλίας Χρυσοχέρης</p>
<p class="en authorname">Elias Chrysocheris</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-63737558401015694272013-06-23T01:25:00.000+03:002014-05-14T00:36:30.917+03:00NoIP στο Raspberry Pi και μείωση του Internet TrafficNoIP in Raspberry Pi and Internet Traffic Reduction<div class="separator" style="clear: both; margin:5px; text-align: center;"><a href="http://tomszpytman.com/images/62.jpeg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img style="border:1px solid #4763B0;border-radius:8px" width="300px" src="http://tomszpytman.com/images/62.jpeg" /></a></div>
<h4 class="el">Εισαγωγή</h4>
<h4 class="en">Introduction</h4>
<p class="el">Πολλές φορές χρειαζόμαστε να στήσουμε κάποιου είδους server έτσι ώστε να μπορούμε να έχουμε πρόσβαση σε αυτόν από τον "έξω κόσμο", δηλαδή από παντού, όπου υπάρχει πρόσβαση στο διαδίκτυο. Το πρόβλημα σε αυτό είναι πως οι περισσότεροι πάροχοι Internet (Internet Service Providers, εν συντομία ISPs) δε δίνουν σταθερή διεύθυνση IP στα router που έχουμε σπίτι μας (εκτός, φυσικά, αν το ζητήσουμε με κάποια παραπάνω χρέωση). Έτσι, θα πρέπει κάθε φορά να γνωρίζουμε την IP διεύθυνση του router μας για να μπορέσουμε να έχουμε πρόσβαση στον server που κάθεται πίσω από αυτό. Αυτόν ακριβώς το σκοπό έχει και το παρόν άρθρο. Τι θα λέγατε όμως, αν το σύστημα που θα μας βοηθούσε είναι ένα <a href="http://www.raspberrypi.org/">Raspberry Pi</a>; Όχι πως αυτά που περιγράφονται εδώ δε μπορούν να εφαρμοστούν και σε άλλο σύστημα υπολογιστή... Αντιθέτως, ένα δυνατό σημείο του ανοικτού λογισμικού, είναι πως η διαχείρισή του γίνεται με τον ίδιο ακριβώς τρόπο, είτε αυτό τρέχει σε ένα μηχάνημα με 64 επεξεργαστές, είτε τρέχει σε μια... <a href="http://farm1.staticflickr.com/21/33247833_74532997e3_z.jpg?zz=1">τοστιέρα</a> (βλ. <a href="http://www.netbsd.org/">NetBSD</a>!).</p>
<p class="en">There are sometimes that we need to setup a small server in a way to have access to it from the "outer world", meaning everywhere, wherever there is internet access. The problem is that most of the Internet Service Providers (abbreviated as ISPs) do not give static IP address to our home routers (unless of course, we ask for it, in extra charge). So, we have to know the IP address of our router in order to gain access to our server behind it. This is the goal of this article. But, what if the helper system for our purpose is a <a href="http://www.raspberrypi.org/">Raspberry Pi</a>? Not that what is described in here cannot be applied to some other computer system... Contrariwise, this is a very powerful part of opensource; the administration and setup of a system is a similar way, whether it runs on a 64 core system, or even a... <a href="http://farm1.staticflickr.com/21/33247833_74532997e3_z.jpg?zz=1">toaster</a> (see <a href="http://www.netbsd.org/">NetBSD</a> site!).</p>
<h4 class="el">Τι θα δούμε</h4>
<h4 class="en">What is in this article</h4>
<p class="el">Παρότι το άρθρο προορίζεται σε ανθρώπους που ξέρουν να ρυθμίζουν routers, να στήνουν servers, να διαχειρίζονται υπηρεσίες σε λειτουργικά όπως το Linux και να έχουν τη δυνατότητα, ίσως, να ασχοληθούν με ένα gadget του τύπου Raspberry Pi, εν τούτης θα δοθούν πληροφορίες ακόμα και σε πιο "αρχικά" πράγματα. Μέσα σε όλους τους σκοπούς του άρθρου είναι να μπορέσει ακόμα και κάποιος αρχάριος να βρει κάποιες εναρκτήριες πληροφορίες, εισαγωγικές περισσότερο σε όλα αυτά με τα οποία σχετίζεται η πρόσβαση ενός υπολογιστή σε ένα άλλο, μέσω του διαδικτύου. Ακόμα και για την πληρότητα του άρθρου, δε θα μπορούσαν να λείπουν αυτές οι πληροφορίες. Αν είστε κάπως πιο προχωρημένος χρήστης/γνώστης και κάποια παράγραφος σας είναι απλή ή δεν προσφέρει κάποιες παραπάνω γνώσεις σε αυτές που ήδη έχετε, μπορείτε ασφαλώς να την προσπεράσετε και να μπείτε στο "ψητό" της ιστορίας.</p>
<p class="en">Though this article is for people who know how to setup a router, servers, administrate services in operating systems such as Linux and have the ability, perhaps, to deal with a gadget of Raspberry Pi's type, yet, the information in here will be in a novice level. Between the article's goals is for a not so advanced user to find some basic steps in all these stuff that communication between two computers through the internet, involves. Even for clarity, some of these information could not be omitted. If you are more advanced user and you find that some paragraphs do not contribute to your knowledge, feel free to skip it and proceed to the "hot point" of the story.</p>
<p class="el">Μια μικρή περίληψη όσων θα δούμε μέσα στο παρόν άρθρο:</p>
<p class="en">A brief of what we will find is:</p>
<ul>
<li><a href="#NoIPDNS">DNS, <span class="el">Ευρετήριο διευθύνσεων διαδικτύου</span><span class="en">Domain names index of the internet</span></a></li>
<li><a href="#NoIPWhat"><span class="el">Διαδικασία ονοματοδοσίας</span><span class="en">"Naming"</span></a></li>
<li><a href="#NoIPDNS"><span class="el">Δυναμικός DNS για δυναμικές IP</span><span class="en">Dynamic DNS for dynamic IP addresses</span></a></li>
<li><a href="#NoIP">NoIP: <span class="el">Υπηρεσία δυναμικού DNS για όλους</span><span class="en">A free Dynamic DNS Service for all</span></a></li>
<li><a href="#NoIPRasbPi"><span class="el">Γιατί το Raspberry Pi;</span><span class="en">Why Raspberry Pi?</span></a></li>
<li><a href="#NoIPClient"><span class="el">Ο Dynamic Update Client της </span>NoIP<span class="en">'s Dynamic Update Client</span></a></li>
<li><a href="#NoIPRouter"><span class="el">Μείωση του </span>Internet Traffic<span class="en"> reduction</span></a></li>
<li><a href="#NoIPUpdater">Dynamic Updater Client script</a></li>
<li><a href="#NoIPService"><span class="el">Μετατροπή του καινούργιου client σε υπηρεσία</span><span class="en">Convertion of the new client to a system service</span></a></li>
<li><a href="#NoIPConcl"><span class="el">Αποτελέσματα</span><span class="en">Conclusions</span></a></li>
</ul>
<a id="NoIPDNS"></a>
<h4 class="el">DNS, Ευρετήριο διευθύνσεων διαδικτύου</h4>
<h4 class="en">DNS, Domain names index of the internet</h4>
<p class="el">Κάθε υπολογιστής ή άλλη συσκευή που συνδέεται στο διαδίκτυο με σκοπό να ανταλλάξει πληροφορίες διαμέσου αυτού, παίρνει μια μοναδική διεύθυνση στον κόσμο. Αυτή είναι και η βασική ιδέα. Αυτή την ονομάζουμε διεύθυνση IP. Φυσικά και υπάρχουν διευθύνσεις που θα τις δούμε να υπάρχουν ταυτόχρονα σε πολλούς υπολογιστές (π.χ. μια διεύθυνση της μορφής <tt>192.168.1.1</tt>), αλλά ας μείνουμε στη βασική ιδέα του συστήματος του διαδικτύου και ας μην επεκταθούμε σε τέτοιες λεπτομέρειες. Το router που έχουμε στο σπίτι μας ή στο γραφείο μας (ή οπουδήποτε, τέλος πάντων) είναι και αυτό μια συσκευή επικοινωνίας που συνδέεται με το διαδίκτυο. Κατά συνέπεια και αυτό έχει μια διεύθυνση IP. Γιατί γίνεται αυτό; Αυτή η διεύθυνση είναι ένα κομμάτι της "ταυτοποίησης" του αντικειμένου. Όταν γίνεται μια επικοινωνία = μεταφορά δεδομένων από ένα σύστημα σε ένα άλλο, τότε απλά οι διευθύνσεις είναι αυτές που καθορίζουν τον αποστολέα και τον παραλήπτη. Όπως ακριβώς και η μεταφορά αλληλογραφίας με το κανονικό ταχυδρομείο που χρειάζεται να φέρει ο φάκελος τις διευθύνσεις αποστολέα και παραλήπτη.</p>
<p class="en">Every computer or other network device that is connected to the internet with the purpose of exchanging data through it, must have a unique address all over the world. That's the basic idea. This is the address we call "IP Address". Of course we will find IP addresses that exist in more than one computer at the same time (ie. an address of type <tt>192.168.1.1</tt>), but lets stick on the basic idea of the internet's system and not expand to such details for now. The routing device (called router) we have at home or office (or wherever) is a communication device that is connected to the internet. So, it also has an IP address. Why that happens? This address is used for some kind of identification of this device. When a communication takes place = data transfer from one system to another, the addresses identify who is the sender and to who is the target, in all over the network; similar to the way mail transfer takes place at the ordinary post office; the envelope has both the sender's and the recipient's address.</p>
<p class="el">Οι διευθύνσεις που δίνονται σε όλα αυτά τα συστήματα επικοινωνίας, είτε είναι υπολογιστές είτε είναι ένας δικτυακός εκτυπωτής κ.λ.π, έχουν τη μορφή 4 αριθμών χωρισμένων από τελείες (.). Ο κάθε αριθμός μπορεί να πάρει τιμές από 0 μέχρι και 255. Υπάρχει και ένας πιο σύγχρονος τρόπος διευθυνσιοδότησης, όπου η κάθε διεύθυνση αποτελείται από 8 τετραψήφιους δεκαεξαδικούς αριθμούς χωρισμένους από άνω-κάτω τελείες (:).</p>
<p class="en">The given addresses to all these communication and networking devices, whether they are computers or network printers etc., they consist of 4 numbers separated by dots (.). Each number cat take a value from 0 to 255. There is also a newer way of addressing where the address is formed by 8 four-digit hexadecimal numbers separated by colons (:).</p>
<p class="el">Και γιατί τα αναφέρουμε όλα αυτά; Βλέπετε πουθενά λέξεις, όπως google.com, blogspot.gr ή my_really_really_fancy_site.biz; Όχι, γιατί <b>ΔΕΝ ΥΠΑΡΧΟΥΝ</b>. Αυτό σημαίνει πως για να μπορέσουμε να επισκεφθούμε τη μηχανή αναζήτησης της Google, το site που φιλοξενεί τα περισσότερα blogs ή μια άλλη τοποθεσία με το πιο σημαντικό υλικό που μας ενδιαφέρει (λέμε τώρα!) θα έπρεπε να θυμόμαστε ένα σωρό νούμερα που να δώσουν στον browser μας να καταλάβει ποια τοποθεσία θέλουμε να δούμε. Λίγο δύσκολο ε;... Ναι. Και για να μπορέσουμε να βρούμε τοποθεσίες στο internet θα έπρεπε να έχουμε ένα <b>τεράστιο</b> κατάλογο με αντιστοιχία διευθύνσεων σε ονόματα των site που αντιστοιχούν, ή ιδιότητες των site κ.λ.π. Και κάθε φορά που θα θέλαμε να επισκεφθούμε μια τοποθεσία θα έπρεπε να κατεβάζουμε τον αντίστοιχο τόμο από τη βιβλιοθήκη μας και να τον ψάχνουμε, μέχρι να βρούμε αυτή την τοποθεσία που ψάχνουμε... Ακόμα χειρότερα, κάθε φορά που ένα καινούργιο site θα δημιουργόταν στο διαδίκτυο, θα έπρεπε να ανανεώσουμε το ράφι με αυτούς τους καταλόγους!</p>
<p class="en">And why do we point all of these? Do you see words like google.com, blogspot.gr or my_really_really_fancy_site.biz anywhere? No, because <b>THEY DO NOT EXIST</b>. In order to visit Google's search engine, the site that contains many blogs or another web site we are interested in, we have to remember a lot of numbers that will give our browser the information of which site we want to visit. Kind of hard, isn't it?... Yeap!. And in order to be able to find out some websites later we should own a really <b>huge</b> index that should have a one to one correlation between addresses and site names or site properties etc. And every time we would like to visit a site we should take the corresponding volume from our library and search through it untili we find tyhe desired site... There's even worse, every time a new site appeared in the total network, we should update the index!</p>
<p class="el">"Χμμμ... Μα εγώ δε θυμάμαι να δίνω τέτοια νούμερα που αναφέρεις στον browser μου...". Επειδή ακριβώς το να θυμόμαστε νούμερα είναι πολύ δυσκολότερο από το να θυμόμαστε λέξεις, για να μη μπαίνουμε στον κόπο να ψάχνουμε τις διευθύνσεις που πρέπει να δώσουμε για να μπορέσουμε να προσπελάσουμε τον κάθε ιστότοπο που επιθυμούμε, έχουν δημιουργηθεί κάποιοι servers οι οποίοι κάνουν ακριβώς αυτό· αντικαθιστούν το τεράστιο ράφι της βιβλιοθήκης μας, που λέγαμε πριν... Τους δίνουμε ένα όνομα ιστότοπου και αν αυτό υπάρχει μας επιστρέφουν διεύθυνση IP στην οποία βρίσκεται ο εν λόγω ιστότοπος. Αλλά μπορούν να κάνουν και το αντίθετο, δηλαδή να μας πουν το όνομα του ιστότοπου στον οποίο οδηγεί μια διεύθυνση.</p>
<p class="en">"Hmmm... But I don't remember specifying such numbers in my browser...". Due to the difficulty in remembering numbers compared to remembering words, in order not to try to search through IP addresses every time we need to access a site, there are some servers they perform this action for us: They replace the huge library shelf we were talking about... We can send them the site name we want to access and they return the IP address the web site in question lies. But they can also perform the reverse function; they can tell the name of the website an IP address points to.</p>
<a id="NoIPWhat"></a>
<h4 class="el">Διαδικασία ονοματοδοσίας</h4>
<h4 class="en">Naming</h4>
<p class="el">Και το ερώτημα είναι πώς γίνεται μια ονοματοδοσία στον τεράστιο χώρο του internet; Όταν κάποιος θελήσει να στήσει ένα server στο διαδίκτυο, τότε θα πρέπει να κατοχυρώσει ένα όνομα, το οποίο όλοι οι υπόλοιποι θα χρησιμοποιούν για να έχουν πρόσβαση σε αυτή την υπηρεσία που προσφέρει ο εν λόγω εξυπηρετητής. Αυτό το όνομα είναι μοναδικό. Αφού κατοχυρωθεί το όνομα, σε κάποιο server του διαδικτύου, μπορεί να φιλοξενηθεί η ιστοσελίδα ή η υπηρεσία που μας ενδιαφέρει. Ο server αυτός έχει κάποια συγκεκριμένη διεύθυνση IP. Μπορεί να ανήκει σε κάποια εταιρία φιλοξενίας (hosting) ιστοσελίδων, ή ακόμα και στον υπολογιστή που έχουμε στο σπίτι μας! Το τελευταίο βήμα, είναι να "παντρέψουμε" το όνομα που κατοχυρώσαμε με τη διεύθυνση στην οποία βρίσκεται η εν λόγω ιστοσελίδα/υπηρεσία· αυτή, συνήθως, τη φτιάχνουμε εμείς.</p>
<p class="en">And the question now is how the naming of the sites happen throughout the huge internet space? If someone wants to set a server in the internet, he must first register a name, the one that all the others will use to be served by the server in question. This name must be unique. After the registration of the name, another server must host the web page or the needed service to be offered. That server must have a specific IP address. It can be owned by a web hosting company, or can be even the computer we have at our place! The final step is to tie together the name and the IP address in question. The web page or the service is the one that we create.</p>
<div class="separator" style="clear: both; margin:5px; text-align: center;"><a href="http://static.ddmcdn.com/gif/dns-rev-1.gif" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img style="border:1px solid #4763B0;border-radius:8px" width="380px" src="http://static.ddmcdn.com/gif/dns-rev-1.gif" /></a></div>
<p class="el">Πού βρίσκεται το πρόβλημα; Όταν το μόνο που μας ενδιαφέρει είναι να έχουμε ένα ωραιότατο server για δική μας δουλειά, θα πρέπει να κατοχυρώσουμε ένα όνομα στο διαδίκτυο (=κόστος), να πληρώσουμε σε κάποια εταιρία hosting χώρο που να τον διαμορφώσουμε κατάλληλα ώστε να φιλοξενήσει την υπηρεσία που μας ενδιαφέρει (=κόστος) και τέλος να δηλώσουμε σε κάποιο DNS ότι το όνομα που κατοχυρώσαμε "δείχνει" στον server της εταιρίας hosting (=κόστος) η οποία φιλοξενεί την υπηρεσία μας... Εναλλακτικά, μπορούμε να πληρώσουμε τον ISP μας για να μας δώσει σταθερή IP διεύθυνση, οπότε τη φιλοξενία της υπηρεσίας μας την κάνουμε στον υπολογιστή στο σπίτι μας. Όλα αυτά μας επιβαρύνουν οικονομικά.</p>
<p class="en">Where the problem is? If the only thing that matters is to have a nice personal server, for our personal usage only, we should buy an internet domain name (=added cost), pay a hosting service company to give us space in their servers, configure that space to host our service (=added cost) and finally submit the new domain name in a DNS pointing the IP address of the host server (=added cost, again) that serves our service... Also an alternative is to pay our ISP to give us a static IP address, so we can use our own computer to serve whatever we want from our home. But all these cost us money.</p>
<p class="el">Το ερώτημα είναι: «Αφού δεν κάνω επαγγελματική ιστοσελίδα, αλλά με ενδιαφέρει να έχω πρόσβαση στο δίκτυό μου για τη δική μου διευκόλυνση και μόνο. Δε μπορώ να το κάνω χωρίς κόστος;» Αυτό που χρειαζόμαστε είναι μια υπηρεσία που να μπορεί να μας αντιστοιχεί μια δυναμική διεύθυνση σε ένα σταθερό όνομα.</p>
<p class="en">The question is: "Since I don't service a professional web page, but I just want to have access to my own home network for my convenience and only, does it have to cost me that much?". In that case what we really need is a web service that can bound a static domain name to a dynamic IP address, just as a normal DNS server does.</p>
<a id="NoIPDNS"></a>
<h4 class="el">Δυναμικός DNS για δυναμικές IP</h4>
<h4 class="en">Dynamic DNS for Dynamic IP addresses</h4>
<p class="el">Αυτή είναι μια υπηρεσία που πλέον βρίσκεται αρκετά στο διαδίκτυο. Η εγγραφή σε μια υπηρεσία δυναμικού DNS είναι μια απλή λύση στο πρόβλημά μας. Οι περισσότερες δυναμικές DNS υπηρεσίες που προσφέρονται από κάποια sites, θέλουν να έχει κάποιος ένα κατοχυρωμένο όνομα. Άλλες πάλι, αφήνουν τον χρήστη να επιλέξει από μια σειρά ονόματα που έχει διαθέσιμα. Ένα χαρακτηριστικό παράδειγμα είναι το DynDNS.</p>
<p class="en">This is a service that can be found nowadays on the internet. The registration in a Dynamic DNS service is a simple solution to our problem. Most of the Dynamic DNS services available through some sites, just need someone to have a registered domain name. Some other, let the user select one from the available to that site domain names. An example is DynDNS.</p>
<p class="el">Το DynDNS είναι ένα site που προσφέρει υπηρεσίες δυναμικού DNS. Ο χρήστης έχει τη δυνατότητα να χρησιμοποιήσει ένα όνομα της αρεσκείας του, αρκεί αυτό να ανήκει σε domains που ανήκουν στην ίδια τη DynDNS. Παράδειγμα, ένας χρήστης θα μπορούσε να χρησιμοποιεί το όνομα eliasfiles.dyndns-at-home.org γιατί ανήκει στο domain της DynDNS (dyndns-at-home.org). Το καλό που έχει το DynDNS είναι πως τα περισσότερα, πλέον, routers έχουν ενσωματωμένη την υποστήριξη για τη συγκεκριμένη υπηρεσία. Όμως, τον τελευταίο καιρό το site άρχισε να προσφέρεις τις υπηρεσίες του με πληρωμή. Πιο συγκεκριμένα, ένας καινούργιος χρήστης είναι υποχρεωμένος να δοκιμάσει την υπηρεσία DynDNSPro ελεύθερα για 14 ημέρες και αν δεν τη διακόψει νωρίτερα τότε χρεώνεται για τη χρήση της. Αυτό του δίνει το δικαίωμα να έχει την υπηρεσία για ένα χρόνο. Αν τη διακόψει πριν τη 14η ημέρα, τότε δε μπορεί να έχει καθόλου υπηρεσίες DynDNS. Για κάποιον ο οποίος θέλει να έχει πρόσβαση σε κάποια αρχεία του, κάποια βάση δεδομένων με δικές του πληροφορίες κ.λ.π. δεν είναι ότι καλύτερο να πρέπει να πληρώσει για κάτι το οποίο δεν του αποφέρει καθόλου κέρδος.</p>
<p class="en">DynDNS is a site that offers Dynamic DNS services. The user has the ability to use a domain name he/she likes, provided that this name belongs to domains that really belong to DynDNS itself. For example, a user could use eliasfiles.dyndns-at-home.org because it belongs to a registered DynDNS domain. The good part is that most of the routers available for home usage can be configured to use this service. But, lately the site started to offer their services with a cost. More specifically, a new user is forced to test the DynDNSPro service free of charge for 14 days only. If he/she does not stop using it then, after the 14th day a small fee is charged for one more year usage. If he/she stops using the service then there will be no more DynDNS services. For someone who wants to have access to his files, a personal database having his own data etc, it is not the best idea to pay for something that does not offer him some income.</p>
<a id="NoIP"></a>
<h4 class="el">NoIP: Υπηρεσία δυναμικού DNS για όλους</h4>
<h4 class="en">NoIP: Dynamic DNS Services for all</h4>
<p class="el">Αρκετό ψάξιμο στο internet μου εμφάνισε σελίδες που προσέφεραν υπηρεσίες δυναμικού DNS, αλλά σε όλες έπρεπε να έχει κάποιος κατοχυρωμένο domain name. Τελικά, μια από όλες μου τράβηξε περισσότερη την προσοχή, η <a href="http://www.noip.com">NoIP</a>. Αυτή η σελίδα προσφέρει υπηρεσίες δυναμικού DNS, αλλά και ελεύθερης κατοχύρωσης ονόματος που θα ανήκει στο domain <tt>no-ip.biz</tt> (και άλλα). Κάτι παρόμοιο, δηλαδή, με το παλιό καλό DynDNS.</p>
<p class="en">After a log search through the internet there were many web sites offering Dynamoc DNS services, but they needed the user to have a domain name already registered. Finally, one of them just paid my attention, <a href="http://www.noip.com">NoIP</a>. That web page offers Dynamic DNS, but also gives the ability to use a NoIP registered domain name that belongs to <tt>no-ip.biz</tt> (and many more). It is something similar to DynDNS.</p>
<p class="el">Τι άλλο προσφέρει η NoIP:</p>
<p class="en">What else does NoIP offer:</p>
<ul>
<li class="el">Ελεύθερο (χωρίς χρέωση) Domain Name που ανήκει στο no-ip.biz (ή κάποιο άλλο από τα προκαθορισμένα του)</li>
<li class="en">Free of charge (no cost at all) Domain Name that belongs to no-ip.biz (or another that belongs to NoIP list)</li>
<li class="el">Έναν client που αναλαμβάνει την ενημέρωση της λίστας του DNS με την καινούργια IP. Αυτόν τον ονομάζει DUC - Dynamic Update Client (περισσότερα ακολούθως)</li>
<li class="en">A client program that updates the DNS database with the new IP when there is an IP address change from our ISP. They call it DUC - Dynamic Update Client (more on this later)</li>
<li class="el">Ο DUC είναι ανοιχτού κώδικα</li>
<li class="en">DUC is open sourced!</li>
<li class="el">Οδηγείες για τη δημιουργία δικού μας client αν δε μας αρέσει ο δικός της</li>
<li class="en">There are also information on how to create our own update client if for some reason we don't like theirs</li>
</ul>
<p class="el">Ο NoIP Client είναι ένα πρόγραμμα που τρέχει στον υπολογιστή μας και ανά τακτά διαστήματα ανιχνεύει τη διεύθυνση που έχουμε από τον ISP και αν δει ότι διαφέρει από την προηγούμενη, ενημερώνει τον DNS Server της NoIP για την καινούργια διεύθυνση. Έτσι, το όνομα το οποίο έχουμε κατοχυρώσει δείχνει στην καινούργια μας διεύθυνση. Το ίδιο ακριβώς σύστημα έχει και το DynDNS με ένα πρόγραμμα client που ονομαζόταν <tt>ddclient</tt>.</p>
<p class="en">NoIP Client is a small program that runs in our computer and at regular intervals it checks for our IP address the ISP has set and if it is different from the one we had earlier, then it updates NoIP DNS server. So, the domain name we have registered points to our new IP address. DynDNS laso uses the same updating system, using a client called <tt>ddclient</tt>.</p>
<p class="el">Πλεονεκτήματα της χρήσης ενός client προγράμματος είναι ότι αυτός τρέχει σε έναν υπολογιστή και ενημερώνει τη NoIP για τις αλλαγές της IP διεύθυνσης χωρίς να χρειάζεται να κάνει κάτι ο χρήστης.</p>
<p class="en">The advantage of using an update client program is that it runs in a computer at the background and informs NoIP whenever there is an IP address change, without user's intervention.</p>
<p class="el">Μειονεκτήματα της χρήσης ενός client είναι πως ο client λειτουργεί μόνο όση ώρα είναι σε λειτουργία ο υπολογιστής που τον τρέχει. Συνεπώς, υπάρχει η περίπτωση να πρέπει να έχουμε ένα υπολογιστή ενεργοποιημένο 24 ώρες το 24ωρο. Ο client ελέγχει για αλλαγή διεύθυνσης ανά τακτά διαστήματα. Τέτοια αλλαγή μπορεί να γίνει οποιαδήποτε ώρα και στιγμή από τον provider. Αυτό οδηγεί στο δεύτερο μειονέκτημά, πως από τον χρόνο που θα εκτελέσει ο ISP μια αλλαγή στη διεύθυνσή μας μέχρι τη στιγμή που ο client θα ελέγξει για μια τέτοια κατάσταση, ο DNS θα έχει την παλιά μας διεύθυνση και έτσι δε θα μπορούμε να έχουμε πρόσβαση στον server μας γι' αυτό το χρονικό διάστημα. Τέλος, ο client για να ανιχνεύσει την αλλαγή της διεύθυνσης, στέλνει ένα request στο server της NoIP. Αυτό σημαίνει διακίνηση δεδομένων στο διαδίκτυο, κατά συνέπεια δε μπορούμε να ρυθμίσουμε τον client να κάνει τον έλεγχο σε πολύ τακτά χρονικά διαστήματα (π.χ. 5 δευτερολέπτων). Χρήση τακτικών ελέγχων βοηθάει στο να μειώσουμε το χρόνο της ασυμφωνίας της διεύθυνσης που έχει ο DNS με την πραγματική μας, μετά από αλλαγή από τον ISP. Ταυτόχρονα, όμως, αυξάνει και τη διακίνηση πληροφορίας προς τον NoIP server. Αποτέλεσμα είναι να κινδυνεύουμε να μας κάνει τελικά ban ο server και να μη δέχεται τις πληροφορίες μας, διότι θεωρεί ότι του κάνουμε ηλεκτρονική επίθεση.</p>
<p class="en">The drawback of using such a client is that it works only when the computer that runs it is powered on. Thus, we may have to keep our computer running 24 hours a day. The client checks for an address change at regular intervals. An IP address can be performed by the internet provider any time. This leads to a second drawback. From the time the ISP changes our IP address till the time the update client does its job, the DNS servers over the internet will have our old IP address, so we will not be able to access our server during that time. Finally, the client tracks the address change by sending a request to NoIP server. This, in turn, means internet traffic, so we cannot configure the client to use a small update interval (such as 5 seconds). The small updating interval helps having a small lag during IP address change and DNS tables updating. But, at the same time increases the traffic to NoIP server. This could make NoIP server to ban us and ignoring information send by our update client, because it could thing we perform an electronic attack.</p>
<a id="NoIPRasbPi"></a>
<h4 class="el">Γιατί το Raspberry Pi;</h4>
<h4 class="en">Why Raspberry Pi?</h4>
<p class="el">Το Raspberry Pi είναι ένας μικρός υπολογιστής μεγέθους πιστωτικής κάρτας (όχι δε μπορείτε να κάνετε πληρωμές σε καταστήματα με αυτό! :)) βασισμένος σε αρχιτεκτονική επεξεργαστή ARM. Καταναλώνει ελάχιστα και τρέχει οποιαδήποτε διανομή Linux (ή ακόμα και <a href="http://www.freebsd.org/">FreeBSD</a>) είναι μεταγλωττισμένη γι' αυτή την αρχιτεκτονική. Είναι πολύ βολικό για τέτοιες καταστάσεις.</p>
<p class="en">Raspberry Pi is a small computer at the size of a credit card (well, no, you cannot perform in shop payments using it! :)) based on ARM architecture. It consumes little power and can run any Linux distribution (or even <a href="http://www.freebsd.org/">FreeBSD</a>) that is compiled for that architecture. It is very convenient for cases like ours.</p>
<div class="separator" style="margin:5px; clear: both; text-align: center;"><a href="http://images.bit-tech.net/content_images/2013/03/raspberry-pi-case-competition-update/pi1l.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img width="320px" style="border:1px solid #4763B0;border-radius:8px" src="http://images.bit-tech.net/content_images/2013/03/raspberry-pi-case-competition-update/pi1l.jpg" /></a></div>
<p class="el">Επίσης, δεν υπάρχει λόγος γιατί να πρέπει να λειτουργεί 24/7 ένας υπολογιστής (εκτός και αν είναι απαραίτητο για άλλους σκοπούς). Το Raspberry Pi λόγω της μικρής του κατανάλωσης, αλλά και του μικρού του μεγέθους, μπορεί να λειτουργεί συνεχώς, χωρίς πρόβλημα, ενώ δεν πιάνει χώρο επάνω σε ένα γραφείο, όπως τα PC. Μπορεί να μπει δίπλα από το router μας (κάποια από αυτά διαθέτουν και μια USB θύρα και μπορούν να το τροφοδοτήσουν), ενώ υπάρχουν αρκετά όμορφα κουτάκια τα οποία το κάνουν να δείχνει σοβαρό σε οποιοδήποτε χώρο (μη φωνάζει η γυναίκα πως δεν ταιριάζει με τις κουρτίνες :Ρ).</p>
<p class="en">There is no reason why a PC computer should be on 24/7 (unless it must be on for specific services). Because Raspberry Pi consumes so little power and because of its small size, it can be powered on without problems, and at the same time it has small footprint on our desktop, unlike PCs. It can live side by side with our router (some of them having USB connectors can also power it). There are also some very good looking boxes for it, making suitable for the space it lives in our house (not to let your wife comlain that it does not suit with the curtains of the room :Ρ).</p>
<p class="el">Όσα περιγράφονται στο παρόν άρθρο έχουν γίνει επάνω στο λειτουργικό Raspbian που είναι βασισμένο στο Debian. Επειδή, όμως, οι διανομές Linux έχουν πάρα πολλά κοινά μεταξύ τους, δεν υπάρχει λόγος γιατί, με έστω λίγες αλλαγές, να μη μπορούν να τρέξουν και σε οποιαδήποτε άλλη διανομή για οποιαδήποτε αρχιτεκτονική.</p>
<p class="en">What is described in this article is done in Raspbian operating system which is based on Debian. But, since Linux distributions share a lot in common, there is no particular reason why, even with small changes, they cannot be done in other distribution or architecture.</p>
<a id="NoIPClient"></a>
<h4 class="el">Ο Dynamic Update Client της NoIP</h4>
<h4 class="en">NoIP Dynamic Update Client</h4>
<p class="el">Η NoIP δίνει έναν client για το update της διεύθυνσης IP στον DNS τους, ο οποίος είναι γραμμένος σε γλώσσα C. Για απλή χρήση είναι αυτό που χρειάζεται κάποιος. Μπορείτε να τον κατεβάσετε και να τον κάνετε compile κανονικά, όπως και κάθε άλλο πρόγραμμα. Στο Raspberry Pi γίνεται κανονικά compile, ενώ τρέχει χωρίς κανένα πρόβλημα.</p>
<p class="en">NoIP provides an update client for updating their DNS server with our new IP address. It is written in C language. For a simple use it is what anybody needs. You can download and compile it normally, as any other program that can be installed from its source code. In Raspberry Pi its compilation and execution runs flawlessly without any problems.</p>
<p class="el">Η εγκατάσταση είναι απλή. Αρχικά κατεβάζετε τον πηγαίο κώδικα, μιας και είναι opensource, από το <a href="http://www.noip.com/">site της NoIP</a>. Στη συνέχεια αποσυμπιέζετε το αρχείο:</p>
<p class="en">The installation is very simple. First you download the program's source code, since it is opensource, from <a href="http://www.noip.com/">NoIP site</a>. The decompression follows:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:~ > tar -xvzf noip-duc-linux.tar.gz
...
pi@raspberrypi:~ >
</div></pre>
<p class="el">Αυτό θα δημιουργήσει ένα κατάλογο με όνομα <tt>noip-<i>version</i></tt>. Μέσα σε αυτόν βρίσκεται όλος ο πηγαίος κώδικας, scripts για διάφορες διανομές ώστε να λειτουργέι σαν υπηρεσία κ.λ.π. Μπορείτε ελεύθερα να περιηγηθείτε μέσα στα περιεχόμενα του καταλόγου. Όταν τελικά αποφασίσετε να το εγκαταστήσετε κάνετε τα ακόλουθα: <i>(η έκδοση που βρίσκεται ο DUC τη στιγμή που γράφεται το άρθρο είναι η 2.1.9-1)</i></p>
<p class="en">A directory named <tt>noip-<i>version</i></tt> will be created. In there you can find the source code, service scripts for some distributions, etc. You can freely browse through the contents of the directory. When you finally decide to install it just do the following: <i>(The version of DUC the time this article is edited is 2.1.9-1)</i></p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:~ > cd ~/noip-2.1.9-1
pi@raspberrypi:~ > make
...
pi@raspberrypi:~ > sudo make install
...
pi@raspberrypi:~ >
</div></pre>
<p class="el">Αυτές οι εντολές θα εγκαταστήσουν το <tt>noip2</tt> στον κατάλογο <tt>/usr/local/bin</tt>. Οι πληροφορίες που δίνονται στα διάφορα αρχεία <tt>README.FIRST</tt> είναι αρκετές για να το χρησιμοποιήσετε.</p>
<p class="en">These commands will install <tt>noip2</tt> in <tt>/usr/local/bin</tt> directory. The provided information by various files like <tt>README.FIRST</tt> are enough to make you use it.</p>
<p class="el">Μιας και τα μειονεκτήματα του DUC τα είδαμε πριν, ας προχωρήσουμε σε μια διαφορετική υλοποίηση από αυτή του NoIP DUC που βελτιώνει κάποια χαρακτηριστικά.</p>
<p class="en">Since we presented the drawbacks of DUC earlier, lets proceed to a different implementation than that of NoIP's DUC, that improves it.</p>
<a id="NoIPRouter"></a>
<h4 class="el">Μείωση του Internet Traffic</h4>
<h4 class="en">Internet Traffic Reduction</h4>
<p class="el">Η μεγαλύτερη διακίνηση πληροφορίας που γίνεται στο Internet από τον client είναι για την εύρεση της IP διεύθυνσης που μας έχει δώσει ο provider μας. Κάθε φορά που ο DUC θέλει να μάθει την IP μας, υποβάλει ένα ερώτημα στον server της NoIP. Αυτός βλέπει από ποια IP γίνεται το ερώτημα και την επιστρέφει στον DUC. Αν διαπιστωθεί αλλαγή της, τότε ο DUC στέλνει άλλο ένα request που αναφέρει πως θα πρέπει να γίνει η αλλαγή της διεύθυνσης και στον κατάλογο του DNS. (αυτή είναι η γενική ιδέα)</p>
<p class="en">The most exchanged data by the client program through the internet is the question of the current IP address our ISP provided to us. Every time DUC wants to find our IP, it sends a request to NoIP's server. The server checks which is the source IP of the request and returns it to DUC. If DUC finds a different IP than the one of the previous request, it sends another request for the DNS table updating (That is the general idea)</p>
<p class="el">Επειδή η αλλαγή της διεύθυνσης συμβαίνει σε αραιά χρονικά διαστήματα (ανά μερικές ημέρες), η περισσότερη επικοινωνία που συμβαίνει (το ερώτημα της τρέχουσας IP διεύθυνσης) είναι άσκοπη. Ταυτόχρονα, σκοπός μας είναι να μπορέσουμε να υποβάλουμε ερώτημα για τη διεύθυνση IP τόσο συχνά ώστε να μην υπάρχει μεγάλο χρονικό διάστημα όπου ο DNS περιέχει παλαιά διεύθυνση (να είναι ασυγχρόνιστος).</p>
<p class="en">Since an IP change happens in very big intervals (several days), the most communication traffic happens (the query of tha current IP address) is pointless. At the same time, our goal is to send an IP address query as often as possible, for the time the DNS contains our old address (not be synchronized) be as small as it can be.</p>
<p class="el">Ο πιο απλός τρόπος είναι να μην υποβάλλεται το ερώτημα στον server της NoIP, αλλά στο router μας. Πολλά router έχουν ενεργοποιημένο telnet server, έτσι ώστε να μπορούμε να συνδεθούμε με αυτό το πρωτόκολλο και να εκτελούμε εντολές. Μια άλλη εναλλακτική υπάρχει αν το router που διαθέτουμε τρέχει ssh server, οπότε μπαίνουμε με ssh στο router και πάλι μπορούμε να εκτελέσουμε εντολές. Κάποια, βέβαια, routers δεν έχουν τίποτα από τα δυο (π.χ. κάτι oxygen)... Εκεί θα πρέπει να κάνουμε ερώτημα μέσω https (συνήθως).</p>
<p class="en">The simplest way is to send the IP address query, not to NoIP's server but to our router. Many routers provide a telnet server, thus, we can connect to it using that protocol and execute commands. Another alternative exists is our router runs a ssh server, so we connect to it using ssh and again we can execute commands. Well, there is also the possibility for some routers not to provide any of the above (ie. some oxygen routers)... We can send them queries using https protocol (usually).</p>
<p class="el">Επειδή δεν είναι σταθερός ο τρόπος με τον οποίο υποβάλλουμε ερώτημα για την IP στο router, σε αυτό το άρθρο θα παρουσιαστεί ένα script που είναι για χρήση σε πρωτόκολλο <tt>telnet</tt> που είναι και το πιο συχνά εμφανιζόμενο. Συγκεκριμένα έχει δοκιμαστεί σε τρία διαφορετικά routers. Ένα ZTE (που δίνει ο ΟΤΕ), ένα TP-Link και ένα AirTies. Φυσικά, με διαφορετικό configuration. Τα δύο από τα τρία εκτελούν κανονικές εντολές Linux, ενώ το TP-Link έχει δικές του εντολές.</p>
<p class="en">Since the way we question our router for our IP address is not by default the same to all routers, in this article we present a script that uses <tt>telnet</tt> protocol, which is the most applicable. We have tested it in three different routers, a ZTE (the Greek Telecomunications Company provides), a TP-Link and an AirTies. Of course, we used different configuration. Two of these execute normal Linux commands, while the TP-Link has its own.</p>
<p class="el">Αρχικά, ας δημιουργήσουμε τις συνθήκες για να κάτσουν τα script. Πρώτο βήμα είναι να φτιαχτεί ο κατάλογος που θα φιλοξενήσει τα scripts:</p>
<p class="en">First, lets create the space our scripts will sit in. The first step is to create a directory that will host the scripts:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:~ > sudo mkdir /usr/scripts
pi@raspberrypi:~ > cd /usr/scripts
pi@raspberrypi:/usr/scripts >
</pre></div>
<p class="el">Ας δούμε το script που υποβάλλει ερώτημα στο router για την IP. Το script είναι γραμμένο σε python. Μιας και δεν είμαι γνώστης της python, δεν περιμένω ότι το script αυτό είναι το τελειότερο του κόσμου (λέμε τώρα!). Είναι το πρώτο script που γράφω στη συγκεκριμένη γλώσσα προγραμματισμού οπότε κάποιος έμπειρος python προγραμματιστής πολύ πιθανό να βρει κάποιες ατέλειες. Επίσης, είναι μια πρώτη έκδοση. Σκοπεύω στο μέλλον (κοντινό) να του μπαλώσω μια "τρύπα" που έχει. Αλλά για την ώρα κάνει τη δουλειά του. Μπορείτε να το κάνετε Copy/Paste στον αγαπημένο σας editor από εδώ:</p>
<p class="en">Lets see the script that questions the router for our current IP address. This script is written in python. Since I'm not a python programmer, I don't expect this script to be the most perfect one all over the world (well... matter of speaking!). It is my first python script so any experiences python programmer will find some defects. Also, this is a first version. In the future (near future) I intend to patch a "whole" in there. But for now it does what it promises. You can Copy/Paste it in your favourite editor from here:</p>
<div class="code"><pre class="prettyprint linenums lang-py">
#!/usr/bin/python
# THE SOFTWARE IS LICENSED UNDER GPL2 GENERAL PUBLIC LICENSE v2.
# IN ORDER TO OBTAIN A COPY OF THIS LICENSE PLEASE VISIT THE FOLLOWING
# ADDRESS:
# http://www.gnu.org/licenses/gpl-2.0.html
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#First import the necessary python libraries
import sys
import os
import telnetlib
#Setup the default values, before using the configuration file
ConfFile = "/etc/GetInetIP.conf"
RouterIP = "192.168.1.1"
UserName = "admin"
Password = "admin"
NetComm = "ifconfig ppp0"
AddrPrefix = "inet "
ExpTime = 0.0001
#If the user has entered a CLI argument, use it as the configuration file to be used
InArgs = len(sys.argv)
if InArgs > 2:
sys.stderr.write("ERROR: Only one input argument expexted!\n")
sys.stderr.write("Usage: GetInetIP [configuration_filename]\n");
exit(1)
elif InArgs == 2:
ConfFile = sys.argv[1]
#Need to check if the user specified filename exists. If not => Error
if not(os.path.exists(ConfFile)):
sys.stderr.write("ERROR: Configuration file" + ConfFile + "not found\n")
exit(2)
#Check for the existance of the configuration file
#Time to import the configuration file's values. If the user specified a configuration file
# then it really exists. But if not, we must try to load the configuration file from
# the default path. If this file doesnot exist, then we ave to use our hardcoded values
#NOTE:The execfile command should be changed for security reasons... A more secure approach
# is to parse the configuration file, and not execute it... (no time to fixit right now)
if os.path.exists(ConfFile):
execfile(ConfFile)
#Connect to the specified router using telnet protocol
Conn = ""
try:
Conn = telnetlib.Telnet(RouterIP)
except:
sys.stderr.write("ERROR: Cannot communicate with" + RouterIP +"\n")
exit(3)
#Send the login credentials
RespStr = "First"
FailCount = 3
while (RespStr != "") and (FailCount > 0):
RespStr = Conn.read_until("\n",ExpTime)
LoginFlag = RespStr.find("login:")
if LoginFlag >= 0:
Conn.write(UserName + "\n")
RespStr = Conn.read_until("\n",ExpTime)
PassFlag = RespStr.find("Password:")
if PassFlag >= 0:
Conn.write(Password + "\n")
RespStr = Conn.read_until("\n",ExpTime)
FailCount -= 1
if FailCount == 0:
sys.stderr.write("ERROR: Credentials failed 3 times\n")
exit(4)
#Now the telnet awaits commands! Issue the command that announces the IP needed
Conn.write(NetComm +"\n")
RespStr = Conn.read_until("\n",ExpTime)
InetFlag = False
while (RespStr != "") and not(InetFlag):
InetStrt = RespStr.find(AddrPrefix)
if InetStrt >= 0:
InetFlag = True
InetStrt += len(AddrPrefix)
InetEnd = RespStr.find(" ",InetStrt)
else:
RespStr = Conn.read_until("\n",ExpTime)
Conn.write("exit\n")
DummyStr = Conn.read_all()
Conn.close()
if not(InetFlag):
sys.stderr.write("ERROR: IP Address not found\n")
exit(5)
OutStr = RespStr[InetStrt:InetEnd]
print(OutStr.strip())
exit(0)
</pre></div>
<p class="el">Αυτό το script το σώζουμε με το όνομα <tt>GetInetIP.py</tt> μέσα στον κατάλογο που φτιάξαμε. Για να λειτουργήσει χρειάζεται και ένα configuration αρχείο μέσα στον κατάλογο <tt>/etc</tt>. Προσοχή χρειάζεται στο ότι στο configuration αρχείο βρίσκονται στοιχεία που <b>δεν πρέπει να φτάσουν στα μάτια τρίτων!</b> Κοινώς, το password του router... Το αρχείο θα πρέπει να ονομάζεται <tt>GetInetIP.conf</tt>:</p>
<p class="en">We save it with the name <tt>GetInetIP.py</tt> under the directory we created earlier. For the script to function properly it needs a configuration file in <tt>/etc</tt> directory. Caution is needed as in this configuration file some strings <b>are for your eyes only!</b> More specifically, your router's password... The file must be named <tt>GetInetIP.conf</tt>:</p>
<div class="code">
<h4 class="el">Configuration για router TP-Link</h4>
<h4 class="en">Configuration for TP-Link router</h4>
<pre class="prettyprint linenums lang-py">
RouterIP = "192.168.1.1"
Password = "MyCrazyPassword"
NetComm = "show wan status"
AddrPrefix = "Ip = "
ExpTime = 0.07
</pre></div>
<p class="el">Ας δούμε λίγο τα περιεχόμενα του configuration αρχείου:</p>
<p class="en">Lets see the bones of this configuration file:</p>
<ul>
<li><b>RouterIP:</b> <span class="el">Δηλώνει τη διεύθυνση IP που έχει το router μας</span><span class="en">Specifies the router's IP address</span></li>
<li><b>UserName:</b> <span class="el">Το όνομα χρήστη για το router. Αν δεν δηλώνεται εδώ χρησιμοποιείται η default τιμή που είναι το admin. Κάποια από τα routers δε ζητάνε το username. Σε αυτή την περίπτωση το script το καταλαβαίνει και δεν το στέλνει.</span><span class="en">The username of the router's administrator. If it not specified it takes the default value which is "admin". Some routers do not ask for a username. In that case the script is smart enough to understand it and it does not send a username at all.</span></li>
<li><b>Password:</b> <span class="el">Το password που χρειαζόμαστε για να κάνουμε login στο router</span><span class="en">The password we need to login to router</span></li>
<li><b>NetComm: </b> <span class="el">Η εντολή που εκτελούμε, όταν κάνουμε telnet στο router που μας δείχνει τη διεύθυνση IP που έχει στο WAN. Για το TP-Link είναι <tt>show wan status</tt>, ενώ για ένα router που τρέχει busybox ή γενικά εκτελεί εντολές Linux είναι κάτι του στυλ <tt>ifconfig ppp0</tt></span><span class="en">The command we need to execute, using telnet, that announces the IP address of the WAN. For TP-Link it is <tt>show wan status</tt>, while for a router that runs busybox or executes Linux commands it is something like <tt>ifconfig ppp0</tt></span></li>
<li><b>AddrPrefix:</b> <span class="el">Όποια και αν είναι η εντολή που μας δίνει την επιθυμητή πληροφορία, δεν δίνει απλά ένα ξερό νούμερο, αλλά ολόκληρο κείμενο. Εδώ περιγράφεται τι περιμένει το script για να βρει ακριβώς πριν τη διεύθυνση IP που μας ενδιαφέρει. Αμέσως μετά από αυτό το κείμενο αναφέρεται η πληροφορία μας.</span><span class="en">Whichever the command is to get our IP address, it does not return only this number, but a whole text containing the desired information. This value describes what the script expects just before the IP address we need to filter. Just after that text placed in this variable the IP address appears.</span></li>
<li><b>ExpTime:</b> <span class="el">Είναι ο χρόνος μέσα στον οποίο αν το router δεν στείλει κάποιο χαρακτήρα, θεωρείται πώς δεν έχει κάτι άλλο να στείλει. Προσοχή, σε άλλα router είναι μικρότερος και σε άλλα μεγαλύτερος. Γενικά, ο μεγάλος χρόνος κάνει για όλα τα router, αλλά καθυστερεί την εξέλιξη του script.</span><span class="en">This is the time that the script expects the router to sent a character. If there is no character during this time interval, the script assumes there is nothing more coming from the router as an answer. Be careful, at some routers this time is small while at others it is larger. In general, a bigger value is suitable for all routers but it slows down the performance of the script.</span></li>
</ul>
<p class="el">Αν μπούμε χειροκίνητα σε ένα TP-Link router και δώσουμε την εντολή <tt>show wan status</tt> τότε θα δούμε τα ακόλουθα:</p>
<p class="en">If we manually connect to a TP-Link router and execute the command <tt>show wan status</tt> then it will return the following:</p>
<div class="code"><pre class="prettyprint">
eliaschr@orion:~> telnet router
Trying 192.168.1.1...
Connected to router.
Escape character is '^]'.
Password: *********************
Copyright (c) 2001 - 2011 TP-LINK TECHNOLOGIES CO., LTD.
TP-LINK> show wan status
PVC-0
Status = Up
PVC-1
Status = Up
PVC-2
Status = Up
PVC-3
Status = Up
PVC-4
Status = Up
Ip = 94.71.120.43
PVC-5
Status = Up
PVC-6
Status = Up
PVC-7
Status = Down
TP-LINK>
</pre></div>
<p class="el">Βλέπουμε ότι ακριβώς πριν την IP που μας ενδιαφέρει βρίσκεται το <tt>Ip = </tt>. Αυτό είναι που βάζουμε στο <tt>AddrPrefix</tt>.</p>
<p class="en">We can see that just before the IP address we need to read is <tt>Ip = </tt>. This is what we set <tt>AddrPrefix</tt> to.</p>
<p class="el">Στην περίπτωση του ZTE και του AirTies ένα configuration αρχείο σαν αυτό που ακολουθεί κάνει τη δουλειά:</p>
<p class="en">In case of a ZTE or an AirTies a configuration file like the following does the necessary job:</p>
<div class="code">
<h4 class="el">Configuration για router ZTE - AirTies - Linux style commands</h4>
<h4 class="en">Configuration for ZTE - AirTies routers - Linux style commands</h4>
<pre class="prettyprint linenums lang-sh">
RouterIP = "192.168.1.1"
Password = "MyCrazyPassword"
NetComm = "ifconfig ppp0"
AddrPrefix = "inet addr:"
ExpTime = 0.05
</pre></div>
<p class="el">Φυσικά, όποιο και να είναι το configuration που θα επιλέξετε, το μόνο σίγουρο είναι πως <b>δεν πρέπει να το διαβάζει κανένας, παρά μόνο ο root!</b>:</p>
<p class="en">Of course, whichever is the configuration you choose, it is mandatory <b>to be accessible by no one, except root!</b>:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:/usr/scripts > chown root:root /etc/GetInetIP.conf
pi@raspberrypi:/usr/scripts > chmod 0600 /etc/GetInetIP.conf
pi@raspberrypi:/usr/scripts >
</pre></div>
<a id="NoIPUpdater"></a>
<h4>Dynamic Updater Client script</h4>
<p class="el">Ωραία! Αφού φτιάξαμε το script που μας διαβάζει την IP από το router μας, μένει να φτιάξουμε και το script που θα κάνει τη δουλειά του NoIP DUC. Δημιουργήστε το αρχείο <tt>IP-Updater.sh</tt> στον κατάλογο <tt>/usr/scripts</tt> που φτιάξαμε πριν. Το αρχείο αυτό θα πρέπει να το κάνετε Copy/Paste από εδώ:</p>
<p class="en">Great! After we created the script that reads our router's WAN IP address, we have to create a new script that will simulate NoIP DUC. Just create the file named <tt>IP-Updater.sh</tt> under the directory <tt>/usr/scripts</tt> as earlier. You can Copy/Paste the source of the script in question from here:</p>
<div class="code"><pre class="prettyprint linenums lang-sh">
#!/bin/bash
# THE SOFTWARE IS LICENSED UNDER GPL2 GENERAL PUBLIC LICENSE v2.
# IN ORDER TO OBTAIN A COPY OF THIS LICENSE PLEASE VISIT THE FOLLOWING
# ADDRESS:
# http://www.gnu.org/licenses/gpl-2.0.html
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# The script uses a configuration file that is called /etc/IP-Updater.conf
# Valid lines in the script are:
# NoIPUser=the_username_of_NoIP_login_account
# NoIPPass=the_password_of_the_account
# NoIPHost=the_host_to_which_the_IP_is_going_to_be_updated
# FindIPComm=/path/to/the_command_line_to_be_executed_to_get_the_IP
# FailIPDelay=Delay in seconds before retrying to find out the new
# IP address, after a failure
# RepeatDelay=Delay in seconds before trying to refresh the IP after a
# successful update
# FailDelay=Delay in seconds if there is a fatal error in NoIP. (Only if PreventExit=true)
# WGetDelay=Delay in seconds if there is a failure in wget to NoIP
# WGetLongFailDelay=Delay in seconds after Maximum number of failures reached
# WGetMaxFails=Maximum wget sequensial failures that make the daemon exit (unless
# PreventExit=true
# MaxFailIPCnt=Maximum number of retries to fetch IP address from router
# while it seems to have connection to the internet
# PreventExit={true/false} If true, then upon fatal error the script never ends
# SuccessCmd=Command to execute after a successful update to No-IP
# FailCmd=Command to execute after a failed NoIP update
# ExitCmd=Command to execute if the program must exit because of Fatal Error
# In ExitCmd, FailCmd and SuccessCmd you can use the following values as input:
# $NoIPResp: if you want to include the responce from NoIP after the
# request of IP Address updating
# $NewIP: the new IP that found and sent to NoIP
# $CurrIP: the old IP that the system had before the update
# $CurDate: the time that the execution of the IP update happened
PIDFILE=/var/run/IP-Updater.pid
PID=$BASHPID
LOGME="logger -ist 'NoIP-Updater'"
TEMPFILE="/tmp/CurrentIP"
TEMPWGET="/tmp/CurrentIP.wget"
CONFFILE="/etc/IP-Updater.conf"
USERAGENT="WGet from Raspberry Pi Linux/1.0 eliaschr@gmail.com"
NoIPUser=""
NoIPPass=""
NoIPHost=""
FindIPComm="echo 'ERROR: No router IP fetch program specified' >&2; exit 4;"
PreventExit=true
FailDelay=1800
MaxFailIPCnt=3
FailIPDelay=15
RepeatDelay=60
WGetDelay=5
WGetLongFailDelay=60
WGetMaxFails=10
SuccessCmd=""
FailCmd=""
ExitCmd=""
WGetErrMess[1]="Generic error code"
WGetErrMess[2]="Parse error"
WGetErrMess[3]="File I/O error"
WGetErrMess[4]="Network failure"
WGetErrMess[5]="SSL verification failure"
WGetErrMess[6]="Username/password authentication failure"
WGetErrMess[7]="Protocol errors"
WGetErrMess[8]="Server issued an error response"
CurrIP="x"
test -r $CONFFILE || ( echo "Failed to load the configuration file $CONFFILE..." >&2;
exit 1 )
source $CONFFILE
touch $TEMPFILE
echo "" > $TEMPFILE
touch $PIDFILE
echo $PID > $PIDFILE
while true
do
source $TEMPFILE
FailCounter=$MaxFailIPCnt
NextDelay=$RepeatDelay
NewIP=`$FindIPComm`
Status=$?
while (( $Status != 0 ))
do
CurDate=`date +%T`
$LOGME "$CurDate WARNING: Could not read the IP address"
if (( $FailCounter == 0 ))
then
$LOGME "Too many failures... Abording"
rm $PIDFILE
exit 2
fi
sleep $FailIPDelay
PingStat=`ping -c1 www.no-ip.com > /dev/null; echo $?`
if [[ "$PingStat" == "0" ]]
then
NewIP=`$FindIPComm`
Status=$?
FailCounter=$((FailCounter -1))
fi
done
if [[ "$CurrIP" != "$NewIP" ]]
then
CurDate=`date +%T`
WGetStatus=`wget -qO $TEMPWGET -U "$USERAGENT" --user=$NoIPUser --password=$NoIPPass "http://dynupdate.no-ip.com/nic/update?hostname=${NoIPHost}&myip=$NewIP"; echo $?`
NoIPResp=`cat $TEMPWGET`
if (( $WGetStatus == 0 ))
then
WGetFails=$WGetMaxFails
case ${NoIPResp/ */} in
"good")
FailIPResult=0
echo "CurrIP=$NewIP" > $TEMPFILE
$LOGME "IP Address successfuly updated"
;;
"nochg")
FailIPResult=1
HostIPResp=`host $NoIPHost`
if (( $? == 0 ))
then
HostIP=${HostIPResp/* /}
if [[ "$HostIP" == "$NewIP" ]]
then
FailIPResult=0
Comment="successfuly"
echo "CurrIP=$HostIP" > $TEMPFILE
else
Comment="but it seems different than expected..."
NextDelay=$FailIPDelay
fi
else
Comment="but could not resolve $NoIPHost"
NextDelay=$FailIPDelay
fi
$LOGME "$CurDate WARNING: The IP in NoIP was updated by another process $Comment"
;;
"nohost")
FailIPResult=1
$LOGME "$CurDate ERROR: Hostname supplied does not exist under specified account"
;;
"badauth")
FailIPResult=1
$LOGME "$CurDate ERROR: Invalid username password combination"
;;
"badagent")
FailIPResult=2
$LOGME "$CurDate ERROR: Client disabled. Client should exit and not perform any more updates without user intervention"
;;
"\!donator")
$LOGME "$CurDate ERROR: An update request was sent including a feature that is not available to that particular user"
FailIPResult=1
;;
"abuse")
$LOGME "$CurDate ERROR: Username is blocked due to abuse. Either for not following our update specifications or disabled due to violation of the No-IP terms of service"
FailIPResult=1
;;
"911")
$LOGME "$CurDate FATAL ERROR: NoIP.com error such as a database outage. Retry the update no sooner 30 minutes"
FailIPResult=1
NextDelay=1800
;;
*)
$LOGME "$CurDate ERROR: Unknown responce from NoIP.com - $NoIPResp"
FailIPResult=1
;;
esac
case $FailIPResult in
0)
eval $SuccessCmd
;;
1)
eval $FailCmd
;;
*)
if $PreventExit
then
NextDelay=$FailDelay
eval $FailCmd
else
eval $ExitCmd
rm $PIDFILE
exit 3
fi
;;
esac
else
$LOGME "$CurDate ERROR: Wget exited with error status $WGetStatus: ${WGetErrMess[$WGetStatus]}"
WGetFails=$((WGetFails -1))
if (( $WGetFails == 0 ))
then
WGetFails=1
NextDelay=$WGetLongFailDelay
else
NextDelay=$WGetDelay
fi
fi
fi
sleep $NextDelay
done
</pre></div>
<p class="el">Αυτό το script είναι γραμμένο σε bash shell. Και αυτό για να λειτουργήσει χρειάζεται το configuration αρχείο του, <tt>/etc/IP-Updater.conf</tt>. Ένα δείγμα του εν λόγω αρχείου φαίνεται ακολούθως:</p>
<p class="en">The is a bash shell script. It also needs its configuration file, <tt>/etc/IP-Updater.conf</tt>. A sample of this file follows:</p>
<div class="code"><pre class="prettyprint linenums lang-sh">
NoIPUser=noipusermail@myisp.gr
NoIPPass="MyUltraFancyPassword!"
NoIPHost=myhostname.no-ip.biz
FindIPComm="/usr/scripts/GetInetIP.py"
FailIPDelay=15
RepeatDelay=60
FailDelay=1800
MaxFailIPCnt=3
PreventExit=true
SuccessCmd="/usr/bin/ttytter -keyf=/etc/ttytter/Servertty -silent -status=\"\`date\` IP Updated successfully. NoIP Response is: \$NoIPResp\""
FailCmd="/usr/bin/ttytter -keyf=/etc/ttytter/Servertty -silent -status=\"\`date\` IP Update failed. NoIP Response is: \$NoIPResp\""
ExitCmd="/usr/bin/ttytter -keyf=/etc/ttytter/Servertty -silent -status=\"\`date\` Fatal Error during IP Update. NoIP response is: \$NoIPResp. Exiting...\""
</pre></div>
<p class="el">Ας δουμε μια λίστα με πιθανές παραμέτρους του αρχείου:</p>
<p class="en">Lets see a list of the possible parameters that can be specified in this file:</p>
<ul>
<li><b>NoIPUser:</b> <span class="el">Δηλώνει τη διεύθυνση mail του λογαριασμού του χρήστη που έχουμε φτιάξει στο NoIP</span><span class="en">Specifies the e-mail address of the NoIP user's account we have created</span></li>
<li><b>NoIPPass:</b> <span class="el">Το password που έχουμε στο NoIP λογαριασμό</span><span class="en">The password for this account</span></li>
<li><b>NoIPHost:</b> <span class="el">Το όνομα του domain που έχουμε καταχωρήσει</span><span class="en">The domain name we own (or the one from the default that NoIP provides).</span></li>
<li><b>FindIPComm:</b> <span class="el">Δηλώνεται το script που όταν τρέξει μας δίνει τη διεύθυνση IP του router. Κοινώς, το script που φτιάξαμε πριν σε python</span><span class="en">The script name (command) that returns the IP address from our router. It is the script in python, we created earlier</span></li>
<li><b>FailIPDelay:</b> <span class="el">Όταν δεν καταφέρει να διαβάσει την IP από το router, όπως σε περίπτωση που το router δεν έχει πάρει ακόμα IP μετά από διακοπή ρεύματος, ή το router είναι σβηστό, το script περιμένει όσα δευτερόλεπτα ορίζονται σε αυτή την παράμετρο, πριν ξαναπροσπαθήσει</span><span class="en">When the script fails to read the WAN IP from the router, as in case the router still waits for the ISP to send its IP after a power failure, or even if the router is powered off, the script sleeps for as many seconds as specified in this parameter before retrying</span></li>
<li><b>RepeatDelay:</b> <span class="el">Όταν διαβάσει σωστά μια IP διεύθυνση, δηλώνει σε πόσο χρόνο θα ξαναπροσπαθήσει να δει αν υπάρχει αλλαγή της</span><span class="en">When the script fetches the IP address correctly, this parameter defines how much time it will wait until it checks again for an IP change</span></li>
<li><b>FailDelay:</b> <span class="el">Όταν υπάρξει πρόβλημα στην ενημέρωση της καινούργιας IP, όπως σε περίπτωση που το NoIP επιστρέψει "911", το script περιμένει όσο χρόνο δηλώνεται εδώ σε δευτερόλεπτα πριν ξαναπροσπαθήσει την ενημέρωση του NoIP DNS</span><span class="en">When there is a failure during NoIP address update request, as in case NoIP server answers with "911", the script waits for such time as described in here, in seconds before retrying</span></li>
<li><b>MaxFailIPCnt:</b> <span class="el">Ο μέγιστος αριθμός προσπαθειών στις οποίες δε θα μπορέσει να διαβάσει την IP διεύθυνση από το router, ενώ πιστοποιείται πως υπάρχει σύνδεση με το internet. Αυτή η κατάσταση κανονικά δεν πρέπει να υπάρξει ποτέ.</span><span class="en">The maximum number of retries that will fail to read the IP address from the router, while there is certified internet connection. Normally, this state will never be reached.</span></li>
<li><b>PreventExit:</b><tt>true</tt> <span class="el">ή</span><span class="en">or</span> <tt>false</tt>. <span class="el">Αν είναι <tt>true</tt> τότε το script δε σταματάει ποτέ, ούτε σε περίπτωση λάθους όπως π.χ. username/password στο NoIP</span><span class="en">If it is <tt>true</tt> the script never ends, not even in case of a failure like ie. wrong NoIP username/password</span></li>
<li><b>SuccessCmd:</b> <span class="el">Εντολή που θα εκτελείται όταν έχουμε μια σωστή απάντηση από το NoIP όσον αφορά την ανανέωση της IP μας. Στο παράδειγμα φαίνεται να τρέχει το <tt>ttytter</tt> με τέτοιο τρόπο ώστε να μπορεί να στέλνει tweet την κατάστασή του. Δώστε βάση στον τρόπο με τον οποίο δηλώνονται μεταβλητές και εσωτερικές εκτελέσεις εντολών, όπως η <tt>date</tt></span><span class="en">Command to be executed when there is a correct answer from NoIP for our IP address updating to DNS tables. In this example <tt>ttytter</tt> is executed in a way to tweet us the DNS status. Pay attention to the way the variables are specified in this command and interna command execution, like <tt>date</tt></span></li>
<li><b>FailCmd:</b> <span class="el">Το ίδιο, αλλά για την περίπτωση όπου υπάρξει απάντηση σφάλματος από το NoIP</span><span class="en">Same thing for the case of a NoIP answer for failure</span></li>
<li><b>ExitCmd:</b> <span class="el">Ομοίως για την περίπτωση όπου υπάρξει τέτοιο σφάλμα όπου θα πρέπει το script να τερματιστεί</span><span class="en">And again same thing in case the failure is severe and the script must be terminated</span></li>
<li><b>WGetDelay:</b> <span class="el">Το script χρησιμοποιεί τη wget για να στείλει το request στο NoIP server. Σε περίπτωση που υπάρξει σφάλμα περιμένει όσο χρόνο του ορίζει αυτή η μεταβλητή</span><span class="en">This script uses wget to send a request to NoIP server. In case of request failure it wait for as long as this parameter specifies</span></li>
<li><b>WGetMaxFails:</b> <span class="el">Όταν υπάρξουν τόσα σφάλματα στη σειρά από τη wget όσα ορίζονται σε αυτή την παράμετρο, τότε ο χρόνος αναμονής μέχρι το επόμενο wget που θα επιχειρηθεί ορίζεται από την <tt>WGetLongFailDelay</tt></span><span class="en">When there are as many wget failures as this parameter specifies, then the delay until any further wget request will be as <tt>WGetLongFailDelay</tt> specifies.</span></li>
<li><b>WGetLongFailDelay:</b> <span class="el">Μετά από <tt>WGetMaxFails</tt> αποτυχίες της wget ο χρόνος που περιμένει πριν ξαναδοκιμάσει να στείλει request ορίζεται από αυτή την παράμετρο</span><span class="en">After <tt>WGetMaxFails</tt> wget failures, the delay interval till next retry is specified by this parameter</span></li>
</ul>
<p class="el">Το script μας δίνει τη δυνατότητα να εκτελέσουμε κάποιες εντολές, ανάλογα με το αν ήταν επιτυχής η αλλαγή της IP, αν υπήρξε κάποιο σφάλμα, ή αν υπήρξε μια ανεπίτρεπτη κατάσταση που οδηγεί το script σε τερματισμό. Οι εντολές αυτές ορίζονται στις παραμέτρους <tt>SuccessCmd</tt>, <tt>FailCmd</tt> και <tt>ExitCmd</tt>. Σε αυτές τις εντολές, μπορεί να θέλουμε να χρησιμοποιήσουμε κάποιες πληροφορίες από το script. Οι δυνατές περιπτώσεις είναι οι:</p>
<p class="en">The script provides us the ability to execute some commands depending on the case of success or failure of the IP update request, or even if there was a severe error that forced the script to terminate. The commands in question are specified in <tt>SuccessCmd</tt>, <tt>FailCmd</tt> and <tt>ExitCmd</tt> parameters. In these commands we may need to use some information coming from the script. The possible script variables are:</p>
<ul>
<li><b>$NoIPResp:</b> <span class="el">Περιέχει την απάντηση από τον server της NoIP</span><span class="en">Contains the answer of the NoIP server</span></li>
<li><b>$NewIP:</b> <span class="el">Περιέχει την καινούργια IP διεύθυνση</span><span class="en">Contains the new IP address</span></li>
<li><b>$CurrIP:</b> <span class="el">Περιέχει την παλιά IP διεύθυνση</span><span class="en">Contains the old IP address</span></li>
<li><b>$CurDate:</b> <span class="el">Περιέχει την ώρα που ανιχνεύτηκε η αλλαγή της IP</span><span class="en">Contains the time value the IP change was detected</span></li>
</ul>
<p class="el">Και φυσικά, μιας και σε αυτό το αρχείο περιέχονται ευαίσθητες πληροφορίες, θα πρέπει να μπορεί να το διαβάσει μόνο ο <tt>root</tt>:</p>
<p class="en">Well, of course in this file there are also sensitive information that only <tt>root</tt> should be able to read:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:/usr/scripts > chown root:root /etc/IP-Updater.conf
pi@raspberrypi:/usr/scripts > chmod 0600 /etc/IP-Updater.conf
pi@raspberrypi:/usr/scripts >
</pre></div>
<p class="el">Τέλος, μιας και αυτά τα δύο scripts είναι βασικά για τη λειτουργία του συστήματός μας, καλό είναι και αυτά να τα κάνουμε μη προσβάσιμα από τους χρήστες (εκτός του <tt>root</tt>):</p>
<p class="en">Finally, since both scripts are mandatory for the functionality of our system, it is a good practice not to let any user access them (unless, of course <tt>root</tt>):</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:/usr/scripts > sudo chown -R root:root /usr/scripts
pi@raspberrypi:/usr/scripts > sudo chmod -R 0700 /usr/scripts
pi@raspberrypi:/usr/scripts >
</pre></div>
<a id="NoIPService"></a>
<h4 class="el">Μετατροπή του καινούργιου client σε υπηρεσία</h4>
<h4 class="en">Conversion of the new client to a system service</h4>
<p class="el">Το τελικό στάδιο είναι να εκτελείται το script που φτιάξαμε ως υπηρεσία του συστήματος. Κάποιος θα μπορούσε πολύ απλά να το τρέξει μέσα από τον cron. Αυτό όμως δεν θεωρείται και τόσο καλή ιδέα. Είναι σαφώς καλύτερα να λειτουργεί όπως όλες οι υπηρεσίες του συστήματος, να ενεργοποιείται και να απενεργοποιείται ανάλογα με το runlevel κ.λ.π. Για να το πετύχουμε αυτό θα πρέπει να φτιάξουμε ένα ακόμα script. Μια παρόμοια εργασία κάναμε και σε προηγούμενο άρθρο. Θα ακολουθήσουμε, λοιπόν, την ίδια τακτική.</p>
<p class="en">The final stage is to let the script we created run as a system service. Somebody would let it start through cron. But this is not considered a good practice. It is far better to let it act as any other system service, start or stop depending on the runlevel of the system, etc. To reach our goal we must create another one script. A similar process we followed in an earlier article. We will follow the same tactics.</p>
<p class="el">Κάντε Copy/Paste τον ακόλουθο κώδικα στον αγαπημένο σας editor:</p>
<p class="en">Again, you can Copy/Paste the following source code in your favourite editor:</p>
<div class="code"><pre class="prettyprint linenums lang-sh">
#! /bin/sh
### BEGIN INIT INFO
# Provides: IP-Updater
# Required-Start: $local_fs $syslog $network
# Required-Stop: $local_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: IP Updater for NoIP Dynamic DNS service
# Description: Start IP Updater to check the IP that the ISP has given to router.
# When the IP is changed, the updater informs NoIP and updates the chosen domain name
# to point to the new IP.
### END INIT INFO
# Author: Elias Chrysocheris <elias_chr@otenet.gr>
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="IP Updating client service for NoIP (http://www.noip.com/)"
NAME=IP-Updater
DAEMON=/usr/scripts/IP-Updater.sh
SCRIPTNAME=/etc/init.d/$NAME
PIDFILE=/var/run/IP-Updater.pid
# Exit if the package is not installed
[ -e "$DAEMON" ] || { echo "Cannot find IP-Updater executable in $DAEMON. Perhaps it is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --test --start --quiet --pidfile $PIDFILE --exec $DAEMON > /dev/null \
|| return 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON &
RETVAL="$?"
[ "$RETVAL" > 2 ] && return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --pidfile $PIDFILE
[ "$?" = 2 ] && return 2
rm $PIDFILE
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
</pre></div>
<p class="el">Το script βασίστηκε για άλλη μια φορά στο κλασικό <tt>skeleton</tt> που υπάρχει στον κατάλογο <tt>/etc/init.d/</tt>. Εκεί θα το σώσουμε σαν <tt>root</tt> με το όνομα <tt>IP-Updater</tt>. Αν δεν έχουμε τη δυνατότητα να το κάνουμε απ' ευθείας, μπορούμε σαν χρήστες να το σώσουμε στον κατάλογό μας και στη συνέχεια να το αντιγράψουμε ως <tt>root</tt> στην κατάλληλη θέση. Στη συνέχεια αλλάζουμε τα δικαιώματα και το κάνουμε εκτελέσιμο και ενημερώνουμε το σύστημα για την καινούργια υπηρεσία:</p>
<p class="en">This script is based once more in the clasical <tt>skeleton</tt> that lives under <tt>/etc/init.d/</tt>. There we eill save it as <tt>root</tt> user under the name <tt>IP-Updater</tt>. If you cannot do it straight forward, you can save it under your home directory and then you can copy it as <tt>root</tt> to the correct place. Then you can change its access rights making it executable and inform the system for the new service:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:/usr/scripts > cd /etc/init.d/
pi@raspberrypi:/etc/init.d > sudo cp /home/pi/IP-Updater .
pi@raspberrypi:/etc/init.d > sudo chmod 0755 IP-Updater
pi@raspberrypi:/etc/init.d > sudo update-rc.d IP-Updater defaults
pi@raspberrypi:/etc/init.d >
</pre></div>
<p class="el">Μετά από αυτό μπορούμε να εκκινήσουμε την υπηρεσία μας. Όμως, για να δοκιμάσουμε ότι όλα βαίνουν καλώς, καλό είναι να δούμε αν ενεργοποιείται αυτόματα με μια επανεκκίνηση:</p>
<p class="en">After that we can start the new service. But first we have to make sure everything is fine and the service starts automatically after a reboot:</p>
<div class="code"><pre class="prettyprint lang-sh">
pi@raspberrypi:/usr/scripts > sudo shutdown -r now
pi@raspberrypi:/etc/init.d >
</pre></div>
<a id="NoIPConcl"></a>
<h4 class="el">Αποτελέσματα</h4>
<h4 class="en">Conclusions</h4>
<p class="el">Εαν όλα έχουν πάει καλά, τότε μπορείτε να παρακολουθήσετε τα μηνύματα στο <tt>/var/log/messages</tt> και να δείτε τη λειτουργία του script. Αν προσέξατε, στο configuration αρχείο του <tt>IP-Updater</tt>, χρησιμοποιείται το <tt>ttytter</tt> που είναι ένας client για το twitter. Μέσω αυτού βλέπουμε on-line τη λειτουργία της αλλαγής διεύθυνσης</p>
<p class="en">If everything is done correctly then you could see the information in <tt>/var/log/messages</tt> and watch the service in action. You must have noticed, in the <tt>IP-Updater</tt> configuration file, <tt>ttytter</tt> is used which is a command line twitter client. Using that we can observe on-line the function of IP updating</p>
<div class="separator" style="clear: both; text-align: center;"><a href="http://pikchurimages.s3.amazonaws.com/pic_aB9o_l.jpg?lm=1371901873" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img style="border:1px solid #4763B0;border-radius:8px" width="240px" src="http://pikchurimages.s3.amazonaws.com/pic_aB9o_l.jpg?lm=1371901873" /></a></div>
<p class="el">Αυτό φυσικά προϋποθέτει να έχετε στήσει το ttytter και να το έχετε ρυθμίσει.</p>
<p class="en">For this you are supposed to have ttytter installed and configured.</p>
<p class="el">Έπειτα από αρκετό καιρό που λειτουργεί η υπηρεσία του NoIP στο Raspberry Pi δεν έχω πετύχει κατάσταση που να μη μπορώ να έχω πρόσβαση μέσω του δικτύου, απομακρυσμένα. Η απόκριση του συστήματος είναι παραπάνω από ικανοποιητική.</p>
<p class="en">Using NoIP service system in Raspberry Pi for enough time now, I never had that awkward moment of not having access to my system through the internet. The system's response is more than satisfactory.</p>
<br />
<p class="el authorname">Ηλίας Χρυσοχέρης</p>
<p class="en authorname">Elias Chrysocheris</p>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com6tag:blogger.com,1999:blog-9147006209672954597.post-23077745006726377612013-05-31T15:25:00.000+03:002013-10-14T00:13:30.211+03:00Ubiquity UniFi Controller Software στο Raspberry PiUbiquity UniFi Controller Software on Raspberry Pi<h4 class="el">Εισαγωγή</h4>
<h4 class="en">Introduction</h4>
<p class="el">Βασικά η ιστορία συνεχίζεται από <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">προηγούμενο άρθρο</a> που βρίσκεται σε αυτό το <a href="http://eliaschr.blogspot.gr/">blog</a>. Για να υπάρξει μια σύνδεση με τα προηγούμενα, θα γίνει μια γενική περιγραφή του προβλήματος. Στη συνέχεια θα δούμε λίγα πράγματα για ένα εργαλείο που θα χρησιμοποιήσουμε (το Raspberry Pi) για τη λύση του προβλήματος και θα προχωρήσουμε στον τρόπο που ακολουθήθηκε για να επιτευχθεί το επιθυμητό αποτέλεσμα.</p>
<p class="en">The story continues from <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">an earlier post</a> posted in the current <a href="http://eliaschr.blogspot.gr/">blog</a>. For clarity and connection to the previously mentioned information, there will be a general description of the problem. Then we will get to know the tool we use in this article (Raspberry Pi) for the solution of the problem and we will present the way we followed to reach our goal.</p>
<p class="el">Επιγραμματικά ακολουθούν:</p>
<p class="en">Briefly:</p>
<ul>
<li><a href="#RPi_prob"><span class="el">Το Βασικό Πρόβλημα</span><span class="en">The Problem</span></a></li>
<li><a href="#RPi_server">Raspberry Pi <span class="el">ως</span><span class="en">as a</span> server...</a></li>
<li><a href="#RPi_setup"><span class="el">Το Στήσιμο</span><span class="en">The Setup</span></a></li>
<li><a href="#RPi_prep"><span class="el">Προεργασία</span><span class="en">Groundwork</span></a></li>
<ul>
<li><a href="#RPi_java">1. <span class="el">Εγκατάσταση </span>Java<span class="en"> Installation</span></a></li>
<li><a href="#RPi_mongodb">2. <span class="el">Εγκατάσταση </span>MongoDB<span class="en"> Installation</span></a></li>
</ul>
<li><a href="#RPi_unifi"><span class="el">Εγκατάσταση </span>UniFi Controller<span class="en"> Installation </span></a></li>
<li><a href="#RPi_service"><span class="el">Δημιουργία </span>Service Script<span class="en"> Creation</span></a></li>
<li><a href="#RPi_conclusions"><span class="el">Συμπεράσματα</span><span class="en">Conclusions</span></a></li>
</ul>
<a id="RPi_prob"></a>
<h4 class="el">Το βασικό πρόβλημα</h4>
<h4 class="en">The Problem</h4>
<p class="el">Το βασικό κομμάτι που μας ενδιαφέρει εδώ, είναι το στήσιμο ενός δικτύου ξενοδοχείου. Αυτό, με τη σειρά του, συνεπάγεται όλο το καλό πακέτο του ελέγχου σύνδεσης των πελατών, ποσού διακίνησης δεδομένων κ.λ.π. Αυτό το επιτυγχάνουν επαρκώς και με το παραπάνω τα Access Points της <a href="http://www.ubnt.com/">Ubiquity</a>. Η χρήση ενός <a href="http://www.ubnt.com/unifi">UniFi Outdoor Access Point</a> λύνει όλα τα προβλήματα δικτύωσης. Το μόνο μειονέκτημα (και αυτό που μας απασχολεί στο παρόν άρθρο) είναι πως θα πρέπει να υπάρχει ένα μηχάνημα που να τρέχει το software της εταιρίας για τον έλεγχο και τη διαχείριση του δικτύου. Αυτό με τη σειρά του συνεπάγεται κατανάλωση ενέργειας για PC, θόρυβος από τα ανεμιστηράκια του, απαραίτητη χρήση UPS που να αντέχει σε μεγάλες διακοπές ρεύματος, license του λειτουργικού του συστήματος αν πρόκειται για μηχάνημα που τρέχει Bugindows, συχνές επανεκκινήσεις λόγω των προβλημάρων του αναφερόμενου λειτουργικού κ.λ.π. Ειδικα τα δύο τελευταία προβλήματα (που είναι και τα πιο σημαντικά) λύθηκαν με την εγκατάσταση λειτουργικού Linux και συγκεκριμένα της διανομής <a href="http://www.opensuse.org/">openSUSE</a>, όπως φαίνεται και σε άλλο άρθρο του ίδιου blog.</p>
<p class="en">The basic part in question at this point is a network setup for a hotel. This means the whole packet of services for controlling client access, bandwidth limiting per client, data quota etc. For <a href="http://www.ubnt.com/">Ubiquity's</a> Access Points this is only part of their capabilities. Usage of a <a href="http://www.ubnt.com/unifi">UniFi Outdoor Access Point</a> is the solution for all our networking problems. The only drawback (and what is covered in this article) is the necessity of a computer running the controller software for all the network monitoring and managing, 24 hours a day. And this, in turn, leads to much energy consumption from a PC, noise from its fans, the necessity of UPS usage that is able to keep the system up during long duration power failures, license for its operating system if it runs Bugindows, probably frequently reboots because of this (non) operating system and many more... Especially the two last problems we presented (which are the most important) were solved by installing a Linux distribution; more specifically <a href="http://www.opensuse.org/">openSUSE</a>, as presented in a previous article in this blog.</p>
<p class="el">Η λύση των υπολοίπων προβλημάτων διερευνήθηκε περισσότερο για να βρει ο γράφων δουλειά να κάνει (!!! Τι πρωτότυπο :)). Δεν είναι κάτι άλλο από το πασίγνωστο, πλέον στο χώρο των gadgetάκιδων, <a href="http://www.raspberrypi.org/">Raspberry Pi</a>.</p>
<p class="en">The research for solutions to the other problems started just for the author to kill some of his spear time (!!! How rare :)). The research led to, famous in the gadget lovers' cycles, <a href="http://www.raspberrypi.org/">Raspberry Pi</a>.</p>
<a id="RPi_server"></a>
<h4 class="el">Raspberry Pi ως server...</h4>
<h4 class="en">Raspberry Pi as a server...</h4>
<p class="el">Το Raspberry Pi είναι ένας υπολογιστής, όπως ακριβώς κι ένα κινητό. Η διαφορά του είναι πως δεν έχει οθόνη. Τι διαθέτει αυτός ο υπολογιστής (βασικά χαρακτηριστικά):</p>
<p class="en">Raspberry Pi is a small computer, just like a smartphone. Its difference is the lack of a screen. Part of its specifications are presented:</p>
<ul>
<li class="el"><b>Επεξεργαστής</b>: ARM στα 700MHz, με δυνατότητα Overclocking στο 1GHz</li>
<li class="en"><b>Processor</b>: ARM running at 700MHz, with Overclocking capability up to 1GHz</li>
<li class="el"><b>Μνήμη</b>: 256 MBytes η παλιά έκδοση (Α), 512 MBytes η έκδοση Β</li>
<li class="en"><b>Memory</b>: 256 MBytes at the old version (Α), 512 MBytes at its newer version, Β</li>
<li><b>Ethernet</b>: 10/100 Mbit</li>
<li><b>Video out</b>: <span class="el">Δε μας ενδιαφέρει. Server θέλουμε να το κάνουμε, αλλά ως άχρηστη πληροφορία της ημέρας διαθέτει έξοδο HDMI και TV</span><span class="en">We don't care. We want to use it as a server, but as useless information of the day it has HDMI and Composite Video outputs</span></li>
<li><b>USB</b>: 2 <span class="el">πόρτες</span><span class="en">ports</span></li>
<li><b>Boot</b>: <span class="el">από κάρτα μνήμης</span><span class="el">from an</span> SD<span class="en"> Card</span></li>
<li class="el"><b>Τροφοδοσία</b>: 5V με μικρή κατανάλωση ρεύματος (μέγιστη στα 700mA στην έκδοση Β)</li>
<li class="en"><b>Power</b>: 5V having small power consumption (maximum 700mA on version Β)</li>
</ul>
<p class="el">Αυτά τα χαρακτηριστικά το κάνουν ιδανικό για χρήση ως server. Δίνουν, επίσης, τη δυνατότητα να μπορέσει να τροφοδοτηθεί, αργότερα, από ένα σύστημα UPS που να παράγει τα 5V που χρειάζονται απ' ευθείας από τη μπαταρία του. Κατά συνέπεια μια διακοπή της ΔΕΗ για... πολλές ώρες δεν θα το ενοχλήσει :)</p>
<p class="en">These specifications make this thing ideal for making a server. They also give it the ability to be, later, powered by a small UPS system that supplies 5V DC straight from a battery, without the need of inverters and 220V AC. So, a power failure because of the power company for... looong duration won't bother the system :)</p>
<p class="el">Άλλο ένα καλό του εν λόγω gadget είναι πως πάρα πολλές διανομές Linux έχουν στηθεί για το Raspberry Pi· ακόμα και <a href="http://www.freebsd.org/">FreeBSD</a> μπορούμε να βρούμε (αν και κανονικά αυτό δεν πρέπει να μας κάνει εντύπωση!). Μιας και την τελευταία φορά που έστησα το σύστημα του UniFi Controller ήταν επάνω σε <a href="http://www.opensuse.org/">openSUSE</a>, δοκίμασα την εν λόγω διανομή και στο Raspberry Pi. Τα αποτελέσματα ήταν θαυμάσια. Το μόνο περίεργο ήταν η εγκατάσταση της <a href="http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html#Java">Java</a>, αλλά δεν ήταν κάτι που να αξίζει αναφοράς.</p>
<p class="en">Another plus of this gadget is that there are so many Linux distributions running on Raspberry Pi right now; you can even find <a href="http://www.freebsd.org/">FreeBSD</a> (though this should not impress us!). Since my last time I set up UniFi Controller was in an <a href="http://www.opensuse.org/">openSUSE</a> Linux, I also tried it in Raspberry Pi. The results were marvellous. The only weird thing was the <a href="http://www.oracle.com/technetwork/articles/java/raspberrypi-1704896.html#Java">Java</a> installation, but nothing worth mentioning here.</p>
<p class="el">Κάτι που με "έτρωγε" ήταν πως αν κάποιος πάρει ένα Raspberry Pi και θελήσει να ασχοληθεί με τη χρήση του σε δίκτυο, όπως και αυτό που ήταν το έναυσμα για αυτή την ιστορία, τότε αμφιβάλλω αν θα ασχοληθεί με το να βάλει openSUSE· σίγουρα θα ασχοληθεί με το "έτοιμο" Raspbian που είναι βασισμένο επάνω στη διανομή <a href="http://www.debian.org/">Debian</a>. Οπότε, για να μπορέσω να συμβάλλω και σε αυτό τον τομέα θα έπρεπε να δοκιμάσω αυτή τη διανομή για τις "ταρζανιές".</p>
<p class="en">Something that really made me worried was that if someone gets a Raspberry Pi and wants to use it like what described in this article then I doubt he/she will install openSUSE; I bet on the default Raspbian operating system that is based on <a href="http://www.debian.org/">Debian</a>. So, for me to be a contributor at this part I should use this distribution for all the play.</p>
<a id="RPi_setup"></a>
<h4 class="el">Το Στήσιμο</h4>
<h4 class="en">The Setup</h4>
<p class="el">Το στήσιμο του συστήματος δεν είναι καθόλου δύσκολο. Μπορεί κάποιος να κατεβάσει το κατάλληλο image και να το γράψει σε μια κάρτα μνήμης SD, ή να χρησιμοποιήσει το <a href="http://www.berryterminal.com/doku.php/berryboot">BerryBoot</a>. Η δεύτερη επιλογή απλά θα προσθέσει μερικά δευτερόλεπτα στο bootάρισμα του συστήματος, αλλά αν κάποιος θέλει να "παίξει" με το Raspberry τότε είναι μια καλή λύση.</p>
<p class="en">The system's setup is not difficult at all. Anyone can download the correct OS image that suits his/her needs and write it in an SD Memory Card. Alternatively <a href="http://www.berryterminal.com/doku.php/berryboot">BerryBoot</a> can be used. The latter will just add some seconds during boot up of the system, but if somebody wants to "play" with Raspberry then it is a marvellous choice.</p>
<p class="el">Η κάρτα που χρησιμοποιήθηκε στο στήσιμό μας είναι μια 8GB SD Class 10. Δίνει αρκετό χώρο για "παιχνίδια", ενώ είναι αρκετά γρήγορη για ένα ικανοποιητικό χρόνο εκκίνησης. Εκεί εγκαταστάθηκε το Raspbian, ρυθμίστηκε για λίγο overclocking (800 MHz) και έγινε και expand το partition που περιέχει το λειτουργικό. Αυτά, επειδή δεν υπήρχε πληκτρολόγιο στο Raspberry, έγινε μέσω <tt>ssh</tt>, εκτελώντας από εκεί το <tt>raspi-config</tt>.</p>
<p class="en">The memory card used here is a 8GB SD Class 10. It gives much space to play, while at the same time is very fast for a short boot time. There was Raspbian installed, configured for some overclocking (800 MHz) and the partition containing the operating system was expanded. Because of lack of a keyboard connected to Raspberry, all these were done through <tt>ssh</tt>, running <tt>raspi-config</tt>.</p>
<p class="el">Σε γενικές γραμμές η εγκατάσταση του συστήματος δε νομίζω πως χρειάζεται παρουσίαση. Όλα υπάρχουν στο Internet και είναι αρκετά κατανοητά για κάποιον ο οποίος αποφασίζει να ασχοληθεί με το Raspberry. Έτσι, οι λεπτομέρειες της εγκατάστασης λειτουργικού και ενεργοποίησης του συστήματος, καθώς επίσης και της αναβάθμισης του λογισμικού δεν περιγράφονται.</p>
<p class="en">In general, the system installation was smooth and it doesn't worth mentioning. Every tip and information on that lies in the Internet and are crystal clear for anybody who wishes to use Raspberry Pi. So, all these installation details as well as those for updating the operating system are not presented.</p>
<p class="el">Η αρχική εγκατάσταση περιέχει ένα χρήστη με το όνομα <tt>pi</tt>, ο οποίος ανήκει στο group <tt>pi</tt>, έχει password το <tt>raspberry</tt>, ενώ το όνομα του συστήματος στο δίκτυο είναι <tt>raspberrypi</tt>. Φυσικά, σε όλα αυτά έγιναν αλλαγές, οπότε ο χρήστης του συστήματος ονομάστηκε <tt>elias</tt> (λέμε τώρα!), το αρχικό group του χρήστη έχει το ίδιο όνομα, ενώ το δικτυακό όνομα του συστήματος έγινε <tt>unificontroll</tt> και διάφορα άλλα μικροσεταρίσματα.</p>
<p class="en">The default installation has a user named <tt>pi</tt>, who belongs to <tt>pi</tt> group, identified by <tt>raspberry</tt> as password and the network name of the system is <tt>raspberrypi</tt>. Of course, changes have been made to all of these settings, so the user name now becomes <tt>elias</tt> (well, for the clarity of this article!), the initial user's group has the same name and the network name becomes <tt>unificontroll</tt>. There were also some minor alterations on the setup not worth mentioning.</p>
<a id="RPi_prep"></a>
<h4 class="el">Προεργασία</h4>
<h4 class="en">Groundwork</h4>
<a id="RPi_java"></a>
<h5 class="el">1. Εγκατάσταση Java</h5>
<h5 class="en">1. Java Installation</h5>
<p class="el">Για να λειτουργήσει το UniFi Controller χρειάζεται τη βάση δεδομένων <a href="http://www.mongodb.org/">mongodb</a> και τη γλώσσα Java να είναι εγκαταστημένα στο σύστημα. Για τη Java δεν υπάρχει κάποιο πρόβλημα, μιας και είναι έτοιμη σε πακέτο <tt>.deb</tt> για το Raspbian. Αρκεί ένα </p>
<p class="en">For UniFi Controller to be able to operate, it needs <a href="http://www.mongodb.org/">mongodb</a> database and Java programming language installed in the target system. Java is no problem since there is already a <tt>.deb</tt> package for Raspbian. Just execute: </p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > sudo apt-get install openjdk-7-jdk
[sudo] password for elias:
.
.
.
</pre></div>
<br />
<a id="RPi_mongodb"></a>
<h5 class="el">2. Εγκατάσταση MongoDB</h5>
<h5 class="en">2. MongoDB Installation</h5>
<p class="el">Το περίεργο της υπόθεσης είναι πως δεν υπάρχει πακέτο για MongoDB (τουλάχιστον μέχρι τη στιγμή που γράφεται το παρόν άρθρο). Κατά συνέπεια μπαίνουμε σε διαδικασίες compile κ.λ.π. Μετά από λίγο ψάξιμο βρέθηκε ένα πολύ καλό άρθρο για την εγκατάσταση της <a href="http://mongopi.wordpress.com/2012/11/25/installation/">mongopi</a> που είναι η μεταφορά της εν λόγω βάσης δεδομένων στο Raspberry. Το συγκεκριμένο άρθρο που βρέθηκε δίνει πληροφορίες για την εγκατάσταση ενός ολόκληρου συστήματος με πολλά Raspberries. Η περιγραφή που θα γίνει στο παρόν άρθρο είναι μόνο για την εγκατάσταση της MongoDB, ως το σημείο που χρειάζεται για να λειτουργήσει με το UniFi Controller.</p>
<p class="en">Perhaps it is strange, but there is no package available for MongoDB (at least at the time of this writing). So, we have to proceed to other procedures like compiling etc. After some searching through the internet there was an article found for <a href="http://mongopi.wordpress.com/2012/11/25/installation/">mongopi</a> installation, which is the database in question patched for Raspberry. This article gives information for the whole process of a system with many Raspberries setup. The description in here, will be only for MongoDB installation, up to the necessary point to be functional and usable by UniFi Controller.</p>
<p class="el">Ο κώδικας της mongopi είναι στο <a href="https://github.com/">github</a>. Για να γίνει η εγκατάσταση θα πρέπει να εγκατασταθούν πρώτα το <tt>git</tt> και κάτι ψιλά... Ξεκινάμε με την εγκατάσταση των απαραίτητων πακέτων γι' αυτή τη δουλειά:</p>
<p class="en">mongopi code is available to download in <a href="https://github.com/">github</a>. For the total installation process to be complete, <tt>git</tt> and some other packages as well, must be installed... Lets start all these necessary installations:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > sudo apt-get install git-core build-essential scons \
libpcre++-dev xulrunner-dev libboost-dev \
libboost-program-options-dev libboost-thread-dev \
libboost-filesystem-dev
.
.
.
</pre></div>
<p class="el">Στη συνέχεια κλωνοποιήσουμε το αποθετήριο με τα αρχεία της mongopi από το github:</p>
<p class="en">OK. Now lets clone the mongopi repository from github:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > git clone git://github.com/RickP/mongopi.git
</pre></div>
<p class="el">Η συνέχεια θέλει υπομονή... Ώρα για compilation... Αυτό γίνεται με τη βοήθεια του εργαλείου <tt>scons</tt> και μπορεί να πάρει αρκετές ώρες (περίπου 4):</p>
<p class="en">What follows needs patience... Time to compile the code... This is done using a tool named <tt>scons</tt> and it may take some hours (well, about 4):</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > cd mongopi
elias@unificontrol:~/mongopi > scons
</pre></div>
<p class="el">Μετά από... λίγη ημέρα :) το compilation θα έχει τελειώσει. Συνέχεια έχει η εγκατάσταση. Αυτή θα χρειαστεί μόνο... 3 ώρες!...</p>
<p class="en">After some... day passes :) the compilation process will be over. Installation follows. This will take only about... 3 hours!...</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~/mongopi > sudo scons --prefix=/opt/mongo install
</pre></div>
<p class="el">Αυτή η εντολή θα εγκαταστήσει τη mongopi στον κατάλογο <tt>/opt/mongo</tt>. Φυσικά η όλη διαδικασία έπιασε και υπερβολικό χώρο στην κάρτα μνήμης (περίπου 2GB) οπότε καλό είναι να σβήσετε τον κατάλογο που περιέχει τον πηγαίο κώδικα:</p>
<p class="en">That command will install mongopi in <tt>/opt/mongo</tt> directory. Naturally, the whole compilation/installation process allocated a huge space in the memory card (something around 2GB) so it is very good thing to delete the directory that contains the source code:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~/mongopi > cd ..
elias@unificontrol:~ > sudo rm -rf mongopi
elias@unificontrol:~ >
</pre></div>
<p class="el">Καλό είναι να μπει στο PATH του συστήματος ο κατάλογος με τα εκτελέσιμα της MongoDB για να είναι εύκολη η διαχείριση των βάσεών της. Αυτό γίνεται απλά με την προσθήκη του στο αρχείο <tt>.bashrc</tt> της ακόλουθης γραμμής:</p>
<p class="en">It is also a nice idea to insert into the PATH system variable the directory that contains all the executables of MongoDB, for easy access during databases administration. Just insert the following line in <tt>.bashrc</tt> file:</p>
<div class="code"><pre class="prettyprint">
export PATH=$PATH:/opt/mongo/bin
</pre></div>
<p class="el">Σε αυτό το σημείο η εγκατάσταση της MongoDB έχει γίνει. Αν χρειαστεί να τη χρησιμοποιήσετε και σε άλλες εφαρμογές, τότε πιθανό είναι να πρέπει να δημιουργήσετε και τον κατάλογο <tt>/data/db</tt> στο σύστημά σας. Αυτό στην περίπτωση του UniFi Controller δεν είναι απαραίτητο γιατί τη δικιά του βάση δεδομένων την κρατάει σε δικό του κατάλογο.</p>
<p class="en">We reached the point that MongoDB is installed in the system. If you are going to also use it in other applications you possibly have to create <tt>/data/db</tt> directory, or mongo will complain. In the case of just using it only with UniFi Controller that step can be omitted, because it uses its own directory for the database contents.</p>
<a id="RPi"></a>
<h4 class="el">Εγκατάσταση UniFi Controller</h4>
<h4 class="en">UniFi Controller Installation</h4>
<p class="el">Η εγκατάσταση του UniFi Controller δεν έχει κάποια δυσκολία. Σε γενικές γραμμές είναι ίδια με αυτή που έχει γίνει και σε <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">προηγούμενο άρθρο</a> σε άλλη έκδοση του λειτουργικού Linux</p>
<p class="en">UniFi Controller installation is not difficult at all. It is about the same as described in a <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">previous article</a> in another Linux distribution.</p>
<p class="el">Ξεκινάμε με το να δημιουργήσουμε ένα group με το όνομα <tt>unifid</tt>, όπου εκεί θα μπει και ο χρήστης που θα έχει τη δυνατότητα του custom portal για τους πελάτες του δικτύου. Μιας και ο μόνος χρήστης που υπάρχει αυτή τη στιγμή στο σύστημα είναι ο <tt>elias</tt>, αυτός είναι που θα προστεθεί και στο εν λόγω group.</p>
<p class="en">Start from creating a user group named <tt>unifid</tt>, that will contain the user who will have the ability to create/alter the custom portal for the network clients. Since the only user existed in the system right now is <tt>elias</tt>, this user will be added into the group in question.</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > sudo addgroup unifid
Adding group `unifid' (GID 1003) ...
Done.
elias@unificontrol:~ > sudo adduser elias unifid
Adding user `elias' to group `unifid' ...
Adding user elias to group unifid
Done.
</pre></div>
<p class="el">Για να δει το σύστημα την αλλαγή στα groups θα πρέπει να κάνουμε ένα <tt>logout</tt> και μετά ξανά login. Αυτό που φαίνεται στις ακόλουθες εντολές είναι η σύνδεση μέσω <tt>ssh</tt> από άλλον υπολογιστή:</p>
<p class="en">For the system to read the new settings in you'll have to <tt>logout</tt> and relogin. What is presented in the following commands is a connection from another computer through <tt>ssh</tt>:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > logout
Connection to 192.168.1.10 closed.
elias@otherpc:~> ssh 192.168.1.10
elias@192.168.1.10's password:
Linux unificontrol 3.6.11+ #456 PREEMPT Mon May 20 17:42:15 BST 2013 armv6l
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Thu May 30 11:43:24 2013 from 192.168.1.20
elias@unificontrol:~ > groups
elias adm dialout cdrom sudo audio video plugdev games users netdev input unifid
elias@unificontrol:~ >
</pre></div>
<p class="el">Το επόμενο βήμα είναι να κατεβάσουμε το <tt>.zip</tt> αρχείο του προγράμματος. Οι διαθέσιμες εκδόσεις είναι δύο:</p>
<p class="en">The next step is to download the desirable <tt>.zip</tt> file of the program. The available versions (at the time of this writing) are two:</p>
<ul>
<li class="el"><b>Έκδοση 2.3.9:</b> Είναι η βασική και σταθερή έκδοση του προγράμματος και βρίσκεται στην τοποθεσία <a href="http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip</a></li>
<li class="en"><b>Version 2.3.9:</b> Its the basic and stable version of the program and can be founded at <a href="http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip</a></li>
<li class="el"><b>Έκδοση 3.1.1b:</b> Είναι η τελευταία έκδοση του προγράμματος αλλά είναι σε δοκιμαστική (beta) κατάσταση ακόμα. Έχει πολλά νέα χαρακτηριστικά και ίσως αξίζει τον κόπο να ασχοληθείτε μαζί της. Μπορείτε να τη βρείτε στην τοποθεσία <a href="http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip</a></li>
<li class="en"><b>Version 3.1.1b:</b> Is the latest version but is still in testing (beta) state. It contains many new features and may be worth trying. It can be founded at <a href="http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip</a></li>
</ul>
<p class="el">Όποια από τις δύο εκδόσεις και αν ενδιαφερθείτε να εγκαταστήσετε, ο τρόπος είναι ακριβώς ο ίδιος. Απλώς κατεβάστε το αρχείο <tt>.zip</tt> και αποσυμπιέστε το. Επειδή θα πρέπει να αποδεχθείτε την άδεια χρήσης του προγράμματος, θα πρέπει να το κατεβάσετε με τη βοήθεια κάποιου browser στον υπολογιστή σας και στη συνέχεια να το μεταφέρετε με <tt>scp</tt> στο Raspberry. Στη συνέχεια το αποσυμπιέζετε:</p>
<p class="en">Whichever of these you may choose to install, the way is exactly the same. Just download the desired <tt>.zip</tt> file and uncompress it. Because you'll have to accept the license agreement, you have to download it using your computer's browser and transfer the file to Raspberry Pi using <tt>scp</tt>. There you can uncompress it:</p>
<div class="code"><pre class="prettyprint">
elias@otherpc:~ > scp ~/Downloads/UniFi.unix.zip 192.168.1.10:/home/elias/
elias@192.168.1.10's password:
UniFi.unix.zip 100% 28MB 1.2MB/s 00:23
elias@otherpc:~ > ssh 192.168.1.10
elias@192.168.1.10's password:
.
.
elias@unificontrol:~ > cd /opt/
elias@unificontrol:/opt > sudo unzip /home/elias/UniFi.unix.zip
Archive: UniFi.unix.zip
creating: UniFi/
creating: UniFi/bin/
linking: UniFi/bin/mongod -> /usr/bin/mongod
.
.
.
elias@unificontrol:/opt >
</pre></div>
<p class="el">Το πρόγραμμα έχει εγκατασταθεί στο Raspberry. Μένουν λίγες ακόμα λεπτές πινελιές για τη λειτουργία του. Καταρχήν το link που βρίσκεται μέσα στον κατάλογο <tt>UniFi/bin</tt> δεν χρειάζεται κάποια αλλαγή, γιατί η εγκατάσταση της MongoDB έχει φροντίσει να υπάρχει το αρχείο <tt>/usr/bin/mongod</tt> που χρειάζεται το UniFi Controller. Αυτό που χρειαζεται να γίνει, είναι να δημιουργθεί ο κατάλογος <tt>data</tt> που θα φιλοξενεί όλες τις παραμέτρους για το δίκτυό μας. Ο κατάλογος αυτός θα περιέχει και το portal της εισόδου των πελατών του ξενοδοχείου στο δίκτυο, έτσι θα πρέπει να μπορεί ο χρήστης που ανήκει στο group <tt>unifid</tt> να αλλάζει τα δεδομένα χωρίς να υπάρχουν προβλήματα με τα δικαιώματα. Επειδή θα πειράξουμε λίγο τη λίστα δικαιωμάτων, θα χρειαστεί να εγκατασταθεί και το πακέτο <tt>acl</tt> με την εντολή:</p>
<p class="en">The program is now installed in Raspbian. There are some finishing touches for its correct operation. Begining with the link that lies in <tt>UniFi/bin</tt> directory, it does not need any change, since the MongoDB installation has placed the executable <tt>/usr/bin/mongod</tt> where UniFi Controller expects it. But what is necessary to be done is the creation of a directory named <tt>data</tt>. In there, all the parameters and information of the network will be stored. There will also be the entry portal of the hotel clients, so the user who belongs to <tt>unifid</tt> group must have the correct access rights for being able to alter those files without problems. We are going to change the access rights list a little bit, so we need to install <tt>acl</tt> package using the command:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/opt > sudo apt-get install acl
...
</pre></div>
<p class="el">Το επόμενο βήμα είναι να δημιουργθεί ο κατάλογος <tt>data</tt> και να του δοθούν τα κατάλληλα δικαιώματα:</p>
<p class="en">The step that follows creates the <tt>data</tt> directory and gives the correct access rights to it:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/opt > cd UniFi
elias@unificontrol:/opt/UniFi > sudo mkdir data
elias@unificontrol:/opt/UniFi > sudo chgrp unifid data
elias@unificontrol:/opt/UniFi > sudo chmod 0774 data
elias@unificontrol:/opt/UniFi > sudo chmod g+s data
elias@unificontrol:/opt/UniFi > sudo setfacl -d -m u::rwX,g::rwX,o::r data
elias@unificontrol:/opt/UniFi > ls -ld data
drwxrwsr--+ 7 root unifid 4096 May 29 13:13 data
elias@unificontrol:/opt/UniFi > getfacl data
# file: data
# owner: root
# group: unifid
# flags: -s-
user::rwx
group::rwx
other::r--
default:user::rwx
default:group::rwx
default:other::r--
elias@unificontrol:/opt/UniFi >
</pre></div>
<p class="el">Πλέον είμαστε έτοιμοι να δοκιμάσουμε αν το πρόγραμμα λειτουργεί σωστά. Μην ξεχνάμε ότι η εγκατάσταση έχει γίνει με τέτοιο τρόπο που τρέχει από τον <tt>root</tt>. Για να ξεκινήσει το UniFi Controller θα πρέπει να δώσουμε την εντολή:</p>
<p class="en">Now we are ready to test if the program works as expected. Do not forget that the installations has been made in a way that only <tt>root</tt> can execute it. To start the UniFi Controller run the following command from the command line interface:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/opt/UniFi > sudo /usr/bin/java -jar /opt/UniFi/lib/ace.jar start &
</pre></div>
<p class="el">Εδώ θα πρέπει να περιμένουμε λίγο χρονικό διάστημα (αρκετά δευτερόλεπτα) πριν καταφέρουμε να μπούμε στο σύστημα. Για να δοκιμάσουμε το σύστημά μας, θα πρέπει να χρησιμοποιήσουμε τον browser ενός υπολογιστή. Αν προσπαθήσουμε να μπούμε πριν το πρόγραμμα κάνει όλα τα απαραίτητα, τότε απλά θα έχουμε μήνυμα λάθους από τον browser. Αν όμως το σύστημα ετοιμαστεί τότε δίνοντας τη διεύθυνση του Raspberry με πόρτα την 8080, θα δούμε την εισαγωγική οθόνη του UniFi Controller. Η διεύθυνση που έχει αυτή τη στιγμή είναι η 192.168.1.10, οπότε η διεύθυνση που θα πληκτρολογήσουμε στον browser μας είναι η <tt>http://192.168.1.10:8080/</tt>. Η σελίδα θα κάνει redirection σε https, αλλά στην ίδια διεύθυνση και ο browser θα μας παραπονεθεί για το πιστοποιητικό της σελίδας. Όταν τελικά το αποδεχτούμε:</p>
<p class="en">We will have to wait for a short time (several seconds) before trying to enter the system. To test it we will have to use the browser of another computer. If we try to enter before the program finishes all its intro tasks then we will simply receive an error message from our browser. But if the system is ready to accept connections, then by entering the IP address of the Raspberry Pi using port 8080, we will get the introduction screen of UniFi Controller. The address used during the righting of this article is 192.168.1.10, so this is the address we will type in our browser: <tt>http://192.168.1.10:8080/</tt>; the page will redirect to https protocol at the same IP address and our browser will complain about this page's certificate. When we finally accept it:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_Ng2WiUhGj1z3VTT7o57fD1c9TjhliXZhiHid8I-6onJQc9EVX2pGnbhnTMvrLlMHRT0ZVOAhjiexf8TWDE76tOQhz9eJOZCaiRu8S5en5xawA9rTWq86C0Qc3X1CoPVrsaa47Jq4KnsV/s1600/RasPi+UniFi1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_Ng2WiUhGj1z3VTT7o57fD1c9TjhliXZhiHid8I-6onJQc9EVX2pGnbhnTMvrLlMHRT0ZVOAhjiexf8TWDE76tOQhz9eJOZCaiRu8S5en5xawA9rTWq86C0Qc3X1CoPVrsaa47Jq4KnsV/s320/RasPi+UniFi1.png" /></a></div>
<p class="el">Για να σταματήσουμε το πρόγραμμα, αρκεί να τρέξουμε την εντολή:</p>
<p class="en">To stop the program, we have to enter the following command:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/opt/UniFi > sudo /usr/bin/java -jar /opt/UniFi/lib/ace.jar stop
</pre></div>
<p class="el">Για την ώρα δεν χρειάζεται να κάνουμε παραμετροποίηση του συστήματος. Μπορούμε να την αφήσουμε για αργότερα, όταν όλα θα είναι έτοιμα!</p>
<p class="en">For now we will not continue to any network configuration. We can leave it for later on, when everything is in place!</p>
<a id="RPi_service"></a>
<h4 class="el">Δημιουργία service script</h4>
<h4 class="en">Service Script Creation</h4>
<p class="el">Τώρα που το σύστημα λειτουργεί, θα πρέπει να το κάνουμε να ενεργοποιείται στα κατάλληλα runlevels του Raspbian.</p>
<p class="en">Now we know that the system works, we must make it automatically activated at the appropriate Raspbian runlevels.</p>
<p class="el">Η διαδικασία είναι η ίδια με αυτή που περιγράφεται στο <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">αντίστοιχο άρθρο για το openSUSE</a>. Ο κατάλογος <tt>/etc/init.d/</tt> περιέχει όλα τα scripts για τα services. Περιέχει κι ένα αρχείο που μας ενδιαφέρει περισσότερο, το <tt>skeleton</tt>. Αυτό είναι ένα αρχείο στο οποίο μπορούμε να βασιστούμε για να φτιάξουμε το δικό μας script, έτσι ώστε το UniFi Controller να μπορεί να ενεργοποιηθεί και να απενεργοποιηθεί όπως ακριβώς και όλα τα υπόλοιπα services που διαθέτει το σύστημα. Το αρχείο που θα δημιουργήσουμε είναι το <tt>unifid</tt>. Μπορείτε να το δημιουργήσετε μόνοι σας από την αρχή, απλά αντιγράφοντας το ακόλουθο και σώζοντάς το μέσα στον εν λόγω κατάλογο:</p>
<p class="en">The procedure is the same as the one described in the <a href="http://eliaschr.blogspot.gr/2013/05/ubiquity-unifi-controller-software.html">similar article for openSUSE</a>. The <tt>/etc/init.d/</tt> contains all the scripts for all the available services. It also contains a file that we need more, named <tt>skeleton</tt>. That is the file we will be based on to create our own service script, to make UniFi Controller activated and deactivated in the same way as the rest of the system's services. The file we will create is called <tt>unifid</tt>. You can create it by yourselves from the very beginning, by simply copying and pasting the following code and saving it in the directory in question:</p>
<div class="code"><pre class="prettyprint lang-sh linenums">
#! /bin/sh
### BEGIN INIT INFO
# Provides: unifid
# Required-Start: $local_fs $syslog $network
# Required-Stop: $local_fs $syslog $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: unifid daemon providing Controller server for UniFi Access Points
# Description: Start unifid to allow the UniFi Controller Software to be able to
# control the UniFi Access Points of Ubiquity in the network. The softare runs in Java
# and is installed in /opt/ directory.
### END INIT INFO
# Author: Elias Chrysocheris <elias_chr@otenet.gr>
#
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="UniFi Controller Service for assisting Ubiquity's UniFi Access Points"
JAVA_BIN=/usr/bin/java
NAME=unifid
MONGOD_BIN=/opt/UniFi/bin/mongod
DAEMON=/opt/UniFi/lib/ace.jar
DAEMON_ARGS="-jar $DAEMON"
SCRIPTNAME=/etc/init.d/$NAME
# Exit if Java package is not installed
[ -x "$JAVA_BIN" ] || { echo "Cannot find java executable in $JAVA_BIN, or java is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Also, mongoDB must be installed. The extra step here is that there must be a valid link in
# /opt/UniFi/bin/mongod that points to the mongod executable
if [ ! \( -e $MONGOD_BIN \) ]
then
echo "Cannot find mongod executable in $MONGOD_BIN, or mongoDB is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi;
fi
# Exit if the package is not installed
[ -e "$DAEMON" ] || { echo "Cannot find UniFi Controller executable in $DAEMON, or the controller software is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --test --start --quiet --exec $JAVA_BIN -- $DAEMON_ARGS start > /dev/null \
|| return 1
start-stop-daemon --start --quiet --exec $JAVA_BIN -- $DAEMON_ARGS start &
RETVAL="$?"
[ $RETVAL > 0 ] && return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --exec $JAVA_BIN -- $DAEMON_ARGS stop
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON
[ "$?" = 2 ] && return 2
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$JAVA_BIN -jar $DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
</pre></div>
<p class="el">Το script θα πρέπει να είναι εκτελέσιμο, οπότε όταν δημιουργηθεί στο δίσκο θα πρέπει να του ενεργοποιηθούν και τα κατάλληλα δικαιώματα εκτέλεσης. Επίσης, η δημιουργία του γίνεται από τον χρήστη <tt>root</tt>, αλλοιώς το σύστημα θα αρνηθεί να το σώσει μέσα στον κατάλογο <tt>init.d</tt>. Τέλος θα πρέπει να γίνουν update τα links των καταλόγων <tt>rc?.d</tt>, έτσι ώστε το service να ξεκινάει ή να σταματάει αυτόματα, ανάλογα με το runlevel στο οποίο μεταπηδάει το Raspbian. Οι εντολές για τα δικαιώματα και την ενημέρωση των runlevels είναι οι ακόλουθες:</p>
<p class="en">The script must be marked executable, so when it is created in the disc we must alter its access rights. Another tip is that it ust be created from the <tt>root</tt> user, or the system will deny its saving into <tt>init.d</tt>. Last, the links of all <tt>rc?.d</tt> directories must be updated, for the service to be started or stopped automatically, according to runlevel transitions of the operating system. The commands for altering the access rights and updating the runlevel links are:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/opt/UniFi > cd /etc/init.d/
elias@unificontrol:/etc/init.d > sudo chmod 0755 unifid
elias@unificontrol:/etc/init.d > sudo update-rc.d unifid defaults
update-rc.d: using dependency based boot sequencing
elias@unificontrol:/etc/init.d >
</pre></div>
<p class="el">Μπορεί να γίνει να δοκιμή του script που μόλις ενεργοποιήθηκε δίνοντας τις ακόλουθες εντολές και κοιτάζοντας τις αποκρίσεις:</p>
<p class="en">We can test the newlly created and activated script by executing the folowing commands and observe their response:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:/etc/init.d > sudo /etc/init.d/unifid start
elias@unificontrol:/etc/init.d > sudo /etc/init.d/unifid status
[ ok ] unifid is running.
elias@unificontrol:/etc/init.d > sudo /etc/init.d/unifid stop
elias@unificontrol:/etc/init.d > sudo /etc/init.d/unifid status
[FAIL] unifid is not running ... failed!
elias@unificontrol:/etc/init.d >
</pre></div>
<p class="el">Αν όλα πήγαν καλά, τότε μετά από μια επανεκκίνηση αν εκτελέσουμε την εντολή <tt>ps aux | grep ace.jar</tt> θα πρέπει να δούμε τα ακόλουθα:</p>
<p class="en">If everything went right, after a restart of Raspbian, using the command <tt>ps aux | grep ace.jar</tt> we must get something like:</p>
<div class="code"><pre class="prettyprint">
elias@unificontrol:~ > ps aux | grep ace.jar
<b>root 3189 54.0 5.2 370688 25212 ? Sl 23:43 0:16 /usr/bin/java -jar /opt/UniFi/lib/ace.jar start</b>
elias 3241 0.0 0.1 3548 892 pts/0 S+ 23:43 0:00 grep --color=auto ace.jar
elias@unificontrol:~ >
</pre></div>
<p class="el">Αυτό που μας ενδιαφέρει είναι η πρώτη γραμμή που δείχνει πως ένα process τρέχει αυτή τη στιγμή στον επεξεργαστή κι έχει την εντολή ενεργοποίησης του service του UniFi Controller. Η συνέχεια είναι απλή. Ανοίγουμε και πάλι τον browser και δίνοντας την IP διεύθυνση του Raspberry με την πόρτα 8080, όπως κάναμε και πριν, ξεκινάμε την παραμετροποίηση του συστήματος των Access Points. Όταν όλα τελειώσουν μπορούμε να έχουμε μια εικόνα σαν αυτή:</p>
<p class="en">What we are interested in, is the first line showing there is an active process running in our processor, started by the same command we used to start the UniFi Controller. What follows is natural; We open a browser in our computer and by entering the Raspberry's IP address and port 8080, as we did before, we can start the configuration of our Access Points. When everything is done we must get a page like that:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaf9OhAeYbLU2pXkKZKFopurZbg-_7094wbroDvOFpuJiQFEG39RnIq1KVo5I4gP5bB60oUGF07U55CKf63ta2Qonvptt6X-WmNvFwQBRxwbDHoRM6AKEthMb64Ef-H7_qhQ-3aJMsktGf/s1600/UniFi+Screenshot.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaf9OhAeYbLU2pXkKZKFopurZbg-_7094wbroDvOFpuJiQFEG39RnIq1KVo5I4gP5bB60oUGF07U55CKf63ta2Qonvptt6X-WmNvFwQBRxwbDHoRM6AKEthMb64Ef-H7_qhQ-3aJMsktGf/s320/UniFi+Screenshot.png" /></a></div>
<a id="RPi_conclusions"></a>
<h4 class="el">Συμπεράσματα</h4>
<h4 class="en">Conclutions</h4>
<p class="el">Το Raspberry Pi, είναι ένα gadgetάκι που, μπορεί κάποιος να μη μείνει ικανοποιημένος αν προσπαθήσει να το χρησιμοποιήσει όπως ένα Desktop υπολογιστή. Όταν το χρησιμοποιήσετε απλά για internet κ.λ.π. θα διαπιστώσετε ότι μοιάζει πολύ με ένα υπολογιστή τεχνολογίας εποχής του <a href="http://en.wikipedia.org/wiki/K_Desktop_Environment_3">KDE3</a>. Ναι μεν μπορείς να κάνεις κάποια δουλειά, αλλά οι χρόνοι καθυστέρησης σε γυρίζουν λίγο πίσω... Από την άλλη, σαν ένας μικρός server έχει αρκετά πλεονεκτήματα. Έχει ικανοποιητική ταχύτητα για τη διαχείριση ενός μικρού δικτύου. Μπορεί να αναλάβει "μικροδουλειές" όπως backup/file server, firewall ή ακόμα και για να τραβάει φωτογραφίες σαν σύστημα παρακολούθησης/ασφάλειας. Στη δική μας περίπτωση, αυτό που μας ενδιέφερε είναι να μπορέσει να λειτουργήσει ως διαχειριστής δικτύου ξενοδοχείου και αυτή τη δουλειά την κάνει αρκετά καλά.</p>
<p class="en">Raspberry Pi is a small gadget that someone may not be satisfied if he/she uses it as a desktop computer. If you use it simply for internet browsing etc. you will find out it is very similar, in terms of processing power, to a computer that used <a href="http://en.wikipedia.org/wiki/K_Desktop_Environment_3">KDE3</a>. It is true you can do some work, but the execution times takes you a little bit back in time... In contrast, working as a small server has many advantages. Its speed is satisfactory for using in a small network. It can handle some simple tasks such as a backup/file server, a firewall or even taking photos as an area survailance/security system. In our case, what we were interested in was to be able to handle access control and portal serving in a hotel's network. And that is a job that can handle very well.</p>
<p class="el">Μια ακόμα δυνατότητα είναι πως μπορεί πολύ εύκολα να τροφοδοτηθεί από μια επαναφορτιζόμενη μπαταρία. Λόγω την μικρής του κατανάλωσης μια τέτοια μπαταρία είναι ικανή να το κρατήσει σε λειτουργία για πραγματικά πολλές ώρες, σε περίπτωση διακοπής της ΔΕΗ.</p>
<p class="en">Another posibility is that it can be easily powered by a rechargable battery. Due to its low power consumption a battery like that can keep it functional even during long time power failures of the power company.</p>
<p class="el">Όσο για την τιμή του, είναι ιδανική για αυτό που προσφέρει και αυτά που μπορεί να κάνει, ειδικά σαν "δικτυακό βοήθημα". Οι γενικές εντυπώσεις μας είναι άριστες!</p>
<p class="en">And for its price, it is ideal for what it can offer and perform, aspecially as a "network assistant". Our general impression is more than surprising!</p>
<p class="el authorname">Ηλίας Χρυσοχέρης</p>
<p class="en authorname">Elias Chrysocheris</p>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com3tag:blogger.com,1999:blog-9147006209672954597.post-15393824492723800552013-05-11T22:25:00.000+03:002013-09-25T01:13:35.436+03:00Ubiquity UniFi Controller Software στο openSUSEUbiquity UniFi Controller Software in openSUSE<h4 class="el">Το ξεκίνημα της ιστορίας</h4>
<h4 class="en">The Beginning Of The Story</h4>
<p class="el">
Κάποια στιγμή μου ζητήθηκε από ένα φίλο να τον βοηθήσω να στήσει ένα δίκτυο σε ένα ξενοδοχείο. Μετά από λίγο ψάξιμο βρέθηκαν τα κατάλληλα εργαλεία για αυτή τη δουλειά: τα Access Points της <a href="http://www.ubnt.com/">Ubiquity</a>. Συγκεκριμένα η απόφαση πήγε στη σειρά <a href="http://www.ubnt.com/unifi">UniFi</a> που έχουν καταπληκτικά χαρακτηριστικά. Δίνουν τη δυνατότητα για custom guest portal για την είσοδο των πελατών, δημιουργία VPNs, μέχρι τέσσερα διαφορετικά SSIDs με το καθένα από αυτά να έχει τα δικά του χαρακτηριστικά, ορισμό μέγιστου bandwidth για κάθε client που συνδέεται επάνω, ορισμό μέγιστου ποσού δεδομένων που θα διακινήσει και πολλά άλλα. Όλα αυτά τα δίνουν σε αρκετά προσιτή τιμή.</p>
<p class="en">Once, a friend of mine asked me to help him set up a wireless network of a hotel. After short searching in the internet and around the necessary tools for this job were found: The Access Points of <a href="http://www.ubnt.com/">Ubiquity</a>. More precisely the decision end up to the <a href="http://www.ubnt.com/unifi">UniFi</a> line that have great specifications. They have the ability to use custom guest portals for the authorisation to the network usage, VPNs, ability to handle up to four wireless SSIDs, each having its own characteristics, bandwidth limit per client, user data quota and many many more; and all these in a very good price.</p>
<p class="el">
Το μειονέκτημα που υπάρχει στην όλη ιστορία είναι πως για να έχει custom guest portal, ή δημιουργία voucher για τους πελάτες, θα πρέπει ένας υπολογιστής να τρέχει συνεχώς το software της μαμάς εταιρίας (Ubiquity). Για να λυθεί αυτό, αρχικά υπήρχε η ιδέα να χρησιμοποιηθεί το μηχάνημα της reception του ξενοδοχείου για αυτή τη δουλειά. Όμως το μηχάνημα αυτό θα πρέπει να σβήνει κάποιες φορές... Άλλο ένα μειονέκτημα είναι ότι το συγκεκριμένο μηχάνημα τρέχει το ακατονόμαστο λειτουργικό.</p>
<p class="en">
The only drawback in the whole system is the necessity to have one computer running the mother company's (Ubiquity's) software 24/7 to give the ability of serving the custom guest portal and client voucher creation. The first idea was to use the reception's computer for that purpose. But this computer is switched off some hours in the night... Another minus in this idea was that this specific machine must run the unnamed operating system (may God make it "operating").</p>
<p class="el">
Μετά από μια επίδειξη του Ubuntu και του <a href="http://www.opensuse.org/">openSUSE</a>, παρότι έχει κάποια ιδέα αυτός ο φίλος από Linux, προτίμησε (τι αναπάντεχο...) να χρησιμοποιήσει το προσωπικό του μηχάνημα με openSUSE και το software της Ubiquity να τρέχει σε αυτό το μηχάνημα. Αυτό το μηχάνημα δεν σβήνει ποτέ, οπότε είναι η καλύτερη ιδέα!</p>
<p class="en">
After a small demonstration of Ubuntu and <a href="http://www.opensuse.org/">openSUSE</a>, though my friend already knew some things about Linux, he prefered (hmmm, how unexpected...) to use openSUSE and Ubiquity's software in his personal computer. That computer could stay alive 24/7, so this was the best idea!</p>
<h4 class="el">Τι θα δούμε</h4>
<h4 class="en">What's in this article</h4>
<p class="el">Τα κομμάτια που θα δούμε σε αυτό το άρθρο είναι τα ακόλουθα:</p>
<p class="en">We are going to discuss the following topics:</p>
<ul>
<li><a href="#Prepare"><span class="el">Προεργασία</span><span class="en"></span>Groundwork</a></li>
<li><a href="#UniFi_install"><span class="el">Εγκατάσταση του UniFi Controller</span><span class="en">UniFi Controller Installation</span></a></li>
<li><a href="#make_group"><span class="el">Δημιουργία group <tt>unifi</tt> - Προαιρετικό Βήμα</span><span class="en"><tt>unifi</tt> Group Creation - Optional Step</span></a></li>
<li><a href="#checksoftware"><span class="el">Έλεγχος του UniFi Controller Software</span><span class="en">UniFi Controller Software Test</span></a></li>
<li><a href="#firewall"><span class="el">Κάποιος μπλοκάρει την επικοινωνία... (Firewall)</span><span class="en">Someone Blocks The Communication... (Firewall)</span></a></li>
<li><a href="#service"><span class="el">Χρήση του UniFi Controller ως service</span><span class="en">Usage Of UniFi Controller As A Service</span></a></li>
<li><a href="#conclusions"><span class="el">Συμπεράσματα</span><span class="en">Conclusions</span></a></li>
</ul>
<a id="Prepare"></a>
<h4 class="el">Προεργασία</h4>
<h4 class="en">Groundwork</h4>
<p class="el">
Η προεργασία για το στήσιμο του συστήματος έχει το κλασικό backup αρχείων, εγκατάσταση του openSUSE στον υπολογιστή και επαναφορά των αρχείων από το backup του προηγούμενου λειτουργικού</p>
<p class="en">
The groundwork we have to do is to backup the system, install openSUSE in the computer and restore the necessary user files form the backup of the previous (ehmmm... non) operating system.</p>
<p class="el">
Στη συνέχεια θα πρέπει να εγκατασταθούν οι εξαρτήσεις που χρειάζεται το UniFi Controller Software. Αυτές δεν είναι πολλές:</p>
<p class="en">
Next, follows the step of dependecies installation of UniFi Controller Software. They are not that many:</p>
<ul>
<li>Java</li>
<li>MongoDB</li>
</ul>
<p class="el">
Η Java είναι από την αρχή εγκαταστημένη στο openSUSE (όπως και σε κάθε διανομή Linux), οπότε το μόνο που υπήρχε σαν εγκατάσταση είναι η <a href="http://www.mongodb.org/">database MongoDB</a>. Δεν υπάρχει ευκολότερο πράγμα από αυτό. Απλώς ανοίγουμε το YaST (από το κεντρικό μενού επιλέγουμε το tab "Computer" και από τη λίστα που εμφανίζεται επιλέγουμε το "Install/Remove Software"</p>
<p class="en">
Java should be already installed in openSUSE (as in every Linux distribution), so the only one left to be installed is <a href="http://www.mongodb.org/">MongoDB database</a>. There is no easier thing than that. Just open YaST (from the main menu select the "Computer" tab and in the appeared list select "Install/Remove Software"</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTK9z7D011LB6uIazMDZW010RSjh13XMFHg01sEFTvDqRsSNwPBHMRRt0m2Hi-nJcGWBD0xfIYbKk9gEa8l73mTUl-ESE_nkoLjo_XkBsxyKpI4Rjp4oif4M0AhyiYx07lW-pkQLtaXUmf/s1600/Ubnt1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTK9z7D011LB6uIazMDZW010RSjh13XMFHg01sEFTvDqRsSNwPBHMRRt0m2Hi-nJcGWBD0xfIYbKk9gEa8l73mTUl-ESE_nkoLjo_XkBsxyKpI4Rjp4oif4M0AhyiYx07lW-pkQLtaXUmf/s320/Ubnt1.png" /></a></div>
<p class="el">
Μετά την εισαγωγή του συνθηματικού του <tt>root</tt>, ανοίγει το κεντρικό παράθυρο του "YaST - Software Management". Στο πεδίο εύρεσης γράφουμε το "<tt>mongodb</tt>" και πατάμε το "Search". Στο δεξί τμήμα του παραθύρου εμφανίζεται και το πακέτο που μας ενδιαφέρει. Κάνουμε διπλό κλικ επάνω του και αμέσως μαρκάρεται για εγκατάσταση. Πατώντας το "Accept" ξεκινάμε την εγκατάσταση του πακέτου μας:</p>
<p class="en">
After typing the <tt>root</tt> password, "YaST - Software Management" main window opens. In the search field type "<tt>mongodb</tt>" and press "Search". At the right part of this window the needed package appears. Double clicking marks the package for installation. By pressing "Accept" the installation begins:</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs02Q2B6y3MEYO4BALmqIRVAEbwzrY-bJSc8nstI24rlQg-EkklL3dgRNO7_nIhxF1nbZdYLiKNvQvOk_dP5e7U5qqkxBzr2oT2914oQTnGIGqWFEvqL1ZtnhCDs_Xpj4taW5PrgQ_YR2S/s1600/Ubnt2.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs02Q2B6y3MEYO4BALmqIRVAEbwzrY-bJSc8nstI24rlQg-EkklL3dgRNO7_nIhxF1nbZdYLiKNvQvOk_dP5e7U5qqkxBzr2oT2914oQTnGIGqWFEvqL1ZtnhCDs_Xpj4taW5PrgQ_YR2S/s320/Ubnt2.png" /></a></div>
<a id="UniFi_install"></a>
<h4 class="el">Εγκατάσταση του UniFi Controller</h4>
<h4 class="en">UniFi Controller Installation</h4>
<p class="el">
Η εγκατάσταση του συστήματος είναι εύκολη. Δεν έχει κάτι το περίπλοκο. Το πρόγραμμα διατίθεται σε μορφή συμπιεσμένου αρχείου <tt>.zip</tt> σε δύο εκδόσεις:</p>
<p class="en">
The installation of the program in question is very simple. It does not contain anything complicated. It is available as a <tt>.zip</tt> file in two versions (at the time of this writing):</p>
<ul>
<li class="el"><b>Έκδοση 2.3.9:</b> Είναι η βασική και σταθερή έκδοση του προγράμματος και βρίσκεται στην τοποθεσία <a href="http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip</a></li>
<li class="en"><b>Version 2.3.9:</b> Is the basic and stable one of the program and can be founded at <a href="http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/2.3.9/UniFi.unix.zip</a></li>
<li class="el"><b>Έκδοση 3.1.1b:</b> Είναι η τελευταία έκδοση του προγράμματος αλλά είναι σε δοκιμαστική (beta) κατάσταση ακόμα. Έχει πολλά νέα χαρακτηριστικά και ίσως αξίζει τον κόπο να ασχοληθείτε μαζί της. Μπορείτε να τη βρείτε στην τοποθεσία <a href="http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip</a></li>
<li class="en"><b>Version 3.1.1b:</b> Is the last version of the program but still in beta state. It has many new features and is worth testing. Can be founded at <a href="http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip">http://www.ubnt.com/downloads/unifi/3.1.1/UniFi.unix.zip</a></li>
</ul>
<p class="el">
Όποια έκδοση και αν προτιμήσετε η εγκατάσταση γίνεται με τον ίδιο τρόπο. Σε γενικές γραμμές, για να είναι κάπως clean το σύστημα, προτείνεται εγκαταστάσεις τέτοιου είδους (που δεν είναι δηλαδή από αποθετήρια του λειτουργικού) να γίνονται στον κατάλογο <tt>/opt/</tt>, ή στον κατάλογο <tt>/usr/local/</tt>. Εδώ η εγκατάσταση θα γίνει στον κατάλογο <tt>/opt/</tt>. Απλά αποσυμπιέστε ως <tt>root</tt> τα περιεχόμενα του αρχείου <tt>.zip</tt> που κατεβάσατε, στον κατάλογο <tt>/opt/</tt>.</p>
<p class="en">
Whichever version you prefer to use, the installation walkthrough is the same. In general, for our system to be cleaner, such installations (meaning, installation of programs not included in the repositories of the system) is better to be either in <tt>/opt/</tt> directory, or <tt>/usr/local/</tt> one. In this article the installation will be in <tt>/opt/</tt>. Just unzip as <tt>root</tt> the <tt>.zip</tt> file you downloaded, at <tt>/opt/</tt> directory.</p>
<div class="code">
<pre class="prettyprint">eliaschr@orion:~> su
Password:
orion:/home/eliaschr # cd /opt/
orion:/opt # unzip /home/eliaschr/Downloads/UniFi.unix.zip
.
.
.
orion:/opt #
</pre>
</div>
<a id="make_group"></a>
<h4 class="el">Δημιουργία group unifi - Προαιρετικό Βήμα</h4>
<h4 class="en"><tt>unifi</tt> Group Creation - Optional Step</h4>
<p class="el">
Επειδή λογικά θα χρειάζεστε κατά καιρούς να κάνετε κάποιες αλλαγές, όπως δημιουργία guest portal κ.λ.π. που έχουν να κάνουν με απ' ευθείας αλλαγές στα αρχεία του δίσκου, καλό είναι να δημιουργήσετε ένα group με ονομασία <tt>unifi</tt> και να κάνετε τα αρχεία του καταλόγου <tt>UniFi/data</tt> να ανήκουν σε αυτό το group. Αν ενεργοποιήσετε και το SGID bit του εν λόγω υποκαταλόγου, τότε κάθε καινούργιο αρχείο ή κατάλογο που θα δημιουργείτε μέσα στον <tt>data</tt> θα ανήκει στο group <tt>unifi</tt>. Είναι προαιρετικό βήμα, αλλά ας δούμε πως γίνεται. Γενικά, οι επεξηγήσεις που υπάρχουν γίνονται όσο το δυνατόν με λιγότερη χρήση κονσόλας για να είναι λίγο πιο κατανοητά σε καινούργιους χρήστες του λειτουργικού:</p>
<p class="en">
Since from time to time you may need to make some alterations of the system, like the alteration of the guest portal etc., on the disc files, it is a very good way to create a user group named <tt>unifi</tt> and make the files in <tt>UniFi/data</tt> directory belong to it. If you also set the SGID bit of the directory in question, then every new file created in <tt>data</tt> will belong to the <tt>unifi</tt> group, also. It is an optional step, but lets see how it is done. In general, the explanations given in here use the command line interface as less as possible, for the new users of the operating system to be able to understand them easier:</p>
<p class="el">
Η δημιουργία του group γίνεται από το YaST. Αφού γίνει η επιλογή του YaST από το μενού και δωθεί ο κωδικός του <tt>root</tt>, εμφανίζεται το κεντρικό παράθυρο. Για τη δημιουργία ένός group γίνεται επιλογή της ομάδας "Security and Users" και στη δεξιά πλευρά του "User and Group Management"</p>
<p class="en">
The group creatin is done in YaST. By selecting YaST from the main menu and the <tt>root</tt> password is given, the main window of the program appears. To create o user group select "Security and Users" at the left side of the window and "User and Group Management" from its right part.</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwiPXMTcTOkaOVmIvKWNo1V1IjY4IsBcFAZgdKFymvOundZIgmGmRFhZoctNrG-twNNNRC0fyJw_QBB_kAijCawpSNBef_D_PWCvlKA4rdyrx0L2_6iV7A9n0ITgYfZlZCsmPUSvv9zkLj/s1600/Ubnt3.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwiPXMTcTOkaOVmIvKWNo1V1IjY4IsBcFAZgdKFymvOundZIgmGmRFhZoctNrG-twNNNRC0fyJw_QBB_kAijCawpSNBef_D_PWCvlKA4rdyrx0L2_6iV7A9n0ITgYfZlZCsmPUSvv9zkLj/s320/Ubnt3.png" /></a></div>
<p class="el">
Το παράθυρο που ανοίγει δείχνει τους χρήστες που υπάρχουν αυτή τη στιγμή στο σύστημα. Στο επάνω μέρος υπάρχουν τέσσερις καρτέλες. Η δεύτερη ονομάζεται "Groups" και μιας και μας ενδιαφέρει να προσθέσουμε ομάδα στο σύστημα, την επιλέγουμε. Με την επιλογή της καρτέλας των ομάδων, εμφανίζονται στην οθόνη οι διαθέσιμες ομάδες ενώ στο κάτω τμήμα της οθόνης υπάρχει το πλήκτρο προσθήκης "Add". Με την επιλογή αυτού του πλήκτρου εμφανίζεται το παράθυρο της προσθήκης ομάδας.</p>
<p class="en">
The window that opens presents the users that exist in the system. At the upper part there are four tabs. The second one is named "Groups" and since we need to add a user group in our system, we select it. After our tab selection, the available groups appear on screen while at the bottom of the screen there is a button named "Add". Selecting this button a new window opens for the new group creation.</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsM6V5MsQMCOIDP2DRLtyq7CIm37FmLlc3A5yL5IseoGaxEZfX0ODGCHN9amliRFw1EbLlVoM4jqmIOCx6xlcjvf3NTO6TdKGn01uiW25EyXJQsMkitI5i4CxalecXyn4MD8DMDur9QPwI/s1600/Ubnt4.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsM6V5MsQMCOIDP2DRLtyq7CIm37FmLlc3A5yL5IseoGaxEZfX0ODGCHN9amliRFw1EbLlVoM4jqmIOCx6xlcjvf3NTO6TdKGn01uiW25EyXJQsMkitI5i4CxalecXyn4MD8DMDur9QPwI/s320/Ubnt4.png" /></a></div>
<p class="el">
Στη θέση ονόματος της καινούργιας ομάδας μπαίνει το όνομα "<tt>unifi</tt>". Το νούμερο του group δεν χρειάζεται να αλλάξει μιας κι επιλέγεται αυτόματα από το σύστημα. Στο δικό σας σύστημα μπορεί να είναι διαφορετικό. Από τη δεξιά στήλη γίνεται επιλογή των χρηστών που θα έχουν τα δικαιώματα να αλλάζουν τις ρυθμίσεις του guest portal χωρίς να χρειάζεται να γίνονται <tt>root</tt>. Στο παραπάνω στιγμιότυπο φαίνονται οι ρυθμίσεις στο δικό μου μηχάνημα, όπου έχει προστεθεί και ο δικός μου χρήστης στο εν λόγω group.</p>
<p class="en">
In the name field of the new group "<tt>unifi</tt>" is placed. The number of the new group does not need to be changed as it is automatically placed by the system. In your system it may be different as it is in the snapshot. From the list at the right of the window the users that will have the access rights to change the guest portal files are selected. After that they will not have to be <tt>root</tt> to do all the job. In the above snapshot there are the settings made in my system, were only my user is added in this group.</p>
<p class="el">
Φυσικά, με το πάτημα του πλήκτρου "ΟΚ" εμφανίζεται και πάλι η αρχική εικόνα. Εκεί πρέπει να φαίνεται και η καινούργια ομάδα που μόλις δημιουργήθηκε. Πατώντας και πάλι το "ΟΚ" εφαρμόζονται οι καινούργιες ρυθμίσεις.</p>
<p class="en">
After pressing "ΟΚ" you return to the previous screen. The new group just created is there. By pressing "ΟΚ" again the new settings are applied to the system.</p>
<p class="el">
Το τελευταίο βήμα είναι να ανήκει ο κατάλογος που μπαίνουν τα δεδομένα στο καινούργιο group. Παράλληλα πρέπει το σύστημα, όταν δημιουργείται ένα καινούργιο αρχείο, να το κάνει να ανήκει και αυτό στο group <tt>unifi</tt>, αυτόματα. Αυτό χρειάζεται για να μπορεί να το διαβάζει και ο server του UniFi Controller Software. Δυστυχώς, εδώ δε μπορούμε να αποφύγουμε την κονσόλα, αλλά γίνεται με απλές εντολές.</p>
<p class="en">
The last step is to make the directory, with the data we need to be able to alter, a part of the new group. At the same time the newly created files must be automatically belong to the same group. This must be done for the UniFi Controller server to be able to read it. Unfortunately this cannot be done without the help of the console, but the commands are simple.</p>
<p class="el">
Ανοίγουμε μια κονσόλα και μπαίνουμε ως <tt>root</tt> εκτελώντας την εντολή <tt>su</tt>. Μετά την εισαγωγή του password του υπερχρήστη εκτελούνται οι εντολές που φαίνονται εδώ:</p>
<p class="en">
Open a console and become <tt>root</tt> by executing <tt>su</tt>. After entering the superuser's password enter the following commands:</p>
<div class="code">
<pre class="prettyprint">eliaschr@orion:~> su
Password:
orion:/home/eliaschr # cd /opt/UniFi/
orion:/opt/UniFi # mkdir data
orion:/opt/UniFi # chgrp unifi data
orion:/opt/UniFi # chmod g+w data
orion:/opt/UniFi # chmod g+s data
</pre>
</div>
<p class="el">
Αυτό που κάνουν οι εντολές είναι να δημιουργήσουν ένα κατάλογο με το όνομα <tt>data</tt> (εντολή <tt>mkdir</tt>), να κάνουν τον κατάλογο αυτό να ανήκει στο group <tt>unifi</tt> που δημιουργήθηκε πριν (εντολή <tt>chgrp</tt>), να δοθούν δικαιώματα ανάγνωσης κι εγγραφής στο group (πρώτη εντολή <tt>chmod</tt>) κι επιπλέον, ό,τι αρχείο ή κατάλογος δημιουργείται εκεί μέσα να ανήκει στο group που ανήκει και ο κατάλογος, δηλαδή το <tt>unifi</tt> (η τελευταία εντολή <tt>chmod</tt>). Η επόμενη εντολή, χρησιμοποιεί ένα σύστημα που ονομάζεται File Access Control List που προσθέτει επιπλέον δικαιώματα. Αυτό που μας ενδιαφέρει είναι τα αρχεία που δημιουργούνται να έχουν διακαιώματα read/write για τον χρήστη και το group, ενώ για τους υπόλοιπους να έχουν μόνο διακαιώματα διαβάσματος:</p>
<p class="en">
What these commands do, is to create a directory with the name <tt>data</tt> (<tt>mkdir</tt> command), make this directory belong to <tt>unifi</tt> group created earlier (<tt>chgrp</tt> command), give read and write access rights to that group (first <tt>chmod</tt> command) and whatever whatever file or directory is created in there is made automatically to belong to the group of its parent, meaning <tt>unifi</tt> (The last <tt>chmod</tt> command). The next command that shall be presented, uses an extended system that is called File Access Control List that extends the access rights of the files. What we need here, is the files that created to have read/write access for both the user and the group, but only read access rights for the rest of the users:</p>
<div class="code">
<pre class="prettyprint">orion:/opt/UniFi # setfacl -d -m u::rwX,g::rwX,o::r data
</pre>
</div>
<p class="el">Τέλος, για να είναι ολοκληρωμένη η εγκατάσταση του συστήματος, θα πρέπει να δημιουργήσουμε ένα link προς το εκτελέσιμο της βάσης δεδομένων. Το link βρίσκεται ήδη στον κατάλογο <tt>/opt/UniFi/bin/</tt> κι έχει το όνομα <tt>mongod</tt>. Δυστυχώς δείχνει σε λάθος τοποθεσία, οπότε πρέπει να το διορθώσουμε:</p>
<p class="en">Last but not least, for the installation to be complete we must create a link to the executable of the database. There is already a link in <tt>/opt/UniFi/bin/</tt> directory named <tt>mongod</tt>. Unfortunately it points to a wrong place, so we must correct it:</p>
<div class="code">
<pre class="prettyprint">orion:/opt/UniFi # cd bin
orion:/opt/UniFi/bin # rm mongod
orion:/opt/UniFi/bin # ln -s /usr/sbin/mongod mongod
</pre>
</div>
<p class="el">Τώρα το εν λόγω link δείχνει στο σωστό σημείο.</p>
<p class="en">Now the link in question points to the correct file.</p>
<p class="el">
Μέχρι εδώ έχουμε κάνει μισή δουλειά... Βασικά μας δίνεται η δυνατότητα να μπορούμε να αλλάζουμε τα δεδομένα των αρχείων που θα δημιουργεί ο server μέσα στον κατάλογο <tt>data</tt> και τους υποκαταλόγους του, ως απλοί χρήστες. Η διαφορά είναι πως αν δημιουργήσουμε κάτι δικό μας, τότε για να το διαβάσει σωστά ο server θα πρέπει να του αλλάξουμε τα δικαιώματα, αλλά αυτό πλέον μπορεί να γίνεται εύκολα από το γραφικό περιβάλλον, χωρίς τη χρήση της κονσόλας...</p>
<p class="en">
Well, up to now we have done half of the job... Actually, we have the access to alter files that the server creates in <tt>data</tt> directory and its siblings as simple users (without being <tt>root</tt>). The difference is that when we create something of our own, for the server to be able to read and manipulate it correctly we will have to change its access rights by hand; but this is not that simple through the graphical environment without the terminal usage...</p>
<a id="checksoftware"></a>
<h4 class="el">Έλεγχος του UniFi Controller Software</h4>
<h4 class="en">UniFi Controller Software Test</h4>
<p class="el">
Σε αυτό το σημείο είμαστε έτοιμοι να δούμε αν το πρόγραμμα που μόλις εγκαταστήσαμε τρέχει σωστά. Το πρόγραμμα είναι γραμμένο σε Java άρα για να τρέξει αρκεί να μπούμε σε μια κονσόλα, ως υπερχρήστες και να εκτελέσουμε την εντολή:</p>
<p class="en">
At that point we are ready to test if the program we've just installed is functional. The program is written in Java so to execute it we need to enter a console and, as superusers run the command:</p>
<div class="code">
<pre class="prettyprint">orion:/whateverpath # java -jar /opt/UniFi/lib/ace.jar start &
</pre>
</div>
<p class="el">
Με την εκτέλεση της εντολής αυτής θα παρατηρήσουμε ότι ο επεξεργαστής αρχίζει και λειτουργεί αρκετά. Μετά από μερικά δευτερόλεπτα, αν δεν έχει εμφανιστεί κανένα μήνυμα λάθους, ο server του UniFi θα έχει ξεκινήσει και ο επεξεργαστής θα έχει πέσει πάλι για ύπνο! Για να τον ελέγξουμε ότι λειτουργεί σωστά αρκεί σε ένα browser να δωθεί η διεύθυνση <tt>http://localhost:8080/</tt></p>
<p class="en">
By executing this command we observe the processor working hard for a while. After some seconds, if there is no error message, UniFi server must be up and running and the processor must have fallen to sleep, again! To test that the server is well functioning the address <tt>http://localhost:8080/</tt> must be entered in a browser.</p>
<p class="el">
Το πρώτο πράγμα που θα εμφανιστεί είναι το προειδοποιητικό μήνυμα για το άγνωστο ssl certificate. Φυσικά και θα πρέπει να γίνει αποδεχτή του και ο browser θα συνεχίσει στην τελική σελίδα που φαίνεται στο στιγμιότυπο:</p>
<p class="en">
The first thing appears on screen is a warning message for an unknown ssl certificate. Of course we must accept it and the browser will continue to the following snapshot:</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuzHwvt5pV4rbRJ5KpF7ca-j1V4Ehti8kh9W0yODQnGwZZGsP3G7ozgQ5GvTfa8PNRmOu2v_4uWc6ydQVWxFdh1HQfMQjAPe9AkWywJuuD9dBcrLPqB_3KdG2DVMJZ0K994eMwV1v0vfIM/s1600/Ubnt5.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiuzHwvt5pV4rbRJ5KpF7ca-j1V4Ehti8kh9W0yODQnGwZZGsP3G7ozgQ5GvTfa8PNRmOu2v_4uWc6ydQVWxFdh1HQfMQjAPe9AkWywJuuD9dBcrLPqB_3KdG2DVMJZ0K994eMwV1v0vfIM/s320/Ubnt5.png" /></a></div>
<p class="el">
Το configuration του συστήματος συνεχίζει με το πάτημα του "Next" κ.λ.π. Στο τέλος θα εμφανιστεί το τελικό login screen.</p>
<p class="en">
The system configuration goes on by pressing the "Next" button etc. In the end there will be the login screen.</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1hN1VbRBMY9jXNeBNGbWrS1_nq7ryyIsLhe73dp1v8utmasoeWkKNvkMvbcuaAPi0jTjPGgu-u1BZPdc5KK4BFDmLSS8dq_NXxJQxAWHmyucPfLNLSm_o-CLzxU2iaFfSqsTu2UcTC3uP/s1600/Ubnt7.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1hN1VbRBMY9jXNeBNGbWrS1_nq7ryyIsLhe73dp1v8utmasoeWkKNvkMvbcuaAPi0jTjPGgu-u1BZPdc5KK4BFDmLSS8dq_NXxJQxAWHmyucPfLNLSm_o-CLzxU2iaFfSqsTu2UcTC3uP/s320/Ubnt7.png" /></a></div>
<p class="el">
Τώρα ο server έχει δημιουργήσει κάποια αρχεία ρυθμίσεων. Μπορούμε να τα δούμε στον κατάλογο <tt>/opt/UniFi/data</tt> παρατηρώντας ότι όλα τα αρχεία ανήκουν όντως στην ομάδα <tt>unifi</tt> όπως ακριβώς ήταν επιθυμητό:</p>
<p class="en">
The server has now created some settings files. We can find then in the <tt>/opt/UniFi/data</tt> directory, noticing that these files really belong to <tt>unifi</tt> group as we needed:</p>
<div class="code">
<pre class="prettyprint">eliaschr@orion:/whateverpath # ls -l /opt/UniFi/data/
total 16
drwxrwsr--+ 2 root unifi 4096 May 10 22:29 backup
drwxrwsr--+ 4 root unifi 4096 May 10 22:30 db
-rw-rw-r-- 1 root unifi 2184 May 10 22:29 keystore
-rw-rw-r-- 1 root unifi 620 May 10 22:51 system.properties
</pre>
</div>
<p class="el">
Αν δεν έχετε ακόμα ενεργοποιημένο κάποιο UniFi Access Point στο δίκτυο δε θα καταλάβετε ένα "πρόβλημα" που υπάρχει. Αν όμως έχετε κάποιο Access Point στο δίκτυο, τότε ας δούμε και πάλι το μήνυμα που υπήρξε στο δεύτερο βήμα της παραμετροποίησης:</p>
<p class="en">
If you have not connected any UniFi Access Point in the network, yet, you will not have noticed a "problem". But if you have then, lets see the message we saw at the second step of the configuration wizard, again:</p>
<div class="center">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_GSL5dCNvsT1sGome28wa-h5768KpZpdcakg2t0lEdNN39r-urxjG3fQI2OEYWbC-uGG_VHZgKL2pT_Od5vt1JgPOEdM_u76NOy3Hbe4z0rUbNHs1JF7kvW5xaDWUkXu8wKqimRmXSTfE/s1600/Ubnt6.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_GSL5dCNvsT1sGome28wa-h5768KpZpdcakg2t0lEdNN39r-urxjG3fQI2OEYWbC-uGG_VHZgKL2pT_Od5vt1JgPOEdM_u76NOy3Hbe4z0rUbNHs1JF7kvW5xaDWUkXu8wKqimRmXSTfE/s320/Ubnt6.png" /></a></div>
<p class="el">
Το σύστημα μας λέει πολύ απλά ότι δεν βρίσκει κανένα Access Point...</p>
<p class="en">
Well, no devices have been discovered, says the system...</p>
<a id="firewall"></a>
<h4 class="el">Κάποιος μπλοκάρει την επικοινωνία... (Firewall)</h4>
<h4 class="en">Someone Blocks The Communication... (Firewall)</h4>
<p class="el">
Ο λόγος που δε μπορούμε να δούμε κανένα από τα Access Points που έχουμε συνδεδεμένα στο δίκτυό μας είναι ότι το Firewall του openSUSE μπλοκάρει την επικοινωνία. Αν γνωρίζουμε λίγα πράγματα από το firewall, τότε μπορούμε να ενεργοποιήσουμε το logging και να δούμε τι προσπαθεί να κάνει ο UniFi Controller το οποίο σταματάει εξ αιτίας του firewall. Θα δούμε μια επικοινωνία broadcast στην πόρτα 10001. Αν επιθυμούμε να έχουμε πρόσβαση στο πρόγραμμα και από άλλο υπολογιστή τότε χρειαζόμαστε και τις πόρτες 8080 και 8443. Αν χρειάζεστε και το shutdown θα πρέπει να ανοιχτεί και η πόρτα 8081. Αυτές είναι οι πόρτες που πρέπει να ανοίξουμε στο τείχος προστασίας για να μπορέσει να λειτουργήσει το σύστημα σωστά.</p>
<p class="en">
The reason we cannot see any of our Access Points through the UniFi Controller is the openSUSE Firewall, blocking the communication. If we are familiar with this firewall, then we can enable its logging and find out what UniFi Controller tries to do that is blocked by openSUSE Firewall. Then, we will notice a broadcast packet using port 10001. If we wish access to the program by another computer, also, we also need access to ports 8080 and 8443. If we also need shutdown access to the Access Point another port must be included in the list; port 8081. These ate the ports we have to unblock in the firewall settings in order for the system to function properly.</p>
<p class="el">
Επειδή μπορεί να θέλετε να αλλάξετε τις πόρτες που χρησιμοποιεί το σύστημα, τότε για να δείτε το πλήρες σετ που χρησιμοποιούνται από τις ρυθμίσεις, αρκεί να ανοίξετε το αρχείο <tt>data/system.properties</tt>. Απλά, στις πόρτες που θα ρυθμίσετε το firewall θα πρέπει να θυμηθείτε και την πόρτα 10001.</p>
<p class="en">
Because you may need to change the ports that the UniFi system uses, to find out the complete set (and alter them) you can open the <tt>data/system.properties</tt> file. Don't forget that together with these ports you also have to unblock 10001 in the firewall settings.</p>
<div class="code">
<pre class="prettyprint lang-sh linenums">portal.http.port=8880
portal.https.port=8843
unifi.db.port=27117
unifi.http.port=8080
unifi.https.port=8443
unifi.shutdown.port=8081
</pre>
</div>
<p class="el">Ας δούμε πως θα ανοίξουμε τις πόρτες που θέλουμε στο τείχος προστασίας. Αρχικά ανοίγουμε το YaST (αν δεν το έχουμε ήδη ανοικτό) και από την αριστερή στήλη επιλέγουμε την ομάδα "Security and Users", ενώ από τη δεξιά πλευρά ανοίγουμε το "Firewall"</p>
<p class="en">Lets see how we can open the necessary ports. First, we open YaST (if we don't have it already), from its left side we choose "Security and Users", and from its right side we select "Firewall"</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8jLW2N5fIuJptY4o5qTW9_AAbrzfbsE3BFrxTCLYy4DP2v9cAN-aqOxDL-_AJOSnM5yJjGLCDwXNbiZsWMw2TNItThrwRBcv00kWUhFLf36CwhSI9-9xoJePv-q7w1yByWzwQSVJvwPX/s1600/Ubnt9.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgM8jLW2N5fIuJptY4o5qTW9_AAbrzfbsE3BFrxTCLYy4DP2v9cAN-aqOxDL-_AJOSnM5yJjGLCDwXNbiZsWMw2TNItThrwRBcv00kWUhFLf36CwhSI9-9xoJePv-q7w1yByWzwQSVJvwPX/s320/Ubnt9.png" /></a></div>
<p class="el">Στο παράθυρο που θα ανοίξει έχουμε και πάλι κατηγορίες ρυθμίσεων από την αριστερή μεριά και η δεξιά αλλάζει ανάλογα με την κατηγορία που θα επιλέξουμε. Η κατηγορία που ας ενδιαφέρει είναι η "Allowed Services"</p>
<p class="en">In the window that appears there are some settings categories at its left side, while the right one changes according to the selected category. The needed one is "Allowed Services"</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLRPbKbPrxgmo54NoMMYFEV2bI_o3CII-1sVqL-vMaVsHjCUluqlgkiL7H9pNKI-bsrajcxj2hmmZYc5OtZwPDFXRFYXAzBiaDdkXSt_oUUdWQwIIF_eSW2B6P9jNGDL2ebIZzam4g7Dol/s1600/Ubnt10.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLRPbKbPrxgmo54NoMMYFEV2bI_o3CII-1sVqL-vMaVsHjCUluqlgkiL7H9pNKI-bsrajcxj2hmmZYc5OtZwPDFXRFYXAzBiaDdkXSt_oUUdWQwIIF_eSW2B6P9jNGDL2ebIZzam4g7Dol/s320/Ubnt10.png" /></a></div>
<p class="el">Επειδή οι πόρτες που θα ανοίξουμε στο τείχος προστασίας δεν ανήκουν σε κάποια γνωστή υπηρεσία θα πρέπει να τις ορίσουμε χειροκίνητα. Για να γίνει αυτό πατάμε το κάτω δεξιά πλήκτρο που ονομάζεται "Advanced...". Θα ανοίξει ένα καινούργιο παράθυρο στο οποίο θα βάλουμε τα νούμερα από τις πόρτες που μας ενδιαφέρουν. Η ρύθμιση φαίνεται στο ακόλουθο στιγμιότυπο:</p>
<p class="en">Since the ports we want to open do not belong to a known service, we have to specify them by hand. To do that we just use the "Advanced..." button, at the down right side of the window. Another window appears in which we specify the number of the ports we want unblocked. They appear in the following snapshot:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL1_WvVAy5PQ8qdhzxR_eXZ8-hbwCnhru6mAJU0SevHKgKE0b2UqxxNNAf_hX3ZjahJ0fp-oOnvx-cCq-D5GDYs8nTxcnEbSIi4nF-9rsFI4IwYJXAi8ukhZS4RjrdGMU9Bdy7mi6y9Qh1/s1600/Ubnt11.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL1_WvVAy5PQ8qdhzxR_eXZ8-hbwCnhru6mAJU0SevHKgKE0b2UqxxNNAf_hX3ZjahJ0fp-oOnvx-cCq-D5GDYs8nTxcnEbSIi4nF-9rsFI4IwYJXAi8ukhZS4RjrdGMU9Bdy7mi6y9Qh1/s320/Ubnt11.png" /></a></div>
<p class="el">Αν υπάρχουν και άλλες πόρτες ρυθμισμένες, απλά προσθέτετε αυτές που φαίνονται στο στιγμιότυπο και δεν σβήνετε τις παλιές. Πατώντας το "ΟΚ" επανερχόμαστε στην προηγούμενη οθόνη.</p>
<p class="en">If there are also other ports set before, then just add the shown ones in the list, without removing the older. By pressing "ΟΚ" the system transfers us to the previous screen.</p>
<p class="el">Αν ρυθμίζετε για πρώτη φορά το τείχος προστασίας, τότε πολύ πιθανό να χρειαστεί να ορίσετε και τη ζώνη προστασίας για την κάρτα δικτύου σας. Για να γίνει αυτό από την αριστερή μεριά του παραθύρου επιλέξτε την κατηγορία "Interfaces". Στη δεξιά μεριά εμφανίζονται όλες οι διαθέσιμες κάρτες δικτύου.</p>
<p class="en">If this is the first time you edit the firewall settings then chances are you'll have to also set the interface zone for your network card. You can do that by selecting the "Interfaces" category to the left side of the window. Then, at the right one appear all the existed network cards.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU4wQhCNJOpFlgsMQzouv1PeGFGjmip93_X2iqIeo67M0gY5kZ5SpaZntIJ4SJjEk7tCO4ZD-N7Zr7ykHXBlnCEVz0sEbH13uHyGANyYzn9k5EJrD-f1piUxnCfvtCjNDGXTOnsvjZXnyB/s1600/Ubnt12.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU4wQhCNJOpFlgsMQzouv1PeGFGjmip93_X2iqIeo67M0gY5kZ5SpaZntIJ4SJjEk7tCO4ZD-N7Zr7ykHXBlnCEVz0sEbH13uHyGANyYzn9k5EJrD-f1piUxnCfvtCjNDGXTOnsvjZXnyB/s320/Ubnt12.png" /></a></div>
<p class="el">Κάνοντας διπλό κλικ στην κάρτα δικτύου που μας ενδιαφέρει εμφανίζεται ένα παράθυρο για τον ορισμό ζώνης. Εκεί ορίσουμε τη ζώνη που μας ενδιαφέρει και πατάμε το "ΟΚ" επανερχόμενοι στο αρχικό παράθυρο.</p>
<p class="en">By double clicking on the network interface we want to setup another dialogue box appears for its zone setting. Choose the zone you are interested in and press "ΟΚ", returning again to the previous screen.</p>
<p class="el">Τελειώνουμε τις ρυθμίσεις του firewall πατώντας "Next" και στη συνέχεια "Finish". Μόλις τελειώσει το σύστημα την εφαρμογή των ρυθμίσεων, το τείχος προστασίας πλέον θα αφήνει την επικοινωνία να γίνει κανονικά.</p>
<p class="en">We end the firewall settings by pressing "Next", followed by "Finish". After tyhe system finishes the application of the new settings, the firewall will be open for the communication of UniFi to the Access Point.</p>
<a id="service"></a>
<h4 class="el">Χρήση του UniFi Controller ως service</h4>
<h4 class="en">Usage Of UniFi Controller As A Service</h4>
<p class="el">Το τελευταίο στάδιο είναι να οριστεί το UniFi Controller ως service, δηλαδή να ανοίγει και να κλείνει ανάλογα με το runlevel του υπολογιστή, χωρίς να χρειάζεται την επέμβαση του χρήστη.</p>
<p class="en">The last step is to make UniFi Controller to run as service, meaning to start and stop according to which runlevel our computer uses, without the need of user intervention.</p>
<p class="el">Για να γίνει αυτό θα πρέπει να δημιουργηθεί ένα script που να μπει μέσα στον κατάλογο <tt>/etc/init.d/</tt>. Αυτό το script θα πρέπει να έχει την ιδιότητα να ξεκινάει και να σταματάει τον server του UniFi, όπως ακριβώς γίνεται και στα υπόλοιπα services του συστήματος. Η βασική βοήθεια για τη συγγραφή αυτού του script είναι το <tt>/etc/init.d/skeleton</tt>. Με λίγο editing αυτού μπορούμε να φτιάξουμε το ακόλουθο:</p>
<p class="en">For this to happen there must be a script in <tt>/etc/init.d/</tt> directory, with the functionality of starting and stopping the UniFi server, in the same way as all the other services of the system do. <tt>/etc/init.d/skeleton</tt> is what will help up create the script in question. A little bit of editing and we create the following:</p>
<div class="code"><pre class="prettyprint linenums lang-sh">
#!/bin/sh
#
# Template SUSE system startup script for service unifid
# Copyright (C) 1995--2005 Kurt Garloff, SUSE / Novell Inc.
#
# This library is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# This library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
# /etc/init.d/unifid
# and its symbolic link
# /usr/sbin/rcunifid
#
# System startup script for the UniFi Controller Server software of Ubiquity. See
# http://www.ubnt.com/
#
# LSB compatible service control script; see http://www.linuxbase.org/spec/
#
# Note: This script uses functions rc_XXX defined in /etc/rc.status on
# UnitedLinux/SUSE/Novell based Linux distributions and is based on /etc/init.d/skeleton
# script provided by the openSUSE Community.
#
### BEGIN INIT INFO
# Provides: unifid
# Required-Start: $syslog $local_fs $network
# Should-Start: $time ypbind smtp
# Required-Stop: $syslog $local_fs $network
# Should-Stop: ypbind smtp
# Default-Start: 3 5
# Default-Stop: 0 1 2 6
# Short-Description: unifid daemon providing Controller server for UniFi Access Points
# Description: Start unifid to allow the UniFi Controller Software to be able to
# control the UniFi Access Points of Ubiquity in the network. The softare runs in Java
# and is installed in /opt/ directory.
### END INIT INFO
#
# Any extensions to the keywords given above should be preceeded by
# X-VendorTag- (X-UnitedLinux- X-SuSE- for us) according to LSB.
#
# Notes on Required-Start/Should-Start:
# * There are two different issues that are solved by Required-Start
# and Should-Start
# (a) Hard dependencies: This is used by the runlevel editor to determine
# which services absolutely need to be started to make the start of
# this service make sense. Example: nfsserver should have
# Required-Start: $portmap
# Also, required services are started before the dependent ones.
# The runlevel editor will warn about such missing hard dependencies
# and suggest enabling. During system startup, you may expect an error,
# if the dependency is not fulfilled.
# (b) Specifying the init script ordering, not real (hard) dependencies.
# This is needed by insserv to determine which service should be
# started first (and at a later stage what services can be started
# in parallel). The tag Should-Start: is used for this.
# It tells, that if a service is available, it should be started
# before. If not, never mind.
# * When specifying hard dependencies or ordering requirements, you can
# use names of services (contents of their Provides: section)
# or pseudo names starting with a $. The following ones are available
# according to LSB (1.1):
# $local_fs all local file systems are mounted
# (most services should need this!)
# $remote_fs all remote file systems are mounted
# (note that /usr may be remote, so
# many services should Require this!)
# $syslog system logging facility up
# $network low level networking (eth card, ...)
# $named hostname resolution available
# $netdaemons all network daemons are running
# The $netdaemons pseudo service has been removed in LSB 1.2.
# For now, we still offer it for backward compatibility.
# These are new (LSB 1.2):
# $time the system time has been set correctly
# $portmap SunRPC portmapping service available
# UnitedLinux extensions:
# $ALL indicates that a script should be inserted
# at the end
# * The services specified in the stop tags
# (Required-Stop/Should-Stop)
# specify which services need to be still running when this service
# is shut down. Often the entries there are just copies or a subset
# from the respective start tag.
# * Should-Start/Stop are now part of LSB as of 2.0,
# formerly SUSE/Unitedlinux used X-UnitedLinux-Should-Start/-Stop.
# insserv does support both variants.
# * X-UnitedLinux-Default-Enabled: yes/no is used at installation time
# (%fillup_and_insserv macro in %post of many RPMs) to specify whether
# a startup script should default to be enabled after installation.
# It's not used by insserv.
#
# Note on runlevels:
# 0 - halt/poweroff 6 - reboot
# 1 - single user 2 - multiuser without network exported
# 3 - multiuser w/ network (text mode) 5 - multiuser w/ network and X11 (xdm)
#
# Note on script names:
# http://www.linuxbase.org/spec/refspecs/LSB_1.3.0/gLSB/gLSB/scrptnames.html
# A registry has been set up to manage the init script namespace.
# http://www.lanana.org/
# Please use the names already registered or register one or use a
# vendor prefix.
# First define a small helper function that converts the number of lines produced by ps
# shell command to a number of LSB status. Needed by the "status" parameter
function ConvertOut() {
if (( $1 < 2 ))
then
CNVOUT=3
else
CNVOUT=0
fi
return $CNVOUT
}
# Check for missing binaries (stale symlinks should not happen)
# Note: Special treatment of stop for LSB conformance
# java executable must be installed...
JAVA_BIN=/usr/bin/java
test -x $JAVA_BIN || { echo "Cannot find java executable in $JAVA_BIN, or java is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Also, mongoDB must be installed. The extra step here is that there must be a valid link in
# /opt/UniFi/bin/mongod that points to the mongod executable
MONGOD_BIN=/opt/UniFi/bin/mongod
if [ ! \( -e $MONGOD_BIN \) ]
then
echo "Cannot find mongod executable in $MONGOD_BIN, or mongoDB is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi;
fi
# Last but not least, the java jar file should be present. No need to be executable, because
# it is executed via java -jar ...
UNIFID_BIN=/opt/UniFi/lib/ace.jar
test -e $UNIFID_BIN || { echo "Cannot find UniFi Controller executable in $UNIFID_BIN, or the controller software is not installed...";
if [ "$1" = "stop" ]; then exit 0;
else exit 5; fi; }
# Source LSB init functions
# providing start_daemon, killproc, pidofproc,
# log_success_msg, log_failure_msg and log_warning_msg.
# This is currently not used by UnitedLinux based distributions and
# not needed for init scripts for UnitedLinux only. If it is used,
# the functions from rc.status should not be sourced or used.
#. /lib/lsb/init-functions
# Shell functions sourced from /etc/rc.status:
# rc_check check and set local and overall rc status
# rc_status check and set local and overall rc status
# rc_status -v be verbose in local rc status and clear it afterwards
# rc_status -v -r ditto and clear both the local and overall rc status
# rc_status -s display "skipped" and exit with status 3
# rc_status -u display "unused" and exit with status 3
# rc_failed set local and overall rc status to failed
# rc_failed <num> set local and overall rc status to <num>
# rc_reset clear both the local and overall rc status
# rc_exit exit appropriate to overall rc status
# rc_active checks whether a service is activated by symlinks
. /etc/rc.status
# Reset status of this service
rc_reset
# Return values acc. to LSB for all commands but status:
# 0 - success
# 1 - generic or unspecified error
# 2 - invalid or excess argument(s)
# 3 - unimplemented feature (e.g. "reload")
# 4 - user had insufficient privileges
# 5 - program is not installed
# 6 - program is not configured
# 7 - program is not running
# 8--199 - reserved (8--99 LSB, 100--149 distrib, 150--199 appl)
#
# Note that starting an already running service, stopping
# or restarting a not-running service as well as the restart
# with force-reload (in case signaling is not supported) are
# considered a success.
case "$1" in
start)
echo -n "Starting unifid "
## Start daemon with startproc(8). If this fails
## the return value is set appropriately by startproc.
/sbin/startproc $JAVA_BIN -jar $UNIFID_BIN start
# Remember status and be verbose
rc_status -v
;;
stop)
echo -n "Shutting down unifid "
## Stop daemon with killproc(8) and if this fails
## killproc sets the return value according to LSB.
#/sbin/killproc $FOO_BIN
$JAVA_BIN -jar $UNIFID_BIN stop
# Remember status and be verbose
rc_status -v
;;
try-restart|condrestart)
## Do a restart only if the service was active before.
## Note: try-restart is now part of LSB (as of 1.9).
## RH has a similar command named condrestart.
if test "$1" = "condrestart"; then
echo "${attn} Use try-restart ${done}(LSB)${attn} rather than condrestart ${warn}(RH)${norm}"
fi
$0 status
if test $? = 0; then
$0 restart
else
rc_reset # Not running is not a failure.
fi
# Remember status and be quiet
rc_status
;;
restart)
## Stop the service and regardless of whether it was
## running or not, start it again.
$0 stop
$0 start
# Remember status and be quiet
rc_status
;;
force-reload)
## Signal the daemon to reload its config. Most daemons
## do this on signal 1 (SIGHUP).
## If it does not support it, restart the service if it
## is running.
echo -n "Reload service unifid "
## if it supports it:
#/sbin/killproc -HUP $FOO_BIN
#touch /var/run/FOO.pid
#rc_status -v
## Otherwise:
$0 try-restart
rc_status
;;
reload)
## Like force-reload, but if daemon does not support
## signaling, do nothing (!)
# If it supports signaling:
echo -n "Reload service unifid "
#/sbin/killproc -HUP $FOO_BIN
#touch /var/run/FOO.pid
#rc_status -v
## Otherwise if it does not support reload:
$0 try-restart
rc_status
#rc_failed 3
#rc_status -v
;;
status)
echo -n "Checking for service unifid "
## Check status with checkproc(8), if process is running
## checkproc will return with exit status 0.
# Return value is slightly different for the status command:
# 0 - service up and running
# 1 - service dead, but /var/run/ pid file exists
# 2 - service dead, but /var/lock/ lock file exists
# 3 - service not running (unused)
# 4 - service status unknown :-(
# 5--199 reserved (5--99 LSB, 100--149 distro, 150--199 appl.)
# NOTE: checkproc returns LSB compliant status values.
# /sbin/checkproc $FOO_BIN
# NOTE: rc_status knows that we called this init script with
# "status" option and adapts its messages accordingly.
# The only way to test if the java program runs is to check it through ps:
JAVA_COUNT=$(ps aux |grep $UNIFID_BIN | wc -l)
# The ps aux shell command if used with the grep shell command, returns one line for grep
# and another line for the real $UNIFID_BIN file. So the result of the executed command is
# 1 if the server is stopped, 2 if the server is started. We need to convert these values
# into valid LSB compliant ones, meaning 3 and 0 respectively. The easiest way to do this
# is to use a function that returns the correct status
ConvertOut $JAVA_COUNT
rc_status -v
;;
#probe)
## Optional: Probe for the necessity of a reload, print out the
## argument to this init script which is required for a reload.
## Note: probe is not (yet) part of LSB (as of 1.9)
#test /etc/FOO/FOO.conf -nt /var/run/FOO.pid && echo reload
#;;
*)
echo "Usage: $0 {start|stop|status|try-restart|restart|force-reload|reload}"
exit 1
;;
esac
rc_exit
</pre></div>
<p class="el">Αυτό το script μπορείτε να το κάνετε copy/paste από εδώ και να το σώσετε μέσα στον κατάλογο του χρήστη με την ονομασία <tt>unifid</tt>. Οι ακόλουθες εντολές πρέπει να εκτελεστούν σε μια κονσόλα από τον υπερχρήστη για να δημιουργηθεί όλη η υποδομή του service:</p>
<p class="en">You can copy/paste the script from here and save it with name <tt>unifid</tt> in the user's home directory (or werever you wish). The following commands must be executed in a console with superuser priviledges, for the service infrastructure to be created:</p>
<div class="code"><pre class="prettyprint">
orion:/home/eliaschr # cp unifid /etc/init.d/
orion:/home/eliaschr # chmod 0755 /etc/init.d/unifid
orion:/home/eliaschr # ln -s /etc/init.d/unifid /sbin/rcunifid
orion:/home/eliaschr # ln -s /etc/init.d/unifid /usr/sbin/rcunifid
</pre></div>
<p class="el">Τώρα θα τεστάρουμε το script και όσα έγιναν για τη χρήση του UniFi ως service. Για να γίνει αυτό θα πρέπει μέσα από το YaST να δούμε τα διαθέσιμα services και να προσπαθήσουμε να ανοίξουμε και να κλείσουμε αυτό που μας ενδιαφέρει, το <tt>unifid</tt>. Αφού ανοίξουμε το YaST (αν δεν το έχουμε ακόμα ανοικτό) και δώσουμε το password του <tt>root</tt> θα πρέπει να κάνουμε τα ακόλουθα:</p>
<p class="en">We can test this script and everything done to make UniFi run as service by using YaST. Through it we will see all the available services and we will try to start and stop the one we created, <tt>unifid</tt>. After running YaST (again, if it is not still running) and enter the <tt>root</tt> password we must do the following:</p>
<p class="el">Ανοίγουμε το "System Services (Runlevel)" από την ομάδα επιλογών "System".</p>
<p class="en">Select the "System Services (Runlevel)" from the "System" group.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCb8I-v8nbKYyes-ZVz71EfVfl1c-WKN21YYHby8CHeaqLhtbkNQKA3vMf7d1w54JiYlobkGuGfsfzbrR1aQNFZxBtERX8_IpwsW7_SG4bkwon0jy3PpVtfJumvrBJB0mSi-XzO5LEkLB1/s1600/Ubnt13.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCb8I-v8nbKYyes-ZVz71EfVfl1c-WKN21YYHby8CHeaqLhtbkNQKA3vMf7d1w54JiYlobkGuGfsfzbrR1aQNFZxBtERX8_IpwsW7_SG4bkwon0jy3PpVtfJumvrBJB0mSi-XzO5LEkLB1/s320/Ubnt13.png" /></a></div>
<p class="el">Στο παράθυρο που ανοίγει θα πρέπει να περιμένουμε λίγο για να αναγνωρίσει το σύστημα όλα τα services που υπάρχουν και να τα ρωτήσει αν είναι ενεργοποιημένα ή όχι. Μετά από λίγο που θα ολοκληρωθεί η λίστα, μπορούμε να βρούμε το service που μόλις δημιουργήσαμε, με την ονομασία <tt>unifid</tt>.</p>
<p class="en">In the window that opens we have to wait some seconds for the system to finish service scanning and find out wether they are running or not. In a while, the list will be complete and there we can search for the service we created with the name <tt>unifid</tt>.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3pHsAKcJqErVvyplaTgGMJ5HU8GSKRJiCXBYd6lvu2NQx5I3UgxD9RfQBpi8k0X0Mx2MrPz2sqP8yUB_jFfFpAnosW4le46JMOu-_CnmlLbBagcYoraweIyXibuhr1US3LDb2Cq3LTA50/s1600/Ubnt14.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3pHsAKcJqErVvyplaTgGMJ5HU8GSKRJiCXBYd6lvu2NQx5I3UgxD9RfQBpi8k0X0Mx2MrPz2sqP8yUB_jFfFpAnosW4le46JMOu-_CnmlLbBagcYoraweIyXibuhr1US3LDb2Cq3LTA50/s320/Ubnt14.png" /></a></div>
<p class="el">Ακόμα πιο ενδιαφέρον είναι αν γυρίσουμε σε Expert Mode, με επιλογή του από το επάνω μέρος της οθόνης. Τότε το παράθυρο μετασχηματίζεται, δίνοντας ακόμα περισσότερες πληροφορίες κι επιλογές:</p>
<p class="en">It becomes more interesting if we select the Expert Mode at the top of the window. The window changes, giving more information and options:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgryfXoW-5wNoLx2SUgiA8xH5U0Nq7fOuCpK-n3iKEsq9OS1wiJzTPixuX9fHojtENcaH4SkB6kB8-bIojCw_5t4TKOzKlBcz0Y5HOLnvS6Sn2fIGUZgVKTjzPcnuZXX9xraBtjVpSvPPxI/s1600/Ubnt15.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgryfXoW-5wNoLx2SUgiA8xH5U0Nq7fOuCpK-n3iKEsq9OS1wiJzTPixuX9fHojtENcaH4SkB6kB8-bIojCw_5t4TKOzKlBcz0Y5HOLnvS6Sn2fIGUZgVKTjzPcnuZXX9xraBtjVpSvPPxI/s320/Ubnt15.png" /></a></div>
<p class="el">Μπορούμε να δοκιμάσουμε την ενεργοποίηση και απενεργοποίηση του service από το κουμπί "Start/Stop/Refresh". Μπορούμε να δούμε την κατάσταση του service αν από το πλήκτρο αυτό επιλέξουμε το "Refresh status...". Αρχικά είναι απενεργοποιημένο. Το αναδυόμενο παράθυρο μας ενημερώνει για αυτή την κατάσταση.</p>
<p class="en">We can test the activation and deactivation by using the "Start/Stop/Refresh" button. We can also observe the status of the service if, from the same button, in its dropdown list we select "Refresh status..." option. In the beginning it is stopped. The pop-up window informs us for this.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9ysupY0NmPZv0JdjBLvS_sv6wpvKgtR-EqMb9InZFjjuc2rDFmB6ZMvb_WWR-Sidi19L_Vpk5qlvjVC0D7UtpWbcMSnoiSb79gkl8ydOurWjNko2MirHyq4bKCHRKiTotk-FQ1UgMKqT/s1600/Ubnt16.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO9ysupY0NmPZv0JdjBLvS_sv6wpvKgtR-EqMb9InZFjjuc2rDFmB6ZMvb_WWR-Sidi19L_Vpk5qlvjVC0D7UtpWbcMSnoiSb79gkl8ydOurWjNko2MirHyq4bKCHRKiTotk-FQ1UgMKqT/s320/Ubnt16.png" /></a></div>
<p class="el">Αν δοκιμάσουμε να ενεργοποιήσουμε το <tt>unifid</tt> από το πλήκτρο με την επιλογή "Start...". Θα ενημερωθούμε ανάλογα:</p>
<p class="en">Lets try to activate <tt>unifid</tt> from the button in question, by choosing "Start...". We will be informed:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6QgwoJriKwbMqT0o41zi04dMRU59loPxIVpK7EmgwFt3KwWy9c7n4yHkwWvHwNI-KMStb371j7qCcpU78jz8-W5xfIxXGFYTI8m34sx_IRNF8pmuIVYULxtr2Rnbj-o6HObn2LZYX0Blw/s1600/Ubnt17.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6QgwoJriKwbMqT0o41zi04dMRU59loPxIVpK7EmgwFt3KwWy9c7n4yHkwWvHwNI-KMStb371j7qCcpU78jz8-W5xfIxXGFYTI8m34sx_IRNF8pmuIVYULxtr2Rnbj-o6HObn2LZYX0Blw/s320/Ubnt17.png" /></a></div>
<p class="el">Φυσικά το αποτέλεσμα θα το δούμε και στη λίστα του κεντρικού παραθύρου. Μπορούμε να ξαναδοκιμάσουμε την κατάσταση που επιστρέφει το script όταν το service είναι ενεργοποιημένο, ξανά με την επιλογή "Refresh status...".</p>
<p class="en">Of course, we will also notice the result in the list of the main window. We can try again to see what is the status that the script returns, now that the service is up and running, again using the "Refresh status..." option.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4sq7ACmAOpetmlNcOqLPr2FmZh75QRMRBhYO0LWFmUsn0BjDudw-HFuIwHAyshBIgYCCa_Dct_pyYT-w3z_CjA7PrDAv6ORi9laEhgCBzMdzzCHOqMU9lDLKOwW-kVSj4w9XyhcJS2zru/s1600/Ubnt18.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4sq7ACmAOpetmlNcOqLPr2FmZh75QRMRBhYO0LWFmUsn0BjDudw-HFuIwHAyshBIgYCCa_Dct_pyYT-w3z_CjA7PrDAv6ORi9laEhgCBzMdzzCHOqMU9lDLKOwW-kVSj4w9XyhcJS2zru/s320/Ubnt18.png" /></a></div>
<p class="el">Ας το απενεργοποιήσουμε πάλι να δούμε την αντίδραση του συστήματος. Επιλέγουμε το "Stop...". Το παράθυρο που θα μας εμφανιστεί είναι το ακόλουθο:</p>
<p class="en">OK. Now, lets deactivate the service again to see the system's reaction. Choose "Stop...". The following window must appear:</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMz2xsfWcK10sOHhiUD_3d65BroSo5HXZCgWS_0c1bfJQZwsY4RYPu6gEBR8k2LBlKtuM0Ab7fgQh_5WHUYOTN0Hfznt5_8a1MpcSL69Nmtn3BZi3D2saYtqJmW-klI5y5KF_lbc1ioBXm/s1600/Ubnt19.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMz2xsfWcK10sOHhiUD_3d65BroSo5HXZCgWS_0c1bfJQZwsY4RYPu6gEBR8k2LBlKtuM0Ab7fgQh_5WHUYOTN0Hfznt5_8a1MpcSL69Nmtn3BZi3D2saYtqJmW-klI5y5KF_lbc1ioBXm/s320/Ubnt19.png" /></a></div>
<p class="el">Φυσικά, κάθε φορά που κάνουμε start το service ο επεξεργαστής εργάζεται αρκετά για ένα χρονικό διάστημα. Όταν τελειώσει, ο server μας είναι ενεργοποιημένος.</p>
<p class="en">Naturally, each time we start the service, the processor starts working hard for a small period of time. When it finishes then our server is up.</p>
<p class="el">Τέλος, όταν ενεργοποιήσουμε την υπηρεσία στο σύστημα από το κάτω δεξιά κουμπί "Set/Reset", θα δούμε ότι το service θα ενεργοποιηθεί στα runlevels 3 και 5, όπως ακριβώς τα ρυθμίσαμε στο script που γράψαμε.</p>
<p class="en">Finaly, after we activate permanently the service using the "Set/Reset" button that lies at the bottom right of the window, we can see that the service is marked for starting at runlevels 3 and 5. This is described in the script we created earlier.</p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHgY_g4UMfa24M0XczGLvqZXP7zdEhwbHjiPbYmW7Jk2ud2rphURVanU2msMYpkyV6suY16aQ5DutkzHuUlZXem94aniP6XjMKS2rOFVfYL7zv22cuThY7gLfbCreIZV8QIkttlm4lcuSs/s1600/Ubnt20.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHgY_g4UMfa24M0XczGLvqZXP7zdEhwbHjiPbYmW7Jk2ud2rphURVanU2msMYpkyV6suY16aQ5DutkzHuUlZXem94aniP6XjMKS2rOFVfYL7zv22cuThY7gLfbCreIZV8QIkttlm4lcuSs/s320/Ubnt20.png" /></a></div>
<p class="el">Όταν το ρυθμίσετε όπως θέλετε μπορείτε να αποθηκεύσετε τις ρυθμίσεις πατώντας το πλήκτρο "ΟΚ".</p>
<p class="en">After you choose the settings at your will, you can store them by pressing "ΟΚ".</p>
<p class="el">Από τώρα και στο εξής δεν είναι ανάγκη να ανοίγετε την κονσόλα για να ξεκινάτε το UniFi Controller Software. Εκτός του ότι μπορείτε να το έχετε να ανοίγει με τον υπολογιστή σας, μπορείτε να το ενεργοποιείτε ή απενεργοποιείτε από το YaST.</p>
<p class="en">From now on, there is no need to open a terminal and start UniFi Controller Software by hand. And besides having it starting automatically while your operating system boots, you can activate and deactivate it at will through YaST.</p>
<p class="el">Όταν το <tt>unifid</tt> είναι ενεργοποιημένο τότε μπορείτε να κάνετε login σε αυτό από τον browser σας, στη διεύθυνση <tt>http://localhost:8080</tt></p>
<p class="en">When <tt>unifid</tt> is activated, you can login to it through your browser, at the address <tt>http://localhost:8080</tt></p>
<div class="center"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzStkclwhzJl1qmmwURJfqgaw5EKHAn1zLcsiSAeTzkxvY_KngWEAJNNLgw_vq6b11KeDjS_K6pXQTFTkEJRKWz_jhoIQUaTivvOJtZHbQBW-iDDSkSIVi3T8RsLvSStIIXravBpTaku9q/s1600/Ubnt8.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzStkclwhzJl1qmmwURJfqgaw5EKHAn1zLcsiSAeTzkxvY_KngWEAJNNLgw_vq6b11KeDjS_K6pXQTFTkEJRKWz_jhoIQUaTivvOJtZHbQBW-iDDSkSIVi3T8RsLvSStIIXravBpTaku9q/s320/Ubnt8.png" /></a></div>
<a id="conclusions"></a>
<h4 class="el">Συμπεράσματα</h4>
<h4 class="en">Conclusions</h4>
<p class="el">Παρότι το πρόγραμμα της εταιρίας Ubiquity έχει γραφτεί σε java και στην αρχή υπήρχαν αμφοβολίες πως θα μπορούσε να λειτουργήσει σωστά ως service, τελικά με λίγο κόπο ακόμα κι αυτό μπόρεσε να λειτουργήσει. Τώρα το σύστημα του ασύρματου δικτύου, μπορεί να παραμετροποιηθεί για τις ανάγκες ενός ξενοδοχείου, ενώ θα μπορούσε να λειτουργήσει ακόμα και σε ένα σύστημα small computer όπως π.χ. το Raspberry Pi, το Cubieboard, το Beagleboard ή ότι άλλο έχετε υπόψη σας :)</p>
<p class="en">Even though Ubiquity's program is written in Java language and in the beginning there was doubt that it could work as a system service, finaly, with a small effort we managed to make it work. No the UniFi Wireless System can be used for covering the needs of a hotel, and it may even run in a small computer system as ie. a Raspberry Pi, Cubieboard, Beagleboard or anyother alike you have in your mind :)</p>
<p class="el">Γενικά το UniFi είναι πολύ ενδιαφέρον και αν και ασχολήθηκα κάμποσο μαζί του ξέρω πολύ καλά πως έχει κρυφά σημεία που δεν τα έχω δει ακόμα!</p>
<p class="en">In general, UniFi is very interesting and, even though I've used it a lot, I know well that there are so many "hidden" things that I haven't seen, yet!</p>
<p class="el">Μια ακόμα επισήμανση που έχω να κάνω είναι πως όλη η διαδικασία ξεκίνησε αρκετό καιρό πριν κι έγινε σε σύστημα openSUSE 12.2</p>
<p class="en">One more note is that all the job is done a while ago and that all the described process is done in openSUSE 12.2</p>
<p class="el authorname">Ηλίας Χρυσοχέρης</p>
<p class="en authorname">Elias Chrysocheris</p>
eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-75892361050486312482013-03-30T01:23:00.000+02:002013-08-21T19:12:18.899+03:00Οδηγός Εγκατάστασης openSUSE 12.3<div dir="ltr" style="text-align:center;" trbidi="on"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1XT6oEYTwc4jhukf7AOJhWMJ8Cgk3nfRC6_gds_h-zknSUARvEnNdWIctWqJ3FUdB4hS-ejCb9KhY5BfwCyfCOAjwbJsJdiiBmrgmmQxfbjLOo0P18S2zVDdy-ctypUwrXEjPFVLScrOV/s1600/snapshot40.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1XT6oEYTwc4jhukf7AOJhWMJ8Cgk3nfRC6_gds_h-zknSUARvEnNdWIctWqJ3FUdB4hS-ejCb9KhY5BfwCyfCOAjwbJsJdiiBmrgmmQxfbjLOo0P18S2zVDdy-ctypUwrXEjPFVLScrOV/s320/snapshot40.png" /></a><br />
</div><br />
<p>Το <a href="http://www.opensuse.org/">openSUSE</a> είναι μια διανομή Linux αρκετά πλούσια σε προγράμματα από την πρώτη στιγμή που εγκαθίσταται στον υπολογιστή μας. Η κοινότητα της διανομής είναι αρκετά ενεργή και η παραγωγή δε θα μπορούσε να είναι διαφορετική από άψογη. Σε γενικές γραμμές κάθε 8 περίπου μήνες βγαίνει και μια καινούργια έκδοση του λειτουργικού, με όλα τα καινούργια καλούδια, τόσο σε γραφικά περιβάλλοντα, όσο και σε θέματα ασφάλειας της καρδιάς ενός λειτουργικού· του πυρήνα.</p><br />
<p>Πριν λίγες ημέρες η κοινότητα του openSUSE μας έκανε την έκπληξη να βγάλει καινούργια έκδοση μέσα σε χρόνο 6 μηνών από την προηγούμενη! Το <a href="https://news.opensuse.org/2013/03/13/opensuse-12-3-free-open-and-awesome/">openSUSE 12.3</a> βγήκε στις 13 Μαρτίου 2013 και ήδη έχει καταλάβει πολλούς υπολογιστές. Για άλλη μια φορά βλέπουμε στους υπολογιστές μας ένα διαμάντι ομορφιάς και σταθερότητας. Όποιος επιθυμεί να το εγκαταστήσει μπορεί να το κατεβάσει από την <a href="http://software.opensuse.org/123/el">ιστοσελίδα της κοινότητας</a>, τόσο σε έκδοση για 32 bit όσο και για 64. Υπάρχουν και εναλλακτικά Live CDs για τον έλεγχο της διανομής στο σύστημά σας στην ίδια σελίδα, ή ακόμα και CD που μπορείτε να κάνετε την εγκατάσταση του λειτουργικού εξ ολοκλήρου από το διαδίκτυο.</p><br />
<p>Ο <a href="http://www.chania-lug.gr/">Σύλλογος Φίλων Ανοικτού Λογισμικού Χανίων</a> έχει, εδώ και χρόνια, ξεκινήσει να παράγει τον <a href="http://wiki.chania-lug.gr/index.php/Opensuse-11.2-guide">Ελληνικό οδηγό εγκατάστασης</a> της εν λόγω διανομής, έτσι δε θα γινόταν να μην ενημερωθεί και ο οδηγός αυτός με βάση την καινούργια έκδοση. Συγκεκριμένα πριν από δύο ημέρες αναρτήθηκε ο καινούργιος οδηγός στην ιστοσελίδα του Συλλόγου, στο κλασικό σημείο του <a href="http://wiki.chania-lug.gr/">wiki</a> του, την <a href="http://wiki.chania-lug.gr/index.php/%CE%94%CE%B7%CE%BC%CE%B9%CE%BF%CF%85%CF%81%CE%B3%CE%AF%CE%B1_%CE%A4%CE%B5%CE%BA%CE%BC%CE%B7%CF%81%CE%AF%CF%89%CF%83%CE%B7%CF%82">Τεκμηρίωση</a>. Εκεί, όποιος ενδιαφέρεται μπορεί να κατεβάσει τον οδηγό και να εγκαταστήσει με ασφάλεια το λειτουργικό στον υπολογιστή του. Ο οδηγός όπως πάντα είναι πλούσιος σε ύλη, χωρίς να είναι υπερβολικά μεγάλος, πάει τον αναγνώστη βήμα βήμα με τη βοήθεια εικόνων στιγμιοτύπων, έτσι ώστε να γίνει σωστά η εγκατάσταση και το λειτουργικό να περιέχει όσα χρειάζεται ο καθημερινός χρήστης υπολογιστών.</p><br />
<div dir="ltr" style="text-align:center;" trbidi="on"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSSzBUIg-6jjEas90P78A5DyA2XH-uwPjWzjKx00X98V139gGfx8xY4YtIgYZNwNxrlIelxBpRVtZ5zkdT-TOw9q2mL-LhRXXXvJCjIUoCeh10gnf7I-HhfNcKptDsY13cr3fnjcKVNMhF/s1600/snapshot1.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSSzBUIg-6jjEas90P78A5DyA2XH-uwPjWzjKx00X98V139gGfx8xY4YtIgYZNwNxrlIelxBpRVtZ5zkdT-TOw9q2mL-LhRXXXvJCjIUoCeh10gnf7I-HhfNcKptDsY13cr3fnjcKVNMhF/s320/snapshot1.png" /></a></div><br />
<p>Μια καινοτομία του οδηγού εγκατάστασης, που υπάρχει από τη πρώτη στιγμή της συγγραφής του, είναι πως δε μένει μόνο στην εγκατάσταση. Ένας από τους σκοπούς του είναι να μην αφήσει το χρήστη με την εντύπωση "Το εγκατάστησες, τώρα χρησιμοποίησε το μόνος σου!", αλλά να τον βοηθήσει ακόμα παραπέρα στο να του δείξει και πώς θα κάνει τα βασικά πράγματα. Ο οδηγός δείχνει πως γίνεται η παραμετροποίηση του συστήματος μέσω του YaST2, πως γίνονται κάποιες παραμετροποιήσεις της επιφάνειας εργασίας κ.λ.π, έτσι ώστε ένας καινούργιος χρήστης να μπορεί εύκολα να βρει αυτά που χρειάζεται με λιγότερο ψάξιμο και όχι τόσο στα τυφλά.</p><br />
<p>Ο οδηγός έχει δημιουργηθεί σε LaTeX, όπως αρμόζει σε έναν οδηγό για ανοικτό λογισμικό. Εκδίδεται σε άδεια χρήσης <a href="http://creativecommons.org/licenses/by-nc/3.0/gr/">Creative Commons</a> ώστε όποιος θέλει να μπορέσει να πάρει τον κώδικα και να τον χρησιμοποιήσει, να τον παραλλάξει ή να παράγει αυτό που χρειάζεται παίρνοντας ιδέες από αυτόν. Τον κώδικα θα τον βρείτε στο ίδιο σημείο που θα βρείτε και τον οδηγό.</p><br />
<p>Ελπίζουμε για άλλη μια φορά να σας φανεί χρήσιμος και να σας γλυτώσει από κακοτοπιές :)</p><br />
<p style="clear: both; text-align: right;"><b><i>Χρυσοχέρης Ηλίας</i></b></p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com3tag:blogger.com,1999:blog-9147006209672954597.post-29559586942618799192013-01-22T18:36:00.000+02:002013-09-12T15:33:59.240+03:00MK809 Android TV και Development ModeMK809 Android TV in Development Mode<h4 class="el">Εισαγωγή</h4>
<h4 class="en">Introduction</h4>
<p class="el">Πριν από λίγο καιρό αγοράσαμε, εγώ κι ένας φίλος, από ένα MK809. Πρόκειται για ένα μικρό stick που περιέχει ένα διπλοπύρηνο ARM μικροελεγκτή στα 1.6GHz με εσωτερική μνήμη 4GB και 1GB DDR3. Γενικά, έχει πολλά καλούδια, αλλά το ωραιότερο είναι πως τρέχει Android 4.1.1.</p>
<p class="en">A few days ago, me and a friend of mine bought a MK809 each. It is a small stick that contains a dual core ARM processor running at 1.6GHz, with internal storage memory of 4GB and 1GB of DDR3 RAM. It provides many nice features but the better of them is it runs Android 4.1.1.</p>
<p class="el">Πήραμε το εργαλείο στα χέρια μας και αρχίσαμε να παίζουμε μαζί του. Εγκαταστήσαμε ότι εφαρμογές και παιχνίδια θέλαμε, <a href="http://xbmc.org/">XBMC 12.0</a> και άλλα. Σερφάραμε στο Internet και ρίξαμε μέσα και ένα VNC έτσι για να κάνουμε τον χαβαλέ μας. Όλα ήταν τέλεια!</p>
<p class="en">When this small tool reached our hands we started "playing" with it. We installed whatever applications and games we wanted, <a href="http://xbmc.org/">XBMC 12.0</a> and many more. We surfed the internet and we also installed a VNC client just for fun. It was awesome!</p>
<h4 class="el">Angry Birds, γιατί τα παιχνίδια δεν είναι μόνο... για να παίζουμε!</h4>
<h4 class="en">Angry Birds, because games are not only... to play!</h4>
<p class="el">Ο τίτλος της παραγράφου φαίνεται λίγο περίεργος;!!! Ναι. Εδώ και αρκετά χρόνια ξέρουμε πολύ καλά πως τα πάντα γίνονται για τα παιχνίδια. Η πρώτη γλώσσα προγραμματισμού που έμαθα ήταν η BASIC μιας και έπαιζα με το αγαπημένο μου ZX Spectrum της εποχής, αλλά η δεύτερη ήταν η Assembly του για να μπορώ να σπάω τα παιχνίδια και να τους βάζω άπειρες ζωές κ.λ.π. Με παρόμοιο τρόπο ξεκίνησε και αυτή εδώ η ιστορία που καταλήγει στο παρών blog post· μόνο που αυτή τη φορά το παιχνίδι ήταν η δημοφιλής σειρά <a href="http://www.angrybirds.com/">Angry Birds</a> και ο τρόπος στο να μεταφέρουμε τα αστεράκια που έχουμε από το κινητό μας στο MK809.</p>
<p class="en">Do you find the title of this paragraph strange?!!! Well, we know that games are responsible for many things that happened on computer science and evolution all these past years. The first programming language I learned was BASIC since I owned a ZX Spectrum then, but the second one is Z80 Assembly for that computer just to be able to crack its games and have infinite lives etc. In a similar way this story started and ended with this blog post; the only difference is the very popular series of <a href="http://www.angrybirds.com/">Angry Birds</a> games and the way to transfer our stars from our smartphone to MK809.</p>
<h4 class="el">Τα διάφορα προγράμματα για Backup ΔΕΝ ΛΕΙΤΟΥΡΓΟΥΝ!...</h4>
<h4 class="en">Various backup applications DO NOT WORK!...</h4>
<p class="el">Αρχικά οι δοκιμές ήταν να μεταφέρουμε τα αστεράκια που με τόσο κόπο είχαμε κερδίσει όλα αυτά τα χρόνια που έχουμε λιώσει τις touchscreen των κινητών μας, με τη βοήθεια backup προγραμμάτων που υπάρχουν στο Google Play... Δεν υπήρξε καμιά επιτυχία σε αυτό. Τι να δοκιμάζουμε προγράμματα που κάνουν backup/restore στην κάρτα μνήμης... Τι να δοκιμάζουμε άλλα που δουλεύουν και μέσω <a href="https://www.dropbox.com/">dropbox</a>... Τίποτα. Μόνο αποτυχίες.</p>
<p class="en">In the beginning we tried to transfer the Angry Birds stars that we gained in such a hard play, melting the touchscreens of our smartphones! We used some backup applications, downloaded from Google Play... Well,... no success... We tried applications that backup and restore the stars in memory card... other programs that use <a href="https://www.dropbox.com/">dropbox</a>... Nothing. Failure... No Success at all!</p>
<p class="el">Κάποια στιγμή, θυμήθηκα ότι παλιότερα μέσω του <tt>adb</tt> που εχει το <a href="http://developer.android.com/sdk/index.html">Android Development Toolkit</a> για το <a href="http://www.eclipse.org/">Eclipse</a>, μπορούσα και έγραφα αρχεία μέσα στο κινητό μου ακόμα και αν δεν ήμουν <tt>root</tt>. Ψάχνοντας στο Internet βρήκαμε κάποιο <a href="http://android.stackexchange.com/questions/2432/how-to-backup-angry-birds-saves-data">blog post</a> που περιγράφει μια τέτοια διαδικασία, οπότε ήμουν σίγουρος πως θα πετυχαίναμε το επιθυμητό αποτέλεσμα!...</p>
<p class="en">At a moment I remembered that once, using <tt>adb</tt> which is in <a href="http://developer.android.com/sdk/index.html">Android Development Toolkit</a> for <a href="http://www.eclipse.org/">Eclipse</a>, I could write files in my cellphone even if I hadn't <tt>root</tt> access. Searching the internet we found a <a href="http://android.stackexchange.com/questions/2432/how-to-backup-angry-birds-saves-data">blog post</a> that describes such a procedure, so I was sure we could do the trick successfully!...</p>
<h4 class="el en">ΜΚ809 USB Development Mode</h4>
<p class="el">Ήρθε η ώρα για το ψητό! Ας συνδέσουμε το MK809 στον υπολογιστή και να το δούμε από το <tt>adb</tt> του Android Development Toolkit. Τρέχουμε από ένα τερματικό την εντολή <tt>adb devices</tt> και... Πού είναι το ΜΚ809, οέωωω! Χμμμ... Κάτι δεν πάει καλά!</p>
<p class="en">Time to play! Lets connect MK809 to the computer and see if we can use <tt>adb</tt> of Android Development Toolkit. In a terminal we execute the command <tt>adb devices</tt> and... What! Were the heck is MK809?!!! Hmmm... Something is wrong!</p>
<p class="el">Μετά από αρκετή αναζήτηση στο internet, βρήκα ένα <a href="http://forum.xda-developers.com/showthread.php?t=2083522">blog post</a> που έλεγε πώς να κάνεις root το ΜΚ809, αλλά... Δεν δούλεψε... Ήταν για bugindows... Επίσης, περισσότερο έμοιαζε για άλλη έκδοση του MK80*, μιας και το blog post ανέφερε κάτι για μια πλαϊνή θύρα USB On-The-Go. Αυτή η θύρα δεν υπάρχει στο MK809.</p>
<p class="en">Again, after a lot of internet searching, we found another <a href="http://forum.xda-developers.com/showthread.php?t=2083522">blog post</a> describing how to root ΜΚ809, but... didn't work... It was for bugindows... At the same time looked that is was for another MK80* device, as blog post was using a USB On-The-Go port at the side of the device. MK809 does not have a USB connector at its side.</p>
<p class="el">Φυσικά το post μου έδωσε μερικές ιδέες μιας και ήταν κοντά στην πραγματικότητα. Μετά από μερικά <tt>lsusb</tt> και δοκιμές, βρήκα ότι το ΜΚ809 το έβλεπε ο υπολογιστής μου ότι συνδεόταν, το λειτουργούσε σαν USB Stick, αλλά developer mode δεν υπήρχε:</p>
<p class="en">Of course, that post gave me some ideas as it was for a similar device, there should be similarities in the logic of the workflow. After some <tt>lsusb</tt> and tests, I found out that my computer could find the ΜΚ809 upon connection and it was using it as a USB memory stick, but there was no developer's mode:</p>
<div class="code"><pre class="prettyprint">orion:/etc/udev # lsusb
Bus 001 Device 002: ID 0bda:0158 Realtek Semiconductor Corp. USB 2.0 multicard reader
Bus 002 Device 002: ID 5986:0130 Acer, Inc
<b>Bus 002 Device 027: ID 2207:0010</b>
Bus 003 Device 005: ID 093a:2510 Pixart Imaging, Inc. Optical Mouse
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
</pre></div>
<p class="el">Η τρίτη γραμμή του <tt>lsusb</tt> είναι που φαίνεται λίγο παράξενη. Αυτή είναι η γραμμή που προστίθεται όταν συνδέσουμε το MK809. Μετά από ώριμη (;) σκέψη καταλήγουμε στο ότι το σύστημα δεν έχει τον απαραίτητο driver για να το λειτουργήσει...</p>
<p class="en">The third line of the <tt>lsusb</tt> snapshot (boldfaced) looks a little bit weird. That is the added line each time we connect MK809. After some mature (?!!! :)) thinking we end up to the conclusion that the system does not have the correct driver module to use it...</p>
<p class="el">Η πραγματικότητα είναι ακόμα πιο περίεργη. Ψάχνοντας λίγο στο διαδίκτυο παρατήρησα ότι το RK3066 που είναι το ολοκληρωμένο που χρησιμοποιεί το MK809 δεν έχει κάτι ιδιαίτερο, εκτός του ότι είναι αρκετά νέο! Άρα, οι ήδη υπάρχοντες drivers θα μπορούσαν να το λειτουργήσουν μια χαρά, μόνο που ήταν αρκετά νέο device για να το αναγνωρίζουν!... Εδώ ξεκινάει ένα μικρό παιχνίδι με το udevd!</p>
<p class="en">Reality is even more weird... Searching a little more the internet (what else could we do?) we found that RK3066, which is the processor of MK809 does not have anything particular compared to other similar devices, except that it is a very new chip. So, it seemed the already existed drivers could handle it without problem, but they didn't know its existence!... Time to play with udevd!</p>
<h4 class="el">udevd rules για την αναγνώριση του ΜΚ809</h4>
<h4 class="en">udevd rules to recognise ΜΚ809</h4>
<p class="el">Άντε να δούμε τι θα κάνουμε για να αναγνωρίσει το σύστημα το καινούργιο chip του MK809. Καταρχήν θα πρέπει να προσθέσουμε μια συνθήκη στο udevd που να αναγνωρίζει το USB Device με id 2207:0010. Στη διανομή <a href="http://www.opensuse.org/">openSUSE</a> οι κανόνες του udevd βρίσκονται μέσα στον κατάλογο <tt>/etc/udev/rules.d/</tt> κι εκεί θα πρέπει να προσθέσουμε το δικό μας. Επειδή η κάθε διανομή έχει τα δικά της, καλό θα είναι για μια άλλη διανομή να βρείτε πού υπάρχουν οι κανόνες και να κάνετε την προσθήκη σε εκείνο τον κατάλογο. Το αρχείο που θα φτιάξουμε είναι το <tt>99-MK809-Android.rules</tt>:</p>
<p class="en">Lets see what can we do to make our system recognise the new chip that MK809 uses. Our first step is to add a udevd rule to recognise USB Devices with id 2207:0010. In <a href="http://www.opensuse.org/">openSUSE</a> udevd rules lie in <tt>/etc/udev/rules.d/</tt> directory. Since in every distribution uses its own directory, it would be nice to find out (if you don't already know) which directory is the appropriate one for this job and make the described addition there. Th file we will add is named <tt>99-MK809-Android.rules</tt>:</p>
<div class="code"><pre class="prettyprint lang-sh">eliaschr@orion:~>su
Password:
orion:/home/eliaschr # cd /etc/udev/rules.d/
orion:/etc/udev/rules.d # vi 99-MK809-Android.rules
#
# udev rules file for MK809 Android TV Stick
#
# Added by me (eliaschr) so as to be able to use MK809 in development mode
# To use it, first enable "USB debugging" in "Developer options" (System Settings)
# and then in the "USB" tab (Device Settings) select "Connect to PC".
#
SUBSYSTEM=="usb", ATTR{idVendor}=="2207", ATTR{idProduct}=="0010", , MODE="0666", SYMLINK+="MK809_adb"
</pre></div>
<p class="el">Σώστε το αρχείο και βγείτε από το <tt>vi</tt>. Φυσικά μπορείτε να χρησιμοποιήσετε όποιον editor θέλετε, ή ακόμα και μια γραμμή εντολής που να φτιάχνει το αρχείο, αρκεί το αποτέλεσμα να είναι το ίδιο.</p>
<p class="en">Save the file and quit <tt>vi</tt>. Of course you can use whatever text editor you like, or even a <tt>cat</tt> bash command (or any other you like) to create the file, as long as it produces the same result.</p>
<p class="el"><b class="redlabel">ΕΝΗΜΕΡΩΣΗ:</b> Σε ένα φίλο που έχει ένα κινητό Huaway Ideos3 έπρεπε να προσθέσουμε ακόμια μια γραμμή στο αρχείο του udev που μόλις δημιουργήσαμε για να μπορέσει το σύστημα να το διαβάσει:</p>
<p class="en"><b class="redlabel">UPDATE:</b> A friend of mine owns a Huaway Ideos3. We had to add another line for that in the udev rule we created in order to make the system recognise his cell phone also:</p>
<div class="code"><pre class="prettyprint lang-sh">SUBSYSTEM=="usb", ATTR{idVendor}=="12d1", ATTR{idProduct}=="1038", , MODE="0666", SYMLINK+="Ideos3_adb"
</pre></div>
<p class="el">Το επόμενο βήμα είναι να πούμε στο <tt>adb</tt> να ψάχνει και αυτή τη συσκευή. Για να γίνει αυτό θα πρέπει να πειράξουμε το αρχείο <tt>adb_usb.ini</tt> που υπάρχει μέσα στον κατάλογο <tt>.android</tt> στο home directory του χρήστη μας:</p>
<p class="en">Next step is to make <tt>adb</tt> to include this device in its search process. In order to make it possible we have to alter <tt>adb_usb.ini</tt> file in <tt>.android</tt> subdirectory in our user's home:</p>
<div class="code"><pre class="prettyprint">eliaschr@orion:~> cd .android
eliaschr@orion:~/.android> vi adb_usb.ini
</pre></div>
<p class="el">Εκεί προσθέτουμε μια γραμμή που περιέχει το:</p>
<p class="en">There, we add a line containing just:</p>
<div class="code"><pre class="prettyprint">0x2207
</pre></div>
<p class="el">Σώστε το αρχείο και βγείτε από το <tt>vi</tt>. Μια σημείωση είναι πως αν είχαμε χρησιμοποιήσει πιο πριν το <tt>adb</tt>, τότε ο server του Android Development Toolkit θα τρέχει, που σημαίνει πως για να διαβάσει τις καινούργιες ρυθμίσεις του αρχείου που μόλις πειράξαμε θα πρέπει να τον ξαναξεκινήσουμε. Η εκκίνηση γίνεται από το πρόγραμμα <tt>adb</tt>. Απλά θα πρέπει εμείς να τον σκοτώσουμε. Αρκεί να εκτελέσουμε την ακόλουθη εντολή:</p>
<p class="en">Save the file and exit <tt>vi</tt>. Note that if we used <tt>adb</tt> earlier while making our experiments, then the Android Development Toolkit server is up and running, meaning that we have to restart it in order to read the new settings. You can restart it using <tt>adb</tt>. Just kill it first with the following command:</p>
<div class="code"><pre class="prettyprint lang-sh">eliaschr@orion:~> adb kill-server
</pre></div>
<p class="el">Το τελευταίο κομμάτι που πρέπει να γίνει είναι να υποχρεώσουμε το udevd να διαβάσει τους καινούργιους κανόνες:</p>
<p class="en">The last part is to force udevd to read the new rules:</p>
<div class="code"><pre class="prettyprint">eliaschr@orion:~>su
Password:
orion:/home/eliaschr # udevadm control --reload-rules
orion:/home/eliaschr #
</pre></div>
<p class="el">Στη συνέχεια συνδέουμε το MK809 με ένα καλώδιο micro USB στον υπολογιστή μας. Στα <i>Settings</i>, από την αριστερή μεριά, στο block <i>SYSTEM</i> επιλέγουμε το "<i>{} Developer options</i>". Στη δεξιά μεριά της οθόνης βλέπουμε όλες τις διαθέσιμες ρυθμίσεις. Αν είναι απενεργοποιημένες, τότε θα πρέπει να τις ενεργοποιήσουμε από τον διακόπτη πάνω και δεξιά στην οθόνη, γυρίζοντάς τον στο "<i>ΟΝ</i>". Από τις επιλογές ενεργοποιούμε τις δύο βασικές στο block "<i>DEBUGGING</i>", που είναι οι "<i>USB debugging</i>" και "<i>Allow mock locations</i>". Η επιλογή "<i>Select debug app</i>" δεν περιέχει κάποια επιλογή, αλλά αυτό δεν μας ενοχλεί.</p>
<p class="en">Lets connect MK809 using a micro USB cable to our computer. Also in MK809 screen, in <i>Settings</i>, at the left side of the screen, in <i>SYSTEM</i> block we select "<i>{} Developer options</i>". In the right part of the screen we can see all the avilable options. If they are disabled we have to enable them first using the switch widget at the top right of the screen, by sliding it to "<i>ΟΝ</i>". From the available options we select the two basic ones in "<i>DEBUGGING</i>" block; they are "<i>USB debugging</i>" and "<i>Allow mock locations</i>". "<i>Select debug app</i>" option does not contain any value, but this is valid.</p>
<p class="el">Τέλος, από την αριστερή πλευρά της οθόνης των ρυθμίσεων επιλέγουμε το "<i>USB</i>" στο block "<i>Device</i>". Τότε στη δεξιά μεριά της οθόνης εμφανίζεται η μόνη επιλογή "<i>Connect to PC</i>". Μόλις την ενεργοποιήσουμε θα δούμε το MK809 να εμφανίζει στην οθόνη στο κάτω μέρος της το μήνυμα "<i>USB debugging connected</i>". Στον υπολογιστή μας θα δούμε ότι το <tt>adb</tt> έχει αναγνωρίσει το MK809 αν εκτελέσουμε την εντολή:</p>
<p class="en">Finally, on the left side of the settings screen we select "<i>USB</i>" in the "<i>Device</i>" block. Then, in the right side we can see the one and only "<i>Connect to PC</i>" option. When we enable this option we can MK809 ahowing a message at the bottom of the screen saying "<i>USB debugging connected</i>". On out computer now, we can use <tt>adb</tt> and confirm that it can recognise MK809 device, using the command:</p>
<div class="code"><pre class="prettyprint lang-sh">eliaschr@orion:~> adb devices
List of devices attached
0123456789ABCDEF device
eliaschr@orion:~>
</pre></div>
<p class="el">Μπορούμε, λοιπόν, να δουλέψουμε κανονικά το ΜΚ809 σε Developer Mode.</p>
<p class="en">So, we can use MK809 in Developer Mode without problems.</p>
<h4 class="el">Bonus για τους αναγνώστες του άρθρου: Angry Birds - Τα scores μας!</h4>
<h4 class="en">Bonus part ro the readers of this article: Angry Birds - Lets copy our scores!</h4>
<h5 class="el">Λίγες τεχνικές λεπτομέρειες</h5>
<h5 class="en">Some technical details</h5>
<p class="el">Η σειρά των παιχνιδιών Angry Birds έχει κάνει γερό πάταγο και δε νομίζω να υπάρχει κανένας που να μην έχει ασχοληθεί έστω και λίγο μαζί τους. Θα ξεκινήσουμε από μερικές μικρές λεπτομέρειες σχετικά με τα δεδομένα που μας ενδιαφέρουν.</p>
<p class="en">The Angry Birds series of games is very popular these days. I don't thing there is anybody that hasn't played one of these games, even for a short time. We will present some of its technical details for their necessary data storage.</p>
<p class="el">Αυτή τη στιγμή υπάρχουν τα εξής παιχνίδια της εν λόγω σειράς:</p>
<p class="en">At the time of this writing the series of these games has:</p>
<ul>
<li>Angry Birds</li>
<li>Angry Birds Seasons</li>
<li>Angry Birds Rio</li>
<li>Angry Birds Space</li>
<li>Angry Birds Star Wars</li>
</ul>
<p class="el">Φυσικά μιλάμε για τις δωρεάν εκδόσεις των παιχνιδιών. Το κάθε ένα από αυτά κρατάει κάποια στοιχεία που έχουν να κάνουν με τα scores των παικτών, κάποια settings κ.λ.π.</p>
<p class="en">Of course we are talking about the free versions of the games. Each one writes some data to keep players' scores, settings etc.</p>
<p class="el">Τα directories που καταγράφονται οι πληροφορίες μέσα σε μια Android συσκευή, είναι:</p>
<p class="en">The directories that hold these files in an Android device are:</p>
<ul>
<li>Angry Birds: <tt>/data/data/com.rovio.angrybirds/</tt></li>
<li>Angry Birds Seasons: <tt>/data/data/com.rovio.angrybirdsseasons/</tt></li>
<li>Angry Birds Rio: <tt>/data/data/com.rovio.angrybirdsrio/</tt></li>
<li>Angry Birds Space: <tt>/data/data/com.rovio.angrybirdsspace.ads/</tt></li>
<li>Angry Birds Star Wars: <tt>/data/data/com.rovio.angrybirdsstarwars.ads.iap/</tt></li>
</ul>
<p class="el">Μέσα εκεί υπάρχει ένας υποκατάλογος με ονομασία <tt>files</tt> κι εκεί περιέχονται τα δεδομένα που μας ενδιαφέρουν. Σε γενικές γραμμές τα δύο βασικά αρχεία είναι τα <tt>highscores.lua</tt> και <tt>settings.lua</tt>. Επιπλέον, τα Angry Birds Space και Angry Birds Star Wars έχουν άλλα τρία αρχεία: <tt>eaglepurchases.lua</tt>, <tt>episodepurchases.lua</tt> και <tt>gamepurchases.lua</tt>. Αυτά είναι τα αρχεία που θα πρέπει να μεταφέρουμε από τη μια συσκευή στην άλλη, προκειμένου να διατηρήσουμε τα highscores μας.</p>
<p class="en">In there, there is a subdirectory called <tt>files</tt> that stores the necessary files we need. In general terms, two are the files that we have to manpulate and these are <tt>highscores.lua</tt> and <tt>settings.lua</tt>. Additionally, Angry Birds Space and Angry Birds Star Wars include three other files, also: <tt>eaglepurchases.lua</tt>, <tt>episodepurchases.lua</tt> and <tt>gamepurchases.lua</tt>. These are the files we must copy from the source device to the other, in order to transfer our highscores to the latter.</p>
<h5 class="el">Μεταφορά αρχείων με το <tt>adb</tt></h5>
<h5 class="en">Files transfer using <tt>adb</tt></h5>
<p class="el">Αρχικά συνδέουμε τη συσκευή η οποία περιέχει τα scores που θέλουμε να μεταφέρουμε. Είναι η συσκευή που έχουμε περάσει ατελείωτες ώρες, παίζοντας, βρίζοντας κ.λ.π. μέχρι να γεμίσουμε τα πάντα με τρία αστεράκια :)</p>
<p class="en">First we connect the source device that contains the scores we want to transfer from, to our computer. Its the device that we've spent infinite ours of playing, cursing etc, until we reach our goal to have three stars in every level :)</p>
<p class="el">Όταν τη συνδέσουμε εκτελούμε τις ακόλουθες εντολές:</p>
<p class="en">In a terminal execute the following commands:</p>
<div class="code"><pre class="prettyprint">eliaschr@orion:~> mkdir AngryBirdsBackup
eliaschr@orion:~> mkdir AngryBirdsBackup/ab/
eliaschr@orion:~> mkdir AngryBirdsBackup/abs/
eliaschr@orion:~> mkdir AngryBirdsBackup/abr/
eliaschr@orion:~> mkdir AngryBirdsBackup/absp/
eliaschr@orion:~> mkdir AngryBirdsBackup/absw/
</pre></div>
<p class="el">Με αυτές δημιουργήσαμε ένα directory για κάθε παιχνίδι, που θα κρατήσει τα ευαίσθητα δεδομένα μας :). Ήρθε η ώρα να μεταφέρουμε τα αρχεία από τη συσκευή στον υπολογιστή μας:</p>
<p class="en">These commands create one directory for each game; that will hold our sensitive data :). Time to copy the files from the source device to our computer:</p>
<div class="code"><pre class="prettyprint">eliaschr@orion:~> cd AngryBirdsBackup/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Get Angry Birds files
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirds/files/highscores.lua ab/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirds/files/settings.lua ab/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Get Angry Birds Season files
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsseasons/files/highscores.lua abs/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsseasons/files/settings.lua abs/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Get Angry Birds Rio files
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsrio/files/highscores.lua abr/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsrio/files/settings.lua abr/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Get Angry Birds Space files
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsspace.ads/files/highscores.lua absp/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsspace.ads/files/settings.lua absp/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsspace.ads/files/episodepurchases.lua absp/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsspace.ads/files/gamepurchases.lua absp/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsspace.ads/files/eaglepurchases.lua absp/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Get Angry Birds Star Wars files
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/highscores.lua absw/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/settings.lua absw/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/episodepurchases.lua absw/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/gamepurchases.lua absw/
eliaschr@orion:~/AngryBirdsBackup> adb pull /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/eaglepurchases.lua absw/
</pre></div>
<p class="el">Αυτά θα αντιγράψουν τα απαραίτητα αρχεία στον υπολογιστή μας. Υπενθυμίζουμε ότι <b>δεν χρειάζεται να είμαστε <tt>root</tt></b> για να γίνουν οι αντιγραφές.</p>
<p class="en">Now the necessary files are in our computer's storage. Remember that <b>we don't need to be <tt>root</tt> user</b> to make the copies.</p>
<p class="el">Αποσυνδέουμε τη συσκευή μας και συνδέουμε το MK809. Αρχικά θα πρέπει να εγκαταστησουμε τα παιχνίδια Angry Birds που μας ενδιαφέρουν. Είναι απαραίτητη προϋπόθεση να παίξουμε τουλάχιστον μια πίστα σε κάθε ένα, για να δημιουργηθεί η δομή των φακέλων όπως ακριβώς χρειάζεται. Αν δεν γίνει αυτό δε θα μπορέσουμε να αντιγράψουμε τα αρχεία με τα scores μας!.</p>
<p class="en">We disconnect the source device and connect MK809. But before we do that we have to install the Angry Birds games in MK809 and must have played at least one level in each one. The games will create the necessary file structure in the device. Fail to do that, we will not be able to copy the score files.!.</p>
<p class="el">Ενεργοποιούμε το <i>Connect to PC</i> (προϋπόθεση φυσικά είναι να έχουμε κάνει και τα υπόλοιπα βήματα για να μπορέσουμε να λειτουργήσουμε το MK809 από το <tt>adb</tt>). Αφού ο υπολογιστής μας το δει εκτελούμε τις αντίθετες αντιγραφές για να μεταφέρουμε τα αρχεία που βρίσκονται στον υπολογιστή μας μέσα στο MK809:</p>
<p class="en">Enable <i>Connect to PC</i> (keep in mind that all the previous steps to make MK809 be recognised by <tt>adb</tt> must be completed). After our computer sees the device we can make the same copies of the files, but in reverse direction; from PC to MK809:</p>
<div class="code"><pre class="prettyprint">eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Save Angry Birds files
eliaschr@orion:~/AngryBirdsBackup> adb push ab/highscores.lua /data/data/com.rovio.angrybirds/files/
eliaschr@orion:~/AngryBirdsBackup> adb push ab/settings.lua /data/data/com.rovio.angrybirds/files/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Save Angry Birds Season files
eliaschr@orion:~/AngryBirdsBackup> adb push abs/highscores.lua /data/data/com.rovio.angrybirdsseasons/files/
eliaschr@orion:~/AngryBirdsBackup> adb push abs/settings.lua /data/data/com.rovio.angrybirdsseasons/files/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Save Angry Birds Rio files
eliaschr@orion:~/AngryBirdsBackup> adb push abr/highscores.lua /data/data/com.rovio.angrybirdsrio/files/
eliaschr@orion:~/AngryBirdsBackup> adb push abr/settings.lua /data/data/com.rovio.angrybirdsrio/files/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Save Angry Birds Space files
eliaschr@orion:~/AngryBirdsBackup> adb push absp/highscores.lua /data/data/com.rovio.angrybirdsspace.ads/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absp/settings.lua /data/data/com.rovio.angrybirdsspace.ads/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absp/episodepurchases.lua /data/data/com.rovio.angrybirdsspace.ads/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absp/gamepurchases.lua /data/data/com.rovio.angrybirdsspace.ads/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absp/eaglepurchases.lua /data/data/com.rovio.angrybirdsspace.ads/files/
eliaschr@orion:~/AngryBirdsBackup> #
eliaschr@orion:~/AngryBirdsBackup> # Save Angry Birds Star Wars files
eliaschr@orion:~/AngryBirdsBackup> adb push absw/highscores.lua /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absw/settings.lua /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absw/episodepurchases.lua /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absw/gamepurchases.lua /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/
eliaschr@orion:~/AngryBirdsBackup> adb push absw/eaglepurchases.lua /data/data/com.rovio.angrybirdsstarwars.ads.iap/files/
</pre></div>
<p class="el">Μετά από αυτές τις εντολές, μπορείτε πλέον να κλείσετε το <i>Connect to PC</i> από το MK809 και να το αποσυνδέσετε. Τρέξτε τα αγαπημένα σας παιχνίδια και απολαύστε όλα τα αστέρια που είχατε κερδίσει από πριν, σε ατελείωτες ώρες παιχνιδιού και κατάρων :)</p>
<p class="en">Now, you can disable <i>Connect to PC</i> from MK809 and disconnect it. Execute your favourite games and enjoy them, having the stars and scores you previously gained so hard, through curses and infinite hours of play, on a different device :)</p>
<p class="el authorname">Χρυσοχέρης Ηλίας</p>
<p class="en authorname">Elias Chrysocheris</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com1tag:blogger.com,1999:blog-9147006209672954597.post-49028314185318480582012-09-27T23:10:00.000+03:002013-08-21T19:32:51.653+03:00Ελληνικός Οδηγός Εγκατάστασης openSUSE 12.2<div dir="ltr" style="text-align: center;" trbidi="on"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuI3WuCZjbnnh20mS8khlNY8KpEbKxrfsQjQvPJYh3ts8_Co85FZMqkBxada03zEs_BwwRDLRy2Y2cMs8UuQRonp5IOoIYYyBEtgaUAjaEG70q1Z8vgd0N6Go1V8E4aossZWZehULQX3US/s1600/snapshot39.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuI3WuCZjbnnh20mS8khlNY8KpEbKxrfsQjQvPJYh3ts8_Co85FZMqkBxada03zEs_BwwRDLRy2Y2cMs8UuQRonp5IOoIYYyBEtgaUAjaEG70q1Z8vgd0N6Go1V8E4aossZWZehULQX3US/s320/snapshot39.png" width="320" /></a><br />
</div><br />
<p>Στις 5 Σεπτεμβρίου 2012 βγήκε και η καινούργια έκδοση του λειτουργικού <a href="http://www.opensuse.org/">openSUSE</a>. Στην έκδοση <a href="http://wiki.opensuse.org/Portal:12.2">openSUSE 12.2</a> θα βρείτε όλο το τελευταίο software που έχει βγει στα γραφικά περιβάλλοντα <a href="http://www.kde.org">KDE4</a>, <a href="http://www.gnome.org">GNOME3</a>, <a href="http://www.xfce.org">XFCE</a> και <a href="http://www.lxde.org">LXDE</a>. Φυσικά υπάρχουν και άλλα μικρότερα και ελαφρύτερα γραφικά περιβάλλοντα. Όλα όπως πάντα, σε αρμονία και την κλασική ομορφιά που μας προσφέρει το openSUSE όλα αυτά τα χρόνια της ύπαρξής του.</p><br />
<p>Η εγκατάσταση γίνεται με τον κλασικό τρόπο του YaST2 χωρίς προβλήματα και αποτελείται από ένα DVD και δύο CD με addons:</p><br />
<ul><li>DVD Εγκατάστασης: Περιέχει όλο το βασικό software ανοικτού λογισμικού μαζί<br />
και τις απαραίτητες μεταφράσεις του συστήματος εγκατάστασης YaST2.</li>
<li>Languages Add-On CD: Περιέχει όλες τις μεταφράσεις για όλα τα προγράμματα<br />
του εγκαταστημένου συστήματος</li>
<li>Non-OSS Add-On: Περιέχει προγράμματα κλειστού λογισμικού που συνήθως<br />
χρησιμοποιούμε, όπως Flash Player, Opera Browser κ.λ.π.</li>
</ul><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg53X9tvnaAldtROivGB_2DV51qoZPCBmoK2HJlpoGwBdVZvs5ylIYWIe_XzVrUyoZTJwbHj9jP2ndmzx3kZVzal4lHWNFxgMbINmh1PrUV4hm3oPPnahF80fxeAJgCu8AwltN5hmX1quyS/s1600/snapshot40.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="240" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg53X9tvnaAldtROivGB_2DV51qoZPCBmoK2HJlpoGwBdVZvs5ylIYWIe_XzVrUyoZTJwbHj9jP2ndmzx3kZVzal4lHWNFxgMbINmh1PrUV4hm3oPPnahF80fxeAJgCu8AwltN5hmX1quyS/s320/snapshot40.png" /></a></div><br />
<p>Η <a href="http://software.opensuse.org/">διάθεση του openSUSE</a> 12.2 γίνεται και σαν Live CD είτε με KDE4 είτε με GNOME3, αλλά και σαν Network Installation όπου κατεβάζετε ένα CD με πολύ βασικό σύστημα εγκατάστασης και όλο το software που εγκαθιστάτε κατεβαίνει εκείνη τη στιγμή από το διαδίκτυο. Αυτό, κατά συνέπεια, σημαίνει πως η εγκατάσταση διαρκεί περισσότερη ώρα, μιας και όλα τα πακέτα κατεβαίνουν μέσω διαδικτύου, από την άλλη δε χρειάζεται κάποιος να κατεβάσει πρώτα τα δύο CD και το DVD εγκατάστασης. Φυσικά θα πρέπει να επιλέξετε αν θέλετε την 32bit έκδοση του λειτουργικού, ή την 64 bit.</p><br />
<p>Για κάποιον που έχει κάνει κάποιες φορές εγκατάσταση στο λειτουργικό, η εγκατάσταση είναι παιχνιδάκι. Για κάποιον ο οποίος είναι καινούργιος στο χώρο του Linux και χρειάζεται λίγη βοήθεια, όπως και με κάθε καινούργια έκδοση, δημιούργησα και τον καινούργιο <a href="http://wiki.chania-lug.gr/index.php/Opensuse-11.2-guide">Οδηγό Εγκατάστασης του openSUSE 12.2</a> στα Ελληνικά. Ο οδηγός είναι ένα project που έχει αναλάβει ο <a href="http://www.chania-lug.gr/">Σύλλογος Φίλων Ανοικτού Λογισμικού Χανίων</a> και έτσι φιλοξενείται στο <a href="http://wiki.chania-lug.gr/">wiki</a> του.</p><br />
<div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhtttDG4af_ghnEYBOtnvMs1RDZnxIGisznQff9ChY-Wrk4bsSiItQtzqfvdEY5FYBjXJ0xwlZYTjOhN9T4MUgBpej-ZtUfzhiLk5U4gbjD_fm_X3sT4Lf-o1i3fDNGCi5XBuzoxjvAcPZ/s1600/snapshot1.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="240" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhtttDG4af_ghnEYBOtnvMs1RDZnxIGisznQff9ChY-Wrk4bsSiItQtzqfvdEY5FYBjXJ0xwlZYTjOhN9T4MUgBpej-ZtUfzhiLk5U4gbjD_fm_X3sT4Lf-o1i3fDNGCi5XBuzoxjvAcPZ/s320/snapshot1.png" /></a></div><br />
<p>Ελπίζω ο οδηγός να φανεί ένα χρήσιμο εργαλείο. Αν παρατηρήσετε κάτι που, αλλάζοντάς το, ο οδηγός γίνεται καλύτερος και πιο καταννοητός, παρακαλώ ενημερώστε με. Κάθε σχόλιο είναι αποδεκτό.</p><br />
<p style="clear: both; text-align: right;"><b><i>Χρυσοχέρης Ηλίας</i></b></p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-60859112904885803112011-12-15T01:29:00.000+02:002013-08-21T19:51:39.750+03:00Τα βασικά προβλήματα του ανοικτού λογισμικού!... (μέρος 1ο - open/libreoffice)<p>Είναι γνωστό πως είμαι από τους θερμούς υποστηρικτές του ανοικτού λογισμικού και χρησιμοποιώ μόνο ΕΛ/ΛΑΚ εφαρμογές στο 90% των εργασιών μου. Το 10% της χρήσης του κλειστού λογισμικού μου είναι στη σχεδίαση κυκλωμάτων, όπου χρησιμοποιώ το EAGLE σε περιβάλλον Linux (αγορασμένο) και οι εκτυπώσεις των CD/DVD με τον εκτυπωτή μου, όπου δεν υποστηρίζεται αυτού του είδους η εκτύπωση στο αγαπημένο μου λειτουργικό...</p>
<p>Αυτό το άρθρο το γράφω στις 01:00 ξημερώματα, γιατί πραγματικά κάθε φορά που χρησιμοποιώ μια από τις "σουίτες γραφείου", όπως θέλουν να τις αποκαλούν κάποιοι, OpenOffice ή LibreOffice, ξέρω ότι το 80% του χρόνου χρήσης θα συνοδεύεται από κατάρες, βρισιές και ατελείωτα χτυπήματα του γραφείου μου. Δεν είναι λίγες οι φορές που αναφέρονται προβλήματα με τις εν λόγω εφαρμογές από φίλους, γνωστούς κ.λ.π. Και οι περισσότεροι είναι υποστηρικτές του Ανοικτού Λογισμικού, όπως εγώ.</p>
<p>Θα ξεκινήσω παραθέτωντας δύο φωτογραφίες. Η πρώτη δείχνει το OpenOffice την ώρα που γράφω ένα ερωτηματολόγιο. Το ερωτηματολόγιο αυτό περιέχει και σχήματα. Έτσι, το διάγραμμα που φαίνεται είναι ένα διάγραμμα, που κατασκευάζεται στην ίδια "σουίτα" (ο Θεός να το κάνει αυτό το πράμα να γίνει σουίτα) γραφείου. Την ώρα που δημιουργείται το σχήμα, όλα φαίνονται μια χαρά:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG-F6C6t5LsCQ9pxnqtrqbnv7qKZjbmTgNSYxsDHrM754VyX1m4e9WKzkmmwf-N48QB0wZaDiaX9Lpoh4XQQH2wR6wJtjMDY1k79g1Z-ggYAZ0I2pzJz25O7LnFc8IWwxg2MNKTFIU_SbV/s1600/openoffice-edit.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="190" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhG-F6C6t5LsCQ9pxnqtrqbnv7qKZjbmTgNSYxsDHrM754VyX1m4e9WKzkmmwf-N48QB0wZaDiaX9Lpoh4XQQH2wR6wJtjMDY1k79g1Z-ggYAZ0I2pzJz25O7LnFc8IWwxg2MNKTFIU_SbV/s320/openoffice-edit.png" /></a></div>
<p>Οι κόκκινες γραμμές ξεκινάνε από το σημείο (0,0), δηλαδή την αρχή των αξόνων.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXYiV6luHPEuHRld8qlJjQlqpSMj_UyPtDwMIbbejRNQ9VS5Ym0GZCFxp6xTKL2R0v31327fXDjM6PAz3Eh1WyvhDfDWn2Gm6FejmxlCSTYQUDAOtO8HlmVWPYOVBJVxBw18G_O5UHk_ww/s1600/openoffice-normal.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="190" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXYiV6luHPEuHRld8qlJjQlqpSMj_UyPtDwMIbbejRNQ9VS5Ym0GZCFxp6xTKL2R0v31327fXDjM6PAz3Eh1WyvhDfDWn2Gm6FejmxlCSTYQUDAOtO8HlmVWPYOVBJVxBw18G_O5UHk_ww/s320/openoffice-normal.png" /></a></div>
<p>Μπορείτε να παρατηρήσετε τη διαφορά στο στιγμιότυπο που φαίνεται εδώ; Είναι το ίδιο στιγμιότυπο, όμως το πρόγραμμα έχει βγει από τη σχεδίαση και έχει μπει και πάλι στη σύνθεση κειμένου. Ξαφνικά οι κόκκινες γραμμές έχουν περάσει κάτω από τον οριζόντιο άξονα!... Δηλαδή, πόση προσπάθεια θέλει αυτό το πράγμα στον προγραμματισμό να γίνει. Τόσο διαφορετικές είναι οι ρουτίνες της σύνθεσης της εικόνας στο write (που είναι ο κειμενογράφος) από το draw (που είναι το κομμάτι του σχεδίου); Δηλαδή πόσο άθλια μπορεί να κάνει τον κώδικά του ένας προγραμματιστής; Πόσο σοβαρά, τελικά, παίρνουμε τη δουλειά που κάνουμε;</p>
<p>Το πρόβλημα δεν είναι το ότι το πρόγραμμα έχει bugs. Ακόμα και το "Hello, world" που θα φτιάξει κάποιος μπορεί να έχει bugs... Το πρόβλημα είναι πως οι διαθέσιμες επιλογές, όσες κι αν φαίνονται να είναι (τα διαφόρων ειδών office που υπάρχουν), τόσο πιο χάλια είναι και η κατάσταση. Το πρόβλημα είναι πως θέλουμε το ανοικτό λογισμικό να είναι αυτό που προτείνουμε στον κόσμο για τη σταθερότητά του, αλλά κανένας μας δεν λέει ότι "φίλε, βάλε Linux και άμα γράψεις ένα σοβαρό κείμενο, να με <strike>χε</strike>χαιρετίσεις!"...</p>
<p>Πρέπει κάποια στιγμή να το πάρουμε χαμπάρι, πως δεν είναι μόνο το kernel και τα εφέ στα γραφικά περιβάλλοντα αυτά που θα κάνουν τον κόσμο να περάσει στο ανοικτό λογισμικό. Όλο το παιχνίδι με το αν το GNOME3.7865455 θα έχει καλύτερα τρισδιάστατα εφέ από το KDE 8.576576554563543-4 είναι μόνο το 0.1% του χρόνου του χρήστη και τίποτα άλλο! Είναι η λειτουργικότητα του όλου πακέτου, λειτουργικού και λογισμικού υποστήριξης, αυτή που θα κάνει κάποιον να μεταβεί στο Linux και να φύγει από κάποιο άλλο λειτουργικό. Και αυτή βασίζεται σε λίγα βασικά πράγματα:</p>
<ol>
<li>Κανένας δε μπορεί να πετάξει στα σκουπίδια τη δουλειά που έχει κάνει μέχρι τώρα σε κάποιο άλλο λειτουργικό. Το πρώτο πράγμα που θέλει είναι κατά κάποιο τρόπο συμβατότητα, ώστε τα αρχεία που έχει δημιουργήσει να μπορεί να τα επεξεργαστεί ΕΠΙΤΥΧΩΣ και με ανοικτό λογισμικό! Με οποιοδήποτε τρόπο θα πρέπει να μπορεί να κάνει import τα αρχεία του και να μπορεί να συνεχίσει τη δουλειά που μέχρι τώρα είχε κάνει, λίγη ή πολλή!</li>
<li>Τα βασικά προγράμματα (δε μιλάω για τα εξηζητημένα, όπως το πακέτο που προανέφερα), όπως κειμενογράφος, λογιστικά φύλλα, παρουσιάσεις, απλή σχεδίαση σχημάτων, media players κ.λ.π. ΝΑ ΛΕΙΤΟΥΡΓΟΥΝ ΧΩΡΙΣ ΝΑ ΚΑΝΟΥΝ ΤΟ ΧΡΗΣΤΗ ΝΑ ΜΑΘΕΙ ΟΛΑ ΤΑ ΤΡΟΠΑΡΙΑ ΜΕ ΑΛΦΑΒΗΤΙΚΗ ΣΕΙΡΑ!!!!! Να μην είναι υποχρεωμένος να μάθει LaTeX για να μπορέσει να γράψει ένα κείμενο δύο σελίδων... Έλεος!</li>
</ol>
<p>Είναι ήδη αργά και πρέπει να συνεχίσω τη δουλειά μου. Ίσως αν έχω οίστρο κάποια άλλη μέρα να δώσω και το δεύτερο μέρος...eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com9tag:blogger.com,1999:blog-9147006209672954597.post-7123877796480627382011-12-04T00:36:00.000+02:002013-08-21T19:52:36.636+03:00openSUSE 12.1 Release Party<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKIBHT2PoO8QHvuF5tmfk3Md8rvW0fI4saWvt4uwW0BEuu4WxG9ajMU-8knFAMZowCherQOBovTRiSCHua7vZIveFhbLryW8VeWev_isXNB6e9Kk8Or6eSfaMw8Vdrlfgesc7kWL5gnKuD/s1600/IMAG0633.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="320" width="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKIBHT2PoO8QHvuF5tmfk3Md8rvW0fI4saWvt4uwW0BEuu4WxG9ajMU-8knFAMZowCherQOBovTRiSCHua7vZIveFhbLryW8VeWev_isXNB6e9Kk8Or6eSfaMw8Vdrlfgesc7kWL5gnKuD/s320/IMAG0633.jpg" /></a></div>
<p>Το openSUSE 12.1 βγήκε πριν λίγες ημέρες. Το πρώτο βήμα ήταν να οργανωθούμε για να βγει και ο καινούργιος οδηγός εγκατάστασής του. Το αμέσως επόμενο; Μα τι άλλο θα μπορούσε να είναι από την οργάνωση ενός Release Party.</p>
<p>Όπως πάντα το υλικό που θα μοιραζόταν στους παρευρισκόμενους το φτιάνω εγώ, μιας και είμαι ο fun της εν λόγω διανομής Linux στο Σύλλογο Φίλων Ανοικτού Λογισμικού Χανίων. Έτσι, ξεκίνησε η κατασκευή όλου του artwork για την εκτύπωση μιας ωραίας θήκης με όλα τα απαραίτητα δισκάκια. Το καλό είναι πως το βασικό template το είχα από τα προηγούμενα Release Parties που είχαμε κάνει. Μιας και το αποτέλεσμα ήταν πολύ καλό, είπα να ακολουθήσω την ίδια διαδικασία με τότε! Και ξεκινάει το GIMP να δουλεύει ασταμάτητα...</p>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNPrhGr_xaJaH8d_-QvR1RYvYPt400RylyVowOg-A1BGxc72QE56iOQt5grFdJKILp3R5lODukk87YJ4ktiODjZ8BXCNA0qRKW2mFaZ4ZWEnQY23SxcCJ13oXVS1k8MAmDf6juujUv8ZEO/s1600/IMAG0630.jpg" imageanchor="1"><img border="0" height="264" width="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNPrhGr_xaJaH8d_-QvR1RYvYPt400RylyVowOg-A1BGxc72QE56iOQt5grFdJKILp3R5lODukk87YJ4ktiODjZ8BXCNA0qRKW2mFaZ4ZWEnQY23SxcCJ13oXVS1k8MAmDf6juujUv8ZEO/s320/IMAG0630.jpg" /></a></div>
<p>Μια πλήρης διανομή openSUSE περιλαμβάνει ένα DVD για την εγκατάσταση του βασικού συστήματος με τα γραφικά περιβάλλοντα, ένα CD που περιέχει τις μεταφράσεις για όλες τις γλώσσες και ένα τρίτο CD που περιέχει προγράμματα κλειστού κώδικα, όπως τον Flash Player κ.α. Φυσικά, άλλα είναι τα δισκάκια για 32 bit αρχιτεκτονικές και άλλα αυτά για 64 bit, εκτός του CD που περιέχει τα προγράμματα κλειστού κώδικα. Το τελευταίο είναι κοινό και για τις δύο αρχιτεκτονικές προσωπικών υπολογιστών. Όλα αυτά μας κάνουν 5 δισκάκια (2 DVD και 3 CD).</p>
<p>Ένας αστικός μύθος για το openSUSE είναι πως το κύριο περιβάλλον εργασίας του είναι το KDE. Αυτό, φυσικά, δεν ισχύει. Το openSUSE υποστηρίζει από την εγκατάσταση όποιο από τα βασικά γραφικά περιβάλλοντα επιθυμεί ο χρήστης, KDE, GNOME, XFCE και LXDE. Φυσικά υπάρχουν και πάρα πολλά ακόμα που μπορεί κάποιος να εγκαταστήσει, αλλά δε θα ήθελα να επεκταθώ σε αυτό. Ο τελικός μου στόχος είναι πως θα έπρεπε να παρέχω και ένα Live CD της διανομής. Επέλεξα το openSUSE 12.1 KDE Live CD γιατί είναι το γραφικό περιβάλλον που θεωρώ ομορφότερο από τα άλλα, ενώ προτίμησα την αρχιτεκτονική των 32 Bit μιας και δεν το προόριζα για την εγκατάσταση της διανομής.</p>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzpggaJnVY7V5B4750ogsMoQf2TbnfT_qUmNBgcq_02lh6tSTcKF9-d4chwiqzFCuKdwoMbnuIhrERGtPcynZFPwrB-q50awdR2sPGxjfEHPqMAo0W1WvPvdIml7b2yJ8YkKi7AiMkxouO/s1600/IMAG0627.jpg" imageanchor="1"><img border="0" height="264" width="440" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzpggaJnVY7V5B4750ogsMoQf2TbnfT_qUmNBgcq_02lh6tSTcKF9-d4chwiqzFCuKdwoMbnuIhrERGtPcynZFPwrB-q50awdR2sPGxjfEHPqMAo0W1WvPvdIml7b2yJ8YkKi7AiMkxouO/s320/IMAG0627.jpg" /></a></div>
<p>Οι φωτογραφίες δείχνουν το αποτέλεσμα της εκτύπωσης των CD/DVD και των εξώφυλλων των θηκών τους. (Ναι, όλα εκτυπώθηκαν στο σπίτι και δεν χρειάστηκε ούτε μελάνι να αλλάξω στον εκτυπωτή μου!):)</p>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz7gJavGNUNeM50jP7rkP913j7my4L-Or71QQ4EGQ_Kc8FMebnXi26PuuivycrIQaKek8NeT8K184pC0ChAAS3ofU0nVzsxgjewvh5Yh67jFRgQ4r7uy0vZHW1SzhhGZAfQbNwhgLQMV7-/s1600/IMAG0640.jpg" imageanchor="1" style="clear:left; float:left;margin-right:1em; margin-bottom:1em"><img border="0" height="320" width="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhz7gJavGNUNeM50jP7rkP913j7my4L-Or71QQ4EGQ_Kc8FMebnXi26PuuivycrIQaKek8NeT8K184pC0ChAAS3ofU0nVzsxgjewvh5Yh67jFRgQ4r7uy0vZHW1SzhhGZAfQbNwhgLQMV7-/s320/IMAG0640.jpg" /></a></div>
<p>Το τελευταίο κομμάτι της οργάνωσης του Release Party περιέχει... δημοκρατικές διαδικασίες στο να κανονίσουμε... τι θα φάμε :P Βασικά μετά από μια πολύ μικρή συζήτηση αποφασίσαμε να βρεθούμε σε μια από τις αγαπημένες μας ταβέρνες, τον Αποκόρωνα στην πόλη των Χανίων. Εκεί, βάλαμε κάτω τα δισκ... εχμμμ... κρεατικά μας και την κάναμε ταράτσα. Μοιράστηκαν και τα πακέτα της διανομής, αλλά δεν τα πολύκοιτάξαμε γιατί το κρέας ήρθε γρήγορα...</p>
<p>Και όπως προείπα, οι φωτογραφίες δείχνουν το αποτέλεσμα... Τα πιάτα ούτε πλύσιμο δεν χρειάζονται! :)</p>
<p>Και αυτή τη φορά περάσαμε θαυμάσια, με μπόλικη σιωπή την ώρα που μιλούσαν τα μαχαιροπήρουνα, αλλά την υπόλοιπη ώρα μιλούσαμε για τα αγαπημένα μας θέματα, τόσο του ανοικτού λογισμικού, όσο και off topic. Ελπίζουμε κι εσείς να περάσατε το ίδιο καλά, ή ακόμα καλύτερα από εμάς. Τα χαμόγελα πραγματικά μας χρειάζονται! :):):):):):):):):):):)</p>
<br />
<b><i>Ηλίας Χρυσοχέρης</i></b>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com2Χανιά, Ελλάς35.5118456721497 24.02080140760801935.375691172149693 23.882560907608021 35.6480001721497 24.159041907608017tag:blogger.com,1999:blog-9147006209672954597.post-68963809556585492152011-11-26T23:11:00.000+02:002013-08-21T19:53:10.839+03:00Οδηγός Εγκατάστασης openSUSE 12.1<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEied6hYs4NNFyWmxCmQ78JNvpgdkzkj5abezxB0AKriRW7BSOzA_0262tFUiMlCLTpEgybO44-pRlEaD96FkiIcTw16Lpm5HTizDKydB_nN7FIkBi-8D_hWJ4yt1bptNwD-HrU7Xi7FzSPT/s1600/openSUSE12.1-img.png" imageanchor="1" style="margin-left:1em; margin-right:1em"><img border="0" height="240" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEied6hYs4NNFyWmxCmQ78JNvpgdkzkj5abezxB0AKriRW7BSOzA_0262tFUiMlCLTpEgybO44-pRlEaD96FkiIcTw16Lpm5HTizDKydB_nN7FIkBi-8D_hWJ4yt1bptNwD-HrU7Xi7FzSPT/s320/openSUSE12.1-img.png" /></a></div>
<p>Είναι γνωστό πως η αγαπημένη μου διανομή Linux είναι το <a href="http://www.opensuse.org/">openSUSE</a>. Πριν από λίγες ημέρες βγήκε και η έκδοση <a href="http://wiki.opensuse.org/Portal:12.1">12.1</a>, οπότε έπρεπε να δημιουργηθεί ο <a href="http://wiki.chania-lug.gr/index.php/Opensuse-11.2-guide">οδηγός εγκατάστασής του</a>, όπως γίνεται κάθε φορά. Ο τρόπος που έχω δει το openSUSE είναι αυτός που με έκανε να ξεκινήσω το project της συγγραφής του οδηγού, τόσο για να βοηθήσω στην απήχηση της διανομής, όσο και στο να βοηθήσω στα διάφορα events του <a href="http://www.chania-lug.gr/">Συλλόγου Φίλων Ανοικτού Λογισμικού Χανίων</a>, στον οποίο είμαι και μέλος.</p>
<p>Στην προηγούμενη έκδοση της διανομής, την <a href="http://wiki.opensuse.org/Portal:11.4">openSUSE 11.4</a>, είχα αργήσει πάρα πολύ να γράψω τον οδηγό εγκατάστασης. Ο υπερβολικός φόρτος εργασίας με έχει κάνει, δυστυχώς, να απέχω και από αυτές τις μικρές εργασίες.</p>
<p>Αυτή τη φορά όμως είπα πως θα έπρεπε να καταφέρω να βγάλω τον οδηγό εγκαίρως, έτσι ώστε να φανεί χρήσιμος σε όποιον προσπαθήσει την εγκατάσταση της έκδοσης 12.1. Φυσικά υπάρχει και ο <a href="http://wiki.chania-lug.gr/index.php/Opensuse-11.2-guide">οδηγός της έκδοσης 11.4</a>, ο οποίος, λόγω της μεγάλης καθυστέρησής του δεν ανακοινώθηκε. Και τους δύο οδηγούς, αλλά και τους προηγούμενους από αυτούς μπορείτε να τους βρείτε σε μορφή pdf στο <a href="http://wiki.chania-lug.gr/index.php/Opensuse-11.2-guide">wiki του ιστότοπου του Συλλόγου Φίλων Ανοικτού Λογισμικού Χανίων</a></p>
<p>Ελπίζω αυτή τη φορά να σας φανεί χρήσιμος. Καλή εγκατάσταση και εύχομαι ο καινούργιος οδηγός να σας φανεί χρήσιμος στην όμορφη εμπειρία του openSUSE</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com4tag:blogger.com,1999:blog-9147006209672954597.post-50417683192365781602011-04-15T19:33:00.000+03:002013-08-21T19:54:50.553+03:00Παρουσίαση του FreeBSD Project στο openFest 2011<style type="text/css">
p { text-indent:13px; text-align:justify;}
</style>
<div class="separator" style="clear: both; text-align: center; margin-bottom:10px;">
<img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSZR-JUjpauqbdPT2BmjQAXpIWo-JMkBL_N9bxXbm-He_Tmqvlf3fjcYqzJYyaIZWuJ8Rjtz3_-l1RgEs9RxpfP2KXCI68EvGnLhTBSqthLDfJ_t5ijN5y2mt0f1sGtVejVatd7cKB5Qj7/s320/FreeBSD-openFest2011.jpg" width="320" /></div>
<p>Στις 9 και 10 Απριλίου έγινε ένα φεστιβάλ ανοικτού λογισμικού στο ΤΕΙ του Πειραιά. Το Φεστιβάλ αυτό ονομάζεται <a href="http://openfest.teipir.gr/">openFest</a> και έχει γίνει ένα από τα επαναλαμβανόμενα events. Κάθε χρόνο τα παιδιά του ΤΕΙ οργανώνουν μια διημερίδα γεμάτη με παρουσιάσεις και workshops με σκοπό την ενημέρωση του κόσμου επάνω στο ανοικτό λογισμικό, τις τεχνολογίες που εισάγει στο χώρο της πληροφορικής αλλά και τη δύναμη που παρέχει στους χρήστες ηλεκτρονικών υπολογιστών.</p>
<p>Τα παιδιά που οργανώσανε το event αξίζουν συγχαρητήρια. Μπορεί να υπήρχε κάποιο πρόβλημα στην πρόσβαση του κοινού στο internet, αλλά μην ξεχνάμε ότι αυτό είχε συμβεί και σε άλλα events που ήταν μεγαλύτερα και είχαν και πιο έμπειρους ανθρώπους στην οργάνωσή τους. Η ύλη ήταν μεγάλη και κάλυπτε κάθε γωνιά του ανοικτού κώδικα. Μια ματιά να ρίξει κάποιος στο <a href="http://openfest.teipir.gr/el/newsletter/">πρόγραμμα</a> δε νομίζω πως θα βρει εύκολα σημείο που να μη θέλει να παρακολουθήσει τουλάχιστον μια παρουσίαση!</p>
<p>Το <a href="http://www.freebsd.org/">FreeBSD Project</a> δε θα μπορούσε να λείπει από αυτό το event. Έτσι, μου δόθηκε η ευκαιρία να παρουσιάσω το αγαπημένο μου λειτουργικό, εκ μέρους της <a href="http://www.freebsdworld.gr/">Ελληνικής Κοινότητας FreeBSD</a>. Ευτυχώς η διαθέσιμη ώρα ήταν αρκετή για να μπορέσω να δώσω στον κόσμο μια παρουσίαση που να εξηγεί τα βασικά, πάντα, του λειτουργικού. Θεωρώ ότι το FreeBSD είναι ό,τι ανώτερο έχει μπει μέσα στον υπολογιστή μου, ενώ ταυτόχρονα μου έχει μάθει απίστευτα πολλά πράγματα!</p>
<p>Η παρουσίαση κράτησε 45 λεπτά μαζί με τις ερωτήσεις του κοινού. Η αίσθηση ήταν πραγματικά υπέροχη. Όλη η παρουσίαση έχει βιντεοσκοπηθεί και αναρτηθεί στο YouTube, αλλά λόγω του ότι το τελευταίο δέχεται βιντεάκια μέχρι 15 λεπτών, αναγκάστηκα να κόψω την παρουσίαση σε 4 κομμάτια. Έτσι, μπορείτε να δείτε τα ακόλουθα:</p>
<ul>
<li><b>Μέρος 1ο:</b> <a href="http://www.youtube.com/watch?v=QbBRjdLSFk0">Εισαγωγή - Τι είναι το FreeBSD</a> (διάρκεια 14:51)</li>
<li><b>Μέρος 2ο:</b> <a href="http://www.youtube.com/watch?v=KIhrUZX8yOk">Ασφάλεια</a> (διάρκεια 12:11)</li>
<li><b>Μέρος 3ο:</b> <a href="http://www.youtube.com/watch?v=fNHTYzAISVQ">Τεχνολογίες προερχόμενες από το openSolaris (διάρκεια 10:42)</a> και</li>
<li><b>Μέρος 4ο:</b> <a href="http://www.youtube.com/watch?v=kGmPp4wrJCw">Ερωτήσεις κοινού (διάρκεια 7:30)</a></li>
</ul>
<p>Στο δεύτερο μέρος, το πρώτο λεπτό προέρχεται και αυτό από την εισαγωγή, αλλά δε χωρούσε μέσα στα 15 λεπτά που θέτει σαν όριο το YouTube...</p>
<p>Η παρουσίαση είναι φτιαγμένη σε LaTeX - Beamer και το τελικό αρχείο μπορείτε να το βρείτε <a href="http://www.chania-lug.gr/sites/default/files/documents/FreeBSD_openFest2011.pdf">εδώ</a>.</p>
<p>Τέλος, να ευχαριστήσω όλο τον κόσμο που παραβρέθηκε στο event, ακόμα περισσότερο όσους παραβρέθηκαν στην αίθουσα της παρουσίασης του FreeBSD, αλλά και τα παιδιά της διοργάνωσης του openFest. Εύχομαι οι προσπάθειες όλων μας να είναι τόσο δυνατές.</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-36193098425591248002011-04-02T22:52:00.000+03:002013-08-21T19:55:37.381+03:00Καθυστέρηση στον ελληνικό οδηγό εγκατάστασης openSUSE 11.4<div class="separator" style="clear: both; text-align: center;">
<a href="http://www.opensuse.org/" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMacemCpPFQlhHaRInQcZ7xGyP-e3PWGcDRGHpF4dyH-vXV3iKvaAizKCaOiE0ElONk2UCi-HNZKE0wOw9ythy5mJuuIPQWERz5bpUdero1h1CgfufO8fOAQnwbhnZ4ukVlVWi3wwRUxrv/s320/opensuse.png" width="320" /></a></div>
<p>Ένα από τα project που έχω στην κοινότητα openSUSE είναι και η συγγραφή ελληνικού οδηγού εγκατάστασης του openSUSE. Ο οδηγός βοηθάει έναν αρχάριο χρήστη να εγκαταστήσει το openSUSE στον υπολογιστή του, έτσι ώστε να μπορεί να τον χρησιμοποιήσει τόσο για το internet, όσο και για χρήση εφαρμογών γραφείου και multimedia.</p>
<p>Το openSUSE έφτασε στην έκδοση <a href="http://software.opensuse.org/114/">11.4</a> εδώ και λίγες ημέρες. Ήδη το έχω εγκαταστήσει σε αρκετούς υπολογιστές και δουλεύει άψογα με όλα του τα κομφόρ! Δυστυχώς όμως λόγω έλλειψης χρόνου δεν έχω ενημερώσει τον οδηγό εγκατάστασης. Η ενημέρωση προβλέπεται να γίνει μέσα στο Πάσχα λόγω των αρκετών projects που τρέχουν αυτή τη στιγμή και έχουν βαθμό προτεραιότητας μεγαλύτερο...</p>
<p>Θα ήθελα να ζητήσω συγγνώμη για την καθυστέρηση. Το ευχάριστο της ιστορίας είναι πως ο ήδη υπάρχων <a href="http://www.freebsdworld.gr/diktia/openSuse113.pdf">οδηγός εγκατάστασης της προηγούμενης έκδοσης (openSUSE 11.3)</a> είναι ικανός να βοηθήσει στην εγκατάσταση και του 11.4 μιας και οι αλλαγές στην εγκατάσταση δεν είναι μεγάλες. Έτσι, όποιος θέλει μπορεί να τον χρησιμοποιήσει άφοβα.</p>
<p>Όταν γίνει και η ενημέρωση του οδηγού εγκατάστασης θα γίνει και το ανάλογο post από αυτό εδώ το blog. Ως τότε... καλές εγκαταστάσεις με τον παλιό οδηγό...</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-84670318356279802582011-03-25T16:55:00.000+02:002013-08-21T19:56:56.996+03:00openFest 2011<style type="text/css">
img.of2011 {
width: 480px;
margin-left: auto;
margin-right: auto;
padding: 5px 10px;
text-align: center;
}
</style>
<p class="center"><a href="http://openfest.teipir.gr/" target="_blank"><img src="http://openfest.teipir.gr/images/banners/openfest-banner.png"></a></p>
<p>Είναι γνωστό πως είμαι fun του ανοικτού λογισμικού. Τα κύρια λειτουργικά μου είναι το <a href="http://www.opensuse.org/">openSUSE</a> και το <a href="http://www.freebsd.org/">FreeBSD</a>. Είναι πραγματικά όμορφο το να ακούω συνεχώς για διοργανώσεις ανοικτού λογισμικού εδώ κι εκεί, στην Ελλάδα και το εξωτερικό. Tις χαιρετίζω και προσπαθώ με τον τρόπο μου να βοηθήσω να ακουστεί το ΕΛ/ΛΑΚ όσο περισσότερο μπορώ.</p>
<p>Αυτή τη φορά άκουσα για τη διοργάνωση <a href="http://openfest.teipir.gr/">openFest 2011</a> η οποία θα γίνει στο ΤΕΙ του Πειραιά από ένα φίλο, λίγες ημέρες μετά από αυτή που έδωσα την παρουσίαση του <a href="http://www.freebsdworld.gr/">FreeBSD Project</a> στο Athens Digital Week 2010. Έτσι, είπα αμέσως πως θα ήταν μια καλή ιδέα να παρουσιάσω κι εκεί το αγαπημένο μου Unix λειτουργικό, ίσως έχοντας περισσότερη ώρα διαθέσιμη από αυτή που είχα στο ADW2010. Αυτό θα είχε ως αποτέλεσμα να μπορέσει ο κόσμος να καταλάβει περισσότερα γι' αυτό μιας και η ροή του λόγου δε θα ήταν σε μορφή "<i>με κυνηγάνε και πρέπει να τρέξω να προλάβω!</i>"</p>
<p>Η διοργάνωση openFest 2011 έχει ένα πολύ πλούσιο <a href="http://openfest.teipir.gr/el/newsletter/">πρόγραμμα</a> για κάθε είδους γούστο. Εκεί, το Σάββατο 9 Απριλίου, θα γίνει και η παρουσίαση του FreeBSD Project. Φυσικά, στις παρουσιάσεις των φίλων μου της <a href="http://opensuseambassadors.blogspot.com/">κοινότητας openSUSE</a> θα είμαι μέσα και θα τους παρακολουθώ, μιας και είμαι και σε αυτή την κοινότητα μέλος, αλλά μην ξεχνάμε ότι το openSUSE είναι και η αγαπημένη μου διανομή Linux.</p>
<p>Έτσι, το Σαββατοκύριακο 9 και 10 Απριλίου μην κανονίσετε τίποτα άλλο από το να παραβρεθείτε στο openFest 2011. Θα χαρούμε πολύ να σας συναντήσουμε</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-7349834500698271432011-02-04T13:07:00.000+02:002013-08-21T19:57:15.020+03:00FOSDEM 2011<div class="separator" style="clear: both; text-align: center;">
<a href="http://fosdem.org/2011/sites/all/themes/fosdem/images/logofosdem2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="74" src="http://fosdem.org/2011/sites/all/themes/fosdem/images/logofosdem2.jpg" width="420" /></a></div>
<br />
<p>Αύριο (5 Φεβρουαρίου 2011) αρχίζει ένα μεγάλο event του ανοικτού λογισμικού στις Βρυξέλες. Η ονομασία του; <a href="http://fosdem.org/2011/">FOSDEM 2011</a>! Είναι το meeting των developers του ανοικτού κώδικα, το οποίο γίνεται κάθε χρόνο. Το event θα κρατήσει δύο ημέρες. Οι παρουσιάσεις και οι ομιλίες είναι πραγματικά ενδιαφέρουσες και ατελείωτες! Μια ματιά αν ρίξει κανείς στο <a href="http://fosdem.org/2011/schedule">πρόγραμμα</a> θα καταλάβει το επίπεδο των ομιλιών και το πλούσιο περιεχόμενό τους για κάθε γούστο.</p>
<p>Οι βαλίτσες είναι έτοιμες! Η checklist για τα πράγματα που δεν πρέπει να ξεχαστούν είναι και αυτή έτοιμη. Και είναι ακόμα νωρίς για να πάω στο αεροδρόμιο... Πραγματικά έχω μεγάλη ανυπομονησία να φτάσει η ώρα όπου θα βρεθώ στο χώρο του ULB Campus Solbosh. Εκεί είναι που σημαντικοί άνθρωπου του χώρου του ανοικτού λογισμικού θα μας εντυπωσιάσουν με τις ομιλίες τους. Και λέω "εντυπωσιάσουν" γιατί το περιεχόμενο των ομιλιών δεν μπορεί να περιγραφεί απλά από ένα άρθρο σε ένα blog...</p>
<p>Όταν το event τελειώσει και επιστρέψουμε στη βάση μας, θα δώσω και περισσότερες πληροφορίες, φωτογραφίες και ό,τι άλλο μπορέσω.</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-25276038613810067842011-01-21T17:24:00.000+02:002013-08-21T19:57:34.559+03:00Drupal 7<p>Πρίν από λίγες ημέρες βγήκε το καινούργιο <a href="http://drupal.org/">Drupal</a>. Συγκεκριμμένα στις 5 Ιανουαρίου 2011 έφτασε και αυτό στην <a href="http://drupal.org/project/drupal">έκδοση 7</a>. Έριξα μια ματιά στα ports του <a href="http://www.freebsd.org/">FreeBSD</a> μου και δεν το βρήκα. Από την άλλη αναρωτήθηκα τι θα μπορούσε να χρειάζεται για να τρέξει μέσα σε ένα FreeBSD Server έτσι ώστε να έχει την ανάγκη να γίνει ολόκληρη η διαδικασία του porting σε FreeBSD. Μιας και είναι γραμμένο σε <a href="http://www.php.net/">PHP5</a> δε θεωρώ ότι χρειάζεται κάποια τρομερή διαδικασία για να τρέξει. Με αυτές τις σκέψεις ξεκίνησα τη διαδικασία να το εγκαταστήσω και να παίξω μαζί του.</p>
<p>Αρχικά κατέβηκε στον υπολογιστή μου το .tar.gz αρχείο. Το αποσυμπίεσα μέσα στο δίσκο στον επιθυμιτό κατάλογο, ακολούθησα τις οδηγείες για την εγκατάστασή του (την παραγωγή του αρχείου settings.php, την κατασκευή της βάσης του και του χρήστη, κ.λ.π.) και ρύθμισα τον Apache μου. Στην αρχή που το ξεκίνησα έλαβα κάποια μηνύματα σφάλματος σχετικά με functions της PHP που δεν υπήρχαν στον υπολογιστή, αλλά αυτό ξεπεράστηκε με το να εγκατάσταθούν από τα ports τα κατάλληλα PHP extensions. Έτσι, κατάφερα πολύ απλά να δω την αρχική σελίδα του.</p>
<p>Εκεί σε κάποιο σημείο, το σύστημα μου παραπονέθηκε για κάποια άλλα PHP extensions που δεν είχα εγκαταστήσει στον υπολογιστή. Μόλις τα εγκατέστησα και επανεκκίνησα τον apache, ένα απλό refresh της σελίδας προχώρησε την εγκατάσταση. Τελικά δεν ήταν καθόλου δύσκολη η εγκατάστασή του. Όλα πήγαν καλά, εμπλουτίσαμε και την PHP μας με μερικά modules και όλα δουλεύουν άψογα.</p>
<p>Με μια πρώτη ματιά μπορεί κάποιος να καταλάβει ότι οι αλλαγές στο interface είναι τεράστιες από αυτό που είχα συνηθίσει. Αλλά όλα είναι απλά να τα βρεί κάποιος και να προχωρήσει στο στήσιμο ενός ωραίου Drupalάτου site! Τι μένει για μένα; Να οργανώσω λίγο τις σκέψεις μου και να δω πως θα στήσω αυτό το <i>πράμα</i> που θέλω για να κάνω τη δουλειά μου. Αν και το πρόβλημα σε αυτές τις περιπτώσεις είναι ο ελεύθερος χρόνος που δεν υπάρχει ποτέ...</p>
<p>Για όλους εσάς που είστε funs του Drupal νομίζω πως θα το ευχαριστηθείτε. Οι υπόλοιποι; Ρίξτε του μια ματιά. Πιστεύω πως θα σας ικανοποιήσει. Και το επόμενό μου εγχείρημα θα είναι το παιχνίδι με το <a href="http://wordpress.org/">Wordpress</a> (:P)</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-51166965189226651762011-01-17T13:12:00.000+02:002013-08-21T19:57:55.039+03:00Αντίστροφη μέτρηση για το openSUSE 11.4<p class="center">
<a href="http://en.opensuse.org/Portal:11.4"><img src="http://countdown.opensuse.org/11.4/medium" border="0"/></a></p>
<p>
Όσοι με γνωρίζουν, ξέρουν καλά ότι είμαι fun του Linux και ειδικότερα της διανομής openSUSE. Συγκεκριμμένα, τη διανομή αυτή την προτιμώ και την προτείνω έντονα για όποιον θέλει να ασχοληθεί σοβαρά. Ο λόγος είναι η πληθώρα εφαρμογών που περιέχει ακόμα και στη default εγκατάσταση και ειδικότερα η ύπαρξη γραφικών εργαλείων για την παραμετροποίηση του συστήματος, εύκολα και γρήγορα. Δεν είμαι αυτός που θα πει ότι η διανομή δεν έχει κουσούρια, αλλά μέσα σε όλες τις διανομές Linux που έχω χρησιμοποιήσει, αυτή είναι που με έχει τραβήξει περισσότερο από όλες τις άλλες.</p>
<p>
Ακόμα και το γεγονός ότι δεν υποχρεώνει κάποιον να χρησιμοποιήσει ένα συγκεκριμμένο γραφικό περιβάλλον από την αρχή της εγκατάστασης, για μένα είναι στα θετικά της διανομής. Πρόσφατα την έκανα εγκατάσταση σε 10 υπολογιστές στο σχολείο με γραφικό περιβάλλον XFCE για να εκμεταλλευτώ τις χαμηλές απαιτήσεις στα χαμηλών προδιαγραφών μηχανήματα της αίθουσας. Σε μερικά φιλαράκια έχω κάνει εγκαταστάσεις με γραφικό περιβάλλον KDE4, οι οποίοι, πλέον, έχουν καεί επάνω στα μηχανήματα τους! Σε έναν ακόμα φίλο εγκατέστησα το openSUSE 11.3 με γραφικό περιβάλλον GNOME γιατί αυτό είχε συνηθίσει από άλλη διανομή. Ο τελευταίος θεώρησε τη διανομή που του έβαλα, καλύτερη από αυτή που είχε.</p>
<p>
Έρχεται σιγά σιγά και ο καιρός της καινούργιας έκδοσης της αγαπημένης μου διανομής Linux. Η έκδοση 11.3 είναι πραγματικά καταπληκτική και ταχύτατη. Σε λίγο καιρό θα βγει και η έκδοση 11.4 από την οποία δεν ξέρω τι παραπάνω να περιμένω. Κάθε φορά η διανομή γίνεται ολοένα και πιο γρήγορη και γεμάτη με προιγράμματα για όλα τα γούστα. Πραγματικά δεν βλέπω την ώρα να τη δοκιμάσω και να σας πω τις εντυπώσεις μου. Μέχρι τότε λοιπόν... υπομονή!</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-11964598562727710962010-12-04T13:51:00.000+02:002013-08-21T20:03:44.321+03:00Video Παρουσίασης του FreeBSD Project στο Athens Digital Week 2010<style>
.ADWvideo {
margin-left: auto;
margin-right: auto;
text-align: center;
}
.ADWroundrect {
border: 1px solid #C0d0FF;
background-color: #FFFFF0;
border-radius: 10px;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
padding-top: 3px;
}
</style>
<p>Έπειτα από αρκετό καιρό, είναι η αλήθεια, κατάφερα και βρήκα λίγο χρόνο για να δω πως θα ανεβάσω το video της παρουσίασης στο <a href="http://www.youtube.com/">YouTube</a>. Το video είναι μεγαλύτερο σε μέγεθος απ' ότι επιτρέπει το YouTube γι' αυτό και αναγκάστηκα να το περάσω σε δύο κομμάτια...</p>
<h4 class="center">Παρουσίαση του FreeBSD Project στο Athens Digital Week 2010 - Μέρος 1ο</h4>
<div class="ADWroundrect">
<div class="ADWvideo">
<object width="380" height="304"><param name="movie" value="http://www.youtube.com/v/3hGopvaggLE?fs=1&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/3hGopvaggLE?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="380" height="304"></embed></object></div>
</div>
<br />
<h4 class="center">Παρουσίαση του FreeBSD Project στο Athens Digital Week 2010 - Μέρος 2ο</h4>
<div class="ADWvideo">
<div class="ADWroundrect">
<object width="380" height="304"><param name="movie" value="http://www.youtube.com/v/gvHeSD1aPNI?fs=1&hl=en_US"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/gvHeSD1aPNI?fs=1&hl=en_US" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="380" height="304"></embed></object></div></div>
<br />
<p>Ελπίζω να σας αρέσει, αν και το χρονικό όριο της παρουσίασης ήταν πολύ μικρό, μικρότερο απ' ότι υπολογίζαμε από την αρχή.</p>
<p>Όσο για φωτογραφίες μπορείτε να δείτε στο <a href="http://www.flickr.com/photos/eliaschr/sets/72157625045748053">flickr set μου.</a></p>
<p><i>Ηλίας Χρυσοχέρης</i></p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-44983512108584842422010-12-02T22:55:00.000+02:002013-08-21T20:06:46.100+03:00Αναβάθμιση σκληρού δίσκου σε laptop με openSUSE<p>
Μιας και τον τελευταίο καιρό οι αλλαγές σκληρού δίσκου στα μηχανήματά μου δίνουν και παίρνουν (:Ρ) είπα να κάνω και μια αλλαγή στο laptop. Βασικά τα partitions του σκληρού μου είχαν αρχίσει να γεμίζουν επικίνδυνα και έτσι χρειαζόμουν ένα μεγαλύτερο σκληρό δίσκο σε χωρητικότητα. Ο αρχικός δίσκος ήταν 320G. Οι κατατμήσεις που περιέχει είναι τέσσερις: Μια που περιέχει το backup των άθλιων Bugindow sVista (ναι καλά διαβάσατε... Το ξαναγράφω για σιγουριά: Bugindow sVista! Δεν υπάρχει λάθος ούτε στο spelling, ούτε στα κενά!) από την εταιρία του laptop, ένα που περιέχει το πλήρες άθλιο λειτουργικό που ανέφερα, αλλά απαραίτητο όταν θέλεις να εκτυπώσεις CD σε Canon εκτυπωτή (:(), και άλλα δύο για το αγαπημένο μου openSUSE που το έχω αφήσει ακόμα στην έκδοση 11.2 (Λειτουργικό + Swap).</p>
<p>
Τόσο το partition των Bugindows όσο και αυτό του Linux έχουν σχεδόν γεμίσει, των Bugindows γιατί είναι μικρό (LOL) και του Linux από ένα σωρό προγράμματα και Virtual Machines που χρησιμοποιώ. Όχι, τα downloaded files δεν βρίσκονται σε αυτό το σκληρό δίσκο, αλλά σε ένα δεύτερο που διαθέτει το laptop (Ναί, έχει δύο σκληρούς δίσκους αυτό το μικρούλι 17ιντσο!).</p>
<p>
"Καλά!", θα έλεγε κάποιος. "Και πού είναι η δυσκολία στο να αντικαταστήσεις τον σκληρό σου δίσκο;". Όχι, δυσκολία δεν υπάρχει, απλά αν περιγράψω κάποια κακώς κείμενα, κάποιος που το κάνει για πρώτη φορά ίσως αποφύγει τα μικροπροβλήματα που δημιουργούνται. Κατά τ' άλλα όλα είναι λογικά και εύκολα. Ο σκοπός μας είναι να αντιγράψουμε τα πάντα από τον ένα σκληρό δίσκο στον άλλο χωρίς ιδιαίτερο κόπο. Όταν τελικά αντικαταστήσουμε τον εσωτερικό σκληρό με τον καινούργιο θα θέλαμε το μηχάνημά μας να κάνει boot όπως ακριβώς ήταν και πριν.</p>
<h3>Τι θα χρειαστούμε αρχικά;</h3>
Η λίστα των απαραίτητων είναι μικρή:<br />
<ul>
<li>Ένα USB κουτάκι με το οποίο θα συνδέσουμε τον καινούριο σκληρό δίσκο στο μηχάνημά μας</li>
<li>Ένα <a href="http://www.clonezilla.org/download/sourceforge/">Live CD</a> με το <a href="http://www.clonezilla.org/">CloneZilla</a></li>
<li>Ένα κατσαβιδάκι για την αλλαγή του σκληρού δίσκου</li>
<li>Αρκετή υπομονή και ώρα!</li>
</ul>
<h3>Προετοιμασία για αντιγραφή των partitions</h3>
<p>
Πρώτα κατεβάζουμε το <a href="http://www.clonezilla.org/download/sourceforge/">CloneZilla</a> και το καίμε σε ένα CD. Εναλλακτικά μπορούμε να κατεβάσουμε την έκδοση για USB Flash Stick και να το έχουμε σε ένα Flashάκι. Με αυτό θα κάνουμε αργότερα boot για να αντιγράψουμε τα partitions του αρχικού σκληρού δίσκου στον καινούργιο. Η συνέχεια είναι λίγο kinky! Θα πρέπει να πω κάποια λίγα πράγματα για τον GRUB. Λίγα και βασικά! Μην περιμένετε να τον αναλύσω εξ ολοκλήρου!</p>
<p>
Κατ' αρχήν, το Linux για να δει τους σκληρούς δίσκους χρησιμοποιεί τα κλασικά device files, <tt>/dev/sda</tt>, <tt>/dev/sdb</tt> κ.λ.π. Υπάρχει, όμως, και ένας εναλλακτικός τρόπος για την πρόσβαση στους σκληρούς δίσκους. Αν μπούμε μέσα στον κατάλογο <tt>/dev/disk</tt>, θα δούμε ότι υπάρχουν κάποιοι υποκατάλογοι ακόμα. Σε ένα σύστημα openSUSE θα βρείτε τους <tt>by-id</tt>, <tt>by-label</tt>, <tt>by-path</tt> και <tt>by-uuid</tt>. Σε κάθε ένα από αυτούς τους υποκαταλόγους βλέπουμε ένα σωρό links που δείχνουν προς τα κλασικά αρχεία των συσκευών <tt>/dev/sda</tt> κ.λ.π. Ο λόγος είναι πως η ανάθεση των device files γίνεται κατά την εκκίνηση και όταν αλλάξουμε κάποιο σκληρό δίσκο, ή ακόμα και αν κάνουμε αναβάθμιση στο BIOS του υπολογιστή, αυτά τα ονόματα δεν θα δείχνουν απαραίτητα στον ίδιο σκληρό δίσκο που εμείς θα θέλαμε, με αποτέλεσμα να έχουμε διάφορες εκπλήξεις! Γι' αυτό το λόγο έχουν δημιουργηθεί και οι υποκατάλογοι μέσα στο <tt>/dev/disk</tt>.</p>
<div class="code">
<pre class="prettyprint">eliaschr@orion:~> cd /dev/disk
eliaschr@orion:/dev/disk> ls -Rl
.:
total 0
drwxr-xr-x 2 root root 380 2010-11-18 11:58 by-id
drwxr-xr-x 2 root root 100 2010-11-18 13:58 by-label
drwxr-xr-x 2 root root 220 2010-11-18 11:58 by-path
drwxr-xr-x 2 root root 140 2010-11-18 13:58 by-uuid
./by-id:
total 0
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 ata-ST9500420AS_5VJ7ND82 -> ../../sda
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 ata-ST9500420AS_5VJ7ND82-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 ata-ST9500420AS_5VJ7ND82-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 ata-ST9500420AS_5VJ7ND82-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 ata-ST9500420AS_5VJ7ND82-part4 -> ../../sda4
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 ata-WDC_WD5000BEVT-00A0RT0_WD-WX10AA9D0409 -> ../../sdb
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 ata-WDC_WD5000BEVT-00A0RT0_WD-WX10AA9D0409-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 9 2010-11-18 11:58 edd-int13_dev80 -> ../../sda
lrwxrwxrwx 1 root root 9 2010-11-18 11:58 edd-int13_dev81 -> ../../sdb
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 scsi-SATA_ST9500420AS_5VJ7ND82 -> ../../sda
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 scsi-SATA_ST9500420AS_5VJ7ND82-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 scsi-SATA_ST9500420AS_5VJ7ND82-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 scsi-SATA_ST9500420AS_5VJ7ND82-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 scsi-SATA_ST9500420AS_5VJ7ND82-part4 -> ../../sda4
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 scsi-SATA_WDC_WD5000BEVT-_WD-WX10AA9D0409 -> ../../sdb
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 scsi-SATA_WDC_WD5000BEVT-_WD-WX10AA9D0409-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 usb-Generic-_Multi-Card_20060413092100000-0:0 -> ../../sdc
./by-label:
total 0
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 Common -> ../../sdb1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 HDD -> ../../sda2
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 _OEMBP -> ../../sda1
./by-path:
total 0
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 pci-0000:00:02.1-usb-0:2:1.0-scsi-0:0:0:0 -> ../../sdc
lrwxrwxrwx 1 root root 9 2010-11-18 11:58 pci-0000:00:06.0-scsi-0:0:0:0 -> ../../sr0
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 pci-0000:00:09.0-scsi-0:0:0:0 -> ../../sda
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 pci-0000:00:09.0-scsi-0:0:0:0-part1 -> ../../sda1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 pci-0000:00:09.0-scsi-0:0:0:0-part2 -> ../../sda2
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 pci-0000:00:09.0-scsi-0:0:0:0-part3 -> ../../sda3
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 pci-0000:00:09.0-scsi-0:0:0:0-part4 -> ../../sda4
lrwxrwxrwx 1 root root 9 2010-11-18 13:58 pci-0000:00:09.0-scsi-1:0:0:0 -> ../../sdb
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 pci-0000:00:09.0-scsi-1:0:0:0-part1 -> ../../sdb1
./by-uuid:
total 0
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 0C90BD9C90BD8D28 -> ../../sda2
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 14A4F162A4F14730 -> ../../sdb1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 269cc848-3599-4559-9c2b-5494643d6b64 -> ../../sda3
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 90CEA1A2CEA180D8 -> ../../sda1
lrwxrwxrwx 1 root root 10 2010-11-18 13:58 970013ea-d703-4b36-8d77-44d9aca0ea65 -> ../../sda4
eliaschr@orion:/dev/disk>
</pre>
</div>
<p>
Αυτά όλα τα links οδηγούν στα κλασικά device files. Αλλά αυτά παράγονται από διάφορα χαρακτηριστικά που έχει ο κάθε συνδεδεμένος σκληρός επάνω στο σύστημά μας (όπως π.χ. όνομα μοντέλου, σειριακός αριθμός κ.λ.π.). Αυτά τα χαρακτηριστικά δεν άλλάζουν ανάλογα με τη σύνδεση, γιατί είναι χαρακτηριστικά του ίδιου του σκληρού δίσκου που υπάρχει στο σύστημα. Γιατί τόσος λόγος για αυτά τα αρχεία; Γιατί ο GRUB ρυθμίζεται με βάση αυτά στο openSUSE και όταν θα αλλάξουμε σκληρό δίσκο στο μηχάνημά μας θα υπάρχει πρόβλημα στην εκκίνηση.</p>
<p>
Το αρχείο το οποίο καθορίζει τις ρυθμίσεις του GRUB είναι το <tt>/boot/grub/grub.conf</tt>, ενώ από αυτό φτιάχνονται και κάποια άλλα αρχεία όπως το <tt>/boot/grub/menu.lst</tt>. Σε αυτά τα δύο αρχεία θα επέμβουμε πριν ξεκινήσουμε την αντιγραφή του σκληρού δίσκου στον καινούργιο.</p>
Πιο συγκεκριμένα, το αρχείο <tt>/boot/grub/grub.conf</tt> περιέχει τα παρακάτω:<br />
<div class="code">
<pre class="prettyprint lang-sh">eliaschr@orion:~> su
Password:
orion:/home/eliaschr # cat /boot/grub/grub.conf
# Modified by YaST2. Last modification on Tue Mar 23 13:58:50 EET 2010
# THIS FILE WILL BE PARTIALLY OVERWRITTEN by perl-Bootloader
# Configure custom boot parameters for updated kernels in /etc/sysconfig/bootloader
default 0
timeout 8
##YaST - generic_mbr
gfxmenu (hd0,2)/boot/message
##YaST - activate
###Don't change this comment - YaST2 identifier: Original name: linux###
title Desktop -- openSUSE 11.2 - 2.6.31.12-0.2
root (hd0,2)
kernel /boot/vmlinuz-2.6.31.12-0.2-desktop root=/dev/disk/by-id/ata-ST9500420AS_5VJ7ND82-part3 resume=/dev/disk/by-id/ata-ST9500420A_5VJ7ND82-part4 quiet showopts vga=0x365
initrd /boot/initrd-2.6.31.12-0.2-desktop
###Don't change this comment - YaST2 identifier: Original name: failsafe###
title Failsafe -- openSUSE 11.2 - 2.6.31.12-0.2
root (hd0,2)
kernel /boot/vmlinuz-2.6.31.12-0.2-desktop root=/dev/disk/by-id/ata-ST9500420AS_5VJ7ND82-part3 showopts apm=off noresume edd=off powersaved=off nohz=off highres=off processor.max_cstate=1 x11failsafe vga=0x314
initrd /boot/initrd-2.6.31.12-0.2-desktop
###Don't change this comment - YaST2 identifier: Original name: windows 1###
title Bugindow sVista
rootnoverify (hd0,1)
chainloader +1
orion:/home/eliaschr #
</pre>
</div>
<p>
Παρατηρούμε ότι στις παραμέτρους <tt>root</tt> και <tt>resume</tt> χρησιμοποιούνται ονομασίες κατατμήσεων από τον υποκατάλογο <tt>/dev/disk/by-id</tt>. Παρατηρούμε, επίσης, τις πρώτες γραμμές να μας προειδοποιούν ότι αυτό το αρχείο αλλάζει από κάποιο script αυτόματα, που σημαίνει ότι αν κάνουμε αλλαγές σε αυτό, κάποια στιγμή οι αλλαγές θα χαθούν. Βέβαια, τα πράγματα δεν είναι τόσο τραγικά, αλλά για να χρησιμοποιήσουμε τις ευκολίες του γραφικού περιβάλλοντος του openSUSE θα το τροποποιήσουμε από το εργαλείο <tt>Yast2</tt>.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOlXUz2QKMp-bK3ZC9o0HI55-yLRF5xWMqMTY2sTzmD7CmfvHdm49wMcMzB9am7ST3lBHRJXEFTBRW1NAwbTebDMSJxCJAQitwCjkVHmOpP56DTyZTmSVvAY0ZIYDoJG9BwpHJe-23Nl2M/s1600/01+-+Menu-Run+Yast2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOlXUz2QKMp-bK3ZC9o0HI55-yLRF5xWMqMTY2sTzmD7CmfvHdm49wMcMzB9am7ST3lBHRJXEFTBRW1NAwbTebDMSJxCJAQitwCjkVHmOpP56DTyZTmSVvAY0ZIYDoJG9BwpHJe-23Nl2M/s320/01+-+Menu-Run+Yast2.png" width="242" /></a></div>
<p>
Αρχικά, από το μενού του γραφικού περιβάλλοντος KDE4 στην καρτέλα "<i>Υπολογιστής</i>" ("<i>Computer</i>") κάνουμε κλικ στην πρώτη επιλογή, "<i>YaST</i>".</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5tauJ1kWDs2wdStT1lNdOB2dGttMQqsD6Ca_yvbojffd1mps0ZXEoY9hQsWrSVfbsZkGqvTKba32jKTyrfaqEEEcE4tMNqpF7ZIHtkDJJBPBWV3kDT26QTZQDaLlFiIgs2TozwD9M7POQ/s1600/02+-+Yast2+System+Bootloader.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5tauJ1kWDs2wdStT1lNdOB2dGttMQqsD6Ca_yvbojffd1mps0ZXEoY9hQsWrSVfbsZkGqvTKba32jKTyrfaqEEEcE4tMNqpF7ZIHtkDJJBPBWV3kDT26QTZQDaLlFiIgs2TozwD9M7POQ/s320/02+-+Yast2+System+Bootloader.png" width="320" /></a></div>
<p>
Από το παράθυρο που ανοίγει επιλέγουμε από την αριστερή στήλη το "<i>Σύστημα</i>" ("<i>System</i>") και από τις επιλογές της δεξιάς στήλης επιλέγουμε το "<i>Bootloader</i>". Τότε θα ανοίξει το ακόλουθο παράθυρο:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4gXEPvG67oxRrbz_mz7gbvUitlIbHn7Haf95cr58ZmzrrgzPiFih_c2dZb0VF7XKT9tDr5o7TsODmiVAZK-zpdgheGDNY-7gUFRtroN1dIsBH4To_fOcWZxbWp5hbSOzdW4l1z5Kxh6R4/s1600/03+-+Available+Options.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="194" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4gXEPvG67oxRrbz_mz7gbvUitlIbHn7Haf95cr58ZmzrrgzPiFih_c2dZb0VF7XKT9tDr5o7TsODmiVAZK-zpdgheGDNY-7gUFRtroN1dIsBH4To_fOcWZxbWp5hbSOzdW4l1z5Kxh6R4/s320/03+-+Available+Options.png" width="320" /></a></div>
<p>
Εκεί, μπορούμε να παρατηρήσουμε τις επιλογές που μας εμφανίζει ο GRUB κατά την εκκίνηση του υπολογιστή μας. Σε αυτές είναι που θα επέμβουμε, λιγάκι. Για να κάνουμε την επέμβαση, απλά επιλέγουμε την επιλογή που μας ενδιαφέρει και πατάμε το "<i>Edit</i>". Τότε εμφανίζεται και το ακόλουθο παράθυρο. Εκεί, φυσικά, οι δικές σας ρυθμίσεις θα είναι διαφορετικές από αυτές που φαίνονται στην εικόνα.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmOfYp7Goswd-XwH3t8hBpILOM4IFUuFeFtZJfKYAU78nEeqRBKRyHx36P7ciTZ2jXvxu0C2xgFH5NzZkN_CPZHz9H-TxdOFI52-uPCYSHgZd_41zfg8FXbL2jYqPVfGVc6gOj05rvgTu8/s1600/04+-+Before+changing+the+disk+references.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmOfYp7Goswd-XwH3t8hBpILOM4IFUuFeFtZJfKYAU78nEeqRBKRyHx36P7ciTZ2jXvxu0C2xgFH5NzZkN_CPZHz9H-TxdOFI52-uPCYSHgZd_41zfg8FXbL2jYqPVfGVc6gOj05rvgTu8/s320/04+-+Before+changing+the+disk+references.png" width="320" /></a></div>
<p>
Οι ρυθμίσεις που μας ενδιαφέρουν είναι οι <tt>root</tt> και η <tt>resume</tt>. Η πρώτη βρίσκεται στο "<i><u>R</u>oot Device</i>", ενώ η δεύτερη βρίσκεται στο "<i>O<u>p</u>tional Kernel Command Line Parameter</i>". Αυτά τα ρυθμίζουμε να περιέχουν τα standard device names ανάλογα με το partition που δείχνουν. Στη δικιά μου περίπτωση είναι αυτά που φαίνονται στην ακόλουθη εικόνα (<tt>/dev/sda3</tt> και <tt>/dev/sda4</tt> αντίστοιχα):</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz-djGkwK15BU4M9pMHoROsNo-0la4nf2IyjUZkZzsyCJB0_uCEukdapO8ohxaji9nNMIXoBcQbaThlfP0JqMQdfl7bb6I6bxTLcv1b_g56QDM9fGYFuYT4Xv4i4koyrCACHc6robzt09q/s1600/05+-+After+changing+the+disk+references.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgz-djGkwK15BU4M9pMHoROsNo-0la4nf2IyjUZkZzsyCJB0_uCEukdapO8ohxaji9nNMIXoBcQbaThlfP0JqMQdfl7bb6I6bxTLcv1b_g56QDM9fGYFuYT4Xv4i4koyrCACHc6robzt09q/s320/05+-+After+changing+the+disk+references.png" width="320" /></a></div>
<p>
Εκεί πατάμε το "<i>OK</i>" και επιστρέφουμε στην προηγούμενη εικόνα. Επαναλαμβάνουμε τα ίδια για κάθε επιλογή του GRUB, και βάζουμε στις ρυθμίσεις τις αντίστοιχες, πάντα, κατατμήσεις σε standard device names. Προσέχουμε να δείχνουν τις σωστές κατατμήσεις κάθε φορά. Στο τέλος πατάμε και σε αυτή την εικόνα το "<i>OK</i>". Ο υπολογιστής κάνει την καινούργια εγκατάσταση του GRUB.</p>
<p>
Κάτι που ΔΕΝ ΠΡΕΠΕΙ ΝΑ ΞΕΧΑΣΟΥΜΕ είναι να κάνουμε τις αντίστοιχες διορθώσεις και στο αρχείο <tt>/etc/fstab</tt>. Για να γίνουν οι αλλαγές πρέπει να είμαστε logged in σαν <tt>root</tt> χρησιμοποιώντας τον αγαπημένο μας editor, όπως π.χ. τον <tt>vi</tt>. Ένα τυπικό αρχείο με τις αλλαγές του είναι το:</p>
<div class="code"><pre class="prettyprint">
orion:/home/eliaschr # cat /etc/fstab
/dev/sda4 swap swap defaults 0 0
/dev/sda3 / ext3 acl,user_xattr 1 1
/dev/sda2 /windows/C ntfs-3g users,gid=users,fmask=113,dmask=002,locale=el_GR.UTF-8 0 0
/dev/sdb1 /windows/D ntfs-3g users,gid=users,fmask=113,dmask=002,locale=el_GR.UTF-8 0 0
proc /proc proc defaults 0 0
sysfs /sys sysfs noauto 0 0
debugfs /sys/kernel/debug debugfs noauto 0 0
usbfs /proc/bus/usb usbfs noauto 0 0
devpts /dev/pts devpts mode=0620,gid=5 0 0
orion:/home/eliaschr #
</pre></div>
<h3>Αντιγραφή των κατατμήσεων στον καινούργιο σκληρό δίσκο</h3>
<p>
Ήρθε η ώρα να κάνουμε boot το CloneZilla. Εδώ οι εικόνες που εμφανίζονται είναι, φυσικά, από εικονικό μηχάνημα γιατί αλλιώς δε θα μπορούσαμε να τις τραβήξουμε από το σύστημα την ώρα που τρέχει. Το εικονικό μηχάνημα θα μας βοηθήσει να καταλάβουμε τι κάνουμε, με τη διαφορά μόνο στις ονομασίες των σκληρών δίσκων.</p>
<p>
Αφού βάλουμε το CD του CloneZilla στον οδηγό του υπολογιστή μας, ελέγχουμε ότι το BIOS μας θα προσπαθήσει να κάνει boot πρώτα από εκεί και όχι από τον σκληρό δίσκο. Αν όλα είναι εντάξει τότε η εκκίνηση του υπολογιστή θα δείξει την ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyWFNn2d4KVxPigJltQAk0vvnu1NUh0sBuf_Bh6X9PP-d6hk-iOEeGY3iBu7jks_LTVf_xUXrJzzzxFKsC4XMnqVjvRFEeZtsvF7JZP7MKS40EyvTRwfZ9dnifKVEhteac0O2a6omZqTAB/s1600/06+-+Booting+CloneZilla.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjyWFNn2d4KVxPigJltQAk0vvnu1NUh0sBuf_Bh6X9PP-d6hk-iOEeGY3iBu7jks_LTVf_xUXrJzzzxFKsC4XMnqVjvRFEeZtsvF7JZP7MKS40EyvTRwfZ9dnifKVEhteac0O2a6omZqTAB/s320/06+-+Booting+CloneZilla.png" width="320" /></a></div>
<p>
Εδώ ξεκινάμε το CloneZilla, όπως φαίνεται και στην εικόνα. Αφού επιλέξουμε στις ακόλουθες εικόνες τη γλώσσα και το keymap του πληκτρολογίου μας (αφήνουμε τα προεπιλεγμένα) καταλλήγουμε στην εικόνα:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5mT7Cci5flCv8mNrwzHDrjDTY8CW_32kvWUpUG93UjOobgmViV6UJiDrn-v2mEtxJYg8-to_MrOTC_DCHMxlk6XTJyXZeeJDVXdVE0gSqQk_R401NylIrl7nL8spuY7Tg3UMLLBQSoook/s1600/07+-+Start+CloneZilla.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="115" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5mT7Cci5flCv8mNrwzHDrjDTY8CW_32kvWUpUG93UjOobgmViV6UJiDrn-v2mEtxJYg8-to_MrOTC_DCHMxlk6XTJyXZeeJDVXdVE0gSqQk_R401NylIrl7nL8spuY7Tg3UMLLBQSoook/s320/07+-+Start+CloneZilla.png" width="320" /></a></div>
<p>
Η επιλογή μας δε θα μπορούσε να είναι άλλη από την εκκίνηση του προγράμματος, όπως φαίνεται και η ενεργοποιημένη επιλογή. Η επόμενη ερώτηση που μας κάνει ο υπολογιστής είναι αν η αντιγραφή θα αφορά image από partition ή αν θα γίνει σε κανονικά devices απ' ευθείας. Εφόσον πάμε να αντιγράψουμε έναν ολόκληρο σκληρό δίσκο σε έναν άλλο, δε θα κάνουμε καθόλου με images των partitions. Οπότε η σωστή επιλογή είναι αυτή που φαίνεται στο στιγμιότυπο:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVrv-RToETnkhl-LQ2whJ8RP-OQkH6qHyoTYYOTzwknqV9O2YiN1LXRh3GRvLthz2IJ3WqlXoDMI8Lm89EltpSIiegR8IE9le6I-ffRqu5jmiCR-EPVZEVho_JNR_v-DYUYcd-zYgUnMSQ/s1600/08+-+Device+to+Device+cloning.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVrv-RToETnkhl-LQ2whJ8RP-OQkH6qHyoTYYOTzwknqV9O2YiN1LXRh3GRvLthz2IJ3WqlXoDMI8Lm89EltpSIiegR8IE9le6I-ffRqu5jmiCR-EPVZEVho_JNR_v-DYUYcd-zYgUnMSQ/s320/08+-+Device+to+Device+cloning.png" width="320" /></a></div>
<p>
Και για όλους εμάς που είμαστε καινούργιοι στο άθλημα του CloneZilla καλό είναι να επιλέξουμε το Beginner mode...</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh7iVRl0a-CMCw0klsWenzqL9DXKv7fYwYEOR8vk3iEQnqve3v9aFYq2x44xSHqmBke-YCwNbcQgsns79ypFEKrSjUrdbuGd9M32xpEVyx9tCT5CJan1SdIIiPXNK2dwOBoTwMizCAWunI/s1600/09+-+Beginner+Mode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="82" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh7iVRl0a-CMCw0klsWenzqL9DXKv7fYwYEOR8vk3iEQnqve3v9aFYq2x44xSHqmBke-YCwNbcQgsns79ypFEKrSjUrdbuGd9M32xpEVyx9tCT5CJan1SdIIiPXNK2dwOBoTwMizCAWunI/s320/09+-+Beginner+Mode.png" width="320" /></a></div>
<p>
Τη συνέχεια, λίγο πολύ, τη φανταζόμαστε. Επιλέγουμε αν η κλωνοποίηση θα γίνει τοπικά ή απομακρυσμένα. Φυσικά επειδή και οι δύο συσκευές σκληρών δίσκων είναι επάνω στο ίδιο μηχάνημα η κλωνοποίηση είναι τοπική. Εδώ καλό είναι να συνδέσουμε τον εξωτερικό σκληρό δίσκο στη USB θύρα πριν προχωρήσουμε. Ο παλιός σκληρός δίσκος, δηλαδή, είναι ο εσωτερικός του μηχανήματος, ενώ ο δίσκος που θα δεχθεί τα δεδομένα είναι ο εξωτερικός που συνδέουμε στη θύρα USB.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbd9FpsvBC7F9qoBqufa8hfdkCM7zHB4XjXTbNNk5SXvpAId-NfmETSFHF-uvbb4yiH8pP9dzlbna1UhE163hIkmmlg-be7o-RznbKEVzvX5SmW8NzO6IEzIgFGpGJTfjdks0tATovYPHn/s1600/10+-+Disk+to+Local+Disk+cloning.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="102" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbd9FpsvBC7F9qoBqufa8hfdkCM7zHB4XjXTbNNk5SXvpAId-NfmETSFHF-uvbb4yiH8pP9dzlbna1UhE163hIkmmlg-be7o-RznbKEVzvX5SmW8NzO6IEzIgFGpGJTfjdks0tATovYPHn/s320/10+-+Disk+to+Local+Disk+cloning.png" width="320" /></a></div>
<p>
Σε αυτό το σημείο θα επιλέξουμε τον σκληρό δίσκο από τον οποίο θα πάρουμε τα δεδομένα (Source). Είναι ο δίσκος που περιέχει τα λειτουργικά συστήματά μας και είναι συνδεδεμένος εσωτερικά στο μηχάνημα. Αυτό σημαίνει ότι θα τον βλέπουμε με το όνομα <tt>sda</tt>.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1WWoyNIpfGl1ekB3PYpuKAhCy8enYiAywXK57mKX4n2wgAtX6GAxFMMsSCXGpVPvYTopCW2tGIYGlFmsHBp6z24ketOQOe1By55hxawB7ZM1DLzH8GaYmBsMl3jyz8cQY1SmnZbqluvbq/s1600/11+-+Select+Source+Disk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="83" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1WWoyNIpfGl1ekB3PYpuKAhCy8enYiAywXK57mKX4n2wgAtX6GAxFMMsSCXGpVPvYTopCW2tGIYGlFmsHBp6z24ketOQOe1By55hxawB7ZM1DLzH8GaYmBsMl3jyz8cQY1SmnZbqluvbq/s320/11+-+Select+Source+Disk.png" width="320" /></a></div>
<p>
Όταν συνδέσαμε τον εξωτερικό σκληρό δίσκο στη θύρα USB είδαμε κάποια μηνύματα που μας έδειχναν την ονομασία του εξωτερικού σκληρού δίσκου. Σε αυτό το παράδειγμα ο εξωτερικός δίσκος είναι ο <tt>sdb</tt>. Αυτόν θα επιλέξουμε και σαν συσκευή που θα δεχθεί τα δεδομένα μας (Destination).</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6arYXvtYG_xu89F2cZ2M5duqHz4HdaVN0Kyn59_sQ2kXHzOTbEq1a0wyjairaxFwN47Xc1gZbXGGNjnnatY6oVfJBA0CjaBoxiaGSqpFQgjEO0jL_2QYzWlF3MCnP_0vpCmpR-HVmETkn/s1600/12+-+Select+Destination+Disk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="76" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6arYXvtYG_xu89F2cZ2M5duqHz4HdaVN0Kyn59_sQ2kXHzOTbEq1a0wyjairaxFwN47Xc1gZbXGGNjnnatY6oVfJBA0CjaBoxiaGSqpFQgjEO0jL_2QYzWlF3MCnP_0vpCmpR-HVmETkn/s320/12+-+Select+Destination+Disk.png" width="320" /></a></div>
<p>
Αφού πατήσουμε το <tt>OK</tt>, είμαστε στο τελευταίο σημείο πριν ξεκινήσει η κλωνοποίηση. Καλό είναι να κάνουμε έναν έλεγχο για το αν έχουμε κάνει τη σωστή επιλογή στους σκληρούς δίσκους, γιατί ένα λάθος θα μπορούσε να είναι μοιραίο για τα δεδομένα μας! Προσοχή!</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVP94bOGl3Fv8xn0a5gR3-BU2ISVIzieHCKb5pHE9rg2s7iQWWJ36vj_zowwNzqyi-OFseUTpfeSOwWkHeJJ6EKtvg8HZ8X4_jPGvhUsOxTg_DCoV9t6Pc_QihnYlOHiHaddyxohamyKwX/s1600/13+-+Disk+Cloning+Starts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVP94bOGl3Fv8xn0a5gR3-BU2ISVIzieHCKb5pHE9rg2s7iQWWJ36vj_zowwNzqyi-OFseUTpfeSOwWkHeJJ6EKtvg8HZ8X4_jPGvhUsOxTg_DCoV9t6Pc_QihnYlOHiHaddyxohamyKwX/s320/13+-+Disk+Cloning+Starts.png" width="320" /></a></div>
<p>
Η τελική μας επιλογή, αν όλα είναι σωστά, είναι να γράψουμε <tt>y</tt> και η κλωνοποίηση ξεκινάει. Τώρα έχετε πάρα πολύ χρόνο να ασχοληθείτε με οτιδήποτε άλλο εκτός από τον υπολογιστή σας... :D</p>
<h3>Τελικές Κινήσεις</h3>
<p>
Όταν τελειώσει η κλωνοποίηση μπορούμε να κάνουμε shutdown στον υπολογιστή μας. Τώρα ήρθε η ώρα να πιάσουμε κατσαβίδι στα χέρια μας και να ανταλλάξουμε θέσεις στους σκληρούς δίσκους. Δεν είναι καμιά ιδιαίτερα δύσκολη διαδικασία, όσο είμαστε προσεκτικοί σε αυτό που κάνουμε, όλα θα πάνε καλά.</p>
<p>
Μόλις γίνει η αλλαγή των σκληρών δίσκων, μπορούμε να ανάψουμε τον υπολογιστή μας ξανά. Αν όλα τα κάναμε σωστά τότε το openSUSE θα εκκινήσει κανονικά!. Το μόνο που θα παρατηρήσουμε είναι ότι η αρχική εικόνα του GRUB δεν έχει το γραφικό τμήμα, αλλά είναι όλη σε text mode. Πώς μπορούμε να το φτιάξουμε αυτό; Με μια κίνηση επανεγκατάστασης δύο πακέτων. Ας δούμε τη διαδικασία:</p>
<p>
Αρχικά τρέχουμε το YaST όπως ακριβώς κάναμε και στην αρχή του άρθρου. Εκεί θα επιλέξουμε τη "<i>Διαχείριση Λογισμικού</i>" ("<i>Software Management</i>").</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTd6EFovaS4iddufDOiSuZoYUsDEghyvJRlOnyQpJAjvBr7pM9vfO22_7g_t-sc_7afz6ujOHzL60iMimTE_U8hT1Kj4q2bqipnmfyxT7JDiyy8ti_GRNCkQeLc8TSt1vgUBcZN-nak-3J/s1600/14+-+YaST+-+Software+Management.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTd6EFovaS4iddufDOiSuZoYUsDEghyvJRlOnyQpJAjvBr7pM9vfO22_7g_t-sc_7afz6ujOHzL60iMimTE_U8hT1Kj4q2bqipnmfyxT7JDiyy8ti_GRNCkQeLc8TSt1vgUBcZN-nak-3J/s320/14+-+YaST+-+Software+Management.png" width="320" /></a></div>
<p>
Εδώ θα ψάξουμε τα διαθέσιμα πακέτα με τη λέξη <tt>grub</tt> οπότε θα μας εμφανίσει ο υπολογιστής μας 3 πακέτα. Τα δύο είναι ήδη εγκαταστημένα.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1gdUKSVWPRVakPXZGVUa-SXIuugET4q0aTZjQ9_Mg6Jn_QWi2BNJXLxhXxqddnEWtRnHdT5oWtnqsRmqB_0pJURdnwA2Fj8cJ4Olj_WqYJsMPSK_OkwX7mH7gQa2tqjLC7rhkljnLIlo/s1600/15+-+YaST+-+GRUB+Update.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1gdUKSVWPRVakPXZGVUa-SXIuugET4q0aTZjQ9_Mg6Jn_QWi2BNJXLxhXxqddnEWtRnHdT5oWtnqsRmqB_0pJURdnwA2Fj8cJ4Olj_WqYJsMPSK_OkwX7mH7gQa2tqjLC7rhkljnLIlo/s320/15+-+YaST+-+GRUB+Update.png" width="320" /></a></div>
<p>
Κάνοντας δεξί κλικ σε μια επιλογή, στο μενού που εμφανίζεται πάμε τον κέρσορα του ποντικιού μας στην επιλογή "<i>Όλα σε αυτή τη λίστα...</i>" ("<i>All in this list...</i>") και εμφανίζεται ακόμα ένα υπομενού. Η επιλογή που μας ενδιαφέρει είναι η "<i>Ενημέρωση χωρίς συνθήκες</i>" ("<i>Update unconditionally</i>"). Όταν κάνουμε την επιλογή τα δύο εικονίδια δίπλα από τα πακέτα που είναι ήδη εγκαταστημένα στον υπολογιστή αλλάζουν και μας δείχνουν ότι πρόκειται να ενημερωθούν. Πατώντας το πλήκτρο "<i>Αποδοχή</i>" ("<i>Accept</i>") που βρίσκεται κάτω και δεξιά, γίνεται η εγκατάσταση των δύο πακέτων. Μετά από αυτό, στην επόμενη επανεκκίνηση του υπολογιστή μας θα δούμε και το κλασικό γραφικό περιβάλλον του GRUB, όπως το είχαμε συνηθίσει!</p>
<h3>Αν κάτι δεν πάει καλά στην εκκίνηση του καινούργιου σκληρού</h3>
<p>
Κάτι που θα πρέπει να πω είναι ότι το openSUSE μας δίνει τη δυνατότητα να κάνουμε επιδιόρθωση του λειτουργικού μας συστήματος από το DVD εκκίνησης. Αν λοιπόν, όταν εκκινήσουμε τον υπολογιστή μας με τον καινούργιο σκληρό δίσκο, δε μπορέσουμε να δούμε την εικόνα του GRUB, τότε μάλλον κάτι έχουμε κάνει λάθος παραπάνω. Μπορούμε πάντα να επιδιορθώσουμε τον bootloader με τη βοήθεια του DVD εγκατάστασης. Αν κάνουμε από αυτό εκκίνηση του υπολογιστή τότε θα δούμε την ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJWqCW6JduXtSpiJQcXgirOWeo7Yw4K5sVgQzr0GP11Q0ZMspN4X1g81EoIeQ2KXRSqgDnV1bkwMDwU4LJFH-UovMdOut2ojjzN9ezzAivywTfRu131YfudWU1pRPCpuiEDkWwTdezSSfW/s1600/16+-+Repair+Installed+System.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJWqCW6JduXtSpiJQcXgirOWeo7Yw4K5sVgQzr0GP11Q0ZMspN4X1g81EoIeQ2KXRSqgDnV1bkwMDwU4LJFH-UovMdOut2ojjzN9ezzAivywTfRu131YfudWU1pRPCpuiEDkWwTdezSSfW/s320/16+-+Repair+Installed+System.png" width="320" /></a></div>
<p>
Η επιλογή "<i>Resque System</i>" μας βγάζει σε κονσόλα όπου έχουμε δικαιώματα υπερχρήστη. Έτσι μπορούμε να κάνουμε ότι θέλουμε στο σύστημά μας. Ενδείκνυται για τους <i>σκληροπυρηνικούς</i> τύπους, που μπορούν να κάνουν τα πάντα από την κονσόλα σε ένα σύστημα. Αν όμως δεν είστε από αυτούς, τότε μπορείτε να επέμβετε στο σύστημα λίγο πιο απλά με το εργαλείο "<i>Repair Installed System</i>", όπως φαίνεται και στην εικόνα.</p>
<p>
Για την πρώτη περίπτωση δεν έχουμε να πούμε και πολλά... Σε αυτό το how-to θα ασχοληθούμε με το εργαλείο που φαίνεται να επιλέγουμε και στο στιγμιότυπο παραπάνω. Μετά την επιλογή του θα δούμε την ακόλουθη εικόνα:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4yO2e3oEqjLBVQnFLLq_WrO2bhxmJlOWurP-ovsvqswlFpC12pZmxTIu4prKBSbtxDIlDS24Qf8hfIyHYJA-o0OyNItgcAJZPC5DK1LGvGXtvxs4gLhfpgZeRHeytSVOmIRFDRAGoi_Dz/s1600/17+-+Expert+Tools.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi4yO2e3oEqjLBVQnFLLq_WrO2bhxmJlOWurP-ovsvqswlFpC12pZmxTIu4prKBSbtxDIlDS24Qf8hfIyHYJA-o0OyNItgcAJZPC5DK1LGvGXtvxs4gLhfpgZeRHeytSVOmIRFDRAGoi_Dz/s320/17+-+Expert+Tools.png" width="320" /></a></div>
<p>
Εδώ η επιλογή "<i>Expert Tools</i>" είναι αυτή που μας χρειάζεται. Αυτή θα μας εμφανίσει αρκετά εργαλεία που θα μπορέσουμε να χρησιμοποιήσουμε για να κάνουμε επιδιόρθωση στο σύστημά μας.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPlVCCUo-nEvDAA3nQkxT5OA2VAeSgKJ6SHGxQ0cFhTCdsl-4dSSXniwuhKrJoQMx9ub2ODwSfWUYGOuh1BTD2OsawHaiVLP8ETvKihWVzYZgopTZz98wEN3PROvehJ6F4QW_Rql44n9gv/s1600/18+-+Install+New+Bootloader.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiPlVCCUo-nEvDAA3nQkxT5OA2VAeSgKJ6SHGxQ0cFhTCdsl-4dSSXniwuhKrJoQMx9ub2ODwSfWUYGOuh1BTD2OsawHaiVLP8ETvKihWVzYZgopTZz98wEN3PROvehJ6F4QW_Rql44n9gv/s320/18+-+Install+New+Bootloader.png" width="320" /></a></div>
<p>
Και η πρώτη επιλογή είναι αυτή που μας χρειάζεται! "<i>Install New Boot Loader</i>". Όταν την επιλέξουμε θα δούμε ένα αρκετά γνώριμο περιβάλλον. Είναι το YaST και συγκεκριμένα το κομμάτι του με το οποίο ρυθμίζουμε, τι άλλο, τον GRUB.</p>
<p>
Κάτω και δεξιά υπάρχει ένα πλήκτρο που ονομάζεται "<i>Ot<u>h</u>er</i>". Όταν το επιλέξουμε εμφανίζεται ένα μενού που έχει κάποιες επιλογές. Αυτή που μας ενδιαφέρει σε πρώτη φάση είναι η επιλογή "<i><u>R</u>eread Configuration from Disk</i>". Όταν κάνουμε κλικ επάνω της, θα δούμε να εμφανίζονται οι επιλογές που έχει κανονικά ο GRUB.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPToSFoT9qNedhbKi2MbzQlzUSKyeBkp2mftGF4lQNlJJ8c-9oFndqqimHC1aPTGVMuH4RMcBdeBOGOEcEX1woTFO4uchJVfLGQzneoS1GCYJHH3qF3wwBHhiVm5NVchBln4o3JSFw_7hZ/s1600/19+-+Reread+Configuration+From+Disk.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgPToSFoT9qNedhbKi2MbzQlzUSKyeBkp2mftGF4lQNlJJ8c-9oFndqqimHC1aPTGVMuH4RMcBdeBOGOEcEX1woTFO4uchJVfLGQzneoS1GCYJHH3qF3wwBHhiVm5NVchBln4o3JSFw_7hZ/s320/19+-+Reread+Configuration+From+Disk.png" width="320" /></a></div>
<p>
Επιστρέφουμε πάλι στο μενού "<i>Ot<u>h</u>er</i>" για να επιλέξουμε την τελευταία επιλογή του, "<i>Write Bootloader Boot Code to Disk</i>".</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwqJczQ7TF10JBFANvM9pXfaPDAyHpWzVnIGL3GQe1E45K8Xvk0e-WNHydjofnD_AlE7ViUvGLPZQt0-cCb0GAvDtsnct_MittM8Slk2nMdYgpj7J_a4MOf7Ol6o6uHFr_ak_Bd5IuV5eU/s1600/20+-+Write+Bootcode.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgwqJczQ7TF10JBFANvM9pXfaPDAyHpWzVnIGL3GQe1E45K8Xvk0e-WNHydjofnD_AlE7ViUvGLPZQt0-cCb0GAvDtsnct_MittM8Slk2nMdYgpj7J_a4MOf7Ol6o6uHFr_ak_Bd5IuV5eU/s320/20+-+Write+Bootcode.png" width="320" /></a></div>
<p>
Τέλος επιλέγουμε την καρτέλα "<i>Boot Lo<u>a</u>der Installation</i>" και εκεί κάνουμε τις ρυθμίσεις που φαίνονται στο ακόλουθο στιγμιότυπο:</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1gdUKSVWPRVakPXZGVUa-SXIuugET4q0aTZjQ9_Mg6Jn_QWi2BNJXLxhXxqddnEWtRnHdT5oWtnqsRmqB_0pJURdnwA2Fj8cJ4Olj_WqYJsMPSK_OkwX7mH7gQa2tqjLC7rhkljnLIlo/s1600/15+-+YaST+-+GRUB+Update.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="195" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK1gdUKSVWPRVakPXZGVUa-SXIuugET4q0aTZjQ9_Mg6Jn_QWi2BNJXLxhXxqddnEWtRnHdT5oWtnqsRmqB_0pJURdnwA2Fj8cJ4Olj_WqYJsMPSK_OkwX7mH7gQa2tqjLC7rhkljnLIlo/s320/15+-+YaST+-+GRUB+Update.png" width="320" /></a></div>
<p>
Αφού γίνουν όλα αυτά, πατάμε το "<i>OK</i>" και αφήνουμε τον υπολογιστή να εγκαταστήσει τον GRUB και πάλι. Έτσι, διορθώνουμε και το πρόβλημα του boot.</p>
<p>
Εδώ, άλλο ένα how-to τελειώνει. Ελπίζω να βοήθησα όποιον ενδιαφέρεται να "μεγαλώσει" λίγο τον σκληρό του δίσκο στο laptop. Αν έχετε openSUSE 11.3, η διαφορά είναι πως εκεί υπάρχει μόνο η επιλογή "<i>Resque System</i>" και έτσι θα έχετε να κάνετε με περιβάλλον κονσόλας, το οποίο βέβαια δεν είναι απαραίτητα κακό! Απλά, μια λίγο καλύτερη γνώση στην εκκίνηση και στα συστήματα αρχείων είναι καλό να υπάρχει, καθώς επίσης να γνωρίζεται εντολές του τύπου <tt>fdisk</tt> κ.λ.π.</p>
<p>
May the source be with you</p>
<p>
<i>Ηλίας Χρυσοχέρης</i></p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-62128171723400363602010-11-25T21:11:00.000+02:002013-08-21T20:08:09.932+03:00Το openSUSE Weekly News τεύχος 150 μεταφρασμένο<p>
Κάποιοι από εσάς μπορεί να ξέρετε ότι πριν από λίγο καιρό (βασικά αρκετό, αλλά εγώ το πήρα χαμπάρι πριν λίγο καιρό :D) συστάθηκε η ελληνική <a href="http://opensuseambassadors.blogspot.com/">κοινότητα openSUSE</a>. Παρότι τον τελευταίο καιρό είμαι λιγάκι πηγμένος (πρωτότυπο...) από τα projects που τρέχουν και δε μπορώ να συνεισφέρω τόσο όσο θα ήθελα σε αυτή την κοινότητα, είμαι κι εγώ μέλος της. Δε θα μπορούσε να είναι διαφορετικά, μιας και όσοι με γνωρίζουν προσωπικά ξέρουν ότι για μένα το <a href="http://www.opensuse.org/">openSUSE</a> είναι η αγαπημένη μου διανομή Linux.</p>
<p>
Τα παιδιά της ομάδας έχουν ήδη ξεκινήσει με πολύ ζήλο τις μεταφράσεις. Είναι αλήθεια πως τα τελευταία χρόνια η μετάφραση στα Ελληνικά ήταν λίγο ελλειπής. Το πρώτο ολοκληρωμένο αποτέλεσμα από την ομάδα είναι η μετάφραση του <a href="http://el.opensuse.org/Weekly_news">openSUSE Weekly News, τεύχους 150</a>. Η ομάδα έχει κάνει καταπληκτική δουλειά και αυτό δείχνει τη μεγάλη όρεξη που έχουν να συνεισφέρουν σε αυτό που τους αρέσει, όπως άλλωστε είναι και το πνεύμα του ανοικτού λογισμικού.</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0tag:blogger.com,1999:blog-9147006209672954597.post-70321702490244591302010-11-22T20:34:00.000+02:002013-08-21T20:08:29.734+03:002o HackFest - HackFest 21-11-2010<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh7GA3LKwgiRZz5086euDr7LOjHxGyQNHok4WNsG1nWP2ESEvRCe_A4hF4Va5HFfVCnZECwTk0JZRuHC7UAWsT7oHutOTVrB7qjcxYjsPFZ_R3D4SidZ2pzzENbkjS987NSPY989htkR6L/s1600/IMAG0216.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh7GA3LKwgiRZz5086euDr7LOjHxGyQNHok4WNsG1nWP2ESEvRCe_A4hF4Va5HFfVCnZECwTk0JZRuHC7UAWsT7oHutOTVrB7qjcxYjsPFZ_R3D4SidZ2pzzENbkjS987NSPY989htkR6L/s320/IMAG0216.jpg" width="320" /></a></div>
<p>
Την Κυριακή 21/11/2010 έλαβε μέρος το δεύτερο οργανωμένο <a href="http://hackfest.gr/">HackFest</a> της χρονιάς στην καφετέρια Floral στα Εξάρχεια της Αθήνας. Το event ξεκίνησε, όπως πάντα, κατά τις 11:00 το πρωί. Εκεί εμφανιστήκαμε ξανά, όσοι αγαπάμε το ανοικτό λογισμικό και μας ενδιαφέρει να συνεισφέρουμε όσο μπορούμε σε αυτό.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv1BQlxhGE-PaHbKuuBdCuLozcUJ8SgdNExZoYOXeh1AmzNeuX1L3DtdMA4S2-C_bKnhbWAWBVQ9xmdAqacEEveB9MgZW-Gn7tSfBHllfY2vjuGW-n2QyDrqn8ty5KUMhm2fjbgHxIQ6F9/s1600/IMAG0217.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjv1BQlxhGE-PaHbKuuBdCuLozcUJ8SgdNExZoYOXeh1AmzNeuX1L3DtdMA4S2-C_bKnhbWAWBVQ9xmdAqacEEveB9MgZW-Gn7tSfBHllfY2vjuGW-n2QyDrqn8ty5KUMhm2fjbgHxIQ6F9/s320/IMAG0217.jpg" width="320" /></a></div>
<p>
Οι συζητήσεις που έγιναν, πολλές! Επικράτησε (στην αρχή) η συζήτηση για το event που οργανώνεται στο ΤΕΙ του Πειραιά, το openFest 2011 (όταν φτιαχτεί και η σελίδα του event θα δώσω και το αντίστοιχο link). Το event θα λάβει χώρα μέσα στο Μάρτιο του 2011, δεδομένου ότι υπάρχουν και άλλα events του ανοικτού λογισμικού αργότερα, όπως η FOSSCOMM 2011 κ.λ.π. Εκεί έχω ζητήσει ήδη να κάνω μια παρουσίαση του <a href="http://www.freebsd.org">FreeBSD Project</a> που είναι ένα από τα αγαπημένα μου. Επίσης σε συνεργασία με την κοινότητα <a href="http://opensuseambassadors.blogspot.com/">openSUSE</a> μπορεί να με δείτε να κάνω κάποια παρουσίαση για την εν λόγω διανομή, ή τουλάχιστον να βοηθήσω στο στήσιμο ενός openSUSE booth. Αυτά είναι απλώς ιδέες και δεν είναι ακόμα τίποτα δρομολογημένο, αλλά οίδωμεν.</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrKiD-enXjfaPzRPqFXiZcFEc7AdH1Sjvd4XrdpLXe0_VJFgko5yZOFMQKrTgT5ddCFbn-WBhE4hqQLDRqN6DBfZYJfQvrFlauuvFSZ-wKEvrqgKPVSjlJut89FpRNQmmWho-bQd4oiSKF/s1600/IMAG0219.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrKiD-enXjfaPzRPqFXiZcFEc7AdH1Sjvd4XrdpLXe0_VJFgko5yZOFMQKrTgT5ddCFbn-WBhE4hqQLDRqN6DBfZYJfQvrFlauuvFSZ-wKEvrqgKPVSjlJut89FpRNQmmWho-bQd4oiSKF/s320/IMAG0219.jpg" width="320" /></a></div>
<p>
Όπως βλέπετε και στις φωτογραφίες, παρότι βρισκόμαστε τόσοι άνθρωποι από διαφορετικές κοινότητες και διανομές, διαφορετικού επιπέδου γνώσεων των εσωτερικών του αγαπημένου μας λειτουργικού συστήματος, φτιάχνουμε πάντα μια εύθυμη ατμόσφαιρα, με μπόλικο χαβαλέ και πειράγματα έτοιμα ο ένας για τον άλλο, αλλά ποτέ με παρεξηγήσεις. Ένα πολύ καλό χαρακτηριστικό που έχουμε είναι ότι τελικά ο ένας ενδιαφέρεται να βοηθήσει τον άλλο και όλοι μαζί να περάσουμε καλά, αλλά και να μάθουμε ο ένας από τον άλλο!</p>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbo6ZA0PGwta-5aywmaMtm3_jYoKH-aPeRzRZwgEldMi5MtsO99VTcAUg_cN75U8Awm4SzpXhM629uLwj2wt8FU7b0kRW0bod7cz6x0Jhzpr3TpmbckplNGR6HYPzK8KEAif2ML4D9OsT/s1600/IMAG0218.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" height="191" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiFbo6ZA0PGwta-5aywmaMtm3_jYoKH-aPeRzRZwgEldMi5MtsO99VTcAUg_cN75U8Awm4SzpXhM629uLwj2wt8FU7b0kRW0bod7cz6x0Jhzpr3TpmbckplNGR6HYPzK8KEAif2ML4D9OsT/s320/IMAG0218.jpg" width="320" /></a></div>
<p>
Εγώ ασχολήθηκα περισσότερο με το να ρυθμίσω μια εγκατάσταση <a href="http://software.opensuse.org/113/en">openSUSE 11.3</a> σε ένα laptop και να εξηγήσω κάποια πράγματα που έχει αυτή η διανομή. Με την συγκεκριμένη διανομή ασχολούμαι πάρα πολλά χρόνια και είμαι αρκετά ευχαριστημένος με την απόδοσή της. Έτσι, τη συνιστώ και σε άλλους και τους βοηθάω στο να καταλάβουν τι ακριβώς είναι αυτό και πως λειτουργεί. Το ίδιο έκανα και στο εν λόγω event, μιας και για άλλη μια φορά βγήκε ο "καθηγητής" από μέσα μου :-P</p>
<p>
Δυστυχώς, παρότι είχαμε μιλήσει με κάποια μέλη της κοινότητας openSUSE και ελπίζαμε να γνωριστούμε στο hackfest και να ανταλλάξουμε απόψεις σχετικά με την κοινότητα και τη διανομή, τελικά δε μπόρεσαν να έρθουν. Δεν πειράζει παιδιά. Ούτως ή άλλως θα υπάρξουν και άλλα events :-D</p>eliaschrhttp://www.blogger.com/profile/17156734589555598339noreply@blogger.com0