Esempio n. 1
0
 def test_cutoff_case_C(self):
     """UNIT test: services.common.slots.cutoff_slot (CASE C)
     CASE C: slot[0] > interval[0] && slot[1] < interval[1]
     """
     self.assertEquals(
         slots.cutoff((
             misc.get_next_midnight(),
             misc.get_next_midnight() + py_delta(hours=1)
         ), (
             misc.get_next_midnight() + py_delta(minutes=15),
             misc.get_next_midnight() + py_delta(minutes=30)
         )), (
             misc.get_next_midnight() + py_delta(minutes=15),
             misc.get_next_midnight() + py_delta(minutes=30)
         )
     )
     self.assertEquals(
         slots.cutoff((
             misc.get_next_midnight(),
             misc.get_next_midnight() + py_delta(hours=1)
         ), (
             misc.get_next_midnight() + py_delta(minutes=15),
             misc.get_next_midnight() + py_delta(hours=1)
         )), (
             misc.get_next_midnight() + py_delta(minutes=15),
             misc.get_next_midnight() + py_delta(hours=1)
         )
     )
Esempio n. 2
0
    def get_applicable(self, groundstation, start=None, end=None):
        """
        This method returns all the availability slots that can be applied
        within the given interval defined by the start and the duration.
        :param groundstation: The object of the GroundStation.
        :param start: Start of the applicability slot.
        :param end: End of the applicability slot.
        :return: The list of the applicable AvailabilitySlots during the
        defined applicability slot.
        """
        if start is None or end is None:
            start, end = simulation.OrbitalSimulator.get_simulation_window()
        elif start >= end:
            raise TypeError(
                '<start=' + str(
                    start
                ) + '> should occurr sooner than <end=' + str(end) + '>'
            )

        result = []

        for a_i in self.filter(
            groundstation=groundstation
        ).filter(start__lt=end, end__gt=start):

            result.append(
                sn_slots.cutoff((a_i.start, a_i.end), (start, end))
            )

        return result
Esempio n. 3
0
    def availability_generates_slots(self, availability_slot):
        """
        Method that generates the Operational slots corresponding to the given
        Availability slot.

        :param availability_slot: reference to the Availability object
        """
        logger.info(
            '>>> @availability_generates_slots.availability_slot = ' + str(
                availability_slot
            )
        )

        # 1) Pass slots for all the spacecraft that:
        #   (a) are compatible with the GroundStation whose rules update
        #       provoked the generation of this Availability slot,
        #   (b) occur within the applicability range of the Availability slot

        compatible_p_slots = pass_models.PassSlots.objects.filter(
            groundstation=availability_slot.groundstation,
            spacecraft__in=[
                c.spacecraft for c in
                compatibility_models.ChannelCompatibility.objects.filter(
                    groundstation=availability_slot.groundstation
                )
            ]
        )

        p_slots = compatible_p_slots.filter(
            OperationalSlotsManager._slots_query(
                availability_slot.start,
                availability_slot.end
            )
        )

        logger.info(
            '>>> @availability_generates_slots.compatible_p_slots = ' +
            sn_misc.list_2_string(compatible_p_slots)
        )
        logger.info(
            '>>> @availability_generates_slots.p = ' + sn_misc.list_2_string(
                p_slots
            )
        )

        # 2) we filter the pass slots that are applicable to the window of this
        #       availability slot; truncating the first and the last one if
        #       necessary

        for p in p_slots:

            start, end = sn_slots.cutoff(
                (availability_slot.start, availability_slot.end),
                (p.start, p.end)
            )

            self.create(
                availability_slot=availability_slot,
                pass_slot=p, start=start, end=end
            )
Esempio n. 4
0
    def get_applicable(self, groundstation, start=None, end=None):
        """
        This method returns all the availability slots that can be applied
        within the given interval defined by the start and the duration.
        :param groundstation: The object of the GroundStation.
        :param start: Start of the applicability slot.
        :param end: End of the applicability slot.
        :return: The list of the applicable AvailabilitySlots during the
        defined applicability slot.
        """
        if start is None or end is None:
            start, end = simulation.OrbitalSimulator.get_simulation_window()
        elif start >= end:
            raise TypeError('<start=' + str(start) +
                            '> should occurr sooner than <end=' + str(end) +
                            '>')

        result = []

        for a_i in self.filter(groundstation=groundstation).filter(
                start__lt=end, end__gt=start):

            result.append(sn_slots.cutoff((a_i.start, a_i.end), (start, end)))

        return result
