Σάββατο 22 Δεκεμβρίου 2018

Simple RTLSDR gui

 

Λίγα λόγια:

Το RTL-SDR είναι ένα πολύ φτηνό dongle αξίας $ 25 USB το οποίο μπορεί να χρησιμοποιηθεί ως ραδιοφωνικός σαρωτής με βάση τον υπολογιστή για λήψη ζωντανών ραδιοφωνικών σημάτων στην περιοχή σας.

 

Code explanation:

Κάνουμε import τα παρακάτω packages.
  • tkinter για το gui
  • matplotlib για graph plotting
  • numpy για αναπαράσταση των δεδομένων ως 64bit complex
  • rtlsdr για να χρησιμοποιήσουμε την rtlsdr κεραία

import matplotlib; matplotlib.use("TkAgg")
import tkinter as tk

import matplotlib.animation as anim
import numpy as np
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg,
                                               NavigationToolbar2TkAgg)
from matplotlib.figure import Figure
from rtlsdr import RtlSdr

LARGE_FONT = ("Verdana", 12)

Κατασκευάζουμε τα widgets στο application

class FrequencyGraph(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "rtlsdr-qui")

        container = tk.Frame(self)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        container.grid(row=0, column=0)

        f_station_label = tk.Label(container, text="Frequency Station", font=LARGE_FONT)
        f_station_label.grid(row=0, column=0)

        self.f_station_entry = tk.Entry(container)
        self.f_station_entry.grid(row=0, column=1)

        f_offset_label = tk.Label(container, text="Frequency Offset", font=LARGE_FONT)
        f_offset_label.grid(row=1, column=0)

        self.f_offset_entry = tk.Entry(container)
        self.f_offset_entry.grid(row=1, column=1)

        sample_rate_label = tk.Label(container, text="Sample Rate", font=LARGE_FONT)
        sample_rate_label.grid(row=2, column=0)

        self.sample_rate_entry = tk.Entry(container)
        self.sample_rate_entry.grid(row=2, column=1)

        sample_count_label = tk.Label(container, text="Sample count", font=LARGE_FONT)
        sample_count_label.grid(row=3, column=0)

        self.sample_count_entry = tk.Entry(container)
        self.sample_count_entry.grid(row=3, column=1)

        b = tk.Button(container, text="Change Settings", command=self.change_settings)
        b.grid(row=4, column=1)

        f = Figure(figsize=(5, 5), dpi=100)


Κάνουμε initialize το RtlSdr object για να αρχίσουμε να καταγράφουμε δεδομένα από την κεραία
και αρχικοποιούμε τις τιμές. Στην συνέχεια κατασκευάζουμε ένα figure canvas το οποίο το κάνουμε
associate με μια function update_plot η οποία θα ευθύνεται για να κρατάει το plot up to date.

        self.sdr = RtlSdr()
        self.ax1 = f.add_subplot(111)

        self.F_station = int(96.9e6)  # Rutgers Radio
        self.F_offset = 300000  # Offset to capture at
        # We capture at an offset to avoid DC spike
        self.Fc = self.F_station - self.F_offset  # Capture center frequency
        self.Fs = int(1140000)  # Sample rate
        self.N = int(262144)  # Samples to capture int()  8192000
        # configure device
        self.sdr.sample_rate = self.Fs  # Hz
        self.sdr.center_freq = self.Fc  # Hz
        self.sdr.gain = 'auto'

        self.f_station_entry.insert(0, "96.9")
        self.f_offset_entry.insert(0, "300000")
        self.sample_rate_entry.insert(0, "1140000")
        self.sample_count_entry.insert(0, "262144")

        samples = self.sdr.read_samples(self.N)
        x1 = np.array(samples).astype("complex64")
        self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc)

        canvas = FigureCanvasTkAgg(f, self)
        anim_void = anim.FuncAnimation(f, self.update_plot, interval=1000, blit=False)
        canvas.show()
        canvas.get_tk_widget().grid(row=0, column=1)
        canvas._tkcanvas.grid(row=0, column=1)


