Blackdown Hills Weather

Gauges.py


#!/usr/bin/env python

"""
Draw Gauges and Banner

usage: python Gauges.py [options] data_dir
options are:
\t-h or --help\t\tdisplay this help
data_dir is the root directory of the weather data
other data is read from weather.ini in the data_dir
"""

import codecs
from WeatherStation import pressure_trend_text, wind_dir_text
#import WeatherStation
import WindRose
from datetime import datetime, timedelta
from time import strftime
import getopt
import math
import os
import sys
import xml.dom.minidom

import DataStore
from Plot import GraphPlotter
from TimeZone import Local, utc
from WeatherStation import dew_point, apparent_temp

import Upload

def ImagePlotter(data_dir, raw_data, hourly_data, daily_data, monthly_data):
    def jump(idx, count):
        while count > 0:
            new_idx = data_set.after(idx + timedelta(seconds=1))
            if new_idx == None:
                break
            idx = new_idx
            count -= 1
        while count < 0:
            new_idx = data_set.before(idx)
            if new_idx == None:
                break
            idx = new_idx
            count += 1
        return idx, count == 0
    # start off in raw data mode
    data_set = raw_data
    # start off in utc
    time_zone = utc
    # jump to last item
    idx, valid_data = jump(datetime.max, -1)
    if not valid_data:
        print >>sys.stderr, "No summary data - run Process.py first"
        return 4
    data = data_set[idx]
    # print "Banner"
    params = DataStore.params(data_dir)
    start = idx - timedelta(minutes=10)
    stop = idx
#    stop = stop + timedelta(minutes=1)
    for data in data_set[start:stop]:
        wind_dir = data['wind_dir']
        #print 'wind_dir', wind_dir
        if wind_dir == None or wind_dir >= 16:
            continue
    # get calibration values
    calib_rain = params.get('calibration', 'rain multiplier', '1.0')
    calib_temp = params.get('calibration', 'temp', '0.0')
    banner_name = params.get('station info', 'banner-name', 'Station Name')
#    print 'calib_rain', calib_rain, 'calib_temp', calib_temp, 'Station Name', banner_name

    # get data values
    temp_out = data['temp_out']
    temp_out += float(calib_temp)
    hum_out = data['hum_out']
    dew_pt = dew_point(data['temp_out'], data['hum_out'])

    # change to hourly_data and jump to last item
    data_set = hourly_data
    idx, valid_data = jump(datetime.max, -1)
    if not valid_data:
        print >>sys.stderr, "No summary data - run Process.py first"
        return 4
    data = data_set[idx]

    abs_pressure = data['abs_pressure']
    rel_pressure = data['rel_pressure']
    wind_ave = data['wind_ave'] * 3.6 / 1.609344
#        print data['wind_ave'], wind_ave
    wind_gust = data['wind_gust'] * 3.6 / 1.609344
    pressure_trend = data['pressure_trend']
# problem with pressure_trend ##################################
    print "pressure trend = ", pressure_trend
    if pressure_trend == None:
        pressure_trend = 0
    app_temp = apparent_temp(temp_out, hum_out, data['wind_ave'])
    # get hourly wind dir value for graph selection
    wind_dir_select = data['wind_dir']

   
    # Convert data to strings
    # change to daily_data and jump to last item
    data_set = daily_data
    idx, valid_data = jump(datetime.max, -1)
    if not valid_data:
        print >>sys.stderr, "No summary data - run Process.py first"
        return 4
    data = data_set[idx]
    rain = data['rain']
    rain = rain * float(calib_rain)
#    print 'rain', rain   
    if rain == 0:
        rainstring = "No rain today"
    else:
        rainstring = "Rain %.1f mm" % (rain)
    x = data['wind_dir']
    if wind_ave < 0.9:
        windstring = "Wind: Calm  "
    else:
        windstring = "Wind " +  wind_dir_text[x] + " @ %.0f mph   Gusting %.0f mph" % (wind_ave, wind_gust)
