예제 #1
0
    def test_notification_api_fail_5xx(self, now_mock, requests_post_mock):
        """ Notifications: Test API failure for notify() - HTTP 5xx """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 17, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=503,
                                                         text='Server Error')

        notification_settings = NotificationSetting.get_solo()
        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.prowl_api_key = self.API_KEY
        notification_settings.next_notification = timezone.now()
        notification_settings.save()

        # When having no data, this should NOT raise an exception.
        if not self.fixtures:
            return dsmr_notification.services.notify()

        with self.assertRaises(AssertionError):
            dsmr_notification.services.notify()

        # HTTP 5xx should delay next call.
        notification_settings = NotificationSetting.get_solo()
        self.assertIsNotNone(notification_settings.notification_service)
        self.assertIsNotNone(notification_settings.prowl_api_key)
        self.assertGreater(notification_settings.next_notification,
                           timezone.now())
예제 #2
0
    def test_notifications(self, now_mock, requests_post_mock):
        """ Notifications: Test notify() (actual notification sender)"""
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 18, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=200,
                                                         text='OK')

        notification_settings = NotificationSetting.get_solo()
        self.assertIsNone(notification_settings.next_notification)
        self.assertFalse(requests_post_mock.called)

        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.prowl_api_key = self.API_KEY
        notification_settings.next_notification = timezone.now()
        notification_settings.save()

        dsmr_notification.services.notify()

        if self.fixtures:
            self.assertTrue(requests_post_mock.called)
        else:
            return self.assertFalse(requests_post_mock.called)

        # Next notification should be pushed.
        self.assertGreater(NotificationSetting.get_solo().next_notification,
                           timezone.now())
예제 #3
0
    def test_notifications(self, now_mock, requests_post_mock):
        """ Notifications: Test notify() (actual notification sender)"""
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 17, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=200,
                                                         text='OK')

        notification_settings = NotificationSetting.get_solo()
        self.assertIsNone(notification_settings.next_notification)
        self.assertFalse(requests_post_mock.called)

        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.prowl_api_key = self.API_KEY
        notification_settings.next_notification = timezone.now()
        notification_settings.save()

        dsmr_notification.services.notify()

        if self.fixtures:
            self.assertTrue(requests_post_mock.called)
        else:
            return self.assertFalse(requests_post_mock.called)

        # Make sure the expected message is created.
        yesterday = (timezone.localtime(timezone.now()) -
                     timezone.timedelta(hours=24)).date()
        stats = DayStatistics.objects.get(day=yesterday)
        api_msg = dsmr_notification.services.create_consumption_message(
            yesterday, stats)
        self.assertTrue(yesterday.strftime("%d-%m-%Y") in api_msg)

        # Next notification should be pushed.
        self.assertGreater(NotificationSetting.get_solo().next_notification,
                           timezone.now())
예제 #4
0
    def test_notify_pre_check_dummy_message(self, now_mock,
                                            send_notification_mock):
        """ Notifications: Test notify_pre_check()'s output when service is set """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2018, 1, 1, 0, 0, 0))

        # Should fail because we haven't set a service
        self.assertFalse(dsmr_notification.services.notify_pre_check())

        notification_settings = NotificationSetting.get_solo()
        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.save()

        # Should be okay now, with dummy message being sent.
        self.assertFalse(send_notification_mock.called)
        self.assertIsNone(NotificationSetting.get_solo().next_notification)
        self.assertTrue(
            dsmr_notification.services.notify_pre_check())  # Execution
        self.assertTrue(send_notification_mock.called)
        self.assertIsNotNone(NotificationSetting.get_solo().next_notification)

        # 'next_notification' is no longer empty, so we should run the normal flow now.
        # First we verify the next_notification check.
        now_mock.return_value = now_mock.return_value - timezone.timedelta(
            minutes=1)
        self.assertFalse(dsmr_notification.services.notify_pre_check())

        # And finally, the flow we were used to.
        now_mock.return_value = now_mock.return_value + timezone.timedelta(
            minutes=5)
        self.assertTrue(dsmr_notification.services.notify_pre_check())