Η update_plot διαβάζει samples από την κεραία και κάνει update το διάγραμμα

    def update_plot(self, i):
        samples = self.sdr.read_samples(self.N)
        x1 = np.array(samples).astype("complex64")
        self.ax1.clear()
        self.ax1.psd(x1, NFFT=2048, Fs=self.Fs, Fc=self.Fc)


To change settings διαβάζει τα values από τα entry widgets και τα αναθέτει ως attributes

    def change_settings(self):
        self.F_station = float(self.f_station_entry.get()) * 10e5  # Rutgers Radio
        self.F_offset = int(self.f_offset_entry.get())  # Offset to capture at
        # We capture at an offset to avoid DC spike
        self.Fc = self.F_station - self.F_offset  # Capture center frequency
        self.Fs = int(self.sample_rate_entry.get())  # Sample rate
        self.N = int(self.sample_count_entry.get())  # Samples to capture int()  8192000
        # configure device
        self.sdr.sample_rate = self.Fs  # Hz
        self.sdr.center_freq = self.Fc  # Hz
        self.sdr.gain = 'auto'

Tέλος κάνουμε αρχικοποιούμε το graphical user interface

if __name__ == '__main__':
    app = FrequencyGraph()
    app.mainloop()

Useful links: https://www.rtl-sdr.com/about-rtl-sdr/

Πέμπτη 20 Δεκεμβρίου 2018

Project: Illumine

Project: Illumine

Ο στόχος του project Illumine είναι δημιουργήσει static APIs on the fly.

Για παράδειγμα έστω ότι κάνεις development πάνω σε ένα service A το οποίο όμως
κάνει ένα ping σε ένα άλλο service B το οποίο όμως δεν θέλεις να το ping-άρεις
για οποιονδήποτε λόγο.

Άντι να κάθεσαι να κάνεις comment-out / comment-in κάθε φορά την γραμμή που κάνει
το ping, λές στο Illumine ότι θες να απαντάει σε κάθε POST request που γίνεται στο /api/v1/health
και τι θες να περιέχει το response.

Έτσι απλά αλλάζεις μόνο το address του service που θα χρησιμοποιήσεις στο address του Illumine
και μπορείς να κάνεις development χωρίς να ανησυχείς για "τρίτα services".

Github Repo: https://github.com/gph03n1x/illumine

Τετάρτη 19 Δεκεμβρίου 2018

Quickstart Redis

O στόχος αυτού του post είναι να δείξει πως μπορείς κάποιος να τρέξει το redis μεσα από το docker και χωρίς να χρειάζεται να το κατεβάσουμε και να κάνουμε extract

About Redis

To Redis είναι ανοιχτού κώδικα in-memory δομών δεδομένων store που μπορεί να χρησιμοποιηθεί ως βάση δεδομένων ή ως message broker ή για caching. Υποστηρίζει πολλές δομές δεδομένων όπως strings, hashes, lists, sets, sorted sets, bitmaps, hyperloglogs, geospatial indexes and streams.

Για περισσότερες πληροφορίες μπορείτε να επισκευτείτε την σελίδα του redis.

Quick run

Θεωρούμε ότι ήδη υπάρχει docker στο μηχάνημα αλλά αν δεν υπάρχει μπορείτε να βρείτε εξαιρετικές οδηγίες για την εγκατάσταση του εδώ.

Προσθέτουμε το παρακάτω κομμάτι κώδικα στο .bashrc

function archives() {
     sudo docker stop archive > /dev/null
     sudo docker rm archive > /dev/null
     sudo docker run --name archive -p 6379:6379 -d redis:5.0 redis-server --appendonly yes > /dev/null
     printf "[*] Redis should be up\n"
} 

στην ουσία απλά τρέχουμε archives στο terminal κάθε φορά που θέλουμε να το σηκώσουμε.

Δευτέρα 17 Δεκεμβρίου 2018

Generating fake traffic

Για να τρέξουμε το παρακάτω πρόγραμμα χρειαζόμαστε δύο από τα παρακάτω packages
  1. requests
  2. requests[socks]
Τρέχουμε τις παρακάτω εντολές  για την εγκατάσταση των πακέτων:

pip install requests
pip install requests[socks]

Στην συνέχεια δημιουργούμε ένα αρχείο traffic.py και κάνουμε import τα παρακάτω libraries



import requests
from requests import exceptions

import random
import time

