Auslesen einer Wetter Webseite und herausfiltern von Wetterdaten

Umstellung der PYWETTER

Hallo Chacky, habe ich wie folgt geändert:

PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
MAIN_URL="http://eichenwetter.homelinux.net/linuxhd/wx.php/"
STATIONS = {
    # Stadtname auf der Seite : Name der Ausgabedatei
    # ein ',' (Komma), falls weitere Staedte folgen
    "koelnbonn": "koelnbonn.txt",
    "frankfurt": "frankfurt.txt",
    "duesseldorf": "duesseldorf.txt",
    "hahn": "hahn.txt",
    "mönchengladbach": "mönchengladbach.txt",
    "nörvenich": "nörvenich.txt"
}
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt
TIMEOUT = 60 # hoechstens 60 Sekunden auf die Daten warten
########################################################
########################################################


Leider keine Veränderung alle Text Dateien bleiben nach wie vor leer.

Aber auch dir recht herzlichen Dank ich habe auch noch keine andere Möglichkeit gefunden den Fehler zu beheben.

Gruß Stefan
 
Das Problem ist folgendes:

PHP:
url = MAIN_URL + station

Das heisst, die URL, die abgerufen wird, bildet sich aus der MAIN_URL und der Stations-ID. Im Fall von Eichenwetter müsste es daher so heissen:
PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
MAIN_URL="http://eichenwetter.homelinux.net/linuxhd/wx.php?icao="
STATIONS = {
    # Stadtname auf der Seite : Name der Ausgabedatei
    # ein ',' (Komma), falls weitere Staedte folgen
    "eddk": "koelnbonn.txt",
    "eddf": "frankfurt.txt"
#usw...
}
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt
TIMEOUT = 60 # hoechstens 60 Sekunden auf die Daten warten
########################################################
########################################################

Allerdings musst du wahrscheinlich noch den Parser anpassen, damit auch die richtigen Teile ausgelesen werden ;)
 
Zuletzt bearbeitet:
Umstellung der PYWETTER hatte Erfolg.

Mensch Männer ich bin stolz auf Euch, ehrlich.
Habe die Pywetter jetzt nochmal so eingestellt wie ihr es mir beschrieben habt.

Schwarze Beere auch dir recht herlichen Dank deine Änderung jetzt eben hat den Fehler beseitigt.

Männer es funktioniert das Projekt ist beendet, Staumeldungen laufen seit ca. 2 Stunden fehlerfrei .

Wetterseite ist auch so geworden wie ich es haben wollte.

Sollte jemand von euch in der Nähe von Köln, Wuppertal, Solingen Remscheid oder in der Eifel wohnen, und auch noch Funkamateur sein, mit der DTMF Eingabe am Funkmikrofon *BAB auf der Frequenz 144.975 im
2 Meter Band kann ab sofort die aktuellen Staumeldungen als Sprachausgabe empfangen. Sofern er denn meine Station hören kann auf dieser Frequenz und es auch mit der Leistung bis zur schafft.

Hier das richtige Script: Parser brauchte ich nicht ändern.

PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
MAIN_URL="http://eichenwetter.homelinux.net/linuxhd/wx.php?icao="
STATIONS = {
    # Stadtname auf der Seite : Name der Ausgabedatei
    # ein ',' (Komma), falls weitere Staedte folgen
    "eddk": "koelnbonn.txt",
    "eddl": "duesseldorf.txt",
    "edln": "noervenich.txt",
    "eddf": "frankfurt.txt",
    "edfh": "hahn.txt"
    }
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt
TIMEOUT = 60 # hoechstens 60 Sekunden auf die Daten warten
########################################################
########################################################
from HTMLParser import HTMLParser
from urllib2 import urlopen
import logging
LOG_FORMAT = "%(asctime)s %(levelname)s: %(filename)s : %(message)s"
DATE_FORMAT = "%d.%m.%Y %H:%M:%S"
logging.basicConfig(filename=ERRORS, format=LOG_FORMAT, datefmt=DATE_FORMAT)
class SimpleHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.parse = False
        self.parsed = False
        self.data = []
    def handle_comment(self, comment):
        if not self.parsed and "PHP" in comment:
            self.parse = True
    def handle_entityref(self, name):
        if self.parse and name == 'deg':  # HTML-Codierung fuer ° 
            self.data.append(' °') 
    def handle_starttag(self, tag, attrs):
        if not self.parsed and tag == 'p':
            self.parse = True
    def handle_endtag(self, tag):
        if tag == 'p':
            self.parse =  False
            self.parsed = True
            
    def handle_data(self, data):
        if self.parse:
            self.data.append(data)
def main():
    for station, filename in STATIONS.items():
        try:
            url = MAIN_URL + station
            parser = SimpleHTMLParser()
            parser.feed(urlopen(url, timeout = TIMEOUT).read())            
            with open(filename, 'wb') as output:
                output.write("".join(parser.data))
        except Exception as ex:
            logging.critical(str(ex))
main()

Schwarze Beere noch für dich: was meintest du mit diesem Zitat:

Zitat von SchwarzeBeere
Die von dir verlinkte Seite nutzt das stark veraltete Skript PHPWeather (welches nicht mehr verwendet werden sollte!), um sogenannte METAR-Daten zu verarbeiten (siehe HTML-Code).

Warum sollte man dies nicht nutzen ? Danke für deine Antwort.

Gruß Stefan :wink:
 
Wenn keine Staumeldungen vorliegen????

Hallo Männer der Ahnung:

Würde gerne das Script der Staumeldungen um einen Eintrag erweitern:

Könnte man das so ergänzen wenn keine Staumeldung vorliegt, dass er in der Ausgabe aufführt:

Zur Zeit liegen keine Verkehrsnachrichten vor, eine gute und sichere Fahrt wünscht Stefan.


Hier das Script der Verkehrs-Warnmeldung:


PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
MAIN_URL = "http://www.radionrw.de/verkehr/vknrw.htm"
OUTPUT = "nrwverkehr.txt"
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt
TIMEOUT = 60 # hoechstens 60 Sekunden auf die Daten warten
########################################################
########################################################
from HTMLParser import HTMLParser
from urllib2 import urlopen
import logging
LOG_FORMAT = "%(asctime)s %(levelname)s: %(filename)s : %(message)s"
DATE_FORMAT = "%d.%m.%Y %H:%M:%S"
logging.basicConfig(filename=ERRORS, format=LOG_FORMAT, datefmt=DATE_FORMAT)
class SimpleHTMLParser(HTMLParser):
    def __init__(self):
        HTMLParser.__init__(self)
        self.parse = False
        self.data = []
    def handle_entityref(self, name):
        if self.parse and name == 'deg':  # HTML-Codierung fuer ° 
            self.data.append(' °') 
    def handle_starttag(self, tag, attrs):
        if tag == 'strong':
            self.parse = True
    def handle_endtag(self, tag):
        if tag == 'strong':
            self.parse =  False
 
    def handle_data(self, data):
        if self.parse:
            self.data.append(data)
def main():
        try:
            url = MAIN_URL
            parser = SimpleHTMLParser()
            parser.feed(urlopen(url, timeout = TIMEOUT).read())
            data = "\n".join([line for line in parser.data if line != ' '])            
            data = data.replace("\r\n",'')
            data.decode('iso8859_15').encode('utf-8')
 
            with open(OUTPUT, 'wb') as output:
                output.write(data)
        except Exception as ex:
            logging.critical(str(ex))
main()
Hintergrund ist das Programm Balabolka meckert da kein Text zum Vorlesen vorhanden is,t möchte er das ich den Cursor bis an eine Stelle füge wo der Text anfängt, da aber kein Text vorhanden ist bleibt er dann so lange dort stehen bis was eingegen wird, deshalb der Nachtrag.



Danke für eure Unterstützung!
 
Zuletzt bearbeitet:
Erstmal etwas Organisatorisches:
Unter "Kontrollzentrum -> Einstellungen ->Einstellungen ändern"
lässt sich ein Thread abonieren sowie automatische Benachrichtigung per Mail bei Antworten einschalten:
attachment.php
ferner sieht man dann direkt in seinem Kontrollzentrum, ob es etwas Neues gibt:
attachment.php
Man muss dann nicht immer direkt im Thread vorbeischauen, ob es eine neue Antwort gab.

Etwas weiter unten geht es zu den Einstellungen des Posting-Editors:
attachment.php
WYSIWYG Editor ist schon ganz ok (sofern man Javascript erlaubt hat) und unterstützt einen bei den ganzen "[ CODE], [ QUOTE]" usw. Geschichten (man markiert z.B den Text, klickt auf
quote.png
und schon werden die Tags [ QUOTE ] [ /QUOTE] drumherum eingefügt (genauso mit Code, Bildern usw.).

Ferner hat dieser Editor noch 2 Buttons:
resize_0.png

resize_1.png

Womit man das Antworteingabefeld vergrößern kann.
Und zumindest unter Chrome habe ich noch so eine "Ecke"
attachment.php
damit lässt sich das Antwortfeld gleich beliebig groß ziehen

Also ich haben den Apache damals ordnungsgemäß aufgesetzt und entsprechende Verzeichnisse etc. umbenannt, gut wäre es aber wenn du mal deine Erfahrung einbringst und mir etwas per Mail sendest wenn ich was vergessen habe, Danke.)
Wie gesagt, das war eher ein obligatorischer Hinweis. Ich habe nur gesehen, dass z.B WebDav:
http://eichenwetter.homelinux.net/webdav/ aktiv ist (und vermutlich einiges mehr, da bei solchen Softwarepaketen vieles "inclusive" ist und mitgestartet wird.

weatherman hat gesagt.:
habe die Zeile 142 gefunden hier die Änderung von mir:
PHP:
$HTTP_SESSION_VARS['pref_units'] = 'only_metric';
    new pw_option_select('pref_units',
                         'You may choose to display the data in several ' .
                         'formats. Please choose one that fits your need.',
                         false,
                         array('both_metric'   => 'Metric first, then imperial',
                               'both_imperial' => 'Imperial first, then metric',
                               'only_metric'   => 'Only metric',
                               'only_imperial' => 'Only imperial'));
Das war eher so gemeint, dass man diese Configuration im Browser aufruft (URL: /weatherphp/config/index.php), einstellt und eine "defaults.php" geliefert bekommt, die man dann im "weatherding-Ornder" platziert.
Meine, aus dem vorherigen Posting, habe ich genauso generieren lassen. Also nicht die config-php Dateien direkt ändern ;).


habe die Zeile unter 671 exakt angepasst auch mit date ändert sich leider nichts.
Ich meine, es hat schon geklappt, war allerdings etwas spät am Abend. Sonst würde ich es lassen - die Zeiteinheiten werden nämlich intern für einige Umrechnungen gebraucht (z.B für die "von vor 16 Minuten um" Meldung) - da etwas auf Geratewohl zu ändern, könnte dies kaputt machen (ich hatte z.B nach irgendeiner Änderung die Meldung "von vor 32949 Stunden" erhalten ;) ).

weatherman hat gesagt.:
habe eben mal den Inhalt der pywetter geändert auf meinen Link:

Leider bleiben jetzt die Flughafentextdateien ohne Füllung.
Ich wusste, ja dass ich irgendetwas vergessen hab' ;). Die Lösung von SchwarzeBeere ist richtig - das Script will einfach eine gültige URL haben. Während das bei flughafenwetter.eu einfach "flughafenwetter/stadt" lautete, wird das bei diesem PHP Script einfach als Paramter angehangen: "eichenwetter.homelinux.net/linuxhd/wx.php?icao="

SchwarzeBeere hat gesagt.:
Allerdings musst du wahrscheinlich noch den Parser anpassen, damit auch die richtigen Teile ausgelesen werden
Soso, an meinen PHP-Skillz zweifeln :evil: ? Ich schreibe doch nix, was mit meinem Script vollkommen inkompatibel ist. Wobei ich zuerst daran dachte, direkt eine Textdatei genrieren zu lassen - allerdings ist Trennung von HTML und Ausgabe in dem Wetterframework nicht wirklich gegeben (und irgendwas muss das Script eher regelmäßig aufrufen). Also tut es auch das Pythonscript, welches einfach den Inhalt des ersten <p></p> Blocks ausgibt.


