def do_check_freshness(self, hosts, services, timeperiods, macromodulations, checkmodulations,
                           checks, when):
        # pylint: disable=too-many-nested-blocks, too-many-branches
        """Check freshness and schedule a check now if necessary.

        This function is called by the scheduler if Alignak is configured to check the freshness.

        It is called for hosts that have the freshness check enabled if they are only
        passively checked.

        It is called for services that have the freshness check enabled if they are only
        passively checked and if their depending host is not in a freshness expired state
        (freshness_expiry = True).

        A log is raised when the freshess expiry is detected and the item is set as
        freshness_expiry.

        :param hosts: hosts objects, used to launch checks
        :type hosts: alignak.objects.host.Hosts
        :param services: services objects, used launch checks
        :type services: alignak.objects.service.Services
        :param timeperiods: Timeperiods objects, used to get check_period
        :type timeperiods: alignak.objects.timeperiod.Timeperiods
        :param macromodulations: Macro modulations objects, used in commands (notif, check)
        :type macromodulations: alignak.objects.macromodulation.Macromodulations
        :param checkmodulations: Checkmodulations objects, used to change check command if necessary
        :type checkmodulations: alignak.objects.checkmodulation.Checkmodulations
        :param checks: checks dict, used to get checks_in_progress for the object
        :type checks: dict
        :return: A check or None
        :rtype: None | object
        """
        now = when

        # Before, check if class (host or service) have check_freshness OK
        # Then check if item want freshness, then check freshness
        cls = self.__class__
        if not self.in_checking and self.freshness_threshold and not self.freshness_expired:
            # logger.debug("Checking freshness for %s, last state update: %s, now: %s.",
            #              self.get_full_name(), self.last_state_update, now)
            if os.getenv('ALIGNAK_LOG_CHECKS', None):
                logger.info("--ALC-- -> checking freshness for: %s", self.get_full_name())
            # If we never checked this item, we begin the freshness period
            if not self.last_state_update:
                self.last_state_update = int(now)
            if self.last_state_update < now - \
                    (self.freshness_threshold + cls.additional_freshness_latency):
                timeperiod = timeperiods[self.check_period]
                if timeperiod is None or timeperiod.is_time_valid(now):
                    # Create a new check for the scheduler
                    chk = self.launch_check(now, hosts, services, timeperiods,
                                            macromodulations, checkmodulations, checks)
                    if not chk:
                        logger.warning("No raised freshness check for: %s", self)
                        return None
                    chk.freshness_expiry_check = True
                    chk.check_time = time.time()
                    chk.output = "Freshness period expired: %s" % (
                        datetime.utcfromtimestamp(int(chk.check_time)).strftime(
                            "%Y-%m-%d %H:%M:%S %Z"))
                    if self.my_type == 'host':
                        if self.freshness_state == 'o':
                            chk.exit_status = 0
                        elif self.freshness_state == 'd':
                            chk.exit_status = 2
                        elif self.freshness_state in ['u', 'x']:
                            chk.exit_status = 4
                        else:
                            chk.exit_status = 3
                    else:
                        if self.freshness_state == 'o':
                            chk.exit_status = 0
                        elif self.freshness_state == 'w':
                            chk.exit_status = 1
                        elif self.freshness_state == 'c':
                            chk.exit_status = 2
                        elif self.freshness_state == 'u':
                            chk.exit_status = 3
                        elif self.freshness_state == 'x':
                            chk.exit_status = 4
                        else:
                            chk.exit_status = 3

                    return chk
                else:
                    logger.debug("Ignored freshness check for %s, because "
                                 "we are not in the check period.", self.get_full_name())
        return None
Check freshness and schedule a check now if necessary.

        This function is called by the scheduler if Alignak is configured to check the freshness.

        It is called for hosts that have the freshness check enabled if they are only
        passively checked.

        It is called for services that have the freshness check enabled if they are only
        passively checked and if their depending host is not in a freshness expired state
        (freshness_expiry = True).

        A log is raised when the freshess expiry is detected and the item is set as
        freshness_expiry.

        :param hosts: hosts objects, used to launch checks
        :type hosts: alignak.objects.host.Hosts
        :param services: services objects, used launch checks
        :type services: alignak.objects.service.Services
        :param timeperiods: Timeperiods objects, used to get check_period
        :type timeperiods: alignak.objects.timeperiod.Timeperiods
        :param macromodulations: Macro modulations objects, used in commands (notif, check)
        :type macromodulations: alignak.objects.macromodulation.Macromodulations
        :param checkmodulations: Checkmodulations objects, used to change check command if necessary
        :type checkmodulations: alignak.objects.checkmodulation.Checkmodulations
        :param checks: checks dict, used to get checks_in_progress for the object
        :type checks: dict
        :return: A check or None
        :rtype: None | object