#      
    tempstring = "%.1f C" % temp_out
    humsring = "Humidity %i %%" % hum_out
    baro = "Barometer %i mb, %s" % (rel_pressure, pressure_trend_text(pressure_trend))
    software = "Powered by G-Weather"
    tnow = strftime('%H:%M   %d %B   ');
    td = strftime('%H:%M &nbsp  on  &nbsp %d %B   ');
    ################################################################################## show ws offline ###################
    #tempstring = 'Station Off-line'
    #rainstring = ''
    #windstring = ''
    #baro = ''
    #humsring = ''
    #td = 'Weather Station Offline'

    # get file locations
    work_dir = params.get('paths', 'work', '/tmp/weather')
#        prog_dir = '/home/gina/weather'
    im_templates_dir = params.get('paths', 'im_templates', '/home/gina/weather/im_templates')
   
    dat_file = work_dir + '/IMscript.ps'
    work_file = work_dir + '/image.png'
    done_file = work_dir + '/newbanner.png'
#        print 'work_dir', work_dir, '   dat_file', dat_file


    # Put time string into time.txt file
    time_file = work_dir + '/time.txt'   
    dat = open(time_file, 'w')
    dat.write(td + '\n')
    dat.close()
    # Add label strings to ImageMagick command string
    dat = open(dat_file, 'w')
    dat.write('#!/bin/bash\n')
    dat.write('# ImageMagick script\n')
    dat.write('convert -size 420x80 xc:lightblue -bordercolor Green -border 2 ' + work_dir + '/canvas-border.gif\n')
    font_dir = '/usr/share/fonts/type1/gsfonts/'
    wr_string = 'convert ' + work_dir + '/canvas-border.gif -gravity north -fill black -font ' + font_dir + 'c059036l.pfb -pointsize 16 '
    wr_string += " -draw 'text 0,5 "
    wr_string += '"' + banner_name + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')
    first_bit = 'convert ' + work_dir + '/image.png -gravity '       
    wr_string = first_bit + 'northwest -fill black -font ' + font_dir + 'a010013l.pfb -pointsize 14 '
    wr_string += " -draw 'text 5,25 "
    wr_string += '"' + tnow + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'center -fill red -font ' + font_dir + 'a010015l.pfb -pointsize 24 '
    wr_string += " -draw 'text +70,-5 "
    wr_string += '"' + tempstring + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'northeast -fill blue -font ' + font_dir + 'a010015l.pfb -pointsize 14 '
    wr_string += " -draw 'text +5,25 "
    wr_string += '"' + rainstring + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'west -fill black -font ' + font_dir + 'a010015l.pfb -pointsize 14 '
    wr_string += " -draw 'text +5,+9 "
    wr_string += '"' + windstring + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'east -fill blue -font ' + font_dir + 'a010015l.pfb -pointsize 14 '
    wr_string += " -draw 'text +5,+9 "
    wr_string += '"' + humsring + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'southwest -fill darkgreen -font ' + font_dir + 'a010015l.pfb -pointsize 14 '
    wr_string += " -draw 'text +5,+5 "
    wr_string += '"' + baro + '"'
    wr_string += "' " + work_file
    dat.write(wr_string + '\n')

    wr_string = first_bit + 'southeast -fill black -font ' + font_dir + 'a010013l.pfb -pointsize 14 '
    wr_string += " -draw 'text +5,+5 "
    wr_string += '"Powered by G-Weather"'
    wr_string += "' " + done_file
 #       print wr_string
    dat.write(wr_string + '\n')

    # Produce Guage  Images
    # print 'Gauges'
    dat.write('#\n# Gauges \n#\n')
    dial_angle = (wind_ave / 50 * 253.0 - 216.5)
    dial_angle_gust = (wind_gust / 50 * 253.0 - 216.5)
