Nieuws:

Welkom, Gast. Alsjeblieft inloggen of registreren.
Heb je de activerings-mail niet ontvangen?

Auteur Topic: Weerbericht in conky suggesties?  (gelezen 2576 keer)

Offline MKe

  • Lid
Weerbericht in conky suggesties?
« Gepost op: 2013/05/08, 12:01:12 »
Hoi,

Ik ben voor de lol bezig om het weer in conky te zetten. Ik heb hiervoor een python script gemaakt die de html van de indexpagina van de buienradar download en vervolgens de juiste waarden eruit haalt:
#!/usr/bin/env python

import sys
import re
import urllib2

regex = {
'temp' : r"/weerstation/grafiek/(?P<niets>\d{4})/ta\?name=Temperatuur&amp;stationname={stad}&amp;extension=in%2Bgraden\">(?P<waarde>.*?)</a>",
'wind' : r'/weerstation/grafiek/(?P<niets>\d{4})/ff\?name=Windsnelheid%2520\(km%2Fu\)&amp;stationname={stad}&amp;extension=km%2Fu">(?P<waarde>.*?)</a>',
'luchtvochtigheid': r'<a href="/weerstation/grafiek/(?P<niets>\d{4})/rh\?name=Luchtvochtigheid&amp;stationname={stad}&amp;extension=procenten">(?P<waarde>.*?)</a>',
'luchtdruk': r'/weerstation/grafiek/(?P<niets>\d{4})/pp\?name=Luchtdruk&amp;stationname=Woensdrecht&amp;extension=hpa">(?P<waarde>.*?)</a> '
}

# gebruik: get_weather_data.py [station] [type data]

stad = sys.argv[1]
searchstring = regex[sys.argv[2]].replace('{stad}',stad)

webtext = urllib2.urlopen('http://www.buienradar.nl/').read()

r = re.compile(searchstring)
value = r.search(webtext)
print value.group('waarde')

De .cokyrc, dit is een gedeelte van mijn script, ik heb de systeminfo e.d. weggelaten. Ik heb deze conky aangepast zodat het op KDE werkt. Ik weet niet hoe goed het wordt weergegeven op Gnome:
# Use Xft?
use_xft yes
xftfont OFL Sorts Mill Goudy:size=8
xftalpha 0.8
text_buffer_size 2048

# Update interval in seconds
update_interval 1

# This is the number of times Conky will update before quitting.
# Set to zero to run forever.
total_run_times 0

# Create own window instead of using desktop (required in nautilus)
background no
own_window yes
own_window_type normal
own_window_argb_visual true
own_window_transparent yes
own_window_hints undecorated,below,sticky,skip_taskbar,skip_pager

# Use double buffering (reduces flicker, may not work for everyone)
double_buffer yes

# Minimum size of text area
minimum_size 180 0
#maximum_width 200

# Draw shades?
draw_shades yes

# Draw outlines?
draw_outline no

# Draw borders around text
draw_borders no

# Stippled borders?
stippled_borders 0

# border margins
border_inner_margin 5

# border width
border_width 1

# Default colors and also border colors
default_color black
default_shade_color grey
default_outline_color black
own_window_colour black
color1 black

# Text alignment, other possible values are commented
#alignment top_left
alignment top_right
#alignment bottom_left
#alignment bottom_right

# Gap between borders of screen and text
# same thing as passing -x at command line
gap_x 35
gap_y 35

# Subtract file system buffers from used memory?
no_buffers yes

# set to yes if you want all text to be in uppercase
uppercase no

# number of cpu samples to average
# set to 1 to disable averaging
cpu_avg_samples 2

# number of net samples to average
# set to 1 to disable averaging
net_avg_samples 2

# Force UTF8? note that UTF8 support required XFT
override_utf8_locale yes

# Add spaces to keep things from moving about?  This only affects certain objects.
use_spacer none

TEXT
# mijn eigen weer script.
${font Goudy Bookletter 1911:style=Bold}HET WEER${font} ${hr 2}
Temp: $alignr ${exec python /home/mke/.conky/weer/get_weather_data.py Rotterdam temp} °C
Wind: $alignr ${exec python /home/mke/.conky/weer/get_weather_data.py Rotterdam wind}
Luchtdruk: $alignr ${exec python /home/mke/.conky/weer/get_weather_data.py Rotterdam luchtdruk} hpa
Luchtvochtigheid: $alignr ${exec python /home/mke/python-play/weer/get_weather_data.py Rotterdam luchtvochtigheid}%

Dit script werkt dus. Alleen wordt het python script 4x aangeroepen en dus de data 4 x gedownload wat mij enigszins inefficiënt lijkt.
Heeft iemand een idee om dit beter te maken?
Alles als een tekst produceren door het python script lijkt me niet handig omdat ik dan ook de opmaak mee moet nemen. Het maakt het python script minder universeel bruikbaar.