예제 #5
0
    def test_set_next_notification_date_for_dst_change(self, now_mock):
        """ Notifications: Test if next notification date is set due to DST change """
        now_mock.return_value = timezone.make_aware(timezone.datetime(2018, 10, 27, 2, 0, 0))  # Do NOT change hour.
        now = timezone.localtime(timezone.now())
        NotificationSetting.objects.update(next_notification=now)

        # This used to trigger a AmbiguousTimeError.
        dsmr_notification.services.set_next_notification()

        notification_settings = NotificationSetting.get_solo()
        next_notification = timezone.localtime(notification_settings.next_notification)
        expected = timezone.datetime(2018, 10, 28, 6, 0, 0)
        expected = timezone.localtime(timezone.make_aware(expected, pytz.timezone(settings.TIME_ZONE), is_dst=True))
        print(next_notification, expected)
        self.assertEqual(next_notification, expected)

        # Check other way around as well, in March.
        now_mock.return_value = timezone.make_aware(timezone.datetime(2019, 3, 30, 1, 0, 0))  # Do NOT change hour.
        now = timezone.localtime(timezone.now())
        NotificationSetting.objects.update(next_notification=now)

        dsmr_notification.services.set_next_notification()

        notification_settings = NotificationSetting.get_solo()
        next_notification = timezone.localtime(notification_settings.next_notification)
        expected = timezone.datetime(2019, 3, 31, 6, 0, 0)
        expected = timezone.localtime(timezone.make_aware(expected, pytz.timezone(settings.TIME_ZONE), is_dst=True))
        self.assertEqual(next_notification, expected)
예제 #6
0
    def test_notifications(self, now_mock, requests_post_mock):
        """ Notifications: Test notify() (actual notification sender)"""
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 17, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=200,
                                                         text='OK')

        settings = NotificationSetting.get_solo()
        self.assertFalse(settings.send_notification)
        self.assertIsNone(settings.next_notification)
        self.assertFalse(requests_post_mock.called)

        settings.send_notification = True
        settings.notification_service = NotificationSetting.NOTIFICATION_NMA
        settings.api_key = 'es7sh2d-DSMR-Reader-Rulez-iweu732'
        settings.next_notification = timezone.localtime(timezone.now())
        settings.save()

        dsmr_notification.services.notify()

        settings = NotificationSetting.get_solo()

        if self.fixtures:
            self.assertTrue(requests_post_mock.called)
        else:
            return self.assertFalse(requests_post_mock.called)

        nma_url = dsmr_notification.services.get_notification_api_url(settings)
        yesterday = (timezone.localtime(timezone.now()) -
                     timezone.timedelta(hours=24)).date()
        stats = DayStatistics.objects.get(day=yesterday)
        api_msg = dsmr_notification.services.create_notification_message(
            yesterday, stats)
        self.assertTrue(yesterday.strftime("%d-%m-%Y") in api_msg)

        # Dissect call
        requests_post_mock.assert_called_once_with(
            nma_url, {
                'apikey':
                settings.api_key,
                'priority':
                dsmr_notification.services.get_notification_priority(),
                'application':
                dsmr_notification.services.get_notification_sender_name(),
                'event':
                dsmr_notification.services.get_notification_event_name(),
                'description':
                api_msg
            })

        tomorrow = (timezone.localtime(timezone.now()) +
                    timezone.timedelta(hours=24)).date()
        self.assertEqual(settings.next_notification, tomorrow)
예제 #7
0
def check_status():
    """ Checks the status of the application. """
    status_settings = StatusNotificationSetting.get_solo()
    notification_settings = NotificationSetting.get_solo()

    if notification_settings.notification_service is None or \
            not dsmr_backend.services.is_timestamp_passed(timestamp=status_settings.next_check):
        return

    if not DsmrReading.objects.exists():
        return StatusNotificationSetting.objects.update(
            next_check=timezone.now() + timezone.timedelta(minutes=5))

    # Check for recent data.
    has_recent_reading = DsmrReading.objects.filter(
        timestamp__gt=timezone.now() -
        timezone.timedelta(minutes=settings.
                           DSMRREADER_STATUS_READING_OFFSET_MINUTES)).exists()

    if has_recent_reading:
        return StatusNotificationSetting.objects.update(
            next_check=timezone.now() + timezone.timedelta(minutes=5))

    # Alert!
    logger.debug(' - Sending notification about datalogger lagging behind...')
    send_notification(
        str(
            _('It has been over {} hour(s) since the last reading received. Please check your datalogger.'
              )), str(_('Datalogger check')))

    StatusNotificationSetting.objects.update(
        next_check=timezone.now() + timezone.timedelta(
            hours=settings.DSMRREADER_STATUS_NOTIFICATION_COOLDOWN_HOURS))