weatherman hat gesagt.:
Könnte man das so ergänzen wenn keine Staumeldung vorliegt, dass er in der Ausgabe aufführt:
Jep, die Ausgabe für "nix" konnte ich zu dem Zeitpunkt nicht testen.
Das sollte funktionieren:
Nach Zeile49, "data.decode('iso8859_15').encode('utf-8')" und vor "with open.."
Code:
if not data.replace("\n",""):
                data = "Zur Zeit liegen keine Verkehrsnachrichten vor, eine gute und sichere Fahrt wuenscht Stefan."
einfügen. So sieht der Abschnitt dann aus:
Code:
...
def main():
        try:
            url = MAIN_URL
            parser = SimpleHTMLParser()
            parser.feed(urlopen(url, timeout = TIMEOUT).read())
            data = "\n".join([line for line in parser.data if line != ' '])            
            data = data.replace("\r\n",'')
            data.decode('iso8859_15').encode('utf-8')
            if not data.replace("\n",""):
                data = "Zur Zeit liegen keine Verkehrsnachrichten vor, eine gute und sichere Fahrt wuenscht Stefan."

            with open(OUTPUT, 'wb') as output:
                output.write(data)
        except Exception as ex:
            logging.critical(str(ex))

main()
Und bevor ich das vergesse:
weatherman hat gesagt.:
Code:
if self.parse and name == 'deg':  # HTML-Codierung fuer ° 
            self.data.append(' °')
Dieses Sonderzeichen  könnte ein Problem für die Sprachausgabe sein. Die Ursache dafür ist ein Editor, der auf utf-8 pfeift und einfach im ASCII Modus öffnet. Entweder editiert man die Pyscripte in einem Editor, der UTF-8 beherrscht (z.B http://www.flos-freeware.ch/notepad2.html ) oder ersetzt
"self.data.append(' °')"
durch
self.data.append(' Grad') (was für die Sprachausgabe hoffentlich keinen Unterschied zum Zeichen macht)
 
Die Software ist einige Jahre alt und wird nicht mehr aktiv maintained. Deswegen existieren u.a. auch einige bekannte Sicherheitslücken und Bugs, die nicht mehr behoben werden, z.B. PHP Weather / Bugs / #51 Multiple Vulnerabilities with PHPW und PHP Weather Multiple Vulnerabilities - Securelist


Es wird auch zum Bsp nicht mehr von allen PHP Versionen/Apacheconfigs folgende deklatration unterstützt ist zwar nur ein kleines das zu ändern, lässt sich aber bestimmt im Script noch mehr nicht mehr genutze sachen finden wie "Register Globals, Magic Quotes etc"

Code:
"$HTTP_SESSION_VARS['pref_units'] = 'only_metric';"
 
Homepageseite erweitert auf alle Flughäfen läuft prima.

Hallo cdw, habe die Einstellungen entsprechend geändert, muss jetzt mal warten bis die Verkehrsseite leer bleibt. Super und Danke.

Ich habe jetzt mal die index.php in phpweather_de angepasst schau mal bitte:

PHP Weather - test


Wie kann ich jetzt noch die Hintergrundfarbe von weiss auf meinen Higru anpassen, hatte mal den Kram von der wx.php kopiert aber der meldet dann den Fehler dass es in der zeile 142 bereits ein text/html gibt, geht auch nicht noch ein styles mit /text/css ja klar.
Aber was müsste ich setzen um einen gleichen Farbton zu erhalten?

Die ursprüngliche wx.php habe ich auch angepasst mit einem entsprechenden Erweiterungslink zur index.php so hat man dann beides.
Gut oder???? sieh mal :

http://eichenwetter.homelinux.net/linuxhd/wx.php

Dann habe ich mir die XAMPP Geschichte mal zur Brust genommen und so einiges zu gemacht. Nochmal Testen bitte ging ja um webdav, mercury, filezilla etc. habe auch einíge Rottpw eingerichtet.

ich hoffe so ists save.

Schönen Tach auch Gruß aus der Eifel Stefan
 
Zuletzt bearbeitet:
Hallo cdw, habe die Einstellungen entsprechend geändert, muss jetzt mal warten bis die Verkehrsseite leer bleibt. Super und Danke.
Ich hab's gestern noch die Uhrzeit erwischt, als keine es keine Verkehrsmeldungen gab - das läuft :)

Sicherheitstechnisch: bitte zumindest den config Ordner (samt Inhalt) sowie "test.php" im phpweatherordner löschen.
Mittels der test.php kann man beliebige Scripte, die sich auf dem Server befinden, ausführen (gerade testweise "index.php" der Hauptseite über Wetterausgabe "nochmal" ausgeführt - da gehen natürlich auch andere Scripte, alles was erraten werden kann).

Ich habe jetzt mal die index.php in phpweather_de angepasst schau mal bitte:
PHP Weather - test


Wie kann ich jetzt noch die Hintergrundfarbe von weiss auf meinen Higru anpassen, hatte mal den Kram von der wx.php kopiert aber der meldet dann den Fehler dass es in der zeile 142 bereits ein text/html gibt.
in der index.php, Zeile 20, statt einfach <body>
HTML:
<body style="background:#DFA56A; color: #000000;">

Die ursprüngliche wx.php habe ich auch angepasst mit einem entsprechenden Erweiterungslink zur index.php so hat man dann beides.
Gut oder???? sieh mal :

http://eichenwetter.homelinux.net/linuxhd/wx.php
Sieht doch ganz gut aus, wobei mir z.B auffällt, dass auf der Wetterbericht im Erweiterungslink keine Füße/Fahrenheitangaben hat ;). Ggf. also die defaults.php in den gleichen Ordner wie wx.php kopieren.


Edit: bitte keine "Fullquotes" (also komplette Beiträge) zitieren. Das ist bei einem Forum unnötig, weil man die Beiträge auch so nachlesen kann ;)
 
Sprachausgabe erkennt doch hochgestelltes o oder GradC

Hallo CDW, bin schon wieder ein Stück weiter, allerdings hattest du Recht mit deiner Angabe:

Citat:

Code:
Und bevor ich das vergesse:

Zitat:
Zitat von [B]weatherman[/B] 
[I]Code:
if self.parse and name == 'deg':  # HTML-Codierung fuer °             self.data.append(' °')
[/I]