#        print wind_ave, dial_angle
#        wr_string = 'convert -size 220x188 xc:transparent  -fill transparent \ '
#        dat.write(wr_string + '\n')
    wr_string = 'convert -size 220x188 xc:transparent  -fill transparent  -draw " '
    wr_string += 'stroke blue fill blue  translate 110,110 rotate %.1f ' % (dial_angle)
    wr_string += "translate 80,0  path 'M 0,0  l -15,-5  +5,+5  -5,+5  +15,-5 z' "
    wr_string += '"  ' + work_dir  + '/arrow_windspeed.png'
    dat.write(wr_string + '\n')
    wr_string = 'convert -size 220x188 xc:transparent  -fill transparent  -draw " '
    wr_string += 'stroke red fill red  translate 110,110 rotate %.1f ' % (dial_angle_gust)
    wr_string += "translate 80,0  path 'M 0,0  l -15,-5  +5,+5  -5,+5  +15,-5 z' "
    wr_string += '"  ' + work_dir  + '/arrow_windspeed_gust.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + im_templates_dir + 'dial_windspeed.png   ' + work_dir + '/arrow_windspeed.png  ' + work_dir + '/gauge_windspeed.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + work_dir + '/gauge_windspeed.png   ' + work_dir + '/arrow_windspeed_gust.png  ' + work_dir + '/gauge_windspeed.png'
    dat.write(wr_string + '\n')

    dial_angle = wind_dir * 22.5 - 90

    wr_string = 'convert -size 200x200 xc:transparent  -fill transparent  -draw " '
    wr_string += 'stroke blue fill blue  translate 100,100 rotate %.1f ' % (dial_angle)
    wr_string += "translate 68,0  path 'M 0,0  l -15,-5  +5,+5  -5,+5  +15,-5 z' "
    wr_string += '"  ' + work_dir  + '/arrow_winddir.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + im_templates_dir + 'dial_compass.png   ' + work_dir + '/arrow_winddir.png  ' + work_dir + '/gauge_winddir.png'
    dat.write(wr_string + '\n')

    my_string = ' -gravity center  -fill black  -font '  + font_dir + '/n021003l.pfb -pointsize '
    wr_string = 'convert -size 300x265 xc:transparent  -fill transparent ' + my_string +  '26  -draw '
    wr_string += "'text 0,-5 "
    wr_string += '"Barometer"'
    wr_string += "' "
    wr_string += my_string + "20  -draw 'text 0,20 "
    p_string = "%.1f mb/hPa" %  (rel_pressure)
    wr_string += '"' + p_string + '"'
    wr_string += "' "
    wr_string += my_string + "20  -draw 'text 0,40 "
    trend_string = "%s"  %  (pressure_trend_text(pressure_trend))
    wr_string += '"'  + trend_string + '"'
    wr_string += "' "
    wr_string += ' -draw " '
    dial_angle = (rel_pressure - 900.0) / 160 * 260 -220
    wr_string += 'stroke blue fill blue  translate 150,150 rotate %.1f ' % (dial_angle)
    wr_string += "translate 120,0  path 'M 0,0  l -22,-7  +7,+7  -7,+7  +22,-7 z' "
    wr_string += '"  ' + work_dir  + '/arrow_baro.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + im_templates_dir + 'dial_barometer.png   ' + work_dir + '/arrow_baro.png  ' + work_dir + '/barometer.png'
    dat.write(wr_string + '\n')

############################################
    # Make thermometer gauge fill
#        print 'Thermometer'
    #temp_out = 0
    max_y = 457
    lx = 53
    hx = 59
    ly = max_y - ((temp_out + 10) * 9)
    hy = 461
    rect_string = "rectangle %i,%i %i,%i" % (lx, ly, hx, hy)
    wr_string = 'convert -size 80x500 xc:transparent '
    wr_string += ' -fill red -stroke red  -draw "'  + rect_string + '"  '
    wr_string += work_dir + '/fill_thermometer.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + work_dir + '/fill_thermometer.png ' + im_templates_dir + 'scale_thermometer.png ' + work_dir + '/thermometer.png'
    dat.write(wr_string + '\n')

    # Make "feels like" gauge fill
#        print 'Feels Like Gauge'
    #dew_pt = 0
    max_y = 457
    lx = 33
    hx = 39
    ly = max_y - ((app_temp + 10) * 9)
    hy = 461
    rect_string = "rectangle %i,%i %i,%i" % (lx, ly, hx, hy)
    wr_string = 'convert -size 100x500 xc:transparent '
    wr_string += ' -fill skyblue -stroke skyblue  -draw "'  + rect_string + '"  '
    wr_string += work_dir + '/fill_dewpoint.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + work_dir + '/fill_dewpoint.png ' + im_templates_dir + 'scale_dewpoint.png ' + work_dir + '/dewpoint.png'
    dat.write(wr_string + '\n')

