Posts by mbrod

    Ja, sehe ich auch so. Ich merke aber schon einen Unterschied, wenn ich mit einem Datenbank Klient direkt auf den Raspi zugreife, oder auf die Kopie auf meinem Webspace. Auf dem Raspi musste ich mehrfach schon Tabellen reparieren. Aber das ist jetzt ein anderes Thema. Danke jedenfalls.

    Seit Anfang 2017 läuft mein Monitoring Projekt auf einem Raspberry. 1 Python Skript schreibt laufend Daten von einem AD-Wandler (Photovoltaik und Akku) in eine Datenbank auf dem Raspi. Das Skript log_adc.py wird beim Start des Raspi gestartet und läuft ununterbrochen und liefert etwa 1 Datensatz pro Sekunde.

    Ein zweites Skript wird alle 2 Minuten per cron gestartet. Es konsolidiert Daten in 2 weiteren Tabellen auf dem Raspi und dupliziert diese Daten auf eine Datenbank auf meinem Webspace: cons_db_export.py

    Ein drittes Skript konsolidiert Tagesdaten.

    Das Ganze läuft all die Jahre recht störungsfrei. Vielleicht pro Halbjahr einmal, das Daten ausbleiben, die mit einem Neustart des Raspi behoben werden können.

    Es scheint allerdings automatische Software Updates des Raspis gegeben zu haben, wobei ich mich nicht erinnere, derartiges konfiguriert zu haben. Soweit ich es nachvollziehen kann, hat es bei der Behandlung von crontabs Änderungen gegeben.

    Grunddaten meines Raspis:

    pi@raspibms:~ $ lsb_release -a

    No LSB modules are available.

    Distributor ID: Raspbian

    Description: Raspbian GNU/Linux 8.0 (jessie)

    Release: 8.0

    Codename: jessie

    Hier die Konfiguration der crontab:

    pi@raspibms:~ $ crontab -l

    # Edit this file to introduce tasks to be run by cron.

    # m h dom mon dow command

    */2 * * * * /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null 2>&1

    3 0 * * * /usr/bin/python3 /home/pi/bms/cons_day_soc.py /dev/null 2>&1

    Python Prozesse:

    pi@raspibms:~ $ ps -ef | grep python

    pi 1883 1 17 Mar08 ? 18:59:30 /usr/bin/python3 /home/pi/bms/log_adc.py

    pi 4194 4190 0 22:40 ? 00:00:00 /bin/sh -c /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null 2>&1

    pi 4195 4194 1 22:40 ? 00:00:03 /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null

    pi 4202 4198 0 22:42 ? 00:00:00 /bin/sh -c /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null 2>&1

    pi 4203 4202 2 22:42 ? 00:00:03 /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null

    pi 4213 4209 0 22:44 ? 00:00:00 /bin/sh -c /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null 2>&1

    pi 4214 4213 12 22:44 ? 00:00:03 /usr/bin/python3 /home/pi/bms/cons_db_export.py /dev/null

    pi 4217 1388 0 22:44 pts/1 00:00:00 grep --color=auto python

    Zwei Dinge verstehe ich nicht:

    1. Wieso wird anscheinend zeitgleich ein zweiter Prozess gestartet?

    2. Wieso scheinen Prozesse noch nach mehreren Minuten nicht beendet zu sein?

    Ich nutze Raspbian Stretch Light. Installation lief problemlos. SSH-Zugang über WLAN im lokalen Netzwerk war ja durch wpa_supplicant.conf sofort verfügbar.

    Der RPi soll zusätzlich einen Accesspoint aufspannen, da er auch ohne Internetverbindung eine Webapplikation zur Verfügung stellen soll.

    Internetzugang über den AP ist nicht nötig.

    Nun habe ich wohl etwa ein halbes Dutzend Anleitungen ausprobiert, bei denen es nur 2 gab, wo ein AP auch sichtbar war:

    1.) ct Digitales Flugblatt. Da war ein Client auch gar nicht vorgesehen. Ich konnte mich aber mit dem AP verbinden und den RPi auch sauber wieder herunterfahren.

    2.) thepi.io. Alles außer Step 8 durchgeführt. Das Ergebnis ist, dass der RPi nach dem Booten im lokalen Netzwerk (Fritz!Box Heimnetzübersicht) erscheint. Etwa 10 Sekunden später erscheint der AP. Weitere 10 Sekunden später verschwindet der Rpi aus dem lokalen Netzwerk. Mit dem AP kann ich mich nicht verbinden. Falsche Passwörter werden abgewiesen. Mit richtigem Passwort bleibt es beim Versuch des Verbindungsaufbaus, der nicht beendet wird. Die in den Kommentaren vorgeschlagene Änderung

    Quote

    I think that, in case you are not interested on Step 8 (i.e., you just want to access your Raspberry Pi through SSH or VNC even in the absence of Wi-Fi network), you also have to avoid the two lines with denyinterfaces in /etc/dhcpcd.conf (Step 3).

    hat keine Auswirkungen auf das Verhalten.

    Da ich bei den Versuchen immer wieder "ausgesperrt" wurde, habe ich mir noch einen Zugang per USB eingerichtet: thepolyglotdeveloper. Das funktioniert einwandfrei.

    Ich habe auch dieses Thema gelesen, konnte aber keine Lösung erkennen.

    Wer kann helfen?

    Was du für nginx installieren musst ist das Paket php-fpm

    Genau! So steht es auch in der Anleitung:

    https://www.raspberrypi.org/documentation/…server/nginx.md

    Allerdings ist der Abschnitt über die Datei /etc/nginx/sites-enabled/default veraltet. Bei mir funktioniert der Abschnitt so:

    Code
    # pass PHP scripts to FastCGI server
        #
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
        
            # With php-fpm (or other unix sockets):
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            # With php-cgi (or other tcp sockets):
        #    fastcgi_pass 127.0.0.1:9000;
        }

    Die apache-Teile kamen mit der PHP-Installation!

    sudo apt-get install php Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: apache2 apache2-bin apache2-data apache2-utils libapache2-mod-php7.0 libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.2-0 php-common php7.0 php7.0-cli php7.0-common php7.0-json php7.0-opcache php7.0-readline ssl-cert

    Ja, das hat was gebracht!

    Ich lerne daraus: Vor dem Installieren neuer Pakete sudo apt-get update aufrufen.

    Installation ist soweit durchgelaufen. Allerdings bezogen sich einige Fehlermeldungen auf den Apache. Ich habe aber Nginx installiert. Kann ich das ignorieren oder muss für den Nginx ein anderes PHP-Paket installiert werden?

    Erfolgreich installiert habe ich MariaDB und Nginx. Nun wollte ich php installieren.

    Wenn ich den Befehl

    Code
    sudo apt-get install php

    eingebe, bekomme ich folgende Antwort:

    Was mache ich falsch?

    So, habe nun die Replikation der lokalen Datenbanktabelle nicht mit C sondern mit PHP realisiert. Dazu habe ich lighttpd installiert.


    Wenn Du nun in Deiner lokalen DB noch eine Tabelle anlegst, in der Du Dir die letzte Timestamp merkst, die Du in Deine Remote-DB hochgeladen hast, kannst Du einfach mittels select ... where Timestamp > UploadTimestamp die Datensätze holen und per fetch und insert in die Remote-DB einfügen.


    Das habe ich über das Feld id erledigt, welches bei jedem neuen Datensatz hochzählt. Man fragt die entfernte Datenbank nach MAX(id) ab und die lokale DB dann alle Datensätze, die größer als MAX(id) sind. Diese werden per INSERT in die entfernte Datenbank übertragen.

    local_db:

    SQL
    SELECT * FROM events WHERE id>1337


    würde z.B. liefern:

    id gpio_id event_time
    1338 1 27.07.2013 11:26:08
    1339 1 27.07.2013 11:26:10
    1340 1 27.07.2013 11:26:12
    1341 1 27.07.2013 11:26:14
    1342 1 27.07.2013 11:26:17

    Das Ergebnis würde ja zeilenweise verarbeitet werden. Also im Prinzip so:

    Code
    while(row_local){
        mysql_query(remote_db, "INSERT INTO events (id,gpio_id,event_time) 
           VALUES (row_local[id],row_local[gpio],row_local[event_time])"
    }


    row_local wäre ein assoziatives Array, wenn die MySQL-Python-API so etwas bereitstellt. Die Syntax in dem Beispiel ist natürlich nicht valide (in welcher Sprache auch?), sondern soll nur das Prinzip verdeutlichen.

    Ich hatte nicht erwähnt, dass die Datenbank des RPis zum Zählen von Impulsen per GPIO eines Stromzählers verwendet werden soll.
    Export/Import scheint mir da keine Lösung zu sein, denn pro Kilowattstunde fallen tausend Datensätze an. Export/Import verstehe ich immer als Gesamtmenge einer Tabelle, die ja nach z.B. einem Jahr schon erheblich sein kann, besonders wenn man möglicherweise alle 8 GPIOs (=8 Zähler) verwenden würde.

    Ich stelle mir vor, die externe Datenbank (remote_db) per cronjob so alle 15 Minuten zu aktualisieren. Dort auch die Visualisierung zu realisieren, sodass sie für alle Interessierten (ggf. per login) per Internet zugänglich ist. So hätte man auch eine Sicherheitskopie.

    In C bin ich halt Neuling. Mit Python habe ich auch null Erfahrung. In PHP hätte ich das wahrscheinlich ruckzuck gelöst. Die Behandlung von Zeichenketten in C ist ja schon arg umständlich. (Stringverkettung in PHP einfach nur ein Punkt.)

    Als Webserver scheint der RPi ja nicht so performant zu sein. Was man so liest. Aber für einen cronjob alle Viertelstunde, sollte es wohl reichen, kommt mir gerade so die Idee.

    Vielleicht sollte ich doch mal Apache und PHP installieren.
    Was meint ihr?

    Hallo miteinander,

    Hintergrund: Die Datensätze aus der Datenbank im RPi sollen auf eine Datenbank bei einem Webhoster repliziert werden.
    Tabellenschema:

    Code
    CREATE TABLE `events` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `gpio_id` tinyint(3) unsigned NOT NULL,
      `event_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`)
    ) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

    Prinzipielles Vorgehen: Abfrage der remote_db: last_id="SELECT MAX(id) FROM events"
    local_db: "SELECT * FROM events WHERE id>last_id". Für jedes Ergebnis soll dann ein INSERT in die remote_db erfolgen.

    Problem: Das Ergebnis durch MYSQL_ROW liegt in einem speziellen Format vor. Etwa so:
    id NULLBYTE gpio_id NULLBYTE event_time NULLBYTE.
    Wobei die Felder jeweils Zeichenketten sind, egal welches Datenbank-Format definiert ist.

    Für die Abfrage "SELECT MAX(id) FROM events" konnte ich das Problem noch lösen durch

    Code
    MYSQL_ROW  row, last_remote_id;
    char last_id[12];
    ...
    last_remote_id = mysql_fetch_row (mysql_res);
    char select[] = {"SELECT * FROM events WHERE id>"};
    sprintf(last_id,"%s",last_remote_id[0]);
    size_t len = MAX - strlen(select)+1;
    strncat(select, last_id, len);


    da dass Ergebnis in diesem Fall nur ein Feld lang ist.
    Wie bekomme ich dass bei "SELECT * FROM events" hin, dass dann 3 Felder umfasst. Also jedes Feld in eine Variable vom Typ char zu packen?

    Ihr habt mir Mut gemacht! Danke.
    So habe ich mir auch noch verschiedene Quellen angeschaut und überall ein ähnliches Muster gefunden. Dann habe ich mit copy and paste aus dreamshaders Schnipsel und Quelle1 sowie Quelle2 folgendes zusammengebaut:

    Das funktioniert :thumbs1:
    Wobei ich die daemonize- und handle_signal- Funktion nicht wirklich durchblicke. Schon erstaunlich, was alles geht, wenn man ein paar Strukturen einfach so zusammen kopiert.

    Für den Stromzähler wird der Dämon ja eigentlich nie beendet, heißt: Die Funktion mysql_close (mysql) wird nie aufgerufen. Gibt es eine Möglichkeit den Dämon "ordentlich" zu beenden, sodass auch mysql_close (mysql) aufgerufen wird? Ich habe mit sudo killall gpiod das natürlich beenden können. Dabei könnte es aber doch möglicherweise Ärger mit mysql geben, wenn das nicht ordentlich geschlossen wird. Oder?

    Na, da habe ich ja mit meiner Frage gleich eine Expertendiskussion ausgelöst, der ich mit meinen bescheidenen Kenntnissen nur peripher folgen kann.

    Und leider scheine ich ja um das Thema daemon nicht herum zu kommen, welches offensichtlich doch recht komplex ist. Werde mich mal an Hand dieser Seite der Thematik nähern. Auf der gleichen Homepage habe ich auch die Infos gefunden wie man MySQL per C anspricht.

    Wird wahrscheinlich eine Zeit dauern, bis ich das alles kapiert habe. Dann melde ich mich wieder. Aber "erledigen" werde ich das Thema erst, wenn ich den daemon ans laufen gebracht habe. (Die Forensoftware ist ja richtig streng. :daumendreh2: )

    Mit dem RPi möchte ich per GPIO jedes Blinken einer LED meines Stromzählers in eine MySQL Datenbank schreiben.
    Dank eines Code-Schnipsels von dreamshader per PN wurde ich schon mal auf den richtigen Pfad geschickt mein Ansinnen umzusetzen. Durchaus schweißtreibend, da Linux, C und vor allem gcc für mich neu sind. Bin eher bei php, Javascript und ein bisschen AppleScript zu Hause.

    Aber im Prinzip klappt schon mal folgendes:


    Mit einer kleinen LED-Testschaltung die einen Fototransistor beleuchtet, der an gpio 0 (WiringPi Nomenklatur) angeschlossen ist, werden problemlos 40 Impulse pro Sekunde in die Datenbank geschrieben. Bei 1000 Impulsen pro kWh würde das einer Momentanleistung von 144 kW entsprechen. Sollte also reichen.

    Nun, damit das Ganze dann produktiv wird, sollte das Programm ja dauerhaft laufen. (Und bei Neustart des RPi auch automatisch starten.) Das Programm mit der Endlosschleife am Leben zu erhalten, erscheint mir etwas "unelegant", und dient ja auch nur zu "unproduktiven" Testzwecken. (Bei AppleScript gibt so eine Möglichkeit "nicht automatisch beenden", um auf bestimmte Events zu reagieren.)

    Eine Möglichkeit scheint mir daemon. Aber wohl auch nicht so einfach umzusetzen.

    Vielleicht kann mir hier jemand den Weg in die richtige (unkomplizierte) Richtung weisen.
    Und die C-Profis dürfen gerne Kritik an meinem Code üben. Ich möchte mich gerne an die üblichen Konventionen halten.

    Danke dbv.
    Aus Bequemlichkeit will ich vollen Zugriff auf den Rpi von meinem Mac aus. Also auch auf den MySQL-Server mit allen Rechten über Netzwerk. Ich bin also schon per ssh mit dem Rpi verbunden. Dann starte ich den MySQL Klienten auf dem Rpi als root:

    Code
    mysql -u root -p


    Passwort sollte man bei der Installation von mysql schon vergeben haben.

    Mal schauen welche Benutzer bei der Installation eingerichtet wurden:

    Code
    mysql> SELECT Host, User, Password FROM mysql.user;


    Antwort:
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]| Host | User | Password |[/font]
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]| localhost | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| raspberrypi | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| 127.0.0.1 | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| ::1 | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| localhost | | |[/font]
    [font="Courier New"]| raspberrypi | | |[/font]
    [font="Courier New"]| localhost | debian-sys-maint | *192220CC1AF5431AD5EBF662A5D371D3992A9C26 |[/font]
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]7 rows in set (0.00 sec)
    [/font]

    Damit User root auch vom Netzwerk Zugang hat, folgendes eingeben:

    Code
    mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'some_pass' WITH GRANT OPTION;


    Wobei some_pass (wahrscheinlich) das gleiche Passwort sein muss wie bei der Installation von mysql.
    Ergebnis:
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]| Host | User | Password |[/font]
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]| localhost | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| raspberrypi | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| 127.0.0.1 | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| ::1 | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]| localhost | | |[/font]
    [font="Courier New"]| raspberrypi | | |[/font]
    [font="Courier New"]| localhost | debian-sys-maint | *192220CC1AF5431AD5EBF662A5D371D3992A9C26 |[/font]
    [font="Courier New"]| % | root | *0C0EF60C660D7DE63B04F75F2FA5DEE0080CF978 |[/font]
    [font="Courier New"]+-------------+------------------+-------------------------------------------+[/font]
    [font="Courier New"]8 rows in set (0.01 sec)
    [font="Arial"]
    Nun habe ich Zugang mit meinem Lieblingsklient "Sequel Pro".[/font][/font]

    Möchte ebenfalls mit einem externen MySQL-Client per Netzwerk auf den MySQL-Server des Rpi zugreifen.
    In der Datei "/etc/mysql/my.cnf" sah es so aus

    Code
    bind-address           = 127.0.0.1


    was im Client zur Fehlermeldung führt: "MySQL-Fehler: Can't connect to MySQL server on '192.168.178.xxx' (61)"
    Erst durch einfügen des #:

    Code
    # bind-address           = 127.0.0.1


    reagierte der Rpi auf Port 3306.
    Zwar noch mit der Fehlermeldung "MySQL-Fehler: Host 'blabla.fritz.box' is not allowed to connect to this MySQL server".
    Der MySQL-Server hat immerhin geantwortet. Das # muss also bleiben.