Dieses Sonderzeichen  könnte ein Problem für die Sprachausgabe sein. Die Ursache dafür ist ein Editor, der auf utf-8 pfeift und einfach im ASCII Modus öffnet. Entweder editiert man die Pyscripte in einem Editor, der UTF-8 beherrscht (z.B [url=http://www.flos-freeware.ch/notepad2.html]flo's freeware - Notepad2[/url] ) oder ersetzt
[PHP] 
 "self.data.append(' °')"
durch
self.data.append(' Grad')                                                                
[/PHP]
 (was für die Sprachausgabe hoffentlich keinen Unterschied zum Zeichen macht)

Leider macht es doch einen Unterschied, egal wie man es händelt, macht man mit Notepad2 die Sache auf erkennt er das ° zwar ordnungsgemäß liesst es aber in der Ausgabe als "hochgestelltes O " vor.

Zieht man sich den Text Original von meiner Flughafenseite setht er dort ja ordnungsgemäß mir einem Leerzeichen zwischen der Temperaturzahl und dem Grad siehe hier:

Code:
[B]Koeln / Bonn, Germany[/B]: Letzter Wetterbericht erstellt [B][U]vor 10 Minuten[/U][/B] um [B]09:20[/B] Uhr. Der Wind erreichte eine Geschwindigkeit von [B]4.6[/B] Kilometer pro Stunde und kam aus Richtung [B]West[/B] ([B]270°[/B]). Die Temperatur betrug [U]9 °C bei einem Taupunkt von 7 °C.[/U] Der Luftdruck stand auf [B]1000[/B] Hektopascall. Die relative Luftfeuchtigkeit erreichte [B]87.3%[/B]. Bewölkung: [B]aufgelockert bewölkt[/B] in der Höhe von [B]244[/B] m und [B]durchbrochene Bewölkung[/B] in der Höhe von [B]366[/B] m. [B]bewölkt[/B] [B]671[/B] m Die Sichtweite reichte [B]6.0[/B] km. Zur Zeit [B]mittel Regen[/B].
Das heisst im Text gibt es ein Leerezichen zwischen 9_°C und z.B. 7_°C
ersetzt man in der pywetter jedoch den selfdata append durch das Wort Grad dann liest er dies als ein Wort mit einzelnen Buchstaben, das heisst Balabolka buckstabiert jetzt GradC als jeden einzelnen Buchstaben weil das Leerzeichen fehlt. Komisch allerdings beim Taupunkt liest er es wieder richtig vor.mmmmhhhh...komisch
Ausserdem müsste man irgendwie noch den Eintrag herausfiltern:
vor 10 Minuten

Es würde reichen wenn man hört, Letzter Wetterbericht erstellt um und dann die letzte Zeit meiner Seite, es kommt sonst zur Verwirrungen hinsichtlich der Zeitangaben weil die pywetter als batch immer zu bestimmten Zeitabständen aufgerufen wird.


Du kannst es aber hier auch mal hören:

http://eichenwetter.homelinux.net/linuxhd/airport/eddk.wav

Gruß Stefan

Erweiterung : Habe in der pw_text_de.php die entsprechende Zeile gefunden und die Uhrzeit herausgenommen, wäre naturlich auch möglich, den String für die reine Uhrzeit habe ich noch nicht gefunden.

Es sieht jetzt so aus:
PHP:
function pw_text_de($weather, $input = array())
     {
    $this->strings['charset']                  = 'ISO-8859-1';
    $this->strings['no_data']                  = 'Für  %s%s%s stehen zur Zeit keine DATEN zur Verfügung.';
    $this->strings['list_sentences_and']       = ' und ';
    $this->strings['list_sentences_comma']     = ', ';
    $this->strings['list_sentences_final_and'] = ', und ';
    $this->strings['location']                 = '%s%s%s:'; //Ortsname
    $this->strings['minutes']                  = ' Minuten';
    $this->strings['time_format']              = 'Letzter Wetterbericht [B][U]erstellt vor %s . [/U][/B]';  // rohe Daten ??
    $this->strings['time_minutes']             = 'und %s%s%s Minuten';
    $this->strings['time_one_hour']            = '%seiner%s Stunde %s';
    $this->strings['time_several_hours']       = '%s%s%s Stunden %s';
    $this->strings['time_a_moment']            = 'im Moment';
    $this->strings['meters_per_second']        = ' Kilometer pro Stunde '; // bei Änderung hier ändern
 
Zuletzt bearbeitet:
Also irgendwie hast Du die Uhrzeitausgabe "kaputt" gemacht - es wird jetzt keine Uhrzeit ausgegeben. Eventuell mal den Inhalt des original "output" Ordners in den aktuellen kopieren, damit das wieder funktioniert.


Hallo CDW, bin schon wieder ein Stück weiter, allerdings hattest du Recht mit deiner Angabe:

Leider macht es doch einen Unterschied, egal wie man es händelt, macht man mit Notepad2 die Sache auf erkennt er das ° zwar ordnungsgemäß liesst es aber in der Ausgabe als "hochgestelltes O " vor.
Wenn man das Script schon vorher mit einem Editor (Windows-Notepad?) bearbeitet hat, hilft auch das öffnen mit Notepad2 nichts mehr - es wurde als "irgendwas" gespeichert.

Zieht man sich den Text Original von meiner Flughafenseite setht er dort ja ordnungsgemäß mir einem Leerzeichen zwischen der Temperaturzahl und dem Grad siehe hier:
...
Das heisst im Text gibt es ein Leerezichen zwischen 9_°C und z.B. 7_°C
Nein, original steht da:
Code:
Die Temperatur betrug <b>10</b> °C bei einem Taupunkt von <b>8</b> °C.
der Browser rendert bei der Anzeige allerdings &nbsp zu einem Leerzeichen und &deg zum ° ;). Und das muss man für die Text-Datei der Sprachausgabe auch (irgendwie) machen - mittels richtiger Kodierung.

Die Kodierungen sind so eine Geschichte (ohne jetzt die Hand für Vollständigkeit oder historische Korrektheit ins Feuer legen zu wollen) - die ganzen Kodierungen sind prinzipiell nix anderes, als Tabellen mit einer Zuordnung "Zahl <-> Bild mit Zeichen, das auf den Monitor gemahlt wird".
Leider war die Entwicklung bis zu einem allgemein akzeptierten Standard (Unicode) "etwas" chaotisch (sprich: jeder wie er lustig war :rolleyes: ) so gibt es immer noch ASCII aus den 1960gern, Codepages wie z.B cp850 aus DOS Zeiten, cp1252 aka Windows-1252 aka "MS erweiterung der ISO8859" (bis jetzt) neben eigentlichen "modernen" Standards). Und da die modernen Zeichensätze i.d.R kompatibel zu ASCII sind, machen insbesondere englischsprachige Entwickler hartnäckig Fehler bzw. bleiben bei uralten Standards (die aktuelle Normierung von Unicode/UTF-8 hat schon ein Jahrzehnt auf dem Buckel, vorgestellt wurden diese vor 20 Jahren).

Lange Rede kurzer Sinn:
Das Problem ist nämlich: ° ist nicht in ASCII enthalten. Und in verschiedenen Kodierungen hat es unterschiedliche Zuordnungen - k.A welche davon die Sprachausgabe nun haben mag oder versteht. Daher habe ich das Script mal erweitert:
Code:
OUTPUT_ENCODING = "Windows-1252"  # "Windows-1252" "utf-8" "cp850"
hier stehen die möglichen Kodierungen (hinter "#" was in Python ein Kommentar einleitet - falls es mit der Voreinstellungen "Windows-1252" nicht klappt, einfach eine andere kopieren und bei "OUTPUT_ENCODING =" einsetzen, dann das Script ausführen und die Textdatei mit Balabolka testen).
Ferner sollte es jetzt nichts ausmachen, das Script mit einem "falschen" Editor zu öffnen, da nun im Code statt "°" eine Zahl steht.

Die andere Scriptversion sollte aber noch sicherer sein - hier wird "°" durch "Grad" ersetzt und "GradC" durch "Grad Celsius" ;)