예제 #8
0
def notify():
    """ Sends notifications about daily energy usage """
    settings = NotificationSetting.get_solo()

    if not should_notify(settings):
        return

    # Just post the latest reading of the day before.
    today = timezone.localtime(timezone.now())
    midnight = timezone.make_aware(
        timezone.datetime(
            year=today.year,
            month=today.month,
            day=today.day,
            hour=0,
        ))

    try:
        notification_api_url = get_notification_api_url(settings)
    except KeyError:
        raise AssertionError('Could not determine notification API url!')

    try:
        stats = DayStatistics.objects.get(day=(midnight -
                                               timezone.timedelta(hours=1)))
    except DayStatistics.DoesNotExist:
        return False  # Try again in a next run

    # For backend logging in Supervisor.
    print(' - Creating new notification containing daily usage.')

    message = create_notification_message(midnight, stats)
    send_notification(notification_api_url, settings.api_key, message)
    set_next_notification(settings, today)
예제 #9
0
    def test_check_status(self, now_mock, requests_post_mock):
        """ Check whether downtime of the datalogger triggers notifications. """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2018, 1, 1, hour=12))
        requests_post_mock.return_value = mock.MagicMock(status_code=200,
                                                         text='OK')

        StatusNotificationSetting.get_solo()
        notification_settings = NotificationSetting.get_solo()
        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.prowl_api_key = self.API_KEY
        notification_settings.save()

        # Schedule ahead.
        StatusNotificationSetting.objects.update(next_check=timezone.now() +
                                                 timezone.timedelta(minutes=1))
        dsmr_notification.services.check_status()

        # No data.
        StatusNotificationSetting.objects.update(next_check=timezone.now())
        DsmrReading.objects.all().delete()
        dsmr_notification.services.check_status()
        self.assertGreater(StatusNotificationSetting.get_solo().next_check,
                           timezone.now())

        # Recent data.
        StatusNotificationSetting.objects.update(next_check=timezone.now())
        DsmrReading.objects.create(
            timestamp=timezone.now() - timezone.timedelta(minutes=45),
            electricity_delivered_1=1,
            electricity_returned_1=2,
            electricity_delivered_2=3,
            electricity_returned_2=4,
            electricity_currently_delivered=5,
            electricity_currently_returned=6,
        )
        dsmr_notification.services.check_status()

        self.assertGreater(StatusNotificationSetting.get_solo().next_check,
                           timezone.now())
        self.assertFalse(requests_post_mock.called)

        # Data from a while ago.
        StatusNotificationSetting.objects.update(next_check=timezone.now())
        DsmrReading.objects.all().delete()
        DsmrReading.objects.create(
            timestamp=timezone.now() - timezone.timedelta(hours=24),
            electricity_delivered_1=1,
            electricity_returned_1=2,
            electricity_delivered_2=3,
            electricity_returned_2=4,
            electricity_currently_delivered=5,
            electricity_currently_returned=6,
        )

        StatusNotificationSetting.objects.update(next_check=timezone.now())

        self.assertFalse(requests_post_mock.called)
        dsmr_notification.services.check_status()
        self.assertTrue(requests_post_mock.called)
예제 #10
0
    def test_notify_pre_check_skip(self, notify_pre_check_mock):
        """ Notifications: Test whether notify_pre_check() skips current day. """
        notify_pre_check_mock.return_value = False

        notification_settings = NotificationSetting.get_solo()
        self.assertIsNone(notification_settings.notification_service)
        self.assertFalse(dsmr_notification.services.notify())
