#!/usr/bin/env python # -*- coding: utf-8 -*- # NOQA import sys import os import platform import signal import datetime import dateutil.parser import tzlocal import time import json import locale import random import math # import urllib # import re from PyQt4 import QtGui, QtCore, QtNetwork from PyQt4.QtGui import QPixmap, QBrush, QColor from PyQt4.QtGui import QPainter, QImage, QFont from PyQt4.QtCore import QUrl from PyQt4.QtCore import Qt from PyQt4.QtNetwork import QNetworkReply from PyQt4.QtNetwork import QNetworkRequest from subprocess import Popen sys.dont_write_bytecode = True from GoogleMercatorProjection import getCorners, getPoint, getTileXY, LatLng # NOQA import ApiKeys # NOQA class tzutc(datetime.tzinfo): def utcoffset(self, dt): return datetime.timedelta(hours=0, minutes=0) class suntimes: def __init__(self, lat, long): self.lat = lat self.long = long def sunrise(self, when=None): if when is None: when = datetime.datetime.now(tz=tzlocal.get_localzone()) self.__preptime(when) self.__calc() return suntimes.__timefromdecimalday(self.sunrise_t) def sunset(self, when=None): if when is None: when = datetime.datetime.now(tz=tzlocal.get_localzone()) self.__preptime(when) self.__calc() return suntimes.__timefromdecimalday(self.sunset_t) @staticmethod def __timefromdecimalday(day): hours = 24.0*day h = int(hours) minutes = (hours-h)*60 m = int(minutes) seconds = (minutes-m)*60 s = int(seconds) return datetime.time(hour=h, minute=m, second=s) def __preptime(self, when): # datetime days are numbered in the Gregorian calendar # while the calculations from NOAA are distibuted as # OpenOffice spreadsheets with days numbered from # 1/1/1900. The difference are those numbers taken for # 18/12/2010 self.day = when.toordinal()-(734124-40529) t = when.time() self.time = (t.hour + t.minute/60.0 + t.second/3600.0) / 24.0 self.timezone = 0 offset = when.utcoffset() if offset is not None: self.timezone = offset.seconds / 3600.0 + (offset.days * 24) def __calc(self): timezone = self.timezone # in hours, east is positive longitude = self.long # in decimal degrees, east is positive latitude = self.lat # in decimal degrees, north is positive time = self.time # percentage past midnight, i.e. noon is 0.5 day = self.day # daynumber 1=1/1/1900 Jday = day+2415018.5 + time - timezone / 24 # Julian day Jcent = (Jday - 2451545) / 36525 # Julian century Manom = 357.52911 + Jcent * (35999.05029 - 0.0001537 * Jcent) Mlong = 280.46646 + Jcent * (36000.76983 + Jcent * 0.0003032) % 360 Eccent = 0.016708634 - Jcent * (0.000042037 + 0.0001537 * Jcent) Mobliq = (23 + (26 + ((21.448 - Jcent * (46.815 + Jcent * (0.00059 - Jcent * 0.001813)))) / 60) / 60) obliq = (Mobliq + 0.00256 * math.cos(math.radians(125.04-1934.136 * Jcent))) vary = (math.tan(math.radians(obliq / 2)) * math.tan(math.radians(obliq / 2))) Seqcent = (math.sin(math.radians(Manom)) * (1.914602 - Jcent*(0.004817 + 0.000014 * Jcent)) + math.sin(math.radians(2 * Manom)) * (0.019993 - 0.000101 * Jcent) + math.sin(math.radians(3 * Manom)) * 0.000289) Struelong = Mlong + Seqcent Sapplong = (Struelong - 0.00569 - 0.00478 * math.sin(math.radians(125.04-1934.136*Jcent))) declination = (math.degrees(math.asin(math.sin(math.radians(obliq)) * math.sin(math.radians(Sapplong))))) eqtime = (4 * math.degrees(vary * math.sin(2 * math.radians(Mlong)) - 2 * Eccent*math.sin(math.radians(Manom)) + 4 * Eccent * vary * math.sin(math.radians(Manom)) * math.cos(2 * math.radians(Mlong)) - 0.5 * vary * vary * math.sin(4 * math.radians(Mlong)) - 1.25 * Eccent * Eccent * math.sin(2*math.radians(Manom)))) hourangle0 = (math.cos(math.radians(90.833)) / (math.cos(math.radians(latitude)) * math.cos(math.radians(declination))) - math.tan(math.radians(latitude)) * math.tan(math.radians(declination))) self.solarnoon_t = (720-4 * longitude - eqtime + timezone * 60) / 1440 # sun never sets if hourangle0 > 1.0: self.sunrise_t = 0.0 self.sunset_t = 1.0 - 1.0/86400.0 return if hourangle0 < -1.0: self.sunrise_t = 0.0 self.sunset_t = 0.0 return hourangle = math.degrees(math.acos(hourangle0)) self.sunrise_t = self.solarnoon_t - hourangle * 4 / 1440 self.sunset_t = self.solarnoon_t + hourangle * 4 / 1440 # https://gist.github.com/miklb/ed145757971096565723 def moon_phase(dt=None): if dt is None: dt = datetime.datetime.now() diff = dt - datetime.datetime(2001, 1, 1) days = float(diff.days) + (float(diff.seconds) / 86400.0) lunations = 0.20439731 + float(days) * 0.03386319269 return lunations % 1.0 def tick(): global hourpixmap, minpixmap, secpixmap global hourpixmap2, minpixmap2, secpixmap2 global lastmin, lastday, lasttimestr global clockrect global datex, datex2, datey2, pdy global sun, daytime, sunrise, sunset global bottom if Config.DateLocale != "": try: locale.setlocale(locale.LC_TIME, Config.DateLocale) except: pass now = datetime.datetime.now() if Config.digital: timestr = Config.digitalformat.format(now) if Config.digitalformat.find("%I") > -1: if timestr[0] == '0': timestr = timestr[1:99] if lasttimestr != timestr: clockface.setText(timestr.lower()) lasttimestr = timestr else: angle = now.second * 6 ts = secpixmap.size() secpixmap2 = secpixmap.transformed( QtGui.QMatrix().scale( float(clockrect.width()) / ts.height(), float(clockrect.height()) / ts.height() ).rotate(angle), Qt.SmoothTransformation ) sechand.setPixmap(secpixmap2) ts = secpixmap2.size() sechand.setGeometry( clockrect.center().x() - ts.width() / 2, clockrect.center().y() - ts.height() / 2, ts.width(), ts.height() ) if now.minute != lastmin: angle = now.minute * 6 ts = minpixmap.size() minpixmap2 = minpixmap.transformed( QtGui.QMatrix().scale( float(clockrect.width()) / ts.height(), float(clockrect.height()) / ts.height() ).rotate(angle), Qt.SmoothTransformation ) minhand.setPixmap(minpixmap2) ts = minpixmap2.size() minhand.setGeometry( clockrect.center().x() - ts.width() / 2, clockrect.center().y() - ts.height() / 2, ts.width(), ts.height() ) angle = ((now.hour % 12) + now.minute / 60.0) * 30.0 ts = hourpixmap.size() hourpixmap2 = hourpixmap.transformed( QtGui.QMatrix().scale( float(clockrect.width()) / ts.height(), float(clockrect.height()) / ts.height() ).rotate(angle), Qt.SmoothTransformation ) hourhand.setPixmap(hourpixmap2) ts = hourpixmap2.size() hourhand.setGeometry( clockrect.center().x() - ts.width() / 2, clockrect.center().y() - ts.height() / 2, ts.width(), ts.height() ) dy = Config.digitalformat2.format(now) if Config.digitalformat2.find("%I") > -1: if dy[0] == '0': dy = dy[1:99] if dy != pdy: pdy = dy datey2.setText(dy) if now.minute != lastmin: lastmin = now.minute if now.time() >= sunrise and now.time() <= sunset: daytime = True else: daytime = False if now.day != lastday: lastday = now.day # date sup = 'th' if (now.day == 1 or now.day == 21 or now.day == 31): sup = 'st' if (now.day == 2 or now.day == 22): sup = 'nd' if (now.day == 3 or now.day == 23): sup = 'rd' if Config.DateLocale != "": sup = "" ds = "{0:%A, %B} {0.day}{1} {0.year}".format(now, sup) ds2 = "{0:%a, %b} {0.day}{1} {0.year}".format(now, sup) datex.setText(ds) datex2.setText(ds2) dt = now.replace(tzinfo=tzlocal.get_localzone()) sunrise = sun.sunrise(dt) sunset = sun.sunset(dt) bottomText = "" bottomText += (Config.LSunRise + "{0:%H:%M}".format(sunrise) + Config.LSet + "{0:%H:%M}".format(sunset)) bottomText += (Config.LMoonPhase + phase(moon_phase())) bottom.setText(bottomText) def tempfinished(): global tempreply, temp if tempreply.error() != QNetworkReply.NoError: return tempstr = str(tempreply.readAll()) tempdata = json.loads(tempstr) if tempdata['temp'] == '': return if Config.metric: s = Config.LInsideTemp + \ "%3.1f" % ((float(tempdata['temp']) - 32.0) * 5.0 / 9.0) if tempdata['temps']: if len(tempdata['temps']) > 1: s = '' for tk in tempdata['temps']: s += ' ' + tk + ':' + \ "%3.1f" % ( (float(tempdata['temps'][tk]) - 32.0) * 5.0 / 9.0) else: s = Config.LInsideTemp + tempdata['temp'] if tempdata['temps']: if len(tempdata['temps']) > 1: s = '' for tk in tempdata['temps']: s += ' ' + tk + ':' + tempdata['temps'][tk] temp.setText(s) def tempm(f): return (f - 32) / 1.8 def speedm(f): return f * 0.621371192 def pressi(f): return f * 0.029530 def heightm(f): return f * 25.4 def barom(f): return f * 25.4 def phase(f): pp = Config.Lmoon1 # 'New Moon' if (f > 0.9375): pp = Config.Lmoon1 # 'New Moon' elif (f > 0.8125): pp = Config.Lmoon8 # 'Waning Crecent' elif (f > 0.6875): pp = Config.Lmoon7 # 'Third Quarter' elif (f > 0.5625): pp = Config.Lmoon6 # 'Waning Gibbous' elif (f > 0.4375): pp = Config.Lmoon5 # 'Full Moon' elif (f > 0.3125): pp = Config.Lmoon4 # 'Waxing Gibbous' elif (f > 0.1875): pp = Config.Lmoon3 # 'First Quarter' elif (f > 0.0625): pp = Config.Lmoon2 # 'Waxing Crescent' return pp def bearing(f): wd = 'N' if (f > 22.5): wd = 'NE' if (f > 67.5): wd = 'E' if (f > 112.5): wd = 'SE' if (f > 157.5): wd = 'S' if (f > 202.5): wd = 'SW' if (f > 247.5): wd = 'W' if (f > 292.5): wd = 'NW' if (f > 337.5): wd = 'N' return wd def gettemp(): global tempreply host = 'localhost' if platform.uname()[1] == 'KW81': host = 'piclock.local' # this is here just for testing r = QUrl('http://' + host + ':48213/temp') r = QNetworkRequest(r) tempreply = manager.get(r) tempreply.finished.connect(tempfinished) def wxfinished_owm(): global wxreply, wxdata, supress_current global wxicon, temper, wxdesc, press, humidity global wind, wind2, wdate, bottom, forecast global wxicon2, temper2, wxdesc2, attribution global daytime owmicons = { '01d': 'clear-day', '02d': 'partly-cloudy-day', '03d': 'partly-cloudy-day', '04d': 'partly-cloudy-day', '09d': 'rain', '10d': 'rain', '11d': 'thunderstorm', '13d': 'snow', '50d': 'fog', '01n': 'clear-night', '02n': 'partly-cloudy-night', '03n': 'partly-cloudy-night', '04n': 'partly-cloudy-night', '09n': 'rain', '10n': 'rain', '11n': 'thunderstorm', '13n': 'snow', '50n': 'fog' } attribution.setText("openweathermap.org") attribution2.setText("openweathermap.org") wxstr = str(wxreply.readAll()) wxdata = json.loads(wxstr) f = wxdata['current'] icon = f['weather'][0]['icon'] icon = owmicons[icon] if not supress_current: wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + icon + ".png") wxicon.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxicon2.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxdesc.setText(f['weather'][0]['description']) wxdesc2.setText(f['weather'][0]['description']) if Config.metric: temper.setText('%.1f' % (tempm(f['temp'])) + u'°C') temper2.setText('%.1f' % (tempm(f['temp'])) + u'°C') press.setText(Config.LPressure + '%.1f' % f['pressure'] + 'mb') humidity.setText(Config.LHumidity + '%.0f%%' % (f['humidity'])) wd = bearing(f['wind_deg']) if Config.wind_degrees: wd = str(f['wind_deg']) + u'°' w = (Config.LWind + wd + ' ' + '%.1f' % (speedm(f['wind_speed'])) + 'kmh') if 'wind_gust' in f: w += (Config.Lgusting + '%.1f' % (speedm(f['wind_gust'])) + 'kmh') wind.setText(w) wind2.setText(Config.LFeelslike + '%.1f' % (tempm(f['feels_like'])) + u'°C') wdate.setText("{0:%H:%M}".format(datetime.datetime.fromtimestamp( int(f['dt'])))) # Config.LPrecip1hr + f['precip_1hr_metric'] + 'mm ' + # Config.LToday + f['precip_today_metric'] + 'mm') else: temper.setText('%.1f' % (f['temp']) + u'°F') temper2.setText('%.1f' % (f['temp']) + u'°F') press.setText( Config.LPressure + '%.2f' % pressi(f['pressure']) + 'in') humidity.setText(Config.LHumidity + '%.0f%%' % (f['humidity'])) wd = bearing(f['wind_deg']) if Config.wind_degrees: wd = str(f['wind_deg']) + u'°' w = (Config.LWind + wd + ' ' + '%.1f' % ((f['wind_speed'])) + 'mph') if 'wind_gust' in f: w += (Config.Lgusting + '%.1f' % ((f['wind_gust'])) + 'kph') wind.setText(w) wind2.setText(Config.LFeelslike + '%.1f' % (f['feels_like']) + u'°F') wdate.setText("{0:%H:%M}".format(datetime.datetime.fromtimestamp( int(f['dt'])))) # Config.LPrecip1hr + f['precip_1hr_in'] + 'in ' + # Config.LToday + f['precip_today_in'] + 'in') for i in range(0, 3): f = wxdata['hourly'][i * 3 + 2] fl = forecast[i] wicon = f['weather'][0]['icon'] wicon = owmicons[wicon] icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap( Config.icons + "/" + wicon + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%A %I:%M%p}".format(datetime.datetime.fromtimestamp( int(f['dt'])))) s = '' pop = 0 ptype = '' paccum = 0 if ('pop' in f): pop = float(f['pop']) * 100.0 if ('snow' in f): ptype = 'snow' paccum = float(f['snow']['1h']) if ('rain' in f): ptype = 'rain' paccum = float(f['rain']['1h']) if (pop > 0.0 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % heightm(paccum) + 'mm ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temp']) + u'°C' else: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % paccum + 'in ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % paccum + 'in ' s += '%.0f' % (f['temp']) + u'°F' wx.setStyleSheet( "#wx { color: " + Config.textcolorWeatherRight13 + "; font-size: " #Text Color of 1-3 Weather on page 1 + str(int(22 * xscale * Config.fontmult)) + "px; }") #Font size wx.setText(f['weather'][0]['description'] + "\n" + s) for i in range(3, 9): f = wxdata['daily'][i - 3] wicon = f['weather'][0]['icon'] wicon = owmicons[wicon] fl = forecast[i] icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + wicon + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%A}".format(datetime.datetime.fromtimestamp( int(f['dt'])))) s = '' pop = 0 ptype = '' paccum = 0 if ('pop' in f): pop = float(f['pop']) * 100.0 if ('rain' in f): ptype = 'rain' paccum = float(f['rain']) if ('snow' in f): ptype = 'snow' paccum = float(f['snow']) if (pop > 0.05 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % heightm(paccum) + 'mm ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temp']['max']) + '/' + \ '%.0f' % tempm(f['temp']['min']) else: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.1f' % paccum + 'in ' else: if (paccum > 0.05): s += Config.LRain + '%.1f' % paccum + 'in ' s += '%.0f' % f['temp']['max'] + '/' + \ '%.0f' % f['temp']['min'] wx.setStyleSheet( "#wx { color: " + Config.textcolorWeatherRight69 + "; font-size: "#Text Color of 6-9 Weather on page 1 + str(int(19 * xscale * Config.fontmult)) + "px; }") wx.setText(f['weather'][0]['description'] + "\n" + s) def wxfinished_ds(): global wxreply, wxdata, supress_current global wxicon, temper, wxdesc, press, humidity global wind, wind2, wdate, bottom, forecast global wxicon2, temper2, wxdesc2, attribution global daytime attribution.setText("DarkSky.net") attribution2.setText("DarkSky.net") wxstr = str(wxreply.readAll()) wxdata = json.loads(wxstr) f = wxdata['currently'] if not supress_current: wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + f['icon'] + ".png") wxicon.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxicon2.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxdesc.setText(f['summary']) wxdesc2.setText(f['summary']) if Config.metric: temper.setText('%.1f' % (tempm(f['temperature'])) + u'°C') temper2.setText('%.1f' % (tempm(f['temperature'])) + u'°C') press.setText(Config.LPressure + '%.1f' % f['pressure'] + 'mb') humidity.setText( Config.LHumidity + '%.0f%%' % (f['humidity']*100.0)) wd = bearing(f['windBearing']) if Config.wind_degrees: wd = str(f['windBearing']) + u'°' wind.setText(Config.LWind + wd + ' ' + '%.1f' % (speedm(f['windSpeed'])) + 'kmh' + Config.Lgusting + '%.1f' % (speedm(f['windGust'])) + 'kmh') wind2.setText(Config.LFeelslike + '%.1f' % (tempm(f['apparentTemperature'])) + u'°C') wdate.setText("{0:%H:%M}".format(datetime.datetime.fromtimestamp( int(f['time'])))) # Config.LPrecip1hr + f['precip_1hr_metric'] + 'mm ' + # Config.LToday + f['precip_today_metric'] + 'mm') else: temper.setText('%.1f' % (f['temperature']) + u'°F') temper2.setText('%.1f' % (f['temperature']) + u'°F') press.setText( Config.LPressure + '%.2f' % pressi(f['pressure']) + 'in') humidity.setText( Config.LHumidity + '%.0f%%' % (f['humidity']*100.0)) wd = bearing(f['windBearing']) if Config.wind_degrees: wd = str(f['windBearing']) + u'°' wind.setText(Config.LWind + wd + ' ' + '%.1f' % (f['windSpeed']) + 'mph' + Config.Lgusting + '%.1f' % (f['windGust']) + 'mph') wind2.setText(Config.LFeelslike + '%.1f' % (f['apparentTemperature']) + u'°F') wdate.setText("{0:%H:%M}".format(datetime.datetime.fromtimestamp( int(f['time'])))) # Config.LPrecip1hr + f['precip_1hr_in'] + 'in ' + # Config.LToday + f['precip_today_in'] + 'in') for i in range(0, 3): f = wxdata['hourly']['data'][i * 3 + 2] fl = forecast[i] icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap( Config.icons + "/" + f['icon'] + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%A %I:%M%p}".format(datetime.datetime.fromtimestamp( int(f['time'])))) s = '' pop = 0 ptype = '' paccum = 0 if ('precipProbability' in f): pop = float(f['precipProbability']) * 100.0 if ('precipAccumulation' in f): paccum = float(f['precipAccumulation']) if ('precipType' in f): ptype = f['precipType'] if (pop > 0.0 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % heightm(paccum) + 'mm ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temperature']) + u'°C' else: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % paccum + 'in ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % paccum + 'in ' s += '%.0f' % (f['temperature']) + u'°F' "#wx { color: " + Config.textcolorWeatherRight13 + "; font-size: " #Text Color of 1-3 Weather on page 1 wx.setText(f['summary'] + "\n" + s) for i in range(3, 9): f = wxdata['daily']['data'][i - 3] fl = forecast[i] icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + f['icon'] + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%A}".format(datetime.datetime.fromtimestamp( int(f['time'])))) s = '' pop = 0 ptype = '' paccum = 0 if ('precipProbability' in f): pop = float(f['precipProbability']) * 100.0 if ('precipAccumulation' in f): paccum = float(f['precipAccumulation']) if ('precipType' in f): ptype = f['precipType'] if (pop > 0.05 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.0f' % heightm(paccum) + 'mm ' else: if (paccum > 0.05): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temperatureHigh']) + '/' + \ '%.0f' % tempm(f['temperatureLow']) else: if (ptype == 'snow'): if (paccum > 0.05): s += Config.LSnow + '%.1f' % paccum + 'in ' else: if (paccum > 0.05): s += Config.LRain + '%.1f' % paccum + 'in ' s += '%.0f' % f['temperatureHigh'] + '/' + \ '%.0f' % f['temperatureLow'] "#wx { color: " + Config.textcolorWeatherRight69 + "; font-size: "#Text Color of 6-9 Weather on page 1 wx.setText(f['summary'] + "\n" + s) cc_code_map = { "freezing_rain_heavy": "Freezing Rain", "freezing_rain": "Freezing Rain", "freezing_rain_light": "Freezing Rain", "freezing_drizzle": "Freezing Drizzle", "ice_pellets_heavy": "Ice Pellets", "ice_pellets": "Ice Pellets", "ice_pellets_light": "Ice Pellets", "snow_heavy": "Heavy Snow", "snow": "Snow", "snow_light": "Light Snow", "flurries": "Flurries", "tstorm": "Thunder Storm", "rain_heavy": "Heavy Rain", "rain": "Rain", "rain_light": "Light Rain", "drizzle": "Drizzle", "fog_light": "Light Fog", "fog": "Fog", "cloudy": "Cloudy", "mostly_cloudy": "Mostly Cloudy", "partly_cloudy": "Partly Cloudy", "mostly_clear": "Mostly Clear", "clear": "Clear" } cc_code_icons = { "freezing_rain_heavy": "freezing_rain_heavy", "freezing_rain": "freezing_rain", "freezing_rain_light": "freezing_rain_light", "freezing_drizzle": "freezing_drizzle", "ice_pellets_heavy": "ice_pellets_heavy", "ice_pellets": "ice_pellets", "ice_pellets_light": "ice_pellets_light", "snow_heavy": "snow_heavy", "snow": "snow", "snow_light": "snow_light", "flurries": "flurries", "tstorm": "tstorm", "rain_heavy": "rain_heavy", "rain": "rain", "rain_light": "rain_light", "drizzle": "drizzle", "fog_light": "fog_light", "fog": "fog", "cloudy": "cloudy", "partly_cloudy": "partly_cloudy_day", "mostly_cloudy": "mostly_cloudy", "mostly_clear": "mostly_clear_day", "clear": "clear_day" } def wxfinished_cc(): global wxreply, wxdata, supress_current global wxicon, temper, wxdesc, press, humidity global wind, wind2, wdate, bottom, forecast global wxicon2, temper2, wxdesc2, attribution global daytime attribution.setText("climacell.co") attribution2.setText("climacell.co") wxstr = str(wxreply.readAll()) wxdata = json.loads(wxstr) f = wxdata dt = dateutil.parser.parse(f['observation_time']['value'])\ .astimezone(tzlocal.get_localzone()) icon = f['weather_code']['value'] icon = cc_code_icons[icon] if not daytime: icon = icon.replace('_day', '_night') if not supress_current: wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + icon + ".png") wxicon.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxicon2.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxdesc.setText(cc_code_map[f['weather_code']['value']]) wxdesc2.setText(cc_code_map[f['weather_code']['value']]) if Config.metric: temper.setText('%.1f' % (tempm(f['temp']['value'])) + u'°C') temper2.setText('%.1f' % (tempm(f['temp']['value'])) + u'°C') press.setText( Config.LPressure + '%.1f' % barom(f['baro_pressure']['value']) + 'mm') humidity.setText( Config.LHumidity + '%.0f%%' % (f['humidity']['value'])) wd = bearing(f['wind_direction']['value']) if Config.wind_degrees: wd = str(f['wind_direction']['value']) + u'°' wind.setText(Config.LWind + wd + ' ' + '%.1f' % (speedm(f['wind_speed']['value'])) + 'kmh' + Config.Lgusting + '%.1f' % (speedm(f['wind_gust']['value'])) + 'kmh') wind2.setText(Config.LFeelslike + '%.1f' % (tempm(f['feels_like']['value'])) + u'°C') wdate.setText("{0:%H:%M}".format(dt)) # Config.LPrecip1hr + f['precip_1hr_metric'] + 'mm ' + # Config.LToday + f['precip_today_metric'] + 'mm') else: temper.setText('%.1f' % (f['temp']['value']) + u'°F') temper2.setText('%.1f' % (f['temp']['value']) + u'°F') press.setText( Config.LPressure + '%.2f' % (f['baro_pressure']['value']) + 'in') humidity.setText( Config.LHumidity + '%.0f%%' % (f['humidity']['value'])) wd = bearing(f['wind_direction']['value']) if Config.wind_degrees: wd = str(f['wind_direction']['value']) + u'°' wind.setText(Config.LWind + wd + ' ' + '%.1f' % (f['wind_speed']['value']) + 'mph' + Config.Lgusting + '%.1f' % (f['wind_gust']['value']) + 'mph') wind2.setText(Config.LFeelslike + '%.1f' % (f['feels_like']['value']) + u'°F') wdate.setText("{0:%H:%M}".format(dt)) # Config.LPrecip1hr + f['precip_1hr_in'] + 'in ' + # Config.LToday + f['precip_today_in'] + 'in') def wxfinished_cc2(): global wxreply, forecast global daytime wxstr2 = str(wxreply2.readAll()) # print('cc2', wxstr2) wxdata2 = json.loads(wxstr2) for i in range(0, 3): f = wxdata2[i * 3 + 2] # print(i, i*3+2, f) fl = forecast[i] wicon = f['weather_code']['value'] wicon = cc_code_icons[wicon] dt = dateutil.parser.parse(f['observation_time']['value']) \ .astimezone(tzlocal.get_localzone()) if dt.day == datetime.datetime.now().day: fdaytime = daytime else: fsunrise = sun.sunrise(dt) fsunset = sun.sunset(dt) print('calc daytime', fdaytime, dt, fsunrise, fsunset) if dt.time() >= fsunrise and dt.time() <= fsunset: fdaytime = True else: fdaytime = False if not fdaytime: wicon = wicon.replace('_day', '_night') icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap( Config.icons + "/" + wicon + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%A %I:%M%p}".format( dateutil.parser.parse(f['observation_time']['value']) .astimezone(tzlocal.get_localzone()))) s = '' pop = float(f['precipitation_probability']['value']) ptype = f['precipitation_type']['value'] if ptype == 'none': ptype = '' paccum = f['precipitation']['value'] if (pop > 0.0 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.01): s += Config.LSnow + '%.0f' % heightm(paccum) + 'mm ' else: if (paccum > 0.01): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temp']['value']) + u'°C' else: if (ptype == 'snow'): if (paccum > 0.01): s += Config.LSnow + '%.0f' % paccum + 'in ' else: if (paccum > 0.01): s += Config.LRain + '%.0f' % paccum + 'in ' s += '%.0f' % (f['temp']['value']) + u'°F' wx.setStyleSheet( # "#wx {color: " + Config.textcolorTime13 + " ; font-size: " + #Text Color of 1-3 Weather on page 1? "#wx { font-size: " + str(int(18 * xscale * Config.fontmult)) + "px; }") #Text weather condition 1-3 lines wx.setText(cc_code_map[f['weather_code']['value']] + "\n" + s) def wxfinished_cc3(): global wxreply3, forecast global daytime wxstr3 = str(wxreply3.readAll()) # print('cc2', wxstr2) wxdata3 = json.loads(wxstr3) ioff = 0 dt = dateutil.parser.parse( wxdata3[0]['observation_time']['value']+"T00:00:00") if datetime.datetime.now().day != dt.day: ioff += 1 for i in range(3, 9): f = wxdata3[i - 3 + ioff] wicon = f['weather_code']['value'] wicon = cc_code_icons[wicon] fl = forecast[i] icon = fl.findChild(QtGui.QLabel, "icon") wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + wicon + ".png") icon.setPixmap(wxiconpixmap.scaled( icon.width(), icon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wx = fl.findChild(QtGui.QLabel, "wx") day = fl.findChild(QtGui.QLabel, "day") day.setText("{0:%a Forecast for %d %b}".format( # day.setText("{0:%A}".format( dateutil.parser.parse( f['observation_time']['value']+"T00:00:00" ) )) s = '' pop = float(f['precipitation_probability']['value']) ptype = '' paccum = float(f['precipitation_accumulation']['value']) wc = f['weather_code']['value'] if 'rain' in wc: ptype = 'rain' if 'drizzle' in wc: ptype = 'rain' if 'ice' in wc: ptype = 'snow' if 'flurries' in wc: ptype = 'snow' if 'snow' in wc: ptype = 'snow' if 'tstorm' in wc: ptype = 'rain' # if (pop > 0.05 and ptype == ''): # if f['temp'][1]['max']['value'] > 28: # ptype = 'rain' # else: # ptype = 'snow' if (pop > 0.05 or ptype != ''): s += '%.0f' % pop + '% ' if Config.metric: if (ptype == 'snow'): if (paccum > 0.01): s += Config.LSnow + '%.0f' % heightm(paccum*15) + 'mm ' else: if (paccum > 0.01): s += Config.LRain + '%.0f' % heightm(paccum) + 'mm ' s += '%.0f' % tempm(f['temp'][1]['max']['value']) + '/' + \ '%.0f' % tempm(f['temp'][0]['min']['value']) else: if (ptype == 'snow'): if (paccum > 0.01): s += Config.LSnow + '%.1f' % (paccum*15) + 'in ' else: if (paccum > 0.01): s += Config.LRain + '%.1f' % paccum + 'in ' s += '%.0f' % f['temp'][1]['max']['value'] + '/' + \ '%.0f' % f['temp'][0]['min']['value'] wx.setStyleSheet( # "#wx { color: " + Config.textcolorTime69 + " ; font-size: " #Text Color of 4-9 Weather on page 1 "#wx { font-size: " + str(int(19 * xscale * Config.fontmult)) + "px; }") #19 Text weather condition 3-9 line wx.setText(cc_code_map[f['weather_code']['value']] + "\n" + s) metar_cond = [ ('CLR', '', '', 'Clear', 'clear-day', 0), ('NSC', '', '', 'Clear', 'clear-day', 0), ('SKC', '', '', 'Clear', 'clear-day', 0), ('FEW', '', '', 'Few Clouds', 'partly-cloudy-day', 1), ('NCD', '', '', 'Clear', 'clear-day', 0), ('SCT', '', '', 'Scattered Clouds', 'partly-cloudy-day', 2), ('BKN', '', '', 'Mostly Cloudy', 'partly-cloudy-day', 3), ('OVC', '', '', 'Cloudy', 'cloudy', 4), ('///', '', '', '', 'cloudy', 0), ('UP', '', '', '', 'cloudy', 0), ('VV', '', '', '', 'cloudy', 0), ('//', '', '', '', 'cloudy', 0), ('DZ', '', '', 'Drizzle', 'rain', 10), ('RA', 'FZ', '+', 'Heavy Freezing Rain', 'sleet', 11), ('RA', 'FZ', '-', 'Light Freezing Rain', 'sleet', 11), ('RA', 'SH', '+', 'Heavy Rain Showers', 'sleet', 11), ('RA', 'SH', '-', 'Light Rain Showers', 'rain', 11), ('RA', 'BL', '+', 'Heavy Blowing Rain', 'rain', 11), ('RA', 'BL', '-', 'Light Blowing Rain', 'rain', 11), ('RA', 'FZ', '', 'Freezing Rain', 'sleet', 11), ('RA', 'SH', '', 'Rain Showers', 'rain', 11), ('RA', 'BL', '', 'Blowing Rain', 'rain', 11), ('RA', '', '+', 'Heavy Rain', 'rain', 11), ('RA', '', '-', 'Light Rain', 'rain', 11), ('RA', '', '', 'Rain', 'rain', 11), ('SN', 'FZ', '+', 'Heavy Freezing Snow', 'snow', 12), ('SN', 'FZ', '-', 'Light Freezing Snow', 'snow', 12), ('SN', 'SH', '+', 'Heavy Snow Showers', 'snow', 12), ('SN', 'SH', '-', 'Light Snow Showers', 'snow', 12), ('SN', 'BL', '+', 'Heavy Blowing Snow', 'snow', 12), ('SN', 'BL', '-', 'Light Blowing Snow', 'snow', 12), ('SN', 'FZ', '', 'Freezing Snow', 'snow', 12), ('SN', 'SH', '', 'Snow Showers', 'snow', 12), ('SN', 'BL', '', 'Blowing Snow', 'snow', 12), ('SN', '', '+', 'Heavy Snow', 'snow', 12), ('SN', '', '-', 'Light Snow', 'snow', 12), ('SN', '', '', 'Rain', 'snow', 12), ('SG', 'BL', '', 'Blowing Snow', 'snow', 12), ('SG', '', '', 'Snow', 'snow', 12), ('GS', 'BL', '', 'Blowing Snow Pellets', 'snow', 12), ('GS', '', '', 'Snow Pellets', 'snow', 12), ('IC', '', '', 'Ice Crystals', 'snow', 13), ('PL', '', '', 'Ice Pellets', 'snow', 13), ('GR', '', '+', 'Heavy Hail', 'thuderstorm', 14), ('GR', '', '', 'Hail', 'thuderstorm', 14), ] def feels_like(f): t = f.temp.value('C') d = f.dewpt.value('C') h = (math.exp((17.625*d)/(243.04+d)) / math.exp((17.625*t)/(243.04+t))) t = f.temp.value('F') w = f.wind_speed.value('MPH') if t > 80 and h >= 0.40: hi = (-42.379 + 2.04901523 * t + 10.14333127 * h - .22475541 * t * h - .00683783 * t * t - .05481717 * h * h + .00122874 * t * t * h + .00085282 * t * h * h - .00000199 * t * t * h * h) if h < 0.13 and t >= 80.0 and t <= 112.0: hi -= ((13 - h) / 4) * math.sqrt((17 - math.abs(t-95)) / 17) if h > 0.85 and t >= 80.0 and t <= 112.0: hi += ((h - 85)/10) * ((87 - t)/5) return hi if t < 50 and w >= 3: wc = 35.74 + 0.6215 * t - 35.75 * \ (w ** 0.16) + 0.4275 * t * (w ** 0.16) return wc return t def wxfinished_metar(): global metarreply global wxicon, temper, wxdesc, press, humidity global wind, wind2, wdate, bottom global wxicon2, temper2, wxdesc2 global daytime wxstr = str(metarreply.readAll()) for wxline in wxstr.splitlines(): if wxline.startswith(Config.METAR): wxstr = wxline print('wxmetar', wxstr) f = Metar.Metar(wxstr) dt = f.time.replace(tzinfo=tzutc()).astimezone(tzlocal.get_localzone()) pri = -1 weather = '' icon = '' for s in f.sky: for c in metar_cond: if s[0] == c[0]: if c[5] > pri: pri = c[5] weather = c[3] icon = c[4] for w in f.weather: for c in metar_cond: if w[2] == c[0]: if c[1] > '': if w[1] == c[1]: if c[2] > '': if w[0][0:1] == c[2]: if c[5] > pri: pri = c[5] weather = c[3] icon = c[4] else: if c[2] > '': if w[0][0:1] == c[2]: if c[5] > pri: pri = c[5] weather = c[3] icon = c[4] else: if c[5] > pri: pri = c[5] weather = c[3] icon = c[4] if not daytime: icon = icon.replace('_day', '_night') wxiconpixmap = QtGui.QPixmap(Config.icons + "/" + icon + ".png") wxicon.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxicon2.setPixmap(wxiconpixmap.scaled( wxicon.width(), wxicon.height(), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)) wxdesc.setText(weather) wxdesc2.setText(weather) if Config.metric: temper.setText('%.1f' % (f.temp.value('C')) + u'°C') temper2.setText('%.1f' % (f.temp.value('C')) + u'°C') press.setText( Config.LPressure + '%.1f' % f.press.value('MB') + 'mb') t = f.temp.value('C') d = f.dewpt.value('C') h = 100.0 * (math.exp((17.625*d)/(243.04+d)) / math.exp((17.625*t)/(243.04+t))) humidity.setText( Config.LHumidity + '%.0f%%' % (h)) wd = f.wind_dir.compass() if Config.wind_degrees: wd = str(f.wind_dir.value) + u'°' ws = (Config.LWind + wd + ' ' + '%.1f' % (f.wind_speed.value('KMH')) + 'kmh') if f.wind_gust: ws += (Config.Lgusting + '%.1f' % (f.wind_gust.value('KMH')) + 'kmh') wind.setText(ws) wind2.setText(Config.LFeelslike + ('%.1f' % (tempm(feels_like(f))) + u'°C')) wdate.setText("{0:%H:%M}".format(dt)) # Config.LPrecip1hr + f['precip_1hr_metric'] + 'mm ' + # Config.LToday + f['precip_today_metric'] + 'mm') else: temper.setText('%.1f' % (f.temp.value('F')) + u'°F') temper2.setText('%.1f' % (f.temp.value('F')) + u'°F') press.setText( Config.LPressure + '%.2f' % f.press.value('IN') + 'in') t = f.temp.value('C') d = f.dewpt.value('C') h = 100.0 * (math.exp((17.625*d)/(243.04+d)) / math.exp((17.625*t)/(243.04+t))) humidity.setText( Config.LHumidity + '%.0f%%' % (h)) wd = f.wind_dir.compass() if Config.wind_degrees: wd = str(f.wind_dir.value) + u'°' ws = (Config.LWind + wd + ' ' + '%.1f' % (f.wind_speed.value('MPH')) + 'mph') if f.wind_gust: ws += (Config.Lgusting + '%.1f' % (f.wind_gust.value('MPH')) + 'mph') wind.setText(ws) wind2.setText(Config.LFeelslike + '%.1f' % (feels_like(f)) + u'°F') wdate.setText("{0:%H:%M} {1}".format(dt, Config.METAR)) # Config.LPrecip1hr + f['precip_1hr_in'] + 'in ' + # Config.LToday + f['precip_today_in'] + 'in') def getwx(): global supress_current supress_current = False try: if Config.METAR != '': supress_current = True getwx_metar() except: pass try: ApiKeys.dsapi getwx_ds() return except: pass try: ApiKeys.ccapi global cc_code_map try: cc_code_map = Config.Lcc_code_map except: pass getwx_cc() return except: pass try: ApiKeys.owmapi getwx_owm() return except: pass def getwx_ds(): global wxurl global wxreply print "getting current and forecast:" + time.ctime() wxurl = 'https://api.darksky.net/forecast/' + \ ApiKeys.dsapi + \ '/' wxurl += str(Config.location.lat) + ',' + \ str(Config.location.lng) wxurl += '?units=us&lang=' + Config.Language.lower() wxurl += '&r=' + str(random.random()) print wxurl r = QUrl(wxurl) r = QNetworkRequest(r) wxreply = manager.get(r) wxreply.finished.connect(wxfinished_ds) def getwx_owm(): global wxurl global wxreply print("getting current and forecast:" + time.ctime()) wxurl = 'https://api.openweathermap.org/data/2.5/onecall?appid=' + \ ApiKeys.owmapi wxurl += "&lat=" + str(Config.location.lat) + '&lon=' + \ str(Config.location.lng) wxurl += '&units=imperial&lang=' + Config.Language.lower() wxurl += '&r=' + str(random.random()) print(wxurl) r = QUrl(wxurl) r = QNetworkRequest(r) wxreply = manager.get(r) wxreply.finished.connect(wxfinished_owm) def getwx_cc(): global wxurl global wxurl2 global wxurl3 global wxreply global wxreply2 global wxreply3 print("getting current:" + time.ctime()) wxurl = 'https://api.climacell.co/v3/weather/realtime?apikey=' + \ ApiKeys.ccapi wxurl += "&lat=" + str(Config.location.lat) + '&lon=' + \ str(Config.location.lng) wxurl += '&unit_system=us' wxurl += '&fields=temp,weather_code,feels_like,humidity,' wxurl += 'wind_speed,wind_direction,wind_gust,baro_pressure' print(wxurl) r = QUrl(wxurl) r = QNetworkRequest(r) wxreply = manager.get(r) wxreply.finished.connect(wxfinished_cc) print("getting hourly:" + time.ctime()) wxurl2 = 'https://api.climacell.co/v3/weather/forecast/hourly?apikey=' + \ ApiKeys.ccapi wxurl2 += "&lat=" + str(Config.location.lat) + '&lon=' + \ str(Config.location.lng) wxurl2 += '&unit_system=us' wxurl2 += '&fields=temp,precipitation,precipitation_type,' wxurl2 += 'precipitation_probability,weather_code' print(wxurl2) r2 = QUrl(wxurl2) r2 = QNetworkRequest(r2) wxreply2 = manager.get(r2) wxreply2.finished.connect(wxfinished_cc2) print("getting daily:" + time.ctime()) wxurl3 = 'https://api.climacell.co/v3/weather/forecast/daily?apikey=' + \ ApiKeys.ccapi wxurl3 += "&lat=" + str(Config.location.lat) + '&lon=' + \ str(Config.location.lng) wxurl3 += '&unit_system=us' wxurl3 += '&fields=temp,precipitation_accumulation,' wxurl3 += 'precipitation_probability,weather_code' print(wxurl3) r3 = QUrl(wxurl3) r3 = QNetworkRequest(r3) wxreply3 = manager.get(r3) wxreply3.finished.connect(wxfinished_cc3) def getwx_metar(): global metarurl global metarreply metarurl = \ "https://tgftp.nws.noaa.gov/data/observations/metar/stations/" + \ Config.METAR + ".TXT" print(metarurl) r = QUrl(metarurl) r = QNetworkRequest(r) metarreply = manager.get(r) metarreply.finished.connect(wxfinished_metar) def getallwx(): getwx() def qtstart(): global ctimer, wxtimer, temptimer global manager global objradar1 global objradar2 global objradar3 global objradar4 global sun, daytime, sunrise, sunset dt = datetime.datetime.now().replace(tzinfo=tzlocal.get_localzone()) sun = suntimes(Config.location.lat, Config.location.lng) sunrise = sun.sunrise(dt) sunset = sun.sunset(dt) if dt.time() >= sunrise and dt.time() <= sunset: daytime = True else: daytime = False getallwx() gettemp() objradar1.start(Config.radar_refresh * 60) objradar1.wxstart() objradar2.start(Config.radar_refresh * 60) objradar2.wxstart() objradar3.start(Config.radar_refresh * 60) objradar4.start(Config.radar_refresh * 60) ctimer = QtCore.QTimer() ctimer.timeout.connect(tick) ctimer.start(1000) wxtimer = QtCore.QTimer() wxtimer.timeout.connect(getallwx) wxtimer.start(1000 * Config.weather_refresh * 60 + random.uniform(1000, 10000)) temptimer = QtCore.QTimer() temptimer.timeout.connect(gettemp) temptimer.start(1000 * 10 * 60 + random.uniform(1000, 10000)) if Config.useslideshow: objimage1.start(Config.slide_time) class SS(QtGui.QLabel): def __init__(self, parent, rect, myname): self.myname = myname self.rect = rect QtGui.QLabel.__init__(self, parent) self.pause = False self.count = 0 self.img_list = [] self.img_inc = 1 self.get_images() self.setObjectName("slideShow") self.setGeometry(rect) self.setStyleSheet("#slideShow { background-color: " + Config.slide_bg_color + "; }") self.setAlignment(Qt.AlignHCenter | Qt.AlignCenter) def start(self, interval): self.timer = QtCore.QTimer() self.timer.timeout.connect(self.run_ss) self.timer.start(1000 * interval + random.uniform(1, 10)) self.run_ss() def stop(self): try: self.timer.stop() self.timer = None except Exception: pass def run_ss(self): self.get_images() self.switch_image() def switch_image(self): if self.img_list: if not self.pause: if Config.RandomWallpaper: self.show_image(random.choice(self.img_list)) else: self.count += self.img_inc if self.count >= len(self.img_list): self.count = 0 self.show_image(self.img_list[self.count]) self.img_inc = 1 def show_image(self, image): image = QtGui.QImage(image) bg = QtGui.QPixmap.fromImage(image) self.setPixmap(bg.scaled( self.size(), QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation)) def get_images(self): self.get_local(Config.slides) def play_pause(self): if not self.pause: self.pause = True else: self.pause = False def prev_next(self, direction): self.img_inc = direction self.timer.stop() self.switch_image() self.timer.start() def get_local(self, path): try: dirContent = os.listdir(path) except OSError: print("path '%s' doesn't exists." % path) for each in dirContent: fullFile = os.path.join(path, each) if os.path.isfile(fullFile) and (fullFile.lower().endswith('png') or fullFile.lower().endswith('jpg')): self.img_list.append(fullFile) class Radar(QtGui.QLabel): def __init__(self, parent, radar, rect, myname): global xscale, yscale self.myname = myname self.rect = rect self.anim = 5 self.zoom = radar["zoom"] self.point = radar["center"] self.radar = radar self.baseurl = self.mapurl(radar, rect) print "map base url: " + self.baseurl QtGui.QLabel.__init__(self, parent) self.interval = Config.radar_refresh * 60 self.lastwx = 0 self.retries = 0 self.corners = getCorners(self.point, self.zoom, rect.width(), rect.height()) self.baseTime = 0 self.cornerTiles = { "NW": getTileXY(LatLng(self.corners["N"], self.corners["W"]), self.zoom), "NE": getTileXY(LatLng(self.corners["N"], self.corners["E"]), self.zoom), "SE": getTileXY(LatLng(self.corners["S"], self.corners["E"]), self.zoom), "SW": getTileXY(LatLng(self.corners["S"], self.corners["W"]), self.zoom) } self.tiles = [] self.tiletails = [] self.totalWidth = 0 self.totalHeight = 0 self.tilesWidth = 0 self.tilesHeight = 0 self.setObjectName("radar") self.setGeometry(rect) self.setStyleSheet("#radar { background-color: grey; }") self.setAlignment(Qt.AlignCenter) self.wwx = QtGui.QLabel(self) self.wwx.setObjectName("wx") self.wwx.setStyleSheet("#wx { background-color: transparent; }") self.wwx.setGeometry(0, 0, rect.width(), rect.height()) self.wmk = QtGui.QLabel(self) self.wmk.setObjectName("mk") self.wmk.setStyleSheet("#mk { background-color: transparent; }") self.wmk.setGeometry(0, 0, rect.width(), rect.height()) for y in range(int(self.cornerTiles["NW"]["Y"]), int(self.cornerTiles["SW"]["Y"])+1): self.totalHeight += 256 self.tilesHeight += 1 for x in range(int(self.cornerTiles["NW"]["X"]), int(self.cornerTiles["NE"]["X"])+1): tile = {"X": x, "Y": y} self.tiles.append(tile) if 'color' not in radar: radar['color'] = 6 if 'smooth' not in radar: radar['smooth'] = 1 if 'snow' not in radar: radar['snow'] = 1 tail = "/256/%d/%d/%d/%d/%d_%d.png" % (self.zoom, x, y, radar['color'], radar['smooth'], radar['snow']) if 'oldcolor' in radar: tail = "/256/%d/%d/%d.png?color=%d" % (self.zoom, x, y, radar['color'] ) self.tiletails.append(tail) for x in range(int(self.cornerTiles["NW"]["X"]), int(self.cornerTiles["NE"]["X"])+1): self.totalWidth += 256 self.tilesWidth += 1 self.frameImages = [] self.frameIndex = 0 self.displayedFrame = 0 self.ticker = 0 self.lastget = 0 def rtick(self): if time.time() > (self.lastget + self.interval): self.get(time.time()) self.lastget = time.time() if len(self.frameImages) < 1: return if self.displayedFrame == 0: self.ticker += 1 if self.ticker < 5: return self.ticker = 0 f = self.frameImages[self.displayedFrame] self.wwx.setPixmap(f["image"]) self.displayedFrame += 1 if self.displayedFrame >= len(self.frameImages): self.displayedFrame = 0 def get(self, t=0): t = int(t / 600)*600 if t > 0 and self.baseTime == t: return if t == 0: t = self.baseTime else: self.baseTime = t newf = [] for f in self.frameImages: if f["time"] >= (t - self.anim * 600): newf.append(f) self.frameImages = newf firstt = t - self.anim * 600 for tt in range(firstt, t+1, 600): print "get... " + str(tt) + " " + self.myname gotit = False for f in self.frameImages: if f["time"] == tt: gotit = True if not gotit: self.getTiles(tt) break def getTiles(self, t, i=0): t = int(t / 600)*600 self.getTime = t self.getIndex = i if i == 0: self.tileurls = [] self.tileQimages = [] for tt in self.tiletails: tileurl = "http://tilecache.rainviewer.com/v2/radar/%d/%s" \ % (t, tt) self.tileurls.append(tileurl) print self.myname + " " + str(self.getIndex) + " " + self.tileurls[i] self.tilereq = QNetworkRequest(QUrl(self.tileurls[i])) self.tilereply = manager.get(self.tilereq) QtCore.QObject.connect(self.tilereply, QtCore.SIGNAL( "finished()"), self.getTilesReply) def getTilesReply(self): print "getTilesReply " + str(self.getIndex) if self.tilereply.error() != QNetworkReply.NoError: return self.tileQimages.append(QImage()) self.tileQimages[self.getIndex].loadFromData(self.tilereply.readAll()) self.getIndex = self.getIndex + 1 if self.getIndex < len(self.tileurls): self.getTiles(self.getTime, self.getIndex) else: self.combineTiles() self.get() def combineTiles(self): global radar1 ii = QImage(self.tilesWidth*256, self.tilesHeight*256, QImage.Format_ARGB32) painter = QPainter() painter.begin(ii) painter.setPen(QColor(255, 255, 255, 255)) painter.setFont(QFont("Arial", 10)) i = 0 xo = self.cornerTiles["NW"]["X"] xo = int((int(xo) - xo)*256) yo = self.cornerTiles["NW"]["Y"] yo = int((int(yo) - yo)*256) for y in range(0, self.totalHeight, 256): for x in range(0, self.totalWidth, 256): if self.tileQimages[i].format() == 5: painter.drawImage(x, y, self.tileQimages[i]) # painter.drawRect(x, y, 255, 255) # painter.drawText(x+3, y+12, self.tiletails[i]) i += 1 painter.end() painter = None self.tileQimages = [] ii2 = ii.copy(-xo, -yo, self.rect.width(), self.rect.height()) ii = None painter2 = QPainter() painter2.begin(ii2) timestamp = "{0:%H:%M} rainviewer.com".format( datetime.datetime.fromtimestamp(self.getTime)) painter2.setPen(QColor(63, 63, 63, 255)) painter2.setFont(QFont("Arial", 8)) painter2.setRenderHint(QPainter.TextAntialiasing) painter2.drawText(3-1, 12-1, timestamp) painter2.drawText(3+2, 12+1, timestamp) painter2.setPen(QColor(192, 192, 192, 255)) # Text color time and RainView.com at the top of the second page painter2.drawText(3, 12, timestamp) painter2.drawText(3+1, 12, timestamp) painter2.end() painter2 = None ii3 = QPixmap(ii2) ii2 = None self.frameImages.append({"time": self.getTime, "image": ii3}) ii3 = None def mapurl(self, radar, rect): mb = 0 try: mb = Config.usemapbox except: pass if mb: return self.mapboxurl(radar, rect) else: return self.googlemapurl(radar, rect) def mapboxurl(self, radar, rect): # note we're using google maps zoom factor. # Mapbox equivilant zoom is one less # They seem to be using 512x512 tiles instead of 256x256 rsize = rect.size() if rsize.width() > 640 or rsize.height() > 640: # message: "Width must be between 1-1280." Error with high resolution screens, this sovles that, borrowed from a few lines down rsize = QtCore.QSize(rsize.width() / 2, rsize.height() / 2) style = 'mapbox/satellite-streets-v10' if 'style' in radar: style = radar['style'] return 'https://api.mapbox.com/styles/v1/' + \ style + \ '/static/' + \ str(radar['center'].lng) + ',' + \ str(radar['center'].lat) + ',' + \ str(radar['zoom']-1) + ',0,0/' + \ str(rsize.width()) + 'x' + str(rsize.height()) + \ '?access_token=' + ApiKeys.mbapi def googlemapurl(self, radar, rect): urlp = [] if len(ApiKeys.googleapi) > 0: urlp.append('key=' + ApiKeys.googleapi) urlp.append( 'center=' + str(radar['center'].lat) + ',' + str(radar['center'].lng)) zoom = radar['zoom'] rsize = rect.size() if rsize.width() > 640 or rsize.height() > 640: rsize = QtCore.QSize(rsize.width() / 2, rsize.height() / 2) zoom -= 1 urlp.append('zoom=' + str(zoom)) urlp.append('size=' + str(rsize.width()) + 'x' + str(rsize.height())) urlp.append('maptype=hybrid') return 'http://maps.googleapis.com/maps/api/staticmap?' + \ '&'.join(urlp) def basefinished(self): if self.basereply.error() != QNetworkReply.NoError: return self.basepixmap = QPixmap() self.basepixmap.loadFromData(self.basereply.readAll()) if self.basepixmap.size() != self.rect.size(): self.basepixmap = self.basepixmap.scaled(self.rect.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation) self.setPixmap(self.basepixmap) # make marker pixmap self.mkpixmap = QPixmap(self.basepixmap.size()) self.mkpixmap.fill(Qt.transparent) br = QBrush(QColor(Config.dimcolor)) painter = QPainter() painter.begin(self.mkpixmap) painter.fillRect(0, 0, self.mkpixmap.width(), self.mkpixmap.height(), br) for marker in self.radar['markers']: if 'visible' not in marker or marker['visible'] == 1: pt = getPoint(marker["location"], self.point, self.zoom, self.rect.width(), self.rect.height()) mk2 = QImage() mkfile = 'teardrop' if 'image' in marker: mkfile = marker['image'] if os.path.dirname(mkfile) == '': mkfile = os.path.join('markers', mkfile) if os.path.splitext(mkfile)[1] == '': mkfile += '.png' mk2.load(mkfile) if mk2.format != QImage.Format_ARGB32: mk2 = mk2.convertToFormat(QImage.Format_ARGB32) mkh = 80 # self.rect.height() / 5 if 'size' in marker: if marker['size'] == 'small': mkh = 64 if marker['size'] == 'mid': mkh = 70 if marker['size'] == 'tiny': mkh = 40 if 'color' in marker: c = QColor(marker['color']) (cr, cg, cb, ca) = c.getRgbF() for x in range(0, mk2.width()): for y in range(0, mk2.height()): (r, g, b, a) = QColor.fromRgba( mk2.pixel(x, y)).getRgbF() r = r * cr g = g * cg b = b * cb mk2.setPixel(x, y, QColor.fromRgbF(r, g, b, a) .rgba()) mk2 = mk2.scaledToHeight(mkh, 1) painter.drawImage(pt.x-mkh/2, pt.y-mkh/2, mk2) painter.end() self.wmk.setPixmap(self.mkpixmap) def getbase(self): global manager self.basereq = QNetworkRequest(QUrl(self.baseurl)) self.basereply = manager.get(self.basereq) QtCore.QObject.connect(self.basereply, QtCore.SIGNAL( "finished()"), self.basefinished) def start(self, interval=0): if interval > 0: self.interval = interval self.getbase() self.timer = QtCore.QTimer() self.timer.timeout.connect(self.rtick) self.lastget = time.time() - self.interval + random.uniform(3, 10) def wxstart(self): print "wxstart for " + self.myname self.timer.start(200) def wxstop(self): print "wxstop for " + self.myname self.timer.stop() def stop(self): try: self.timer.stop() self.timer = None except Exception: pass def realquit(): QtGui.QApplication.exit(0) def myquit(a=0, b=0): global objradar1, objradar2, objradar3, objradar4 global ctimer, wtimer, temptimer objradar1.stop() objradar2.stop() objradar3.stop() objradar4.stop() ctimer.stop() wxtimer.stop() temptimer.stop() if Config.useslideshow: objimage1.stop() QtCore.QTimer.singleShot(30, realquit) def fixupframe(frame, onoff): for child in frame.children(): if isinstance(child, Radar): if onoff: # print "calling wxstart on radar on ",frame.objectName() child.wxstart() else: # print "calling wxstop on radar on ",frame.objectName() child.wxstop() def nextframe(plusminus): global frames, framep frames[framep].setVisible(False) fixupframe(frames[framep], False) framep += plusminus if framep >= len(frames): framep = 0 if framep < 0: framep = len(frames) - 1 frames[framep].setVisible(True) fixupframe(frames[framep], True) class myMain(QtGui.QWidget): def keyPressEvent(self, event): global weatherplayer, lastkeytime if isinstance(event, QtGui.QKeyEvent): # print event.key(), format(event.key(), '08x') if event.key() == Qt.Key_F4: myquit() if event.key() == Qt.Key_F2: if time.time() > lastkeytime: if weatherplayer is None: weatherplayer = Popen( ["mpg123", "-q", Config.noaastream]) else: weatherplayer.kill() weatherplayer = None lastkeytime = time.time() + 2 if event.key() == Qt.Key_Space: nextframe(1) if event.key() == Qt.Key_Left: nextframe(-1) if event.key() == Qt.Key_Right: nextframe(1) if event.key() == Qt.Key_F6: # Previous Image objimage1.prev_next(-1) if event.key() == Qt.Key_F7: # Next Image objimage1.prev_next(1) if event.key() == Qt.Key_F8: # Play/Pause objimage1.play_pause() if event.key() == Qt.Key_F9: # Foreground Toggle if foreGround.isVisible(): foreGround.hide() else: foreGround.show() def mousePressEvent(self, event): if type(event) == QtGui.QMouseEvent: nextframe(1) configname = 'ConfigDay' if len(sys.argv) > 1: configname = sys.argv[1] if not os.path.isfile(configname + ".py"): print "Config file not found %s" % configname + ".py" exit(1) Config = __import__(configname) # define default values for new/optional config variables. try: Config.location except AttributeError: Config.location = Config.wulocation try: Config.metric except AttributeError: Config.metric = 0 try: Config.weather_refresh except AttributeError: Config.weather_refresh = 30 # minutes try: Config.radar_refresh except AttributeError: Config.radar_refresh = 10 # minutes try: Config.fontattr except AttributeError: Config.fontattr = '' try: Config.dimcolor except AttributeError: Config.dimcolor = QColor('#000000') Config.dimcolor.setAlpha(0) try: Config.DateLocale except AttributeError: Config.DateLocale = '' try: Config.wind_degrees except AttributeError: Config.wind_degrees = 0 try: Config.digital except AttributeError: Config.digital = 0 try: Config.Language except AttributeError: try: Config.Language = Config.wuLanguage except AttributeError: Config.Language = "en" try: Config.fontmult except AttributeError: Config.fontmult = 1.0 try: Config.LPressure except AttributeError: Config.LPressure = "Pressure " Config.LHumidity = "Humidity " Config.LWind = "Wind " Config.Lgusting = " gusting " Config.LFeelslike = "Feels like " Config.LPrecip1hr = " Precip 1hr:" Config.LToday = "Today: " Config.LSunRise = "Sun Rise:" Config.LSet = " Set: " Config.LMoonPhase = " Moon Phase:" Config.LInsideTemp = "Inside Temp " Config.LRain = " Rain: " Config.LSnow = " Snow: " try: Config.Lmoon1 Config.Lmoon2 Config.Lmoon3 Config.Lmoon4 Config.Lmoon5 Config.Lmoon6 Config.Lmoon7 Config.Lmoon8 except AttributeError: Config.Lmoon1 = 'New Moon' Config.Lmoon2 = 'Waxing Crescent' Config.Lmoon3 = 'First Quarter' Config.Lmoon4 = 'Waxing Gibbous' Config.Lmoon5 = 'Full Moon' Config.Lmoon6 = 'Waning Gibbous' Config.Lmoon7 = 'Third Quarter' Config.Lmoon8 = 'Waning Crecent' try: Config.digitalformat2 except AttributeError: Config.digitalformat2 = "{0:%H:%M:%S}" try: Config.useslideshow except AttributeError: Config.useslideshow = 0 # # Check if Mapbox API key is set, and use mapbox if so try: if ApiKeys.mbapi[:3].lower() == "pk.": Config.usemapbox = 1 except AttributeError: pass try: if Config.METAR != '': from metar import Metar except AttributeError: pass lastmin = -1 lastday = -1 pdy = "" lasttimestr = "" weatherplayer = None lastkeytime = 0 lastapiget = time.time() app = QtGui.QApplication(sys.argv) desktop = app.desktop() rec = desktop.screenGeometry() height = rec.height() width = rec.width() signal.signal(signal.SIGINT, myquit) w = myMain() w.setWindowTitle(os.path.basename(__file__)) w.setStyleSheet("QWidget { background-color: black;}") # fullbgpixmap = QtGui.QPixmap(Config.background) # fullbgrect = fullbgpixmap.rect() # xscale = float(width)/fullbgpixmap.width() # yscale = float(height)/fullbgpixmap.height() xscale = float(width) / 1440.0 yscale = float(height) / 900.0 frames = [] framep = 0 frame1 = QtGui.QFrame(w) frame1.setObjectName("frame1") frame1.setGeometry(0, 0, width, height) frame1.setStyleSheet("#frame1 { background-color: black; border-image: url(" + Config.background + ") 0 0 0 0 stretch stretch;}") frames.append(frame1) if Config.useslideshow: imgRect = QtCore.QRect(0, 0, width, height) objimage1 = SS(frame1, imgRect, "image1") frame2 = QtGui.QFrame(w) frame2.setObjectName("frame2") frame2.setGeometry(0, 0, width, height) frame2.setStyleSheet("#frame2 { background-color: blue; border-image: url(" + Config.background + ") 0 0 0 0 stretch stretch;}") frame2.setVisible(False) frames.append(frame2) # frame3 = QtGui.QFrame(w) # frame3.setObjectName("frame3") # frame3.setGeometry(0,0,width,height) # frame3.setStyleSheet("#frame3 { background-color: blue; border-image: # url("+Config.background+") 0 0 0 0 stretch stretch;}") # frame3.setVisible(False) # frames.append(frame3) foreGround = QtGui.QFrame(frame1) foreGround.setObjectName("foreGround") foreGround.setStyleSheet("#foreGround { background-color: transparent; }") foreGround.setGeometry(0, 0, width, height) squares1 = QtGui.QFrame(foreGround) squares1.setObjectName("squares1") squares1.setGeometry(0, height - yscale * 600, xscale * 340, yscale * 600) squares1.setStyleSheet( "#squares1 { background-color: transparent; border-image: url(" + Config.squares1 + ") 0 0 0 0 stretch stretch;}") squares2 = QtGui.QFrame(foreGround) squares2.setObjectName("squares2") squares2.setGeometry(width - xscale * 340, 0, xscale * 340, yscale * 900) squares2.setStyleSheet( "#squares2 { background-color: transparent; border-image: url(" + Config.squares2 + ") 0 0 0 0 stretch stretch;}") if not Config.digital: clockface = QtGui.QFrame(foreGround) clockface.setObjectName("clockface") clockrect = QtCore.QRect( width / 2 - height * .4, # 2 .4 height * .45 - height * .35, # .45 .35 Just had to lower the entire clock by a little, was a little too high height * .8, #.8 height * .8) #.8 clockface.setGeometry(clockrect) clockface.setStyleSheet( "#clockface { background-color: transparent; border-image: url(" + Config.clockface + ") 0 0 0 0 stretch stretch;}") hourhand = QtGui.QLabel(foreGround) hourhand.setObjectName("hourhand") hourhand.setStyleSheet("#hourhand { background-color: transparent; }") minhand = QtGui.QLabel(foreGround) minhand.setObjectName("minhand") minhand.setStyleSheet("#minhand { background-color: transparent; }") sechand = QtGui.QLabel(foreGround) sechand.setObjectName("sechand") sechand.setStyleSheet("#sechand { background-color: transparent; }") hourpixmap = QtGui.QPixmap(Config.hourhand) hourpixmap2 = QtGui.QPixmap(Config.hourhand) minpixmap = QtGui.QPixmap(Config.minhand) minpixmap2 = QtGui.QPixmap(Config.minhand) secpixmap = QtGui.QPixmap(Config.sechand) secpixmap2 = QtGui.QPixmap(Config.sechand) else: clockface = QtGui.QLabel(foreGround) clockface.setObjectName("clockface") clockrect = QtCore.QRect( width / 2 - height * .4, height * .45 - height * .4, height * .8, height * .8) clockface.setGeometry(clockrect) dcolor = QColor(Config.digitalcolor).darker(0).name() lcolor = QColor(Config.digitalcolor).lighter(120).name() clockface.setStyleSheet( "#clockface { background-color: transparent; font-family:sans-serif;" + " font-weight: light; color: " + lcolor + "; background-color: transparent; font-size: " + str(int(Config.digitalsize * xscale)) + "px; " + Config.fontattr + "}") clockface.setAlignment(Qt.AlignCenter) clockface.setGeometry(clockrect) glow = QtGui.QGraphicsDropShadowEffect() glow.setOffset(0) glow.setBlurRadius(50) glow.setColor(QColor(dcolor)) clockface.setGraphicsEffect(glow) radar1rect = QtCore.QRect(3 * xscale, 344 * yscale, 300 * xscale, 275 * yscale) objradar1 = Radar(foreGround, Config.radar1, radar1rect, "radar1") radar2rect = QtCore.QRect(3 * xscale, 622 * yscale, 300 * xscale, 275 * yscale) objradar2 = Radar(foreGround, Config.radar2, radar2rect, "radar2") radar3rect = QtCore.QRect(13 * xscale, 50 * yscale, 700 * xscale, 700 * yscale) # left map of the second page objradar3 = Radar(frame2, Config.radar3, radar3rect, "radar3") radar4rect = QtCore.QRect(726 * xscale, 50 * yscale, 700 * xscale, 700 * yscale)#right card objradar4 = Radar(frame2, Config.radar4, radar4rect, "radar4") datex = QtGui.QLabel(foreGround) datex.setObjectName("datex") datex.setStyleSheet("#datex { font-family:sans-serif; color: " +# Top line color (date) Config.textcolorTopLine + "; background-color: transparent; font-size: " + str(int(47 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") datex.setAlignment(Qt.AlignHCenter | Qt.AlignTop) datex.setGeometry(0, 0, width, 100 * yscale) datex2 = QtGui.QLabel(frame2) datex2.setObjectName("datex2") datex2.setStyleSheet("#datex2 { font-family:sans-serif; color: " +# Color Day of week on second page Config.textcolorDatex2 + "; background-color: transparent; font-size: " + str(int(50 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") datex2.setAlignment(Qt.AlignHCenter | Qt.AlignTop) datex2.setGeometry(800 * xscale, 780 * yscale, 640 * xscale, 100)# 800 780 640 100 Date on second page datey2 = QtGui.QLabel(frame2) datey2.setObjectName("datey2") datey2.setStyleSheet("#datey2 { font-family:sans-serif; color: " +# Time on second page Config.textcolorDatey2 + "; background-color: transparent; font-size: " + str(int(50 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") datey2.setAlignment(Qt.AlignHCenter | Qt.AlignTop) datey2.setGeometry(800 * xscale, 840 * yscale, 640 * xscale, 100)# 800 840 640 100 Time to second page attribution = QtGui.QLabel(foreGround) attribution.setObjectName("attribution") attribution.setStyleSheet("#attribution { " + # Climacell text top left on first page " background-color: transparent; color: " + Config.textcolorClimaCell + "; font-size: " + str(int(12 * xscale)) + "px; " + Config.fontattr + "}") attribution.setAlignment(Qt.AlignTop) attribution.setGeometry(6 * xscale, 3 * yscale, 100 * xscale, 100) ypos = -25 wxicon = QtGui.QLabel(foreGround) wxicon.setObjectName("wxicon") wxicon.setStyleSheet("#wxicon { background-color: transparent; }") wxicon.setGeometry(75 * xscale, ypos * yscale, 150 * xscale, 150 * yscale)# 75 150 150 icon top left attribution2 = QtGui.QLabel(frame2) attribution2.setObjectName("attribution2") attribution2.setStyleSheet("#attribution2 { " + # 12 Climacell text at bottom left on second page "background-color: transparent; color: " + Config.textcolorClimaCell2 + "; font-size: " + str(int(12 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") attribution2.setAlignment(Qt.AlignTop) attribution2.setGeometry(6 * xscale, 880 * yscale, 100 * xscale, 100) wxicon2 = QtGui.QLabel(frame2) wxicon2.setObjectName("wxicon2") wxicon2.setStyleSheet("#wxicon2 { background-color: transparent; }") wxicon2.setGeometry(0 * xscale, 750 * yscale, 150 * xscale, 150 * yscale) ypos += 130 wxdesc = QtGui.QLabel(foreGround) wxdesc.setObjectName("wxdesc") wxdesc.setStyleSheet("#wxdesc { background-color: transparent; color: " +# Current weather first page color on top left "CLEAR" Config.textcolorWeather + "; font-size: " + str(int(30 * xscale)) + "px; " + Config.fontattr + "}") wxdesc.setAlignment(Qt.AlignHCenter | Qt.AlignTop) wxdesc.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) wxdesc2 = QtGui.QLabel(frame2) wxdesc2.setObjectName("wxdesc2") wxdesc2.setStyleSheet("#wxdesc2 { background-color: transparent; color: " +# Weather text color on the second page Config.textcolorWeather2 + "; font-size: " + str(int(50 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") wxdesc2.setAlignment(Qt.AlignLeft | Qt.AlignTop) wxdesc2.setGeometry(400 * xscale, 800 * yscale, 400 * xscale, 100) # Weather condition on the 2nd page ypos += 25 temper = QtGui.QLabel(foreGround) temper.setObjectName("temper") temper.setStyleSheet("#temper { background-color: transparent; color: " +# Temperature at the top left first page Config.textcolorTemper + "; font-size: " + str(int(70 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") temper.setAlignment(Qt.AlignHCenter | Qt.AlignTop) temper.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100 * yscale) temper2 = QtGui.QLabel(frame2) temper2.setObjectName("temper2") temper2.setStyleSheet("#temper2 { background-color: transparent; color: " +# Temperature on the left on the second page Config.textcolorTemper2 + "; font-size: " + str(int(70 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") temper2.setAlignment(Qt.AlignHCenter | Qt.AlignTop) temper2.setGeometry(125 * xscale, 780 * yscale, 300 * xscale, 100) ypos += 80 press = QtGui.QLabel(foreGround) press.setObjectName("press") press.setStyleSheet("#press { background-color: transparent; color: " +# Pressure text color first page Config.textcolorPress + "; font-size: " + str(int(25 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") press.setAlignment(Qt.AlignHCenter | Qt.AlignTop) press.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) ypos += 30 humidity = QtGui.QLabel(foreGround) humidity.setObjectName("humidity") humidity.setStyleSheet("#humidity { background-color: transparent; color: " +# Humidity text first page Config.textcolorHumidity + "; font-size: " + str(int(25 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") humidity.setAlignment(Qt.AlignHCenter | Qt.AlignTop) humidity.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) ypos += 30 wind = QtGui.QLabel(foreGround) wind.setObjectName("wind") wind.setStyleSheet("#wind { background-color: transparent; color: " +#Color of wind speed first page Config.textcolorWind + "; font-size: " + str(int(20 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") wind.setAlignment(Qt.AlignHCenter | Qt.AlignTop) wind.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) ypos += 20 wind2 = QtGui.QLabel(foreGround) wind2.setObjectName("wind2") wind2.setStyleSheet("#wind2 { background-color: transparent; color: " +# Feels like temp first page Config.textcolorFeelsLike + "; font-size: " + str(int(22 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") wind2.setAlignment(Qt.AlignHCenter | Qt.AlignTop) wind2.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) ypos += 20 wdate = QtGui.QLabel(foreGround) wdate.setObjectName("wdate") wdate.setStyleSheet("#wdate { background-color: transparent; color: " +#15 Font size Data on:? Config.textcolorDataOn + "; font-size: " + str(int(15 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") wdate.setAlignment(Qt.AlignHCenter | Qt.AlignTop) wdate.setGeometry(3 * xscale, ypos * yscale, 300 * xscale, 100) bottom = QtGui.QLabel(foreGround) bottom.setObjectName("bottom") bottom.setStyleSheet("#bottom { font-family:sans-serif; color: " +# Bottom line text first page (moon, sun rise/set) Config.textcolorBottom + "; background-color: transparent; font-size: " + str(int(28 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") bottom.setAlignment(Qt.AlignHCenter | Qt.AlignTop) bottom.setGeometry(0, height - 50 * yscale, width, 50 * yscale) temp = QtGui.QLabel(foreGround) temp.setObjectName("temp") temp.setStyleSheet("#temp { font-family:sans-serif; color: " +# Color temperature DS18b20 Config.textcolorDS18b20 + "; background-color: transparent; font-size: " + str(int(30 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") temp.setAlignment(Qt.AlignHCenter | Qt.AlignTop) temp.setGeometry(0, height - 100 * yscale, width, 50 * yscale) forecast = [] for i in range(0, 9): lab = QtGui.QLabel(foreGround) lab.setObjectName("forecast" + str(i)) # lab.setStyleSheet("QWidget { background-color: transparent; color: " + lab.setStyleSheet("QWidget { background-color: transparent" + # Config.textcolorTime69 + "; font-size: " + str(int(20 * xscale * Config.fontmult)) + "px; " + Config.fontattr + "}") # lab.setStyleSheet("QWidget { background-color: transparent; font-size: " + # str(int(20 * xscale * Config.fontmult)) + # "px; " + # Config.fontattr + # "}") lab.setGeometry(1137 * xscale, i * 100 * yscale, 300 * xscale, 100 * yscale) icon = QtGui.QLabel(lab) #Icon icon.setStyleSheet("#icon { background-color: transparent; }") icon.setGeometry(0, 0, 100 * xscale, 100 * yscale) icon.setObjectName("icon") wx = QtGui.QLabel(lab) # wx.setStyleSheet(Config.textcolorwx) wx.setStyleSheet("#wx { background-color: transparent; color:" + Config.textcolorTime13 + ";}") # wx.setStyleSheet("#wx { background-color: transparent;}") wx.setGeometry(100 * xscale, 5 * yscale, 200 * xscale, 120 * yscale) wx.setAlignment(Qt.AlignLeft | Qt.AlignTop)#Text alignment weather condition 1-9 line wx.setWordWrap(True) wx.setObjectName("wx") day = QtGui.QLabel(lab) # day.setStyleSheet(Config.textcolorDayWeek)# #The color of all the days of the week day.setStyleSheet("#day { background-color: transparent; }" + Config.textcolorTime69 + ";}") # day.setStyleSheet("#day { background-color: transparent; }") day.setGeometry(100 * xscale, 75 * yscale, 200 * xscale, 25 * yscale) #Date day.setAlignment(Qt.AlignRight | Qt.AlignBottom) #Aligning days of the week day.setObjectName("day") forecast.append(lab) manager = QtNetwork.QNetworkAccessManager() # proxy = QNetworkProxy() # proxy.setType(QNetworkProxy.HttpProxy) # proxy.setHostName("localhost") # proxy.setPort(8888) # QNetworkProxy.setApplicationProxy(proxy) stimer = QtCore.QTimer() stimer.singleShot(10, qtstart) # print radarurl(Config.radar1,radar1rect) w.show() w.showFullScreen() sys.exit(app.exec_())