Ausserdem müsste man irgendwie noch den Eintrag herausfiltern:
vor 10 Minuten

Es würde reichen wenn man hört, Letzter Wetterbericht erstellt um und dann die letzte Zeit meiner Seite, es kommt sonst zur Verwirrungen hinsichtlich der Zeitangaben weil die pywetter als batch immer zu bestimmten Zeitabständen aufgerufen wird.

Ausgabe ohne "vor", nur "um 16:50 Uhr."
In pw_text_de.php:
Zeile30:
Original
PHP:
    $this->strings['time_format']              = 'Neuester Wetterbericht von vor %s um %s%s%s Uhr. ';  // rohe Daten ??
neu:
PHP:
$this->strings['time_format']              = 'Neuester Wetterbericht um %s Uhr. ';
Die Formattierung findet im pw_text.php statt:
Zeile 673:
PHP:
    return sprintf($this->strings['time_format'],
                   $time_ago,
                   $this->properties['mark_begin'],
                   $gmtime,
                   $this->properties['mark_end']);
ersetzen durch:
PHP:
    return sprintf($this->strings['time_format'],  $gmtime);
Ausgabe in Form von "um 16 Uhr 50 Minuten." oder (falls Minuten = 00) "um 16 Uhr".
pw_text.php
Zeile 671 bis 678, neuer Inhalt
PHP:
$gmtime = date('H:i', $time);
    $time_array = explode(':', $gmtime,2);
    if ($time_array == FALSE){
        $time_array = "unbekannt";
    }
    return sprintf($this->strings['time_format'], $time_array[0]) . ($time_array[1] == '00' ? '.' : ($time_array[1].' Minuten.'));
pw_text_de.php, Zeile 29, neue Inhlat:
PHP:
    $this->strings['time_format']              = 'Neuester Wetterbericht um %s Uhr ';
 
Alles geändert es läuft wie ein Länderspiel ***TOP***

Hörmal CDW was hat du denn gelernt, doch bestimmt Programmierer.
Äh Mann das ist top, es läuft sehr gut und alles ist in Ordnung.
Habe die pw_text_de noch ein bischen angepasst, es klingt so deutlich besser, werde ich mal weiter beobachten, es gibt ja noch andere Wetteransagen, zu anderen Jahreszeiten die mache ich mir dann so wie es am besten klingt.


Eine aller letzte Bitte noch, kann man das Wort Germany noch entfernen am Textanfang hinter dem Flughafen ich meine das hier:

Code:
[B]Koeln / Bonn, [U]Germany[/U][/B]: Letzter Wetterbericht

Ers spricht das so komisch weils english ist....Lächel

Dann gehe ich dir auch nicht mehr auf den Wecker, ehrlich es reicht dann auch...

gruß Stefan:):wink:
 
Das Übersetzungen dazu sind im Unterordner db\files\stations.db "versteckt".
Die stations.db kann man mit einem Texteditor öffnen, Inhalt ist dann:
Code:
...
EDDB:Berlin-Schoenefeld:Germany:DE                                                                                             
EDDC:Dresden-Klotzsche:Germany:DE                                                                                              
EDDE:Erfurt-Bindersleben:Germany:DE 
...
Mit "Bearbeiten->Ersetzen" kann man dann alle "Germany" Einträge durch "Deutschland" ersetzen.
 
Na ganz so einfach ist es dann wohl doch nicht !

Hallo CDW,

habe die Datei mal angeschaut und versucht mit verschiedenen Tricks etwas abzuändern.

Code:
EDDK:Koeln / Bonn:Germany:DE


Und zwar passiert da folgendes:

Wenn man die EDDK Zeile mit dem Wort Germany durch Deutschland ersetzt, schmeißt er da etwas durcheinander, ist aber so gesehen auch nicht kritisch, er schreibt dann nämlich nur noch die Kurzbezeichnung des Flughafens hin, und der Wetterbericht beginnt dann wie folgt:

EDDK Letzter Wetterbericht von .....usw.

Würde bedeuten die Ortsbezeichnung in diesem Fall Köln Bonn wird herausgefiltert, ich kann mir auch denken woran das liegt....
Das Script sucht in der "Ursprungsdatenbank" nach EDDK:

http://weather.noaa.gov/pub/data/observations/metar/decoded/EDDK.TXT

Da in diesem Textfile

