def parseTimeZone( tweet_dict ): # Method to retrieve the timezone based on the user coordinates. tf = TimezoneFinder() if 'place' in tweet_dict.keys(): if tweet_dict['place'] is not None: if 'bounding_box' in tweet_dict['place'].keys(): if 'coordinates' in tweet_dict['place']['bounding_box'].keys(): if len(tweet_dict['place']['bounding_box'] ['coordinates']) > 0: longitude = float(tweet_dict['place']['bounding_box'] ['coordinates'][0][0][0]) latitude = float(tweet_dict['place']['bounding_box'] ['coordinates'][0][0][1]) timezone = tf.timezone_at(lat=latitude, lng=longitude) if timezone is None: timezone = tf.closest_timezone_at(lat=latitude, lng=longitude) return timezone else: return None else: return None else: return None else: return None else: return None
def detect_timezone(config): try: tf = TimezoneFinder() timezone_str = tf.timezone_at(lng=config.lat_lon_coord[1], lat=config.lat_lon_coord[0]) if (timezone_str == None): timezone_str = tf.certain_timezone_at(lng=config.lat_lon_coord[1], lat=config.lat_lon_coord[0]) elif (timezone_str == None): timezone_str = tf.closest_timezone_at(lng=config.lat_lon_coord[1], lat=config.lat_lon_coord[0]) if (timezone_str != None): config.timezone = timezone(timezone_str) config.tz_label = config.timezone config.valid = True config.logger.console_log(config, "control", "info", "timezone detected >> " + timezone_str, False) else: if (config.mode == "batch"): config.logger.console_log( config, "control", "error", "timezone could not be auto-detected, given lat long may be offshore", True) #exit on auto detect failure else: config.logger.console_log( config, "control", "error", "timezone could not be auto-detected, given lat long may be offshore", False) except: config.logger.console_log(config, "control", "error", "Timezone detect encoutered an error", False) return config
def time(self, city: str): g = geocoders.GoogleV3() (latitude, longitude) = g.geocode(city)[1] tf = TzF() dt_format = "%I:%M %p" time = datetime.now( timezone(tf.closest_timezone_at(lng=longitude, lat=latitude))).strftime(dt_format) return time
def get_tz(location): tf = TimezoneFinder() try: tz_str = tf.closest_timezone_at(lat=location.latitude, lng=location.longitude) except Exception as e: tz_str = 'UTC' #log return tz_str
def timezone_name(self): tz_finder = TimezoneFinder() tz_name = tz_finder.timezone_at(lng=self.longitude, lat=self.latitude) if tz_name is None: tz_name = tz_finder.closest_timezone_at(lng=self.longitude, lat=self.latitude) if tz_name is None: raise ValueError('No timezone exists for this geo location') return tz_name
def get_offset(lat, lng): """ returns a location's time zone offset from UTC in minutes. """ tf = TimezoneFinder() today = datetime.now() tz_name = timezone(tf.closest_timezone_at(lng=lng, lat=lat)) # ATTENTION: tz_target could be None! handle error case today_target = tz_target.localize(today) today_utc = utc.localize(today) return (today_utc - today_target).total_seconds() / 60
def get_timezone(lat, lon): """ returns time difference in hours""" tf = TimezoneFinder() tz = tf.closest_timezone_at(lng=lon, lat=lat) #print("TZ-------------", tz, lat, lon) dtest = datetime.datetime(2010, 2, 1, 0) t1 = pd.Timestamp(dtest).tz_localize(tz) # local time t2 = t1.tz_convert("utc") # utc time t1 = t1.tz_localize(None) t2 = t2.tz_localize(None) # returns hours. must add this to local time to get utc. return (t2 - t1).seconds / 3600.0
def user_login_preupdate(sender, user, **kwargs): # get request data from custom middleware thread_local = RequestMiddleware.thread_local if hasattr(thread_local, 'request'): request = thread_local.request userIP = request.META['REMOTE_ADDR'] else: excp_lg.error('No http request available for:' + user.username) userIP = None if userIP == "127.0.0.1": userIP = "98.204.240.42" if userIP: try: geo = GeoIP2() city_dx = geo.city(userIP) lat = float(city_dx['latitude']) lng = float(city_dx['longitude']) tf = TimezoneFinder() timezone = tf.timezone_at(lng=lng, lat=lat) if timezone is None: timezone = tf.closest_timezone_at(lng=lng, lat=lat) if not timezone: excp_lg.error("TimeZone not found for " + user.username) prof_m = MT.Profile.objects.get(UserFK=user) prof_m.IP = userIP prof_m.Country = city_dx['country_name'] prof_m.Region = city_dx['region'] prof_m.City = city_dx['city'] prof_m.TimeZone = timezone prof_m.save() except Exception as ex: excp_lg.error(ex) # display welcome message if not user.last_login: first_login = True # reconnect the built-in signal update_last_login(sender, user, **kwargs)
def getTimeZone( location ): from timezonefinder import TimezoneFinder tf = TimezoneFinder( ) if isinstance( location, str ): location = getLocation( location ) elif not isinstance( location, RPNLocation ): raise ValueError( 'location name or location object expected' ) timezone_name = tf.timezone_at( lat = location.getLat( ), lng = location.getLong( ) ) if timezone_name is None: timezone_name = tf.closest_timezone_at( lat = location.getLat( ), lng = location.getLong( ) ) return timezone_name
def getTimeZoneName(value): if isinstance(value, RPNDateTime): return value.tzname() if isinstance(value, str): value = getLocation(value) elif not isinstance(value, RPNLocation): raise ValueError('location name or location object expected') tzFinder = TimezoneFinder() timezoneName = tzFinder.timezone_at(lat=value.getLat(), lng=value.getLong()) if timezoneName is None: timezoneName = tzFinder.closest_timezone_at(lat=value.getLat(), lng=value.getLong()) return timezoneName
def find_timezone(lat, lng): tf = TimezoneFinder() lat = float(lat) lng = float(lng) try: timezone_name = tf.timezone_at(lng=lng, lat=lat) if timezone_name is None: timezone_name = tf.closest_timezone_at(lng=lng, lat=lat) if timezone_name is None: timezone_name = 'UTC' # maybe even increase the search radius when it is still None except ValueError: timezone_name = 'UTC' except UnknownTimeZoneError: timezone_name = 'UTC' return timezone_name
def update_local_timezone(self): ############################################################################################################# # # set_city_tz_date_time() uses package TimezoneFinder # https://github.com/MrMinimal64/timezonefinder # # timezone_at() # This is the default function to check which timezone a point lies within # - (similar to tzwheres tzNameAt()). # - If no timezone has been found, None is being returned. # PLEASE NOTE: This approach is optimized for speed and the common case to only query # points within a timezone. The last possible timezone in proximity is always returned # (without checking if the point is really included). # # So results might be misleading for points outside of any timezone. # # Example: # longitude = 13.358 # latitude = 52.5061 # tf.timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Berlin' # # certain_timezone_at() # NOTE: The timezone polygons do NOT follow the shorelines any more! This causes the # computed distance from a timezone polygon to be not really meaningful/accurate. # # Only use this when the point is not inside a polygon (simply computes and compares the # distances to the polygon boundaries!). This returns the closest timezone of all polygons # within +-1 degree lng and +-1 degree lat (or None). # # Example: # longitude = 12.773955 # latitude = 55.578595 # tf.closest_timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Copenhagen' # ############################################################################################################# tf = TimezoneFinder() # self.local_timezone will be of string format 'Europe/London' self.local_timezone = tf.closest_timezone_at(lng=self.geocode_lng, lat=self.geocode_lat)
def nux_finalize(request): response_data = {} # print("SAVE SETTINGS") # CREATE USER SETTINGS working_settings = UserSetting(user=request.user, begin_date=pytz.utc.localize( datetime.now())) working_settings.save() working_settings.phone_input = request.POST['phone_input'] working_settings.phone = request.POST['phone_input'] working_carrier = Carrier.objects.all().get( carrier=request.POST['carrier_search']) if 'location' in request.POST.keys(): working_settings.location = request.POST['location'] # Figure out the TZ g = geocoders.GoogleV3() place, (lat, lng) = g.geocode(request.POST['location']) tf = TimezoneFinder() timeZoneStr = tf.closest_timezone_at(lng=lng, lat=lat) working_settings.timezone_search = timeZoneStr working_settings.timezone = timeZoneStr # working_settings.timezone_search = if 'carrier_search' in request.POST.keys(): working_settings.carrier = request.POST['carrier_search'] #set up the SMS address working_settings.sms_address = working_settings.phone_input + working_carrier.sms_address working_settings.settings_complete = True working_settings.send_text_check = True working_settings.send_text = True working_settings.text_request_stop = False working_settings.save() # Make the timing working_timing = Timing(user=request.user, default_timing=False, fuzzy=True, repeat=True) working_timing.save() working_timing = save_timing_function(request, working_timing) working_timing.save() # CREATE POSSIBLE TEXT working_text = PossibleText(user=request.user, text=request.POST['text_content'], date_created=datetime.now(pytz.utc)) working_text.save() working_text.timing = working_timing working_text.tmp_save = False working_text.save() # SEND WELCOM TEXT wtc = "Welcome to Sentimini! If you didn't just sign up, then just text 'stop'. Otherwise schedule some texts!" if PossibleText.objects.all().filter(user=request.user).filter( text=wtc).count() < 1: welcome_text_p = PossibleText(user=request.user, text=wtc, active=False, tmp_save=True) welcome_text_p.save() welcome_text_p = PossibleText.objects.all().filter(user=request.user).get( text=wtc) print("welcome_text_p", welcome_text_p) welcome_text_a = ActualText(user=request.user, text=welcome_text_p, time_to_send=datetime.now(pytz.utc)) welcome_text_a.save() return HttpResponse(json.dumps(response_data), content_type="application/json")
#: NOTE: External packages that needs to be installed. import arrow import requests from timezonefinder import TimezoneFinder longitude = -35.201 latitude = -5.766 tf = TimezoneFinder(in_memory=True) timezone = tf.closest_timezone_at(lng=longitude, lat=latitude) response = requests.get('https://api.stormglass.io/v1/tide/extremes/point', params={ 'lat': latitude, 'lng': longitude }, headers={'Authorization': '<ENTER API KEY>'}) json_data = response.json() print(f'Distance to station: {json_data["meta"]["station"]["distance"]}') for extrema in json_data['extremes']: print( f'{arrow.get(extrema["timestamp"]).to(timezone).format("dddd HH:mm")}: {extrema["height"]}' )
def __init__(self, dataframe): self.df = dataframe.copy() #self.df = self.df.assign(distance = lambda x: haversine((x.icao_dep_latitude,x.icao_dep_longitude),(x.icao_arr_latitude,x.icao_arr_longitude),unit='nmi')) # (1) Calculate the haversine distance between origin and destination # (2) And, using GPS coordinates, look up the time zone offset on arrival! distances = [] tzO = [] # List of timezones at origin airport(s) tzD = [] # List of timezone names at arrival airport(s) for r in self.df[[ 'icao_dep_latitude', 'icao_dep_longitude', 'icao_arr_latitude', 'icao_arr_longitude' ]].itertuples(index=False): (lat1, lon1, lat2, lon2) = r tf = TimezoneFinder() dist = haversine((lat1, lon1), (lat2, lon2), unit='nmi') dist = int(dist) distances.append(dist) try: tzO_name = timezone(tf.closest_timezone_at(lat=lat1, lng=lon1)) except: tzD_name = timezone(tf.closest_timezone_at(lat=lat2, lng=lon2)) tzO_name = tzD_name try: tzD_name = timezone(tf.closest_timezone_at(lat=lat2, lng=lon2)) except: tzD_name = tzO_name tzO.append(tzO_name) tzD.append(tzD_name) self.df = self.df.assign(distance=distances) self.df = self.df.assign(tzo=tzO) # hh:mm time zone difference self.df = self.df.assign( tzd=tzD) # time zone difference in minutes (as float) # Calculate the time en route based on aircraft climb/cruise speeds # and haversine distance # # Also, the estimated arrival time! ete = [] arrivaltimes = [] arrivaldays = [] arrivaldisplay = [] for i, r in self.df.iterrows(): dist = float(r.distance) speed1 = float(r.speed1) speed2 = float(r.speed2) #offset = float(r.offset) if dist < 80: enroute = dist / speed1 * 60.0 minutes = enroute % 60 hours = int(enroute / 60) minutes = int(minutes) hours = int(enroute / 60) else: enroute1 = 80.0 / speed1 * 60.0 enroute2 = (dist - 80.0) / speed2 * 60.0 enroute = enroute1 + enroute2 minutes = enroute % 60 minutes = int(minutes) hours = int(enroute / 60) ete.append('{:02d}'.format(hours) + ':' + '{:02d}'.format(minutes)) # Calculate arrival time metadata = ModelMetaData() depstring = str(r.weekdayid) + ' ' + r.departing timeObject = datetime.strptime(depstring, '%w %H:%M') timeObject = timezone(str(r.tzo)).localize(timeObject) timeObject = timeObject + timedelta(minutes=enroute + 20) arrivalObject = timeObject.astimezone(timezone(str(r.tzd))) arrivalDay = int(arrivalObject.strftime('%w')) arrivalDay -= 1 arrivalDay = (int(r.weekdayid) + arrivalDay) % 7 arrivaldays.append(arrivalDay) arrivaltimes.append(arrivalObject.strftime('%H:%M')) arrivaldisplay.append(metadata.dayIndex[arrivalDay] + ' ' + arrivalObject.strftime('%H:%M')) self.df = self.df.assign(duration=ete) self.df = self.df.assign(arrivalday=arrivaldays) self.df = self.df.assign(arrivaltime=arrivaltimes) self.df = self.df.assign(arriving=arrivaldisplay)
from timezonefinder import TimezoneFinder TimezoneFinder.using_numba() # this is a static method returning True or False tf = TimezoneFinder() # or tf = TimezoneFinder(in_memory=True) longitude, latitude = 13.358, 52.5061 tf.timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Berlin' tf.certain_timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Berlin' longitude = 12.773955 latitude = 55.578595 tf.closest_timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Copenhagen' longitude = 42.1052479 latitude = -16.622686 tf.closest_timezone_at(lng=longitude, lat=latitude, delta_degree=2, exact_computation=True, return_distances=True, force_evaluation=True) tf.get_geometry(tz_name='Africa/Addis_Ababa', coords_as_pairs=True) tf.get_geometry(tz_id=400, use_id=True) # To maximize the chances of getting a result in a Django view it might look like:
from timezonefinder import TimezoneFinder tf = TimezoneFinder() for longitude in range(-180, 180, 10): for latitude in range(-90, 90, 10): timezone_name = tf.closest_timezone_at(lng=longitude, lat=latitude, delta_degree=3) if timezone_name != None: print(longitude, latitude, timezone_name)
exit() try: from timezonefinder import TimezoneFinder except Exception as e: print(e) exit() tz = TimezoneFinder() try: tz_str = tz.timezone_at(lng=lon, lat=lat) if tz_str == None: #tz_str = tz.certain_timezone_at(lng=lon, lat=lat) tz_str = tz.closest_timezone_at(lng=lon, lat=lat) print(tz_str) if tz_str != None: cmd = [ "sudo", "timedatectl", "set-timezone", tz_str, ] print(cmd) try: subprocess.run(cmd) except: subprocess.call(cmd)
def save_settings(request): response_data = {} # print("SAVE SETTINGS") if 'id' in request.POST.keys(): if request.POST['save_type'] == "save_settings_button": working_settings = UserSetting.objects.all().get( id=int(request.POST['id'])) working_settings.phone_input = request.POST['phone_input'] working_settings.phone = request.POST['phone_input'] working_carrier = Carrier.objects.all().get( carrier=request.POST['carrier_search']) if 'location' in request.POST.keys(): working_settings.location = request.POST['location'] print("LOCATION", request.POST['location']) # Figure out the TZ g = geocoders.GoogleV3() place, (lat, lng) = g.geocode(request.POST['location']) print("place", place) print("lat", lat) print("lng", lng) tf = TimezoneFinder() timeZoneStr = tf.closest_timezone_at(lng=lng, lat=lat) print("timeZoneStr", timeZoneStr) working_settings.timezone_search = timeZoneStr working_settings.timezone = timeZoneStr # working_settings.timezone_search = if 'carrier_search' in request.POST.keys(): working_settings.carrier = request.POST['carrier_search'] if request.POST['email_checkbox'] == 'true': working_settings.send_email_check = True else: working_settings.send_email_check = False if request.POST['text_checkbox'] == 'true': working_settings.send_text_check = True else: working_settings.send_text_check = False if request.POST['research_check'] == 'true': working_settings.research_check = True else: working_settings.research_check = False if request.POST['pause_text_checkbox'] == 'true': working_settings.pause_text_checkbox = True else: working_settings.pause_text_checkbox = False ##### DO THE PROCESS #set up the timezone # if 'Eastern Standard Time' in request.POST['tz_search']: # working_settings.timezone = 'America/New_York' # elif 'Central Standard Time' in request.POST['tz_search']: # working_settings.timezone = 'America/Chicago' # elif 'Mountain Standard Time' in request.POST['tz_search']: # working_settings.timezone = 'America/Denver' # elif 'Pacific Standard Time' in request.POST['tz_search']: # working_settings.timezone = 'America/Los_Angeles' # else: # working_settings.timezone = working_settings.timezone_search #set up the SMS address working_settings.sms_address = working_settings.phone_input + working_carrier.sms_address working_settings.settings_complete = True working_settings.send_text_check = True working_settings.send_text = True working_settings.text_request_stop = False working_settings.save() wtc = "Welcome to Sentimini! If you didn't just sign up, then just text 'stop'. Otherwise schedule some texts!" if PossibleText.objects.all().filter(user=request.user).filter( text=wtc).count() < 1: welcome_text_p = PossibleText(user=request.user, text=wtc, active=False, tmp_save=True) welcome_text_p.save() welcome_text_p = PossibleText.objects.all().filter( user=request.user).get(text=wtc) print("welcome_text_p", welcome_text_p) welcome_text_a = ActualText(user=request.user, text=welcome_text_p, time_to_send=datetime.now(pytz.utc)) welcome_text_a.save() else: print("REJECT SETTINGS") working_settings = UserSetting.objects.all().get( id=int(request.POST['id'])) working_settings.settings_complete = True working_settings.send_text_check = False working_settings.send_text = False working_settings.text_request_stop = True working_settings.save() return HttpResponse(json.dumps(response_data), content_type="application/json")
from timezonefinder import TimezoneFinder TimezoneFinder.using_numba() # this is a static method returning True or False tf = TimezoneFinder() # or tf = TimezoneFinder(in_memory=True) longitude, latitude = 13.358, 52.5061 tf.timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Berlin' tf.certain_timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Berlin' longitude = 12.773955 latitude = 55.578595 tf.closest_timezone_at(lng=longitude, lat=latitude) # returns 'Europe/Copenhagen' longitude = 42.1052479 latitude = -16.622686 tf.closest_timezone_at(lng=longitude, lat=latitude, delta_degree=2, exact_computation=True, return_distances=True, force_evaluation=True) tf.get_geometry(tz_name='Africa/Addis_Ababa', coords_as_pairs=True) tf.get_geometry(tz_id=400, use_id=True) # To maximize the chances of getting a result in a Django view it might look like: def find_timezone(request, lat, lng): lat = float(lat) lng = float(lng)
def get_image_metadata(image_filename, tz=None): print image_filename img = PIL.Image.open(image_filename) exif = getExifFromImage(img) img.close() image_entry = {} image_entry["original_uri"] = image_filename exif_time = getExifTime(exif) # without information on when the image was taken, it's not useful. this is the minimum required metadata. if exif_time is not None: # extract information from GPS metadata (lat, lon, alt, gps_time, gps_direction) = getGPS(exif) # gps_time = gps_time.isoformat() if isinstance(gps_time, time) else gps_time image_entry["latitude"] = lat image_entry["longitude"] = lon image_entry["altitude"] = alt image_entry["direction"] = gps_direction image_entry["exposure_time"] = getExposureTime(exif) image_entry["flash_fired"] = getFlashFired(exif) timezonefinder = TimezoneFinder() try: tz = timezone(timezonefinder.timezone_at(lng=lon, lat=lat)) except ValueError: print "No lat lon, using previous timezone" except TypeError: print "No lat lon, using previous timezone" except AttributeError: try: print "searching area" tz = timezone(timezonefinder.closest_timezone_at(lng=lon, lat=lat)) except AttributeError: print "failed to find timezone, using previous" if gps_time is not None: # if image time matches GPS time, use the more precise GPS time if (exif_time.minute == gps_time.minute) and (abs(exif_time.second - gps_time.second) < 2): exif_time = exif_time.replace(second=gps_time.second, microsecond=gps_time.microsecond) # is_dst is only used when the time is ambiguous (thanks, Daylight Savings Time!) tz_offset = tz.utcoffset(exif_time, is_dst=False) tz_name = tz.tzname(exif_time, is_dst=False) # convert to UTC exif_time = exif_time - tz_offset image_entry["datetime"] = {"utc_timestamp": exif_time, "tz_offset": tz_offset.total_seconds(), "tz_name": tz_name}; # geocode location if lat is not None: geolocation_url = "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + str(lat) + "," + str(lon) + "&key=" + GOOGLE_API_KEY geolocation = json.loads(urllib2.urlopen(geolocation_url).read()) image_entry["geolocation"] = geolocation else: print 'skipping processing' # orient and resize images (size, resized_images) = orient_and_resize(image_entry["original_uri"]) image_entry["resized_uris"] = resized_images image_entry["size"] = size return (image_entry, tz)
tf = TimezoneFinder() nullzones = 0 id = 0 ids2 = {} with open("stations.csv", 'w', newline='') as myfile: wr = csv.writer(myfile) for station in stations: if len(station) < 7: if not is_float(station[3]): print(station) timezone = tf.timezone_at(lng=float(station[4]), lat=float(station[3])) if timezone is None: timezone = tf.closest_timezone_at(lng=float(station[4]), lat=float(station[3])) if timezone is None: continue if timezone not in timezones.values(): timezones[id] = timezone ids2[timezone] = id id += 1 wr.writerow((station[0], station[1], ids[station[2]], station[3], station[4], station[5], ids2[timezone])) else: print(station) with open("timezones.csv", 'w', newline='') as myfile: wr = csv.writer(myfile) for key, value in timezones.items(): wr.writerow(
class Parameters(CleepModule): """ Parameters application. Allow to configure Cleep parameters: * system time(current time, sunset, sunrise) according to position * system locale Useful doc: * debian timezone: https://wiki.debian.org/TimeZoneChanges * python datetime handling: https://hackernoon.com/avoid-a-bad-date-and-have-a-good-time-423792186f30 """ MODULE_AUTHOR = "Cleep" MODULE_VERSION = "2.1.1" MODULE_CATEGORY = "APPLICATION" MODULE_DEPS = [] MODULE_DESCRIPTION = "Configure generic parameters of your device" MODULE_LONGDESCRIPTION = ( "Application that helps you to configure generic parameters of your device" ) MODULE_TAGS = ["configuration", "date", "time", "locale", "lang"] MODULE_COUNTRY = None MODULE_URLINFO = "https://github.com/tangb/cleepmod-parameters" MODULE_URLHELP = None MODULE_URLBUGS = "https://github.com/tangb/cleepmod-parameters/issues" MODULE_URLSITE = None MODULE_CONFIG_FILE = "parameters.conf" # default position to raspberry pi foundation DEFAULT_CONFIG = { "position": { "latitude": 52.2040, "longitude": 0.1208 }, "country": { "country": "United Kingdom", "alpha2": "GB" }, "timezone": "Europe/London", "timestamp": 0, } SYSTEM_ZONEINFO_DIR = "/usr/share/zoneinfo/" SYSTEM_LOCALTIME = "/etc/localtime" SYSTEM_TIMEZONE = "/etc/timezone" NTP_SYNC_INTERVAL = 60 def __init__(self, bootstrap, debug_enabled): """ Constructor Args: bootstrap (dict): bootstrap objects debug_enabled (bool): flag to set debug level to logger """ # init CleepModule.__init__(self, bootstrap, debug_enabled) # members self.hostname = Hostname(self.cleep_filesystem) self.sun = Sun() self.sunset = None self.sunrise = None self.suns = { "sunset": 0, "sunset_iso": "", "sunrise": 0, "sunrise_iso": "" } self.timezonefinder = TimezoneFinder() self.timezone_name = None self.timezone = None self.time_task = None self.sync_time_task = None self.__clock_uuid = None # code from https://stackoverflow.com/a/106223 self.__hostname_pattern = ( r"^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*" r"([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$") # events self.time_now_event = self._get_event("parameters.time.now") self.time_sunrise_event = self._get_event("parameters.time.sunrise") self.time_sunset_event = self._get_event("parameters.time.sunset") self.hostname_update_event = self._get_event( "parameters.hostname.update") self.country_update_event = self._get_event( "parameters.country.update") def _configure(self): """ Configure module """ # add clock device if not already added if self._get_device_count() < 1: self.logger.debug("Add default devices") clock = {"type": "clock", "name": "Clock"} self._add_device(clock) # prepare country country = self._get_config_field("country") if not country: self.set_country() # prepare timezone timezone_name = self._get_config_field("timezone") self.timezone = timezone(timezone_name or get_localzone().zone) # compute sun times self.set_sun() # store device uuids for events devices = self.get_module_devices() for uuid in devices: if devices[uuid]["type"] == "clock": self.__clock_uuid = uuid def _on_start(self): """ Module starts """ # restore last saved timestamp if system time seems very old (NTP error) saved_timestamp = self._get_config_field("timestamp") if (int(time.time()) - saved_timestamp) < 0: # it seems NTP sync failed, launch timer to regularly try to sync device time self.logger.info( "Device time seems to be invalid (%s), launch synchronization time task", datetime.datetime.utcnow().isoformat(), ) self.sync_time_task = Task(Parameters.NTP_SYNC_INTERVAL, self._sync_time_task, self.logger) self.sync_time_task.start() # launch time task (synced to current seconds) seconds = 60 - (int(time.time()) % 60) self.time_task = Task(60.0, self._time_task, self.logger) timer = Timer(0 if seconds == 60 else seconds, self.time_task.start) timer.start() def _on_stop(self): """ Module stops """ if self.time_task: self.time_task.stop() def get_module_config(self): """ Get full module configuration Returns: dict: module configuration """ config = {} config["hostname"] = self.get_hostname() config["position"] = self.get_position() config["sun"] = self.get_sun() config["country"] = self.get_country() config["timezone"] = self.get_timezone() return config def get_module_devices(self): """ Return clock as parameters device Returns: dict: module devices """ devices = super().get_module_devices() for uuid in devices: if devices[uuid]["type"] == "clock": data = self.__format_time() data.update({ "sunrise": self.suns["sunrise"], "sunset": self.suns["sunset"] }) devices[uuid].update(data) return devices def __format_time(self): """ Return time with different splitted infos Returns: dict: time data:: { timestamp (int): current timestamp iso (string): current datetime in iso 8601 format year (int) month (int) day (int) hour (int) minute (int) weekday (int): 0=monday, 1=tuesday... 6=sunday weekday_literal (string): english literal weekday value (monday, tuesday, ...) } """ # current time utc_now = utc.localize(datetime.datetime.utcnow()) local_now = utc_now.astimezone(self.timezone) weekday = local_now.weekday() if weekday == 0: weekday_literal = "monday" elif weekday == 1: weekday_literal = "tuesday" elif weekday == 2: weekday_literal = "wednesday" elif weekday == 3: weekday_literal = "thursday" elif weekday == 4: weekday_literal = "friday" elif weekday == 5: weekday_literal = "saturday" elif weekday == 6: weekday_literal = "sunday" return { "timestamp": datetime.datetime.timestamp(utc_now), "iso": local_now.isoformat(), "year": local_now.year, "month": local_now.month, "day": local_now.day, "hour": local_now.hour, "minute": local_now.minute, "weekday": weekday, "weekday_literal": weekday_literal, } def _sync_time_task(self): """ Sync time task. It is used to try to sync device time using NTP server. Note: This task is launched only if device time is insane. """ if Parameters.sync_time(): self.logger.info("Time synchronized with NTP server (%s)" % datetime.datetime.utcnow().isoformat()) self.sync_time_task.stop() self.sync_time_task = None def _time_task(self): """ Time task used to refresh time """ now_formatted = self.__format_time() self.logger.trace("now_formatted: %s" % now_formatted) # send now event now_event_params = copy.deepcopy(now_formatted) now_event_params.update({ "sunrise": self.suns["sunrise"], "sunset": self.suns["sunset"] }) self.time_now_event.send(params=now_event_params, device_id=self.__clock_uuid) # send sunrise event if self.sunrise: if (now_formatted["hour"] == self.sunrise.hour and now_formatted["minute"] == self.sunrise.minute): self.time_sunrise_event.send(device_id=self.__clock_uuid) # send sunset event if self.sunset: if (now_formatted["hour"] == self.sunset.hour and now_formatted["minute"] == self.sunset.minute): self.time_sunset_event.send(device_id=self.__clock_uuid) # update sun times after midnight if now_formatted["hour"] == 0 and now_formatted["minute"] == 5: self.set_sun() # save last timestamp in config to restore it after a reboot and NTP sync failed (no internet) if not self.sync_time_task: self._set_config_field("timestamp", now_formatted["timestamp"]) def set_hostname(self, hostname): """ Set raspi hostname Args: hostname (string): hostname Returns: bool: True if hostname saved successfully, False otherwise Raises: InvalidParameter: if hostname has invalid format """ # check hostname if re.match(self.__hostname_pattern, hostname) is None: raise InvalidParameter("Hostname is not valid") # update hostname res = self.hostname.set_hostname(hostname) # send event to update hostname on all devices if res: self.hostname_update_event.send(params={"hostname": hostname}) return res def get_hostname(self): """ Return raspi hostname Returns: string: raspberry pi hostname """ return self.hostname.get_hostname() def set_position(self, latitude, longitude): """ Set device position Args: latitude (float): latitude longitude (float): longitude Raises: CommandError: if error occured during position saving """ if latitude is None: raise MissingParameter('Parameter "latitude" is missing') if not isinstance(latitude, float): raise InvalidParameter('Parameter "latitude" is invalid') if longitude is None: raise MissingParameter('Parameter "longitude" is missing') if not isinstance(longitude, float): raise InvalidParameter('Parameter "longitude" is invalid') # save new position position = {"latitude": latitude, "longitude": longitude} if not self._set_config_field("position", position): raise CommandError("Unable to save position") # reset python time to take into account last modifications before # computing new times time.tzset() # and update related stuff self.set_timezone() self.set_country() self.set_sun() # send now event self._time_task() def get_position(self): """ Return device position Returns: dict: position coordinates:: { latitude (float), longitude (float) } """ return self._get_config_field("position") def get_sun(self): """ Compute sun times Returns: dict: sunset/sunrise timestamps:: { sunrise (int), sunset (int) } """ return self.suns def set_sun(self): """ " Compute sun times (sunrise and sunset) according to configured position """ # get position position = self._get_config_field("position") # compute sun times self.sunset = None self.sunrise = None if position["latitude"] != 0 and position["longitude"] != 0: self.sun.set_position(position["latitude"], position["longitude"]) self.sunset = self.sun.sunset().astimezone(self.timezone) self.sunrise = self.sun.sunrise().astimezone(self.timezone) self.logger.debug("Found sunrise:%s sunset:%s" % (self.sunrise, self.sunset)) # save times self.suns["sunrise"] = int(self.sunrise.strftime("%s")) self.suns["sunrise_iso"] = self.sunrise.isoformat() self.suns["sunset"] = int(self.sunset.strftime("%s")) self.suns["sunset_iso"] = self.sunset.isoformat() def set_country(self): """ Compute country (and associated alpha) from current internal position Warning: This function can take some time to find country info on slow device like raspi 1st generation (~15secs) """ # get position position = self._get_config_field("position") if not position["latitude"] and not position["longitude"]: self.logger.debug( "Unable to set country from unspecified position (%s)" % position) return # get country from position country = {"country": None, "alpha2": None} try: # search country coordinates = ((position["latitude"], position["longitude"]), ) # need a tuple geo = reverse_geocode.search(coordinates) self.logger.debug("Found country infos from position %s: %s" % (position, geo)) if (geo and len(geo) > 0 and "country_code" in geo[0] and "country" in geo[0]): country["alpha2"] = geo[0]["country_code"] country["country"] = geo[0]["country"] # save new country if not self._set_config_field("country", country): raise CommandError("Unable to save country") # send event self.country_update_event.send(params=country) except CommandError: raise except Exception: self.logger.exception("Unable to find country for position %s:" % position) def get_country(self): """ Get country from position Returns: dict: return country infos:: { country (string): country label alpha2 (string): country code } """ return self._get_config_field("country") def set_timezone(self): """ Set timezone according to coordinates Returns: bool: True if function succeed, False otherwise Raises: CommandError: if unable to save timezone """ # get position position = self._get_config_field("position") if not position["latitude"] and not position["longitude"]: self.logger.warning( "Unable to set timezone from unspecified position (%s)" % position) return False # compute timezone current_timezone = None try: # try to find timezone at position current_timezone = self.timezonefinder.timezone_at( lat=position["latitude"], lng=position["longitude"]) if current_timezone is None: # extend search to closest position # TODO increase delta_degree to extend research, careful it use more CPU ! current_timezone = self.timezonefinder.closest_timezone_at( lat=position["latitude"], lng=position["longitude"]) except ValueError: # the coordinates were out of bounds self.logger.exception("Coordinates out of bounds") except Exception: self.logger.exception( "Error occured searching timezone at position") if not current_timezone: self.logger.warning( "Unable to set device timezone because it was not found") return False # save timezone value self.logger.debug("Save new timezone: %s" % current_timezone) if not self._set_config_field("timezone", current_timezone): raise CommandError("Unable to save timezone") # configure system timezone zoneinfo = os.path.join(self.SYSTEM_ZONEINFO_DIR, current_timezone) self.logger.debug("Checking zoneinfo file: %s" % zoneinfo) if not os.path.exists(zoneinfo): raise CommandError('No system file found for "%s" timezone' % current_timezone) self.logger.debug('zoneinfo file "%s" exists' % zoneinfo) self.cleep_filesystem.rm(self.SYSTEM_LOCALTIME) self.logger.debug('Writing timezone "%s" in "%s"' % (current_timezone, self.SYSTEM_TIMEZONE)) if not self.cleep_filesystem.write_data(self.SYSTEM_TIMEZONE, "%s" % current_timezone): self.logger.error( 'Unable to write timezone data on "%s". System timezone is not configured!' % self.SYSTEM_TIMEZONE) return False # launch timezone update in background self.logger.debug("Updating system timezone") command = Console() res = command.command( "/usr/sbin/dpkg-reconfigure -f noninteractive tzdata", timeout=15.0) self.logger.debug("Timezone update command result: %s" % res) if res["returncode"] != 0: self.logger.error("Error reconfiguring system timezone: %s" % res["stderr"]) return False # TODO configure all wpa_supplicant.conf country code # propagate changes to cleep self.timezone = timezone(current_timezone) self._time_task() return True def get_timezone(self): """ Return timezone Returns: string: current timezone name """ return self._get_config_field("timezone") @staticmethod def sync_time(): """ Synchronize device time using NTP server Note: This command may lasts some seconds Returns: bool: True if NTP sync succeed, False otherwise """ console = Console() resp = console.command("/usr/sbin/ntpdate-debian", timeout=60.0) return resp["returncode"] == 0 def get_non_working_days(self, year=None): """ Return non working days of current year Args: year (int): get non working day for specified year. If not specified use current year Returns: list: list of non working days of the year. List can be empty if error occured:: [ { datetime (string): non working day (date in iso format YYYY-MM-DD) label (string): english name of non working day }, ... ] """ self._check_parameters([{ "name": "year", "type": int, "value": year, "none": True, }]) try: country = self._get_config_field("country") continent_code = country_alpha2_to_continent_code( country["alpha2"]) continent_name = convert_continent_code_to_continent_name( continent_code).lower() continent_name = (continent_name.lower().replace( "south", "").replace("north", "").strip()) workalendar = importlib.import_module( f"workalendar.{continent_name}") fixed_country = "".join( [part.capitalize() for part in country["country"].split()]) _class = getattr(workalendar, fixed_country) _instance = _class() year = year or datetime.datetime.now().year holidays = _instance.holidays(year) return [(date.isoformat(), label) for (date, label) in holidays] except Exception: self.logger.exception("Unable to get non working days:") return [] def is_non_working_day(self, day): """ Check if specified day is non working day according to current locale configuration Args: day (string): day to check (must be iso format XXXX-MM-DD) Returns: bool: True if specified day is a non working day, False otherwise """ self._check_parameters([{ "name": "day", "type": str, "value": day, }]) year = datetime.date.fromisoformat(day).year non_working_days = self.get_non_working_days(year=year) return any(a_day == day for (a_day, label) in non_working_days) def is_today_non_working_day(self): """ Check if today is non working day according to current locale configuration Args: day (datetime.date): day to check Returns: bool: True if specified day is a non working day, False otherwise """ today = datetime.date.today() return self.is_non_working_day(today.isoformat())
def get_pvgis_tmy(lat, lon, outputformat='json', usehorizon=True, userhorizon=None, startyear=None, endyear=None, url=URL, timeout=30, localtime=False): """ Get TMY data from PVGIS. For more information see the PVGIS [1]_ TMY tool documentation [2]_. Parameters ---------- lat : float Latitude in degrees north lon : float Longitude in dgrees east outputformat : str, default 'json' Must be in ``['csv', 'basic', 'epw', 'json']``. See PVGIS TMY tool documentation [2]_ for more info. usehorizon : bool, default True include effects of horizon userhorizon : list of float, default None optional user specified elevation of horizon in degrees, at equally spaced azimuth clockwise from north, only valid if `usehorizon` is true, if `usehorizon` is true but `userhorizon` is `None` then PVGIS will calculate the horizon [3]_ startyear : int, default None first year to calculate TMY endyear : int, default None last year to calculate TMY, must be at least 10 years from first year url : str, default :const:`pvlib.iotools.pvgis.URL` base url of PVGIS API, append ``tmy`` to get TMY endpoint timeout : int, default 30 time in seconds to wait for server response before timeout localtime: bool, default False if True, convert index to local time given by longitude and latitude, else tz=UTC Returns ------- data : pandas.DataFrame the weather data months_selected : list TMY year for each month, ``None`` for basic and EPW inputs : dict the inputs, ``None`` for basic and EPW meta : list or dict meta data, ``None`` for basic Raises ------ requests.HTTPError if the request response status is ``HTTP/1.1 400 BAD REQUEST``, then the error message in the response will be raised as an exception, otherwise raise whatever ``HTTP/1.1`` error occurred See also -------- read_pvgis_tmy References ---------- .. [1] `PVGIS <https://ec.europa.eu/jrc/en/pvgis>`_ .. [2] `PVGIS TMY tool <https://ec.europa.eu/jrc/en/PVGIS/tools/tmy>`_ .. [3] `PVGIS horizon profile tool <https://ec.europa.eu/jrc/en/PVGIS/tools/horizon>`_ """ # use requests to format the query string by passing params dictionary params = {'lat': lat, 'lon': lon, 'outputformat': outputformat} # pvgis only likes 0 for False, and 1 for True, not strings, also the # default for usehorizon is already 1 (ie: True), so only set if False if not usehorizon: params['usehorizon'] = 0 if userhorizon is not None: params['userhorizon'] = ','.join(str(x) for x in userhorizon) if startyear is not None: params['startyear'] = startyear if endyear is not None: params['endyear'] = endyear res = requests.get(url + 'tmy', params=params, timeout=timeout) # PVGIS returns really well formatted error messages in JSON for HTTP/1.1 # 400 BAD REQUEST so try to return that if possible, otherwise raise the # HTTP/1.1 error caught by requests if not res.ok: try: err_msg = res.json() except Exception: res.raise_for_status() else: raise requests.HTTPError(err_msg['message']) # initialize data to None in case API fails to respond to bad outputformat data = None, None, None, None # get time zone name if localtime tz = None if localtime: tf = TimezoneFinder() try: tz = tf.timezone_at(lng=lon, lat=lat) if tz is None: tz = tf.closest_timezone_at(lng=lon, lat=lat) except ValueError: # this line is never reached because if the lat, lon are # the response is HTTP/1.1 400 BAD REQUEST which is handle # by PVGIS in the requests pass if outputformat == 'json': src = res.json() return _parse_pvgis_tmy_json(src, tz) elif outputformat == 'csv': with io.BytesIO(res.content) as src: data = _parse_pvgis_tmy_csv(src, tz) elif outputformat == 'basic': with io.BytesIO(res.content) as src: data = _parse_pvgis_tmy_basic(src, tz) elif outputformat == 'epw': with io.StringIO(res.content.decode('utf-8')) as src: data, meta = parse_epw(src) if tz is not None: data.index = data.index.tz_convert(tz) data.index.name = f'time({tz})' data = (data, None, None, meta) else: # this line is never reached because if outputformat is not valid then # the response is HTTP/1.1 400 BAD REQUEST which is handled earlier pass return data
def main(): tf = TimezoneFinder() datefmt = '%Y-%m-%d' timefmt = '%H:%M:%S' fsq_data = pd.read_csv("foursquaredata.csv", sep=',') #time zones longitudes = fsq_data["Longitude"] latitudes = fsq_data["Latitude"] places = fsq_data["Place"] check_in_date = fsq_data["Check in Date"] link = fsq_data["Link"] description = fsq_data["Description"] DoW = [] month = [] day = [] year = [] hour = [] minute = [] date = [] time = [] timezones = [] airport = [] gym = [] pool = [] office = [] placetype = [] # -> 2009-07-10 14:44:59.193982-04:00 for i in range(len(longitudes)): timezone = tf.closest_timezone_at(lng=longitudes[i], lat=latitudes[i]).encode('utf-8') timezones.append(timezone) if "Airport" in places[i]: airport.append(1) else: airport.append(0) if "Gym" in places[i]: gym.append(1) else: gym.append(0) if "Pool" in places[i] or "Aquatic" in places[i]: pool.append(1) else: pool.append(0) if "NBA HQ" in places[i] or "Facebook" in places[i]: office.append(1) else: office.append(0) if "Airport" in places[i]: placetype.append("Airport") elif "Gym" in places[i]: placetype.append("Gym") elif "Pool" in places[i] or "Aquatic" in places[i]: placetype.append("Pool") elif "NBA HQ" in places[i] or "Facebook" in places[i]: placetype.append("Work") else: placetype.append("None of Above") ###time zones timezoneset = list(set(timezones)) check_in_date[1].split(",") commasplit = lambda x: x.split(", ") spacesplit = lambda x: x.split(" ") checkinsplit = check_in_date.apply(commasplit) #fmt = '%Y-%m-%d %H:%M:%S %Z%z' #not python 2.7 compatabile? fmt = '%Y-%m-%d %H:%M:%S' localtimes = [] #array of local times localtimes_dates = [] #get UTC time and convert to local time print "Converting UTC to Local Time" for i in range(len(checkinsplit)): if checkinsplit[i][1].endswith(" +0000"): checkinsplit[i][1] = checkinsplit[i][1][:-6] utc = datetime.strptime(checkinsplit[i][1], '%d %b %y %H:%M:%S') ##get time (UTC) utc_as_localtime = convert_UTC_local_timezone( timezones[i], utc, timezoneset) #datetime obj w/local time #adjust for DST - get datetime object localtime_DST_adjusted = adjust_DST(utc_as_localtime, timezones[i]) date = localtime_DST_adjusted.strftime(datefmt) time = localtime_DST_adjusted.strftime(timefmt) localtimes.append(time) localtimes_dates.append(date) month.append(localtime_DST_adjusted.month) DoW.append(localtime_DST_adjusted.weekday()) #day of week year.append(localtime_DST_adjusted.year) hour.append(localtime_DST_adjusted.hour) minute.append(localtime_DST_adjusted.minute) day.append(localtime_DST_adjusted.day) #numerical day of month #local_tz = timezone(timezones[i]) #WTF doesn't work in python 2.7? but works in python 3.2??? #utc = local_tz.localize(utc) #utc.strftime(fmt) #datetime.strptime('03 Mar 14 17:51:19 +0000', '%d %b %y %H:%M:%S %z') ##get UTC time foursquaredata = np.column_stack([ places, check_in_date, localtimes, localtimes_dates, timezones, link, latitudes, longitudes, description, DoW, month, day, year, hour, minute, placetype, gym, airport, pool, office ]) #concatenate columns titles = [ "Place", "Check in Date", "Local Time", "Date", "Time Zone", "Link", "Latitude", "Longitude", "Description", "Day_of_Week", "Month", "Day", "Year", "Hour", "Minute", "PlaceType", "Gym", "Airport", "Pool", "Office" ] foursquare = pd.DataFrame(foursquaredata, columns=titles) '''with open(filename, "w") as f: writer = csv.writer(f, delimiter=",") #header of the data writer.writerow(["Place", "Check in Date", "Local Time" , "Link", "Latitude", "Longitude", "Description", "Day_of_Week", "Month", "Day", "Year", "Hour", "Minute", "PlaceType", "Gym", "Airport", "Pool", "Office"]) writer.writerows(foursquaredata)''' filename = "FOURSQUARE_DATA_With_Local_Times.csv" foursquare.to_csv(filename, sep=',') print "Done!" os.system('say "DunDunDun Donnne"')