Ο κώδικας είναι πολύ απλός. Δημιουθργούμε 3 λίστες μια για proxies, μια για user-agents και μια για links.

INTERVAL = 1

PROXIES = [
    "socks5://207.154.233.200:1080",
    "socks5://139.5.27.11:9999",
    "socks5://124.65.128.150:2360",
    "socks5://107.170.42.147:28429",
    "socks5://220.79.34.109:2018",
]

USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.113 Safari/537.36",
    "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.157 Safari/537.36",
    "Mozilla/5.0 (Windows NT 5.1; rv:7.0.1) Gecko/20100101 Firefox/7.0.1",
    "Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/60.0.3112.107 Mobile Safari/537.36"
]

LINKS = [
    "https://excelsi-or.blogspot.com/2016/12/blog-post_99.html",
    "https://excelsi-or.blogspot.com/2016/07/api-documentation.html",
    "https://excelsi-or.blogspot.com/2016/06/python-3.html"
]

με το random.choice pick-άρουμε ένα item από το κάθε list

while True:
    link_to_visit = random.choice(LINKS)
    user_agent_to_use = random.choice(USER_AGENTS)
    proxy_to_use = random.choice(PROXIES)

Κάνουμε ένα request στον server και αν έχουμε κάποιο error συνήθως οφείλεται στον proxy οπότε τον αφαιρούμε από την λίστα με τους διαθέσιμους proxy


    try:
        response = requests.get(link_to_visit,
                            headers={'User-Agent': user_agent_to_use},
                            proxies={'https': proxy_to_use})
    except (ConnectionResetError, exceptions.ConnectionError):
        PROXIES.remove(proxy_to_use)
        print("Proxy removed")
    else:
        print("Request done")
        print(response)
    time.sleep(INTERVAL)

τέλος για να μην flood-άρουμε τον server κάνουμε ένα time sleep, δηλαδή μπλοκάρουμε το πρόγραμμα για 1 second.

Το αποτέλεσμα φαίνεται στην σελίδα με τα στατιστικά του blogger. Παρόλα αυτά αποτελεί μια naive υλοποίηση καθώς ένα πιο προχωρημένο analytics πρόγραμμα όπως για παράδειγμα το google analytics καταλαβαίνει ότι το traffic μας το δημιουργεί robot. Ένας απλός τρόπος να φιλτράρει αρκετά bots κάποιος είναι να δει αν ο επισκέπτης εκτελεί javascript.

Δευτέρα 26 Δεκεμβρίου 2016

Γράφοι χωρίς συντεταγμένες.


Σε μια εργασία που είχα πρόσφατα για τεχνητή 
νοημοσύνη μας δίνονταν γράφοι με την εξής μορφή:
Μπορείτε να δείτε όλοκληρο το text εδώ

και έπρεπε να εμφανίζουμε το path από ένα αρχικό 
κόμβο σε έναν τελικό κόμβο δοκιμάζοντας
διάφορους αλγόριθμους αναζήτησης όπως ο A* , 
uniform cost , depth first search , breadth first search.

Οπότε μετά το πέρας της εργασίας απέκτησα το εξής ερώτημα:

-Πως θα μπορούσε κάποιος να απεικονήσει τους παραπάνω γράφους χωρίς να γνωρίζει λεπτομέρειες όπως συντεταγμένες.

Η αρχική ιδέα ήταν να δημιουργήσω ομογενείς κύκλους με κέντρο τον κόμβο που έχει ευρετικό 0. Άρα με βάση την ευρετική τιμή του κάθε κόμβου η ευρετική τιμή θα αποτελούσε την ακτίνα του κόμβου από το 0,0 όπου βρίσκεται ο κόμβος - στόχος αυτός που έχει ευρετικό 0.
Και για να μην είναι όλοι οι κόμβοι στην ίδια ευθεία πολύ απλά ο καθένας θα έχει γωνία: (count / πλήθος των κόμβων * 2π)
Όπου το count θα ξεκινάει από το 1 και θα ανεβαίνει κατα 1 για κάθε κόμβο. O κώδικας που χρησιμοποιήθηκε είναι της παρακάτω μορφής και έβγαζε έναν γράφο όπως αυτόν