Re: Weerbericht in conky suggesties?
« Reactie #1 Gepost op: 2013/05/08, 17:16:11 »
Moet er even bijzeggen dat ik weinig verstand heb van conky's schrijven maar denk dat je grofweg 2 dingen kunt doen:

* Het script een string laten produceren (met alle vier de datatypen) en het conkyscript deze laten parsen om er temperatuur, windrichting e.d. uit te halen.
* Het weerscript de weergegevens naar een tekstbestandje laten schrijven en daarbij ook bijhouden wanneer de laatste update was. Zo kan het pythonscript bij aanroepen bepalen of er opnieuw gegevens moeten worden gedownload van buienradar.nl of dat ze uit de 'cache' kunnen worden gepakt. Voor conky verandert er dan niets, die blijft dezelfde aanroepen doen alleen het pythonscript handelt de verzoeken dan anders af.

Offline MKe

  • Lid
Re: Weerbericht in conky suggesties?
« Reactie #2 Gepost op: 2013/05/08, 19:00:22 »
Dat parsen in het conky script is idd waar ik naar zoek. Ik heb ook niet veel verstand van conky, python ligt mij beter :)

Offline MKe

  • Lid
Re: Weerbericht in conky suggesties?
« Reactie #3 Gepost op: 2013/06/10, 15:31:28 »
FF als update en misschien wil iemand anders hier ook gebruik van maken.
Ik heb het volgende script gemaakt om het weer van Buienradar te halen. De output is in een vorm dat Conky kan lezen:
#!/usr/bin/env python
'''
Usage: get_weather.py <weersstation>
Weerstations kunnen worden gevonden op de buienradar site.
'''
import sys
import re
import urllib2

from time import localtime, strftime

regex = r'/weerstation/grafiek/\d{4}/.{2}\?name=(?P<soort>.*?)(%2520\(km%2Fu\)|)&amp;stationname={stad}&amp;extension=.*?">(?P<waarde>.*?)</a>'
stad = sys.argv[1]

webtext = urllib2.urlopen('http://www.buienradar.nl/')
tabel = webtext.read()
webtext.close()
print('Tijd: $alignr {tijd}'.format(tijd=strftime("%X ", localtime())))
r = re.compile(regex.replace('{stad}',stad))
waarde = [m.groupdict() for m in r.finditer(tabel)]

for w in waarde:
    print('{soort}: $alignr {waarde}'.format(soort=w['soort'],waarde=w['waarde']))

Ik heb ook een dergelijk script gemaakt voor verkeers informatie.
#!/usr/bin/env python
'''
usage:
get_traffic.py weg1,weg2,weg3
 voorbeeld: get_traffic.py A16,A17,A2
'''
import sys
import re
import urllib2
from textwrap import wrap
from time import localtime, strftime


wegen = sys.argv[1].replace(',','|')

# haal webpagine binnen
fin = urllib2.urlopen('http://vid.nl/VI/overzicht/')#file('temp','r')#text = fin.read()
tabel = fin.read()
fin.close()

print('Tijd: $alignr {tijd}'.format(tijd=strftime("%X ", localtime())))

# regex voor parsen webpagina
searchstring = r'<span class="vi-wegnr">(?P<weg>{weg})</span>(?s).*?<dd class="vi-traject vi-bericht">(?P<where>.*?)</dd>(?s).*?<span class="vi-km">(?P<length>.*?)</span>'
r = re.compile(searchstring.format(weg=wegen))
waarde = [m.groupdict() for m in r.finditer(tabel)]

if waarde:
    for w in waarde:
        print w['weg'] + '$alignr ' + w['length']
        print '\n'.join(wrap(w['where'],30))

else:
    print 'no traffic on {wegen}'.format(wegen = sys.argv[1])

Re: Weerbericht in conky suggesties?
« Reactie #4 Gepost op: 2013/06/11, 17:27:27 »
Bedankt voor de update :) Ik gebruik het niet in conky maar vind het deselniettemin een leuk script. Heb toch maar even verder gewerkt aan mijn eigen idee om de geparseerde data van Buienradar in een cachebestandje op te slaan. Als de cache niet ouder is dan 5 minuten wordt het waarde-object uit dat bestand gebruikt. In plaats van in een eigen formaat opslaan heb ik de module Pickle daarvoor gebruikt (kende ik nog niet).

Het regex-gedeelte is gewoon jouw code, daar brand ik me niet aan ;)

Het script werkt zo dat data voor Rotterdam opvragen een cachebestand Rotterdam.pkl aanmaakt. Volkel maakt Volkel.pkl aan etc.
#!/usr/bin/env python
'''
Usage: get_weather.py <weersstation>
Weerstations kunnen worden gevonden op de buienradar site.
'''
import sys
import re
import urllib2
import pickle

from time import time

# Aantal seconden dat de weerdata oud mag zijn alvorens er weer wordt gekeken op buienradar.
interval = 300