############################################
    # Make rain gauge fill
#        print 'Rain Gauge'
    max_y = 491     
    lx = 10
    hx = 17
    hy = 491

    rain_units = rain * 1.0
#        rain_units = 0
    if rain_units == 0:
        fill = 'white'
    else:
        fill = 'blue'
    if rain_units < 3:
        ly = max_y - rain_units * 40
    elif rain_units < 5:
        r = rain_units - 3.0
        ly = max_y - (30 * 4) - r * 30
    else:
        max_y = max_y - 30.0 - (50 * 3) + (math.log10(25) * 300)
        y1 = math.log10(rain_units * 5)
#            print y1
        ly =  max_y - (y1 * 300)
    rect_string = "rectangle %i,%i %i,%i" % (lx, ly, hx, hy)
    wr_string = 'convert -size 70x510 xc:transparent '
    wr_string += ' -fill %s -stroke %s  -draw "' % (fill, fill)
#        print wr_string
    wr_string += rect_string + '"  ' + work_dir + '/fill_rain.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + work_dir + '/fill_rain.png ' + im_templates_dir + 'scale_rain.png ' + work_dir + '/gauge_rain.png'
    dat.write(wr_string + '\n')
    wr_string = 'convert -resize 103.5% ' + work_dir + '/gauge_rain.png ' + work_dir + '/gauge_rain.png'
    dat.write(wr_string + '\n')
   
    # Humidity gauge
#        print 'Humidity Gauge'
    max_y = 510
    lx = 53
    hx = 59
#        print hum_out
    ly = max_y - (hum_out * 5)
#        ly = max_y - (99 * 5)
    hy = max_y - 1
    rect_string = "rectangle %i,%i %i,%i" % (lx, ly, hx, hy)
    wr_string = 'convert -size 80x520 xc:transparent '
    wr_string += ' -fill skyblue -stroke skyblue  -draw "'  + rect_string + ' "  ' + work_dir + '/fill_humidity.png '
#        print wr_string
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity center ' + work_dir + '/fill_humidity.png ' + im_templates_dir + 'scale_humidity.png ' + work_dir + '/gauge_humidity.png'
#        print wr_string
    dat.write(wr_string + '\n')

######################################################################################################################################################################

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Humidity.png ' + work_dir + '/24hrs-Humidity.png ' + work_dir + '/24hrs-Humidity.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Humidity.png ' + work_dir + '/28days-humidity.png ' + work_dir + '/28days-humidity.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Humidity.png ' + work_dir + '/7days-humidity.png ' + work_dir + '/7days-humidity.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Temperature2.png ' + work_dir + '/24hrs-Temperature.png ' + work_dir + '/24hrs-Temperature.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Temperature2.png ' + work_dir + '/7days-temperature.png ' + work_dir + '/7days-temperature.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-Temperature-28.png ' + work_dir + '/28days-temperature.png ' + work_dir + '/28days-temperature.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind.png ' + work_dir + '/24hrs-Wind.png ' + work_dir + '/24hrs-Wind.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind.png ' + work_dir + '/28days-wind.png ' + work_dir + '/28days-wind.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind.png ' + work_dir + '/7days-wind.png ' + work_dir + '/7days-wind.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-hourly-rain.png ' + work_dir + '/24hrs-Rain.png ' + work_dir + '/24hrs-Rain.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-hourly-rain.png ' + work_dir + '/7days-rain.png ' + work_dir + '/7days-rain.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-daily-rain.png ' + work_dir + '/28days-rain.png ' + work_dir + '/28days-rain.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-pressure.png ' + work_dir + '/24hrs-Pressure.png ' + work_dir + '/24hrs-Pressure.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-pressure.png ' + work_dir + '/7days-pressure.png ' + work_dir + '/7days-pressure.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-pressure.png ' + work_dir + '/28days-pressure.png ' + work_dir + '/28days-pressure.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind-dir.png ' + work_dir + '/7days-wind-dir.png ' + work_dir + '/7days-wind-dir.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity northwest ' + im_templates_dir + 'S.png ' + work_dir + '/7days-wind-dir.png ' + work_dir + '/7days-wind-dir.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind-dir.png ' + work_dir + '/28days-wind-dir.png ' + work_dir + '/28days-wind-dir.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity northwest ' + im_templates_dir + 'S.png ' + work_dir + '/28days-wind-dir.png ' + work_dir + '/28days-wind-dir.png'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind-dir.png ' + work_dir + '/7days-wind-dir-S.png ' + work_dir + '/7days-wind-dir-S.png'
    dat.write(wr_string + '\n')
    wr_string = 'composite -gravity northwest ' + im_templates_dir + 'N.png ' + work_dir + '/7days-wind-dir-S.png ' + work_dir + '/7days-wind-dir-S.png'
    dat.write(wr_string + '\n')
