def test_is_dayTime_true_complex(self): timeZone = pytz.timezone('Europe/Berlin') sunrise = Helpers.timestamp_to_timezone(1604296782, timeZone) sunset = Helpers.timestamp_to_timezone(1604331478, timeZone) now = timeZone.localize( datetime(year=2020, month=11, day=2, hour=15, minute=0, second=0)) self.assertTrue(Helpers.is_dayTime(sunrise, sunset, now))
def fetch(self, pageName: str) -> Dict: weatherService = ServiceManager.get_instance( ).get_service_by_type_name('WeatherService') fetchIntervalInSeconds = 60 * 10 # query api less often timeZone = pytz.timezone(self._settings['timeZone']) # cache key will be determined in service weatherData = weatherService.get_data('', fetchIntervalInSeconds, self._settings) currentWeather = weatherData['current'] currentTemperature = currentWeather['temp'] feelsLike = currentWeather['feels_like'] windSpeed = currentWeather['wind_speed'] * 3.6 icon = currentWeather['weather'][0]['id'] sunrise = Helpers.timestamp_to_timezone(currentWeather['sunrise'], timeZone) sunset = Helpers.timestamp_to_timezone(currentWeather['sunset'], timeZone) isDayTime = Helpers.is_dayTime(sunrise, sunset, datetime.now(tz=timeZone)) temperatureRounded = Helpers.round_to_decimals(currentTemperature, 1) feelsLikeRounded = Helpers.round_to_decimals(feelsLike, 0) return { 'temperature': temperatureRounded, 'temperatureColor': Helpers.determine_color_for_temperature(float(temperatureRounded)), 'feelsLike': feelsLikeRounded, 'feelsLikeColor': Helpers.determine_color_for_temperature(float(feelsLikeRounded)), 'icon': icon, 'iconColor': Helpers.determine_color_for_weather_icon(icon, isDayTime), 'windDegrees': currentWeather['wind_deg'], 'windSpeed': f'{Helpers.round_to_decimals(windSpeed, 1)} km/h', 'windSpeedColor': Helpers.determine_color_for_wind(windSpeed), 'isDayTime': isDayTime, 'description': currentWeather['weather'][0]['description'] }
def fetch(self, pageName: str) -> Dict: weatherService = ServiceManager.get_instance().get_service_by_type_name('WeatherService') fetchIntervalInSeconds = 60 * 10 # query api less often timeZone = pytz.timezone(self._settings['timeZone']) # cache key will be determined in service weatherData = weatherService.get_data('', fetchIntervalInSeconds, self._settings) sunrise = Helpers.timestamp_to_timezone(weatherData['current']['sunrise'], timeZone) sunset = Helpers.timestamp_to_timezone(weatherData['current']['sunset'], timeZone) hourData = [] hourlyForecast = weatherData['hourly'] for entry in hourlyForecast[:12]: timestamp = Helpers.timestamp_to_timezone(entry['dt'] + 1800, timeZone) isDayTime = Helpers.is_dayTime(sunrise, sunset, currentTimestamp=timestamp) temperature = entry['temp'] iconId = entry['weather'][0]['id'] if isDayTime: icon = f'wi-owm-day-{iconId}' else: icon = f'wi-owm-night-{iconId}' rainProbability = round(entry['pop'] * 100, -1) # -1 rounds to the next ten windSpeed = entry['wind_speed'] * 3.6 temperatureRounded = Helpers.round_to_decimals(temperature, 0) windSpeedRounded = Helpers.round_to_decimals(windSpeed, 0) hourData.append({ 'hour': timestamp.strftime('%H'), 'temperature': temperatureRounded, 'temperatureColor': Helpers.determine_color_for_temperature(float(temperatureRounded)), 'icon': icon, 'iconColor': Helpers.determine_color_for_weather_icon(iconId, isDayTime), 'windSpeed': f'{windSpeedRounded} km/h', 'windSpeedColor': Helpers.determine_color_for_wind(float(windSpeedRounded)), 'rainProbability': f'{Helpers.round_to_decimals(rainProbability, 0)} %', 'isDayTime': isDayTime, 'description': entry['weather'][0]['description'] }) return { 'hours': hourData }
def test_timestamp_to_timezone_london(self): timestamp = 1604331478 timeZone = pytz.timezone('Europe/London') expected = datetime(year=2020, month=11, day=2, hour=15, minute=37, second=58, tzinfo=timeZone) self.__compareDates(expected, Helpers.timestamp_to_timezone(timestamp, timeZone))
def _fetch_data(self, settings: Dict) -> Dict: fetchType = settings['fetchType'] if fetchType == 'minMax': joinedIDs = '&'.join([ f'sensorIds={item}' for item in settings["sensorIDsForMinMax"] ]) startDateTime = urllib.parse.quote(settings['startDateTime']) endDateTime = urllib.parse.quote(settings['endDateTime']) urlMinMax = Helpers.join_url_parts( settings['url'], f'measurements/minMax?{joinedIDs}' f'&startDateTime={startDateTime}' f'&endDateTime={endDateTime}') minMaxResponse = requests.get(urlMinMax) if minMaxResponse.status_code != 200: raise Exception( f'Invalid status code: {minMaxResponse.status_code}') return minMaxResponse.json() urlSensorInfo = Helpers.join_url_parts(settings['url'], 'sensor', str(settings['sensorID'])) if fetchType == 'all': if 'startDateTime' in settings and 'endDateTime' in settings: startDateTime = urllib.parse.quote(settings['startDateTime']) endDateTime = urllib.parse.quote(settings['endDateTime']) urlSensorValue = Helpers.join_url_parts( urlSensorInfo, f'measurements' f'?startDateTime={startDateTime}&endDateTime={endDateTime}' ) else: urlSensorValue = Helpers.join_url_parts( urlSensorInfo, 'measurements') else: urlSensorValue = Helpers.join_url_parts(urlSensorInfo, 'measurements/latest') sensorInfoResponse = requests.get(urlSensorInfo) if sensorInfoResponse.status_code != 200: raise Exception( f'Invalid status code: {sensorInfoResponse.status_code}') urlDeviceInfo = Helpers.join_url_parts( settings['url'], 'device', str(sensorInfoResponse.json()['device_id'])) deviceInfoResponse = requests.get(urlDeviceInfo) if deviceInfoResponse.status_code != 200: raise Exception( f'Invalid status code: {deviceInfoResponse.status_code}') sensorValueResponse = requests.get(urlSensorValue) if sensorValueResponse.status_code != 200: raise Exception( f'Invalid status code: {sensorValueResponse.status_code}') return { 'deviceInfo': deviceInfoResponse.json(), 'sensorInfo': sensorInfoResponse.json(), 'sensorValue': sensorValueResponse.json() }
def _send_notification(self, warningSettings: Dict, sensorInfo: Dict, deviceInfo: Dict, timeSinceLastValue: str): if not warningSettings['enableNotificationViaPushbullet']: return if not timeSinceLastValue: self._notificationSent = False return if self._notificationSent: return token = warningSettings['pushbulletToken'] sensorName = sensorInfo['name'] sensorType = sensorInfo['type'] deviceName = deviceInfo['name'] title = 'DashboardLeaf - Outdated Value Warning' description = f'Last value for sensor "{sensorName}" received {timeSinceLastValue} ' \ f'(type: {sensorType}, device: {deviceName})' Helpers.send_notification_via_pushbullet(token, title, description) self._notificationSent = True
def _send_notification(self, remainingDays: int, nextEventDate: str): notificationSettings = self._settings['notificationViaPushbullet'] if not notificationSettings['enable']: self._lastNotificationDate = None return if remainingDays != notificationSettings['daysBeforeEvent']: self._lastNotificationDate = None return now = self._get_current_date_time() if now.hour < notificationSettings['hour']: self._lastNotificationDate = None return if self._is_already_notified(now): return self._lastNotificationDate = now.date() title = 'DashboardLeaf - Garbage Schedule Notification' description = f'"{self._settings["garbageType"]}" will be collected in {remainingDays} days ({nextEventDate})' Helpers.send_notification_via_pushbullet( notificationSettings['pushbulletToken'], title, description)
def _prepare_measurement_data( self, measurements: List[Dict]) -> Tuple[List[str], List[str]]: x = [] y = [] for measurement in measurements: timestamp = measurement['timestamp'] x.append(timestamp) value = float(measurement['value']) y.append( Helpers.round_to_decimals(value, self._settings['decimals'])) x.reverse() y.reverse() return x, y
def test_is_dayTime_differentDays(self): sunrise = datetime(year=2020, month=11, day=1, hour=8, minute=0, second=0) sunset = datetime(year=2020, month=11, day=1, hour=17, minute=0, second=0) currentTimestamp = datetime(year=2020, month=11, day=2, hour=12, minute=0, second=0) self.assertTrue(Helpers.is_dayTime(sunrise, sunset, currentTimestamp))
def fetch(self, pageName: str) -> Dict: weatherService = ServiceManager.get_instance( ).get_service_by_type_name('WeatherService') fetchIntervalInSeconds = 60 * 10 # query api less often # cache key will be determined in service weatherData = weatherService.get_data('', fetchIntervalInSeconds, self._settings) forecast = weatherData['daily'] forecastData = {} icons = [] for day in forecast: date = day['dt'] date = datetime.fromtimestamp(date) formattedDate = datetime.strftime(date, self.DATE_FORMAT) icon = day['weather'][0]['id'] iconColor = Helpers.determine_color_for_weather_icon(icon, True) isWeekDay = date.weekday() < 5 description = day['weather'][0]['description'] icons.append({ 'icon': icon, 'iconColor': iconColor, 'isWeekDay': isWeekDay, 'description': description }) forecastData[formattedDate] = (int(day['temp']['min']), int(day['temp']['max'])) minValues = [x[0] for x in forecastData.values()] maxValues = [x[1] for x in forecastData.values()] return { 'formattedDates': list(forecastData.keys()), 'minValues': minValues, 'maxValues': maxValues, 'icons': icons, }
def test_is_dayTime_false_after(self): sunrise = datetime(year=2020, month=11, day=1, hour=8, minute=0, second=0) sunset = datetime(year=2020, month=11, day=1, hour=17, minute=0, second=0) currentTimestamp = datetime(year=2020, month=11, day=1, hour=18, minute=0, second=0) self.assertFalse(Helpers.is_dayTime(sunrise, sunset, currentTimestamp))
def test_join_url_parts(self): self.assertEqual( 'https://myWebsite/eimer/0815', Helpers.join_url_parts('https://myWebsite', 'eimer', '0815'))
def test_round_to_decimals_zero(self): self.assertEqual('0', Helpers.round_to_decimals(0.428, 0))
def test_round_to_decimals_one(self): self.assertEqual('0.4', Helpers.round_to_decimals(0.428, 1))