Code:
Koeln / Bonn, [U]Germany[/U] (EDDK) 50-52N 007-10E 100MMay 31, 2013 - 07:50 AM EDT / 2013.05.31 1150 UTCWind: from the N (360 degrees) at 9 MPH (8 KT):0Visibility: greater than 7 mile(s):0Sky conditions: mostly cloudyWeather: light rainTemperature: 62 F (17 C)Dew Point: 53 F (12 C)Relative Humidity: 72%Pressure (altimeter): 29.77 in. Hg (1008 hPa)ob: EDDK 311150Z 36008KT 9999 -RA FEW035 SCT080 BKN130 17/12 Q1008 NOSIGcycle: 12

jedoch das Wort Germany fehlt, vermute ich mal dass er dann einfach nur noch EDDK auf meiner Seite stehen lässt. Deshalb habe ich zunächst mal den Urzustand wieder hergestellt, da er die Buchstaben mit Balabolka wieder einzeln vorliest und Leute die mit Flughafenwetter nix zu tun haben, den Begriff EDDK ja eh nicht kennen.

Aber ich sage mal so, ich kann damit leben , wollte dir nur nochmal eine Rückmeldung geben.

Gruß Stefan


[/QUOTE]
 
Ok, eine "dreckige", aber funktionierende Lösung wäre in der Ausgabe das Wort "germany" durch Deutschland zu ersetzen:
wx.php
PHP:
...
$output = $text->print_pretty();
Anfügen:
PHP:
$output = str_replace('Germany','Deutschland', $output);
 
Die Dreckige Lösung funktioniert einwandfrei!

Hallo CDW, ich würde dich gern nochmal um etwas bitten, mir scheint du kannst offensichtlich jedes Problem lösen.

Könntest du das pynrwstau.py noch mit einem Hinztriller versehen.
Unter Hinztriller versteht man den Verkehrswarnton den man immer im Radio hört bevor die Verkehrsmeldungen kommen.

Ich habe den natürlich schon für dich besorgt er liegt bei mir auf der HD unter:

http://eichenwetter.homelinux.net/linuxhd/Stau/Hinztriller.wav

Aber das geht ja so auch garnicht, das sind ja zwei unterschiedliche Wavfiles, wie will man die denn verbinden, neh ich glaube ich habe da zu voreilig geschrieben.

Die Funkamateure nutzen das Verkehrswarnmodul fleißig und da ja auch immer was los ist auf unseren Autobahnen, wurde der Hinztriller gewünscht. Ich habe natürlich nicht gleich zugesagt, da ich ja nicht über deine freie Zeit verfügen möchte, was ich aber mal sagen muss ist egal mit welchem Problem ich hier komme, du hast alles gelöst und das ohne ein einziges mal zu meckern Hut ab Jung.:thumb_up:

Das wäre ja auch der Idealfall wenn jemand die Staumeldungen per Funk aufruft mittels dtmf und vorher noch den Verkehrswarnton erklingt, das wäre dann ja ein Wavefile neh, vergiss es mal ich habe da wohl falsch gedacht, oder??

Wie kann ich Dir den mal was gutes tun ??

Gruß und recht herzlichen Dank für alles , danke danke danke.
 
Zuletzt bearbeitet:
Könntest du das pynrwstau.py noch mit einem Hinztriller versehen.
Unter Hinztriller versteht man den Verkehrswarnton den man immer im Radio hört bevor die Verkehrsmeldungen kommen.
...
Aber das geht ja so auch garnicht, das sind ja zwei unterschiedliche Wavfiles, wie will man die denn verbinden, neh ich glaube ich habe da zu voreilig geschrieben.
Es geht schon, aber wäre es nicht einfacher, Hinztriller.wav vor der Verkehrsansage abzuspielen?

Die einfache Version zum Verbinden der Audidateien in Python wäre:
Code:
#! /usr/bin/env python
# -*- coding: utf-8 -*-

HINZTRILLER = "Hinztriller.wav"
TRAFFIC_NEWS = "verkehrsansage_balabolka.wav"
OUTPUT = "stau.wav"
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt


import wave
import logging

LOG_FORMAT = "%(asctime)s %(levelname)s: %(filename)s : %(message)s"
DATE_FORMAT = "%d.%m.%Y %H:%M:%S"
logging.basicConfig(filename=ERRORS, format=LOG_FORMAT, datefmt=DATE_FORMAT)

def main():
    try:
        whistle = wave.open(HINZTRILLER, 'rb')
        traffic =  wave.open(TRAFFIC_NEWS,'rb')
        output = wave.open(OUTPUT,'wb') 
        output.setparams(traffic.getparams())
        output.writeframes(whistle.readframes(whistlepy.getnframes()))
        output.writeframes(traffic.readframes(traffic.getnframes()))
        
    except Exception as ex:
        logging.critical(str(ex))
    finally:
        output.close()
        whistle.close()
        traffic.close()
    