예제 #11
0
def send_notification(message, title):
    """ Sends notification using the preferred service """
    notification_settings = NotificationSetting.get_solo()

    DATA_FORMAT = {
        NotificationSetting.NOTIFICATION_PUSHOVER: {
            'url': NotificationSetting.PUSHOVER_API_URL,
            'data': {
                'token': notification_settings.pushover_api_key,
                'user': notification_settings.pushover_user_key,
                'priority': '-1',
                'title': title,
                'message': message
            }
        },
        NotificationSetting.NOTIFICATION_PROWL: {
            'url': NotificationSetting.PROWL_API_URL,
            'data': {
                'apikey': notification_settings.prowl_api_key,
                'priority': '-2',
                'application': 'DSMR-Reader',
                'event': title,
                'description': message
            }
        },
    }

    response = requests.post(
        **DATA_FORMAT[notification_settings.notification_service])

    if response.status_code == 200:
        return

    # Invalid request, do not retry.
    if str(response.status_code).startswith('4'):
        logger.error(
            ' - Notification API returned client error, wiping settings...')
        NotificationSetting.objects.update(notification_service=None,
                                           pushover_api_key=None,
                                           pushover_user_key=None,
                                           prowl_api_key=None,
                                           next_notification=None)
        Notification.objects.create(
            message='Notification API error, settings are reset. Error: {}'.
            format(response.text),
            redirect_to='admin:dsmr_notification_notificationsetting_changelist'
        )

    # Server error, delay a bit.
    elif str(response.status_code).startswith('5'):
        logger.warning(
            ' - Notification API returned server error, retrying later...')
        NotificationSetting.objects.update(next_notification=timezone.now() +
                                           timezone.timedelta(minutes=5))

    raise AssertionError('Notify API call failed: {0} (HTTP {1})'.format(
        response.text, response.status_code))
예제 #12
0
    def test_invalid_api_url(self):
        """ Notifications: Test if inappropriate services get caught """

        settings = NotificationSetting.get_solo()
        settings.send_notification = True
        settings.notification_service = 'DSMR-Reader-Rulez'
        settings.api_key = 'es7sh2d-DSMR-Reader-Rulez-iweu732'
        settings.save()

        with self.assertRaises(AssertionError):
            dsmr_notification.services.notify()
예제 #13
0
    def test_no_daystatistics(self):
        """ Notifications: Test no notification because of no stats"""

        DayStatistics.objects.all().delete()

        settings = NotificationSetting.get_solo()
        settings.send_notification = True
        settings.notification_service = NotificationSetting.NOTIFICATION_NMA
        settings.api_key = 'es7sh2d-DSMR-Reader-Rulez-iweu732'
        settings.save()

        self.assertFalse(dsmr_notification.services.notify())
예제 #14
0
    def test_set_next_notification_date(self, now_mock):
        """ Notifications: Test if next notification date is set """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 16, 0, 0, 0))

        now = timezone.localtime(timezone.now())
        NotificationSetting.objects.update(next_notification=now)

        dsmr_notification.services.set_next_notification()

        notification_settings = NotificationSetting.get_solo()
        self.assertEqual(
            notification_settings.next_notification,
            timezone.make_aware(timezone.datetime(2016, 11, 17, 6, 0, 0)))
예제 #15
0
    def test_notification_dummy_provider_signal(self, now_mock, send_robust_mock):
        if not self.fixtures:
            return

        now_mock.return_value = timezone.make_aware(timezone.datetime(2016, 11, 17, hour=0, minute=5))

        notification_settings = NotificationSetting.get_solo()
        notification_settings.notification_service = NotificationSetting.NOTIFICATION_DUMMY
        notification_settings.next_notification = timezone.now()
        notification_settings.save()

        self.assertFalse(send_robust_mock.called)
        dsmr_notification.services.notify()
        self.assertTrue(send_robust_mock.called)
예제 #16
0
    def test_set_next_notification_date(self, now_mock):
        """ Notifications: Test if next notification date is set """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 16))

        now = timezone.localtime(timezone.now())
        tomorrow = (timezone.localtime(timezone.now()) +
                    timezone.timedelta(hours=24)).date()

        settings = NotificationSetting.get_solo()
        settings.next_notification = now
        settings.save()

        dsmr_notification.services.set_next_notification(settings, now)

        self.assertEqual(settings.next_notification, tomorrow)
