#!/usr/bin/python3 """ A simple script that sends the daily weather to a FreeMobile phone """ import datetime import json import locale import logging import os import pyowm import requests import sys class WeatherToFreemobile(): def __init__(self, config_file): logging.info('Load configuration from {}'.format(config_file)) with open(config_file) as configuration: self.config = json.load(configuration) logging.info('Setting locale') try: locale.setlocale(locale.LC_TIME, self.config['locale']) except locale.Error: logging.warning( 'Error setting locale {}'.format(self.config['locale']) ) logging.info('Opening OpenWeatherMap API') apikey = self.config['openweathermap_apikey'] apilanguage = self.config['openweathermap_language'] self.owm = pyowm.OWM(apikey, language=apilanguage) def send_sms_to_freemobile(self, message): """ Sends a SMS using the FreeMobile API https://mobile.free.fr/moncompte/index.php?page=options """ data = { 'user': self.config['freemobile_user'], 'pass': self.config['freemobile_apikey'], 'msg': bytes(message, 'utf-8').decode('iso-8859-1') } logging.debug(data) logging.info('Contacting FreeMobile API') r = requests.post('https://smsapi.free-mobile.fr/sendmsg', json=data) if r.status_code == 200: logging.info('SMS sent') else: logging.warning('SMS *not* sent. Status code %s', r.status_code) def get_weather(self): """ Gets the weather forecast from OpenWeatherMap """ city = self.config['openweathermap_city'] number_of_days = self.config['number_of_days'] fc = self.owm.daily_forecast(city, limit=number_of_days+1) f = fc.get_forecast() return_message = [] for weather in f: weather_date = weather.get_reference_time('date') date_diff = weather_date.date() - datetime.date.today() # Workaround API returning yesterday's weather" # https://openweathermap.desk.com/customer/en/portal/questions/ # 17649060-between-hours-of-12-midnight-and-7am-gmt-we-are-receiving # -the-wrong-data-for-most-locations if( date_diff < datetime.timedelta(0) or date_diff >= datetime.timedelta(number_of_days) ): logging.info('Skipped {} (cf. API Bug)'.format(weather_date)) else: temp = weather.get_temperature(unit='celsius') rain = weather.get_rain().get('all', 0) return_message.append( '{}: {} (min {}ºC, max {}ºC, rain:{}mm)'.format( weather_date.strftime('%A %d').title(), weather.get_detailed_status(), round(float(temp['min'])), round(float(temp['max'])), rain ) ) if(rain and date_diff == datetime.timedelta(0)): return_message.append(self.get_rain()) logging.info("Got the following weather: {}".format(return_message)) return "\n".join(return_message) def get_rain(self): """ Gets the rain forecast from OpenWeatherMap """ city = self.config['openweathermap_city'] fc = self.owm.three_hours_forecast(city) f = fc.get_forecast() return_message = [] for weather in f: weather_date = weather.get_reference_time('date') if(weather_date.date() != datetime.date.today()): break return_message.append(" - {:2d}h : {}mm".format( weather_date.hour, round(float(weather.get_rain().get('3h', 0)), 1) )) return "\n".join(return_message) if __name__ == "__main__": logging.basicConfig( level=logging.WARNING, format=' %(asctime)s - %(levelname)s - %(message)s' ) if len(sys.argv) > 1: wtf = WeatherToFreemobile(sys.argv[1]) else: config_file = os.path.join( os.path.dirname(os.path.realpath(sys.argv[0])), 'config.json' ) wtf = WeatherToFreemobile(config_file) wtf.send_sms_to_freemobile(wtf.get_weather())