Esempio n. 5
0
    def generate_available_slots_once(rule_values, interval=None):
        """
        This method generates the available slots for a only-once rule that
        starts and ends in the given dates, during the specified interval.
        :param interval: Interval of applicability
        :param rule_values: The values for the ONCE availability rule
        """
        if interval is None:
            interval = simulation.OrbitalSimulator.get_simulation_window()

        try:
            r = AvailabilityRuleOnce.objects.get(
                availabilityrule_ptr_id=rule_values['id']
            )
        except dj_exceptions.ObjectDoesNotExist as ex:
            logger.warning(
                '>>> Child rule does not exist, returning no slots, ex = ' +
                str(ex)
            )
            return []

        try:
            slot = slots.cutoff(
                interval, (r.starting_time, r.ending_time)
            )
        except ValueError as ex:
            logger.warning(
                '>>> onceRules.generate_available_slots, no slots generated, '
                'ex = ' + str(ex)
            )
            return []

        return [slot]
Esempio n. 6
0
    def generate_available_slots_daily(rule_values, interval=None):
        """
        This method generates the available slots for a daily rule that
        starts and ends in the given dates, during the specified interval.
        TODO :: improve the generation algorithm in order to avoid generating
                slots since the start of the rule until the validity of the
                current interval (can be long)
        :param interval: Interval of applicability
        :param rule_values: The values for the ONCE availability rule
        """
        if interval is None:
            interval = simulation.OrbitalSimulator.get_simulation_window()

        try:
            r = AvailabilityRuleDaily.objects.get(
                availabilityrule_ptr_id=rule_values['id'])
        except dj_exceptions.ObjectDoesNotExist as ex:
            logger.warning(
                '>>> Child rule does not exist, returning no slots, ex = ' +
                str(ex))
            return []

        result = []
        slot_i = slots.position(interval, (r.starting_time, r.ending_time))

        while slot_i[0] < interval[1]:

            slot = slots.cutoff(interval, slot_i)
            result.append((slot[0], slot[1]))

            slot_i = (slot_i[0] + py_timedelta(days=1),
                      slot_i[1] + py_timedelta(days=1))

        return result
Esempio n. 7
0
    def generate_available_slots_once(rule_values, interval=None):
        """
        This method generates the available slots for a only-once rule that
        starts and ends in the given dates, during the specified interval.
        :param interval: Interval of applicability
        :param rule_values: The values for the ONCE availability rule
        """
        if interval is None:
            interval = simulation.OrbitalSimulator.get_simulation_window()

        try:
            r = AvailabilityRuleOnce.objects.get(
                availabilityrule_ptr_id=rule_values['id'])
        except dj_exceptions.ObjectDoesNotExist as ex:
            logger.warning(
                '>>> Child rule does not exist, returning no slots, ex = ' +
                str(ex))
            return []

        try:
            slot = slots.cutoff(interval, (r.starting_time, r.ending_time))
        except ValueError as ex:
            logger.warning(
                '>>> onceRules.generate_available_slots, no slots generated, '
                'ex = ' + str(ex))
            return []

        return [slot]
Esempio n. 8
0
    def availability_generates_slots(self, availability_slot):
        """
        Method that generates the Operational slots corresponding to the given
        Availability slot.

        :param availability_slot: reference to the Availability object
        """
        logger.info('>>> @availability_generates_slots.availability_slot = ' +
                    str(availability_slot))

        # 1) Pass slots for all the spacecraft that:
        #   (a) are compatible with the GroundStation whose rules update
        #       provoked the generation of this Availability slot,
        #   (b) occur within the applicability range of the Availability slot

        compatible_p_slots = pass_models.PassSlots.objects.filter(
            groundstation=availability_slot.groundstation,
            spacecraft__in=[
                c.spacecraft
                for c in compatibility_models.ChannelCompatibility.objects.
                filter(groundstation=availability_slot.groundstation)
            ])

        p_slots = compatible_p_slots.filter(
            OperationalSlotsManager._slots_query(availability_slot.start,
                                                 availability_slot.end))

        logger.info('>>> @availability_generates_slots.compatible_p_slots = ' +
                    sn_misc.list_2_string(compatible_p_slots))
        logger.info('>>> @availability_generates_slots.p = ' +
                    sn_misc.list_2_string(p_slots))

        # 2) we filter the pass slots that are applicable to the window of this
        #       availability slot; truncating the first and the last one if
        #       necessary

        for p in p_slots:

            start, end = sn_slots.cutoff(
                (availability_slot.start, availability_slot.end),
                (p.start, p.end))

            self.create(availability_slot=availability_slot,
                        pass_slot=p,
                        start=start,
                        end=end)