main()
setzt allerings voraus, dass die Staumeldungen und Hinztriller Sound im exakt gleichen Ausgabeformat vorliegen - sonst ist der Klang sehr verzehrrt (gut, man kann's auch die Normalisierung/Angleichung komplett in Python machen - das setzt allerdings Zusatzmodule voraus, die erstmal installiert werden müssen)

Ich hab' mal die Hinztriller angepasst (siehe Anhang).

Anleitung:
Bei Win XP gibt es unter Zubehör den Audiorecorder (oder so ähnlich, habe hier nur die englische Version).
Dieser kann nicht nur aufzeichnen, sondern auch umwandeln.

Das Programm zeigt mir (unter Datei->Eigenschaften) für die heruntergeladene "stau.wav" an:
PCM 16.000 kHz, 16 Bit, Mono
und das für die Hinztriller.wav:
PCM 8.000 kHz, 8 Bit, Mono

Ich vermute mal, dass Balabolka immer das gleiche Format erzeugt (also PCM 16Khz 16bit Mono). Also kann man einfach die Hinztriller.wav "umwandeln" und dann verwenden (im Audiorecorder: Speichern unter -> Format "ändern" -> ein Dialog mit Formatauswahl (hier nach "PCM 16.000 kHz, 16 Bit, Mono" suchen). Dann speichern. Das obige Skript sollte dann nach Balabolka ausgeführt werden (und Balabolka-Ausgabedatei entsprechend anders benannt werden ;) )

Ggf. ist man auf Dauer mit einem "anständigen" Audio-Editor, der auch die Lautstärke usw. anheben kann, besser bedient.

Gruß, CDW
 
Script meldet Fehler in der Ausgabe!

Moin CDW,
zunächst mal vielen Dank für die Beantwortung meiner Frage.

Ich habe mal folgendes getan:

Script leicht geändert:

PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-
HINZTRILLER = "Hinztriller.wav"
TRAFFIC_NEWS = "Verkehrsansage.wav"
OUTPUT = "stau.wav"
ERRORS = "errors.txt"  # Fehlerausgabe in errors.txt

import wave
import logging
LOG_FORMAT = "%(asctime)s %(levelname)s: %(filename)s : %(message)s"
DATE_FORMAT = "%d.%m.%Y %H:%M:%S"
logging.basicConfig(filename=ERRORS, format=LOG_FORMAT, datefmt=DATE_FORMAT)
def main():
    try:
        whistle = wave.open(HINZTRILLER, 'rb')
        traffic =  wave.open(TRAFFIC_NEWS,'rb')
        output = wave.open(OUTPUT,'wb')
        output.setparams(traffic.getparams())
        output.writeframes(whistle.readframes(whistlepy.getnframes()))
        output.writeframes(traffic.readframes(traffic.getnframes()))
    except Exception as ex:
        logging.critical(str(ex))
    finally:
        output.close()
        whistle.close()
        traffic.close()
main()

So habe also nur das Wort verkehrsansage eingefügt.
Da es aber keine Verkehrsansage. wav gibt, habe ich mal die Stau.wav kopiert in Verkehrsansage.wav umbenannt.

Dann habe ich alles in den ordner linuxhd\Stau kopiert.

Deine zu letzt programmierte PY heisst bei mir Warndienst.py.

Sie wird per Batch von C:\warndienst.bat aufgerufen. Der Inhalt der Bat:

PHP:
cd\
cd xampp\htdocs\linuxhd\python
warndienst.py

aufgerufen.
Ergebnis beim Aufrufen:

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
C:\Dokumente und Einstellungen\STROMSPAR-PC>cd\
C:\>Warndienst.bat
C:\>cd\
C:\>cd xampp\htdocs\linuxhd\python
C:\xampp\htdocs\linuxhd\python>warndienst.py
Traceback (most recent call last):
File "C:\xampp\htdocs\linuxhd\python\warndienst.py", line 33, in <module>
main()
File "C:\xampp\htdocs\linuxhd\python\warndienst.py", line 29, in main
output.close()
UnboundLocalError: local variable 'output' referenced before assignment
C:\xampp\htdocs\linuxhd\python>

Im Ordner Stau liegen 4 dateien:
Hinztriller.wav, stau.wav, meine Umbenannte Verkehrsansage.wav, weil wenn diese nicht vorhanden ist schreib er: kann warndienst.py.wav nicht finden und die warndienst.py, sowie die errors.txt, in dieser steht nach dem Aufruf der warndienst.py

Inhalt der errors.txt

05.06.2013 17:59:42 CRITICAL: warndienst.py : global name 'whistlepy' is not defined


Rufe ich die warndienst.pyp aus dem Ordner Stau auf legt er zwar eine stau.wav an die ist dann aber plötzlich leer.

Ich weis mir keinen rat mehr, habe aber gesehen das in der PY wo das Wort Hinztriller steht hinter dem Komma ein leerzeichen mehr als in der zeile darunter steht, muss das so??

PHP:
whistle = wave.open(HINZTRILLER, 'rb')
        traffic =  wave.open(TRAFFIC_NEWS,'rb')

Danke Gruß Stefan ich habe das mit der Balabolka.wav auch nicht so richtig verstanden daher das umbenennen in Verkehrsansage wav.


Ich habe natürlich auch alle erforderlichen dateien nach linuxhd\python kopiert, selbst wenn ich das script per mouse klick im Ordner Stau oder auch in \python starte kommen die gleichen Fehler.

C:\>warndienst

C:\>cd\

C:\>cd xampp\htdocs\linuxhd\python

C:\xampp\htdocs\linuxhd\python>warndienst.py
Traceback (most recent call last):
File "C:\xampp\htdocs\linuxhd\python\warndienst.py", line 33, in <module>
main()
File "C:\xampp\htdocs\linuxhd\python\warndienst.py", line 29, in main
output.close()
UnboundLocalError: local variable 'output' referenced before assignment
 
Zuletzt bearbeitet:
Es geht schon, aber wäre es nicht einfacher, Hinztriller.wav vor der Verkehrsansage

Hallo CDW,

Es geht schon, aber wäre es nicht einfacher, Hinztriller.wav vor der Verkehrsansage abzuspielen?


Wie sollman das denn über Funk realisieren, die Gatewaynutzer rufen per DTMF mit der Eingabe BAB* die Staumeldungen ab, wie kann ich die dazu veranlassen vorher einen Hinztriller abzurufen, na gut vielleicht hast du ja da noch eine Idee.

Habe jetzt die letzten Fünf Tage immer wieder mal probiert das letzte Script von dir anzupassen, aber leider kommen immer wieder die gleichen Fehler.

Gruß Stefan
 
Hi,
ich habe das Script mal umgeschrieben:
PHP:
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import wave
import logging

HINZTRILLER = r"Hinztriller.wav"
TRAFFIC_NEWS = r"verkehrsansage_balabolka.wav"
OUTPUT = r"stau.wav"
LOG = "log.txt" # Logausgabe
LOG_LEVEL = logging.INFO # logging.CRITICAL



LOG_FORMAT = "%(asctime)s %(levelname)s: %(filename)s %(lineno)d: %(message)s"
DATE_FORMAT = "%d.%m.%Y %H:%M:%S"
logging.basicConfig(filename=LOG, format=LOG_FORMAT, datefmt=DATE_FORMAT,
                    level = LOG_LEVEL)

def wave_read(name):
    try:
        logging.info("Oeffne %s" % name)
        inp_wave = wave.open(name, 'rb')
        logging.info("Lese Waveheader von <%s>" % name)
        params = inp_wave.getparams()
        logging.info("Eingelesene Daten: <%s>" % str(params))
        frame_number = inp_wave.getnframes()
        logging.info("Anzahl der Frames laut Header: %d" % frame_number)        
        frames = inp_wave.readframes(frame_number)
        return params, frames
    except (IOError, wave.Error) as err:
        logging.critical("Fehler beim Einlesen von <%s>\n" % name + str(err))
    finally:
        try:
            inp_wave.close()
        except IOError as err:
            logging.critical("Fehler beim Schliessen von <%s>\n" % name + str(err))
        except (NameError, UnboundLocalError):
            pass

def main():
    try:
        traffic_header, traffic_frames = wave_read(TRAFFIC_NEWS)
        whistle_header, whistle_frames = wave_read(HINZTRILLER)
        # header =  tuple (nchannels, sampwidth, framerate,
        #                  nframes, comptype, compname)
        # compare: nchannels, sample width, framerate, compression
        NAMES = ("number of channels", "sample width", "framerate", "compression")
        for i,name in zip([0, 1, 2, 4, 5], NAMES) :
            if traffic_header[i] != whistle_header[i]:
                logging.warning("Unterschiedliche Werte für %s!\n"
                                "<%s>:%s | <%s>:%s" % (name, TRAFFIC_NEWS,
                                 traffic_header[i], HINZTRILLER, whistle_header[i]))
        if None in (traffic_header, traffic_frames,
                    whistle_header, whistle_frames):
            logging.critical("Nicht alle noetigen Daten wurden eingelesen!")
            return
        logging.info("Erstelle Ausgabedatei <%s>" % OUTPUT)
        out_wav = wave.open(OUTPUT, 'wb')
        logging.info("Schreibe Headerdaten in <%s>" % OUTPUT)
        out_wav.setparams(traffic_header)
        logging.info("Schreibe Audioframes von <%s> in <%s>" % (HINZTRILLER, OUTPUT))
        out_wav.writeframes(whistle_frames)
        logging.info("Schreibe Audioframes von <%s> in <%s>" % (TRAFFIC_NEWS, OUTPUT))
        out_wav.writeframes(traffic_frames)
        
        
    except Exception as err:
        logging.critical("Fehler beim Verbinden der <%s> und <%s>" %
                         (TRAFFIC_NEWS, HINZTRILLER) + str(err))
    finally:
        try:
            out_wav.close()
        except NameError:
            pass
        except Exception as err:
            logging.critical("Fehler beim Schliessen der <%s>" % OUTPUT + str(err))
    
main()
Das dürfte jetzt eine deutlich detailliertere und lesbare Fehlerausgabe in der Datei "log.txt" produzieren - mit Einzelschritten, was nun wo gemacht wird.

ich habe das mit der Balabolka.wav auch nicht so richtig verstanden daher das umbenennen in Verkehrsansage wav.
Ich meinte nur die Ausgabedatei von Balabolka:
Zum Testen habe ich nämlich einfach die WAV Datei von http://eichenwetter.homelinux.net/linuxhd/Stau/Stau.wav genommen.
Deswegen bin ich auch ausgegangen, dass Balabolka als Ausgabe die "Stau.wav" produziert.

Also: Du brauchst einmal die Ausgabedatei von Balabolka: "Stau.wav" (?)
Das ist im Script als
TRAFFIC_NEWS = r"verkehrsansage_balabolka.wav"
eingestellt, darf natürlich auch geändert werden.
------------
Der Wert kann (und muss eigentlich, falls das Script und die Wavedateien in unterschiedlichen Orndern liegen) ein Pfad zu der WAV-Datei sein:
Absoluter Pfad (also mit Laufwerk und dem gesamten Ordnerpfad)
TRAFFIC_NEWS = r"C:\XYZordner\linuxhd\Stau\stau.wav"

oder ein relativer Pfad:
z.B wenn das Script in "C:\...<viele Ornder>...\linuxhd\python\pywave.py" Unterordner ist und die Wavedateien in "C:\<..viele Ordner>..\linxhd\Stau\stau.wav" :
TRAFFIC_NEWS = r"../Stau/stau.wav"
Dabei sagt "../" in Pfadangaben (egal ob windows, linux usw, es ist übergreifend):
"nehme den aktuellen Ordner als "Anker" und gehe einen Ebene höher"
z.B wenn das Script nun in "C:\<vieleOrdner>\linuxhd\python\waveproducer\" liegt und die Wavedateien in "C:\<vieleOrdner>\linuxhd\Stau\":
TRAFFIC_NEWS = r"../../Stau/stau.wav"
"nehme den aktuellen Ordner als "Anker" und gehe zwei Ebenen höher"
----------
Die normalisierte "Hinztrliller.wav" (aus dem letzten Posting, sonst wie gesagt, wird das verzerrt abgespielt).
HINZTRILLER = r"Hinztriller.wav"
oder absolut: r"C:\linuxhd\Stau\Hinztriller.wav"
oder relativ: r"../Stau/Hinztriller.wav"

Und eine Ausgabe:
OUTPUT = r"stau.wav"
Absolut: r"C:\linuxhd\Stau\stau.wav"
relativ: r"../Stau/stau.wav"

In dieser Version des Scripts kann man auch direkt die "stau.wav" als Ein und Ausgabe nehmen. Das Script kann allerdings nicht unterscheiden, ob ein Hinztriller schon hinzugefügt wurde (also läuft man der Gefahr, dass es doppelt und dreifach hinzugefügt wird, sofern das Script mehrfach aufgerufen wird) - deswegen wäre es vielleicht besser, Balabolka die Ausgabe unter einem anderen Namen produzieren zu lassen (z.B "stau_meldungen.wav") und das Script dann "Hinztriller.wav" und "stau_meldungen.wav" zu einer "stau.wav" verbinden zu lassen.

Wie sollman das denn über Funk realisieren, die Gatewaynutzer rufen per DTMF mit der Eingabe BAB* die Staumeldungen ab,
k.A ;). Ich dachte nur, dass man in der verwendeten Software einstellen kann, dass mehrere Dateien nacheinander abgespielt werden.

PS: bei Fehlern einfach dann die "log.txt" posten.
 
Zurück
Oben