예제 #17
0
    def test_notification_api_fail_other(self, now_mock, requests_post_mock):
        """ Notifications: Test API failure for notify() - HTTP xxx """
        now_mock.return_value = timezone.make_aware(timezone.datetime(2016, 11, 17, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=300, text='xxxxx')  # Just for code coverage.

        notification_settings = NotificationSetting.get_solo()
        notification_settings.notification_service = NotificationSetting.NOTIFICATION_PROWL
        notification_settings.prowl_api_key = self.API_KEY
        notification_settings.next_notification = timezone.now()
        notification_settings.save()

        # When having no data, this should NOT raise an exception.
        if not self.fixtures:
            return dsmr_notification.services.notify()

        with self.assertRaises(AssertionError):
            dsmr_notification.services.notify()
예제 #18
0
 def get_context_data(self, **kwargs):
     context_data = super(Configuration, self).get_context_data(**kwargs)
     # 20+ queries, we should cache this at some point.
     context_data.update(
         dict(
             api_settings=APISettings.get_solo(),
             backend_settings=BackendSettings.get_solo(),
             backup_settings=BackupSettings.get_solo(),
             consumption_settings=ConsumptionSettings.get_solo(),
             datalogger_settings=DataloggerSettings.get_solo(),
             dropbox_settings=DropboxSettings.get_solo(),
             email_settings=EmailSettings.get_solo(),
             frontend_settings=FrontendSettings.get_solo(),
             mindergas_settings=MinderGasSettings.get_solo(),
             mqtt_broker_settings=MQTTBrokerSettings.get_solo(),
             mqtt_jsondaytotals_settings=JSONDayTotalsMQTTSettings.get_solo(
             ),
             mqtt_splittopicdaytotals_settings=
             SplitTopicDayTotalsMQTTSettings.get_solo(),
             mqtt_jsoncurrentperiodtotals_settings=
             JSONCurrentPeriodTotalsMQTTSettings.get_solo(),
             mqtt_splittopiccurrentperiodtotals_settings=
             SplitTopicCurrentPeriodTotalsMQTTSettings.get_solo(),
             mqtt_jsongasconsumption_settings=JSONGasConsumptionMQTTSettings
             .get_solo(),
             mqtt_splittopicgasconsumption_settings=
             SplitTopicGasConsumptionMQTTSettings.get_solo(),
             mqtt_splittopicmeterstatistics_settings=
             SplitTopicMeterStatisticsMQTTSettings.get_solo(),
             mqtt_jsontelegram_settings=JSONTelegramMQTTSettings.get_solo(),
             mqtt_rawtelegram_settings=RawTelegramMQTTSettings.get_solo(),
             mqtt_splittopictelegram_settings=SplitTopicTelegramMQTTSettings
             .get_solo(),
             notification_settings=NotificationSetting.get_solo(),
             pvoutput_api_settings=PVOutputAPISettings.get_solo(),
             pvoutput_addstatus_settings=PVOutputAddStatusSettings.get_solo(
             ),
             retention_settings=RetentionSettings.get_solo(),
             weather_settings=WeatherSettings.get_solo(),
             influxdb_settings=InfluxdbIntegrationSettings.get_solo(),
         ))
     return context_data
예제 #19
0
    def test_should_notify_set(self):
        """ Notifications: Test should_notify()'s output when service is set """

        settings = NotificationSetting.get_solo()
        settings.send_notification = True
        settings.notification_service = NotificationSetting.NOTIFICATION_NMA
        settings.save()
        self.assertTrue(settings.send_notification)

        # Should fail because we haven't set an API key
        self.assertFalse(dsmr_notification.services.should_notify(settings))

        settings.api_key = 'es7sh2d-DSMR-Reader-Rulez-iweu732'
        settings.save()
        self.assertTrue(dsmr_notification.services.should_notify(settings))

        settings.next_notification = None
        dsmr_notification.services.set_next_notification(
            settings, timezone.make_aware(timezone.datetime(2116, 11, 16)))
        self.assertFalse(dsmr_notification.services.should_notify(settings))
예제 #20
0
def notify_pre_check():
    """ Checks whether we should notify """
    notification_settings = NotificationSetting.get_solo()

    if notification_settings.notification_service is None:
        return False

    # Dummy message?
    if notification_settings.next_notification is None:
        send_notification(message='DSMR-reader notification test.',
                          title='DSMR-reader Test Notification')
        NotificationSetting.objects.update(next_notification=timezone.now())
        return True

    # Ready to go, but not time yet.
    if notification_settings.next_notification is not None and timezone.now(
    ) < notification_settings.next_notification:
        return False

    return True
예제 #21
0
    def test_notification_api_fail(self, now_mock, requests_post_mock):
        """ Notifications: Test API failure for notify() """
        now_mock.return_value = timezone.make_aware(
            timezone.datetime(2016, 11, 17, hour=0, minute=5))
        requests_post_mock.return_value = mock.MagicMock(status_code=403,
                                                         text='Forbidden')

        settings = NotificationSetting.get_solo()
        settings.send_notification = True
        settings.notification_service = NotificationSetting.NOTIFICATION_NMA
        settings.api_key = 'es7sh2d-DSMR-Reader-Rulez-iweu732'
        settings.next_notification = timezone.localtime(timezone.now())
        settings.save()

        if self.fixtures:
            with self.assertRaises(AssertionError):
                dsmr_notification.services.notify()
        else:
            # When having no data, this should NOT raise an exception.
            return dsmr_notification.services.notify()

        with self.assertRaisesMessage(
                AssertionError, 'Notify API call failed: Forbidden (HTTP403)'):
            dsmr_notification.services.notify()
예제 #22
0
    def test_should_notify_skip(self):
        """ Notifications: Test whether should_notify() skips current day. """

        settings = NotificationSetting.get_solo()
        self.assertFalse(settings.send_notification)
        self.assertFalse(dsmr_notification.services.should_notify(settings))
예제 #23
0
 def setUp(self):
     self.instance = NotificationSetting().get_solo()
예제 #24
0
def send_notification(message: str, title: str) -> None:
    """ Sends notification using the preferred service """
    logger.debug(' - Preparing notification: %s | %s', title, message)
    notification_settings = NotificationSetting.get_solo()

    # Allow hooks (e.g. plugins)
    notification_sent.send_robust(None, title=title, message=message)

    # Plugins only require the hook above.
    if notification_settings.notification_service == NotificationSetting.NOTIFICATION_DUMMY \
            or notification_settings.notification_service is None:
        logger.debug(
            ' - Notification service is dummy (or not set). Hook triggered, skipping notification.'
        )
        return

    DATA_FORMAT = {
        NotificationSetting.NOTIFICATION_PUSHOVER: {
            'url': NotificationSetting.PUSHOVER_API_URL,
            'data': {
                'token': notification_settings.pushover_api_key,
                'user': notification_settings.pushover_user_key,
                'priority': '-1',
                'title': title,
                'message': message
            }
        },
        NotificationSetting.NOTIFICATION_PROWL: {
            'url': NotificationSetting.PROWL_API_URL,
            'data': {
                'apikey': notification_settings.prowl_api_key,
                'priority': '-2',
                'application': 'DSMR-Reader',
                'event': title,
                'description': message
            }
        },
        NotificationSetting.NOTIFICATION_TELEGRAM: {
            'url':
            '{}{}/sendMessage'.format(NotificationSetting.TELEGRAM_API_URL,
                                      notification_settings.telegram_api_key),
            'data': {
                'chat_id': notification_settings.telegram_chat_id,
                'disable_notification': 'true',
                'text': message
            }
        },
    }

    logger.debug(' - Sending notification')
    response = requests.post(
        timeout=settings.DSMRREADER_CLIENT_TIMEOUT,
        **DATA_FORMAT[notification_settings.notification_service])

    if response.status_code == 200:
        logger.debug(' - Notification sent')
        return

    # Invalid request, do not retry.
    if str(response.status_code).startswith('4'):
        logger.error(
            ' - Notification API returned client error, wiping settings...')
        NotificationSetting.objects.update(notification_service=None,
                                           pushover_api_key=None,
                                           pushover_user_key=None,
                                           prowl_api_key=None,
                                           next_notification=None,
                                           telegram_api_key=None,
                                           telegram_chat_id=None)
        Notification.objects.create(
            message='Notification API error, settings are reset. Error: {}'.
            format(response.text),
            redirect_to='admin:dsmr_notification_notificationsetting_changelist'
        )

    # Server error, delay a bit.
    elif str(response.status_code).startswith('5'):
        logger.warning(
            ' - Notification API returned server error, retrying later...')
        NotificationSetting.objects.update(next_notification=timezone.now() +
                                           timezone.timedelta(minutes=5))

    raise AssertionError('Notify API call failed: {0} (HTTP {1})'.format(
        response.text, response.status_code))
예제 #25
0
    def test_should_notify_default(self):
        """ Notifications: Test should_notify() default behaviour. """

        settings = NotificationSetting.get_solo()
        self.assertFalse(settings.send_notification)
        self.assertFalse(dsmr_notification.services.should_notify(settings))
예제 #26
0
 def test_notify_pre_check_default(self):
     """ Notifications: Test notify_pre_check() default behaviour. """
     notification_settings = NotificationSetting.get_solo()
     self.assertIsNone(notification_settings.notification_service)
     self.assertFalse(dsmr_notification.services.notify_pre_check())
예제 #27
0
 def setUp(self):
     NotificationSetting.get_solo()