Esempio n. 9
0
    def pass_generates_slots(self, pass_slot):
        """
        Method that generates all the Operational slots related to the newly
        created pass slot.

        :param pass_slot: reference to the Pass slot
        """

        # 0) Check compatibility... if not compatible, no slot
        if not compatibility_models.ChannelCompatibility.objects.filter(
            groundstation=pass_slot.groundstation,
            spacecraft=pass_slot.spacecraft
        ).exists():

            logger.warn('No compatibility for pass slot = ' + str(pass_slot))
            return

        # 1) Availability slots for all the spacecraft that:
        #   (a) are owned by the GroundStation over which the Spacecraft passes,
        #   (b) occur within the applicability range of the Availability slot
        a_slots = availability_models.AvailabilitySlot.objects.filter(
            groundstation=pass_slot.groundstation
        ).filter(
            OperationalSlotsManager._slots_query(
                pass_slot.start,
                pass_slot.end
            )
        )

        # 2) we filter the pass slots that are applicable to the window of this
        #       availability slot; truncating the first and the last one if
        #       necessary
        for a in a_slots:

            start, end = sn_slots.cutoff(
                (a.start, a.end), (pass_slot.start, pass_slot.end)
            )

            self.create(
                availability_slot=a, pass_slot=pass_slot, start=start, end=end
            )
Esempio n. 10
0
    def generate_available_slots_daily(rule_values, interval=None):
        """
        This method generates the available slots for a daily rule that
        starts and ends in the given dates, during the specified interval.
        TODO :: improve the generation algorithm in order to avoid generating
                slots since the start of the rule until the validity of the
                current interval (can be long)
        :param interval: Interval of applicability
        :param rule_values: The values for the ONCE availability rule
        """
        if interval is None:
            interval = simulation.OrbitalSimulator.get_simulation_window()

        try:
            r = AvailabilityRuleDaily.objects.get(
                availabilityrule_ptr_id=rule_values['id']
            )
        except dj_exceptions.ObjectDoesNotExist as ex:
            logger.warning(
                '>>> Child rule does not exist, returning no slots, ex = ' +
                str(ex)
            )
            return []

        result = []
        slot_i = slots.position(interval, (r.starting_time, r.ending_time))

        while slot_i[0] < interval[1]:

            slot = slots.cutoff(interval, slot_i)
            result.append((slot[0], slot[1]))

            slot_i = (
                slot_i[0] + py_timedelta(days=1),
                slot_i[1] + py_timedelta(days=1)
            )

        return result
Esempio n. 11
0
    def pass_generates_slots(self, pass_slot):
        """
        Method that generates all the Operational slots related to the newly
        created pass slot.

        :param pass_slot: reference to the Pass slot
        """

        # 0) Check compatibility... if not compatible, no slot
        if not compatibility_models.ChannelCompatibility.objects.filter(
                groundstation=pass_slot.groundstation,
                spacecraft=pass_slot.spacecraft).exists():

            logger.warn('No compatibility for pass slot = ' + str(pass_slot))
            return

        # 1) Availability slots for all the spacecraft that:
        #   (a) are owned by the GroundStation over which the Spacecraft passes,
        #   (b) occur within the applicability range of the Availability slot
        a_slots = availability_models.AvailabilitySlot.objects.filter(
            groundstation=pass_slot.groundstation).filter(
                OperationalSlotsManager._slots_query(pass_slot.start,
                                                     pass_slot.end))

        # 2) we filter the pass slots that are applicable to the window of this
        #       availability slot; truncating the first and the last one if
        #       necessary
        for a in a_slots:

            start, end = sn_slots.cutoff((a.start, a.end),
                                         (pass_slot.start, pass_slot.end))

            self.create(availability_slot=a,
                        pass_slot=pass_slot,
                        start=start,
                        end=end)