-Τό πρόβλημα με το εξής σύστημα είναι ότι οι γραμμές και οι κόμβοι τέμνονται συχνά.

Η δεύτερη ιδέα είναι ξεκινόντας από έναν κόμβο να αρχίσεις να τοποθετείς γύρω του σε έναν κύκλο όλους τους γειτονικούς του κόμβους οι οποίοι δεν έχουν ήδη τοποθετηθεί .Η φόρμουλα των γωνιών του κύκλου είναι όμοια με την παραπάνω: (count / πλήθος των γειτονικών κόμβων * 2π)


-Το κακό είναι ότι αυτή η μέθοδος λειτουργεί μόνο για γράφους των οποίων ΌΛΟΙ οι κόμβοι είναι συνδεδεμένοι στον γράφο.

Σάββατο 16 Ιουλίου 2016

ΟΑΣΑ τηλεματική API documentation

Όπως πολλοί μπορεί να έχετε δει , εδώ και αρκετό ο Ο.Α.Σ.Α. έχει προσθέσει μια καινούργια τεχνολογία σε όλες τις στάσεις των λεωφορείων, μέσα από την οποία μπορεί να μάθει κάποιος σε πόση ώρα θα βρίσκεται στην στάση το λεωφορείο που περιμένει . Επίσης έχει δημιουργήσει μια εφαρμογή για android η οποία δείχνει live και τις τοποθεσίες των λεωφορείων .

Μου κάνει ένας συνάδελφος καθώς γυρνάμε από την βόλτα μας αν θα ηταν δυνατό να χρησιμοποιήσουμε και εμείς τα δεδομένα του Ο.Α.Σ.Α.για μια δικιάς μας εφαρμογή .

Ανοίγω λοιπόν το http://telematics.oasa.gr/ και ψάχνω να βρω όλα τα linked javascript αρχεία.
Βρίσκω λοιπόν μερικά jquery αρχεία και αυτό το link (http://telematics.oasa.gr/js/script.js).
Ψάχνωντας για το εξής string "$.ajax" βρίσκω όλα τα POST requests που κάνει το script στο http://telematics.oasa.gr/api/ και στην συνέχεια αφού διάβασα λίγο τον κώδικα έφτιαξα ένα unofficial documentation (http://oasa-telematics-api.readthedocs.io/en/latest/) .


Καλή επιτυχία σε ότι φτιάξετε, όσοι το χρησιμοποιήσετε και καλό καλοκαίρι .

P.S : Για όσους θέλετε να κάνετε contribute μπορείτε να κάνετε fork από το repo μου που βρίσκεται 
εδώ

Παρασκευή 24 Ιουνίου 2016

Python 3

Ήρθε ο καιρός για την μεγάλη απόφαση . Python 2 ή Python 3 ; 

Κατά την διάρκεια του fosscomm 2016 έκανα μια παρουσίαση σχετικά με ασύγχρονο προγραμματισμό . Στην παρουσίαση λοιπόν έθεσα το παραπάνω ερώτημα , και εξήγησα ότι η Python 3 προσφέρει σημαντικές δυνατότητες που δεν υπάρχουν στην Python 2.
Θεωρώ λοιπόν ότι πλέον δεν αξίζει τον κόπο να γράφω python2 & python3 οπότε προσωπικά
θα γράφω από εδώ και στο εξής μόνο σε python3 έτσι ώστε να μπορώ να απολαμβάνω όλες τις
δυνατότητες που προσφέρει η γλώσσα χωρίς να χρειάζεται να σκέφτομαι το αν θα λειτουργεί ο κώδικας και σε python2.

Στο branch stop-words του project Hurricane άρχισα να υποστηρίζω python3 για τις νέες εκδόσεις .
και άρχισα να σχεδιάζω νέα χαρακτηριστικά όπως
  • αφαίρεση από τα δεδομένα των λεγόμενων stop-words 
  • updated urls 
  • ο crawler θα σέβεται το robots.txt 
  • καλύτερη δομή κώδικα 

Μερικοί σημαντικοί σύνδεσμοι:
http://python3statement.github.io/
http://www.snarky.ca/why-python-3-exists
https://asmeurer.github.io/blog/posts/moving-away-from-python-2/