############################################
    #d = (wind_dir_select + 1) / 2
    d = (WindRose.RosePlotter.dir_wind + 1) / 2
    print d
    #d = 2
    print '-->', d
    #print wind_dir_select, d
    if d == 0:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'N.png ' + work_dir + '/24hrs-wind-dir-cN.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d
    elif d == 1:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'NE.png ' + work_dir + '/24hrs-wind-dir-cNE.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d
    elif d == 2:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'E.png ' + work_dir + '/24hrs-wind-dir-cE.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d
    elif d == 3:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'SE.png ' + work_dir + '/24hrs-wind-dir-cSE.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d, im_templates_dir, im_temp#lates_dir + 'SE.png '
    elif d == 4:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'S.png ' + work_dir + '/24hrs-wind-dir-cS.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d
    elif d == 5:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'SW.png ' + work_dir + '/24hrs-wind-dir-cSW.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d
    elif d == 6:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'W.png ' + work_dir + '/24hrs-wind-dir-cW.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d, 'right'
    else:
        wr_string = 'composite -gravity northwest ' + im_templates_dir + 'NW.png ' + work_dir + '/24hrs-wind-dir-cNW.png ' + work_dir + '/24hrs-wind-dir.png'
        #print d, 'else'
    dat.write(wr_string + '\n')

    wr_string = 'composite -gravity north ' + im_templates_dir + 'Title-wind-dir.png ' + work_dir + '/24hrs-wind-dir.png ' + work_dir + '/24hrs-wind-dir.png'
    dat.write(wr_string + '\n')

##############################################################################################################################################################

    dat.write('###### End of script ######\n')
    dat.write('#\n')

    dat.close()
#        print 'Running IM Script'
#        os.system('cat ' + dat_file)
    os.system('bash ' + dat_file)
    # print 'Adding files to upload list'
    uploads = []
    uploads.append(work_dir + '/newbanner.png')
    uploads.append(work_dir + '/time.txt')
    uploads.append(work_dir + '/gauge_windspeed.png')
    uploads.append(work_dir + '/gauge_winddir.png')
    uploads.append(work_dir + '/barometer.png')
    uploads.append(work_dir + '/dewpoint.png')
    uploads.append(work_dir + '/thermometer.png')
    uploads.append(work_dir + '/gauge_rain.png')
    uploads.append(work_dir + '/gauge_humidity.png')
#    print 'uploads', uploads
    return uploads

def main(argv=None):
    if argv is None:
        argv = sys.argv
    try:
        opts, args = getopt.getopt(argv[1:], "", ['help'])
    except getopt.error, msg:
        print >>sys.stderr, 'Error: %s\n' % msg
        print >>sys.stderr, __doc__.strip()
        return 1
    # check arguments
    if len(args) != 1:
        print >>sys.stderr, 'Error: 1 argument required\n'
        print >>sys.stderr, __doc__.strip()
        return 2
    # process options
    for o, a in opts:
        if o == '--help':
            print __doc__.strip()
            return 0
    return ImagePlotter(args[0], DataStore.data_store(args[0]), DataStore.hourly_store(args[0]), DataStore.daily_store(args[0]), DataStore.monthly_store(args[0]))
    sys.exit(main())

Page created  15 August 2010