def getValueFromPickleFile():
  waarde = None
  try:
    pickleBestand = open(cacheBestand,'rb')
    waarde = pickle.load(pickleBestand)
    pickleBestand.close() 
  except IOError:
    print("Cachebestand bestaat niet. Nieuwe data downloaden nodig.")
    return None 
  return waarde

def recentPickleFileExists():
  waarde = getValueFromPickleFile() 
  if waarde != None:
    for w in waarde:
      if w['soort'] == 'Tijd':     
updateTime = int(w['waarde'])
if (time() - updateTime) < interval:
  return True
else:
  print("Cache in bestand %s verouderd. Nieuwe data downloaden nodig."%cacheBestand)
  return False

def downloadWeatherData(stad):
  print("Attempting to fetch data from Buienradar.nl") 
  regex = r'/weerstation/grafiek/\d{4}/.{2}\?name=(?P<soort>.*?)(%2520\(km%2Fu\)|)&amp;stationname={stad}&amp;extension=.*?">(?P<waarde>.*?)</a>' 
  webtext = urllib2.urlopen('http://www.buienradar.nl/')
  tabel = webtext.read()
  webtext.close() 
  r = re.compile(regex.replace('{stad}',stad)) 
  waarde = [m.groupdict() for m in r.finditer(tabel)] 
  waarde.append({'waarde':'%d'%int(time()),'soort':'Tijd'}) 
  # Maak nieuw of overschrijf picklebestand met nieuwe data
  pickleBestand = open(cacheBestand,'wb')
  pickle.dump(waarde,pickleBestand)
  pickleBestand.close()
  return waarde

cacheBestand = ""
stad = ""
try:
  stad = sys.argv[1]
except IndexError:
  sys.exit("Geen plaats opgegeven.")
if stad != "":
  cacheBestand = "%s.pkl"%stad
 
waarde = None
if recentPickleFileExists() == True:
  print("Recent cachebestand aanwezig (%s), data downloaden niet nodig."%cacheBestand)
  waarde = getValueFromPickleFile()
else:
  waarde = downloadWeatherData(stad)

if waarde != None:
  for w in waarde:
    print('{soort}: {waarde}'.format(soort=w['soort'],waarde=w['waarde']))



Offline MKe

  • Lid
Re: Weerbericht in conky suggesties?
« Reactie #5 Gepost op: 2013/06/11, 23:18:46 »
Leuk :) Waar ga je het voor gebruiken? Pickle is idd erg handig als opslag. Import cpickle is trouwens dezelfde module, maar dan in c geprogrammeerd en dus nog iets sneller. Werkt hetzelfde, alleen importeer je cpickle, je zou dus de import kunne vervangen door 'import cpickle as pickle'. Is hier niet zo van belang, maar als je veel data gaat wegschrijven is het snelheidsverschil behoorlijk.

Trouwens in plaats van ' if waarde != None' en 'if waarde = True' kun je ook gewoon 'if waarde:' zeggen. Alle drie statements werken.

Re: Weerbericht in conky suggesties?
« Reactie #6 Gepost op: 2013/06/11, 23:50:48 »
Leuk :) Waar ga je het voor gebruiken? Pickle is idd erg handig als opslag. Import cpickle is trouwens dezelfde module, maar dan in c geprogrammeerd en dus nog iets sneller. Werkt hetzelfde, alleen importeer je cpickle, je zou dus de import kunne vervangen door 'import cpickle as pickle'. Is hier niet zo van belang, maar als je veel data gaat wegschrijven is het snelheidsverschil behoorlijk.

cPickle is zelfs heel wat sneller. Ik weet niet of het tegenwoordig nog van toepassing is, maar als ge niet zeker zijt of de C-extensie wel gecompileert is, is het beter om terug te vallen op de Python implementatie. Het kon nogal eens voorvallen met het zelf installeren van Python via de broncode.

try:
    import cPickle as pickle
except ImportError:
    import pickle

Trouwens in plaats van ' if waarde != None' en 'if waarde = True' kun je ook gewoon 'if waarde:' zeggen. Alle drie statements werken.

Voor Nonetype controles is het beter om de is-operator te gebruiken (enkel Nonetypes!):
>>> spam = None
>>> spam is None
True
>>> spam is not None
False

Booleans hebben inderdaad geen controle nodig:
>>> eggs = True
>>> print "Got eggs!" if eggs else "No eggs!"
Got eggs!

Re: Weerbericht in conky suggesties?
« Reactie #7 Gepost op: 2013/06/12, 12:40:49 »
Voor mij was het ook meer voor de lol, even mijn Python wat bijschaven :P Heb al wel redelijk wat met Python gedaan maar al een tijdje niet meer. Beide bedankt voor de stijltips! Nu heb ik gewoon een handig commando om snel vanuit de terminal het weerbericht op te halen.