def _calculate_lap_total(laps: List[LapStatus]) -> LapStatus:
    start_lap = laps[0]
    end_lap = laps[-1]

    total_status = LapStatus(id=f"{start_lap.id} - {end_lap.id}",
                             startTimePit=start_lap.startTimePit,
                             endTimePit=start_lap.endTimePit,
                             startTime=start_lap.startTime,
                             endTime=end_lap.endTime,
                             startOdo=start_lap.startOdo,
                             endOdo=end_lap.endOdo,
                             insideTemp=end_lap.insideTemp,
                             outsideTemp=end_lap.outsideTemp,
                             startSOC=start_lap.startSOC,
                             endSOC=end_lap.endSOC,
                             startRangeIdeal=start_lap.startRangeIdeal,
                             endRangeIdeal=end_lap.endRangeIdeal,
                             startRangeEst=start_lap.startRangeEst,
                             endRangeEst=end_lap.endRangeEst,
                             startRangeRated=start_lap.startRangeRated,
                             endRangeRated=end_lap.endRangeRated,
                             consumptionRated=start_lap.consumptionRated,
                             finished=False)

    # TODO calculate energy as sum
    energy = 0
    chargeSocAdded = 0
    chargeEnergyAdded = 0
    chargeRangeAdded = 0
    now = pendulum.now(tz='utc')
    duration = pendulum.Period(now, now)
    pit_duration = pendulum.Period(now, now)
    chargeDuration = pendulum.Period(now, now)
    for lap in laps:
        energy += lap.energy
        duration += lap.duration
        pit_duration += lap.pitDuration
        chargeSocAdded += lap.chargeSocAdded if lap.chargeSocAdded else 0
        chargeEnergyAdded += lap.chargeEnergyAdded if lap.chargeEnergyAdded else 0
        chargeRangeAdded += lap.chargeRangeRatedAdded if lap.chargeRangeRatedAdded else 0
        chargeDuration += lap.chargeDuration if lap.chargeDuration else pendulum.Period(
            now, now)
    total_status.energy = energy
    total_status.duration = duration
    total_status.pitDuration = pit_duration
    total_status.chargeSocAdded = chargeSocAdded
    total_status.chargeEnergyAdded = chargeEnergyAdded
    total_status.chargeRangeRatedAdded = chargeEnergyAdded
    total_status.chargeDuration = chargeDuration

    return total_status
Esempio n. 2
0
def get_graph_charging_lap_data():
    lap_id = request.args.get('lap')
    field = request.args.get('field')

    laps = data_processor.get_laps_raw()
    lap = laps[int(lap_id) if lap_id else -1]
    lap_data = lap['lap_data']
    lap_chargings = data_processor.get_car_chargings(int(lap_id))
    charges = lap_chargings[0]['charges']

    graph_periods = [
        pendulum.Period(charges[0]['date'], charge['date'])
        for charge in charges
    ]
    graph_labels = [
        f"{raw_value.hours:02d}:{raw_value.minutes:02d}:{raw_value.remaining_seconds:02d}"
        for raw_value in graph_periods
    ]
    graph_data = [
        float(charge[field]) if charge[field] is not None else None
        for charge in charges
    ]
    return _jsonify({
        "labels": graph_labels,
        "values": graph_data,
        'raw': lap_chargings
    })
Esempio n. 3
0
    def test_split_job(self, mocker, api, edge_class, next_edge_class,
                       id_field):
        """Test that split will correctly downsize edge_object"""
        interval = pendulum.Period(pendulum.Date(2010, 1, 1),
                                   pendulum.Date(2010, 1, 10))
        params = {"time_increment": 1, "breakdowns": []}
        job = InsightAsyncJob(api=api,
                              edge_object=edge_class(1),
                              interval=interval,
                              params=params)
        mocker.patch.object(edge_class,
                            "get_insights",
                            return_value=[{
                                id_field: 1
                            }, {
                                id_field: 2
                            }, {
                                id_field: 3
                            }])

        small_jobs = job.split_job()

        edge_class.get_insights.assert_called_once()
        assert len(small_jobs) == 3
        assert all(j.interval == job.interval for j in small_jobs)
        for i, small_job in enumerate(small_jobs, start=1):
            assert str(
                small_job
            ) == f"InsightAsyncJob(id=<None>, {next_edge_class(i)}, time_range={job.interval}, breakdowns={[]})"
Esempio n. 4
0
    def test_read_records_all(self, mocker, api):
        """1. yield all from mock
        2. if read slice 2, 3 state not changed
            if read slice 2, 3, 1 state changed to 3
        """
        job = mocker.Mock(spec=InsightAsyncJob)
        job.get_result.return_value = [
            mocker.Mock(), mocker.Mock(),
            mocker.Mock()
        ]
        job.interval = pendulum.Period(pendulum.date(2010, 1, 1),
                                       pendulum.date(2010, 1, 1))
        stream = AdsInsights(
            api=api,
            start_date=datetime(2010, 1, 1),
            end_date=datetime(2011, 1, 1),
            insights_lookback_window=28,
        )

        records = list(
            stream.read_records(
                sync_mode=SyncMode.incremental,
                stream_slice={"insight_job": job},
            ))

        assert len(records) == 3
Esempio n. 5
0
 def test_expiry_delta(self, dummy_user: auth.User):
     expiry_delta = timedelta(hours=1)
     token = auth.AuthToken.create(dummy_user, expiry_delta=expiry_delta)
     payload = auth.AuthToken.verify(token)
     iat = pendulum.from_timestamp(payload['iat'])
     exp = pendulum.from_timestamp(payload['exp'])
     assert pendulum.Period(start=iat,
                            end=exp).as_timedelta() == expiry_delta
Esempio n. 6
0
 def should_turn_on(self):
     if self.start_at is None or self.ends_at is None:
         return True
     date_start = pendulum.now().replace(hour=self.start_at.hour,
                                         minute=self.start_at.minute)
     date_end = pendulum.now().replace(hour=self.ends_at.hour,
                                       minute=self.ends_at.minute)
     period = pendulum.Period(date_start, date_end)
     return now() in period
Esempio n. 7
0
 def _table_header(self):
     """Generate header for COUNTER table for report, as list of cells."""
     header_cells = list(HEADER_FIELDS[self.report_type])
     start_month_first_day = datetime.date(
         self.period[0].year, self.period[0].month, 1
     )
     for d_obj in pendulum.Period(start_month_first_day, self.period[1]).range(
         "months"
     ):
         header_cells.append(d_obj.strftime("%b-%Y"))
     return header_cells
Esempio n. 8
0
def test_slice_gen():
    start_date = TEST_DATE
    generator = AdjustableSliceGenerator(start_date)
    dates = []
    for i in generator:
        dates.append(i)
        generator.adjust_range(
            pendulum.Period(start=start_date, end=start_date))
    assert dates
    days = [(slice.end_date - slice.start_date).total_days()
            for slice in dates]
    assert days[1] == AdjustableSliceGenerator.DEFAULT_RANGE_DAYS
Esempio n. 9
0
    def test_str(self, api, account):
        interval = pendulum.Period(pendulum.Date(2010, 1, 1),
                                   pendulum.Date(2011, 1, 1))
        job = InsightAsyncJob(
            edge_object=account,
            api=api,
            params={"breakdowns": [10, 20]},
            interval=interval,
        )

        assert str(
            job
        ) == f"InsightAsyncJob(id=<None>, {account}, time_range=<Period [2010-01-01 -> 2011-01-01]>, breakdowns=[10, 20])"
Esempio n. 10
0
    def test_between(self):
        times = [time(12, 00), time(23, 00)]

        timedeltas = [
            timedelta(hours=1),
            timedelta(days=1),
            timedelta(days=2),
            timedelta(days=3),
            timedelta(days=6),
        ]

        for t in times:
            for weekday in WEEKDAYS:
                day = weekday[0]

                for delta in timedeltas:
                    openingperiod = OpeningPeriod.objects.create(
                        store=self.store, day=day, time=t, duration=delta)
                    period = openingperiod.period(
                        OpeningPeriod.weekday_as_datetime(weekday=day,
                                                          time=t,
                                                          store=self.store))
                    period_before = pendulum.Period(
                        start=period.start - timedelta(seconds=2),
                        end=period.start - timedelta(seconds=1),
                    )
                    period_over_start = pendulum.Period(
                        start=period_before.start,
                        end=period.start + timedelta(seconds=1))
                    period_in = pendulum.Period(
                        start=period.start + timedelta(seconds=1),
                        end=period.end - timedelta(seconds=1),
                    )
                    period_over_end = pendulum.Period(
                        start=period.end - timedelta(seconds=1),
                        end=period.end + timedelta(seconds=1),
                    )
                    period_after = pendulum.Period(
                        start=period.end + timedelta(seconds=1),
                        end=period.end + timedelta(seconds=2),
                    )
                    period_over = pendulum.Period(
                        start=period.start - timedelta(seconds=1),
                        end=period.end + timedelta(seconds=1),
                    )

                    for p in [period_before, period_after]:
                        periods = OpeningPeriod.objects.between(period=p)
                        self.assertEqual(len(periods), 0)

                    for p in [
                            period_over_start, period_in, period_over_end,
                            period_over
                    ]:
                        periods = OpeningPeriod.objects.between(period=p)
                        self.assertEqual(len(periods), 1)

                    openingperiod.delete()
Esempio n. 11
0
 def _fill_months(self):
     """Ensure each month in period represented and zero fill if not."""
     start_month_first_day = datetime.date(
         self.period[0].year, self.period[0].month, 1
     )
     start, end = start_month_first_day, self.period[1]
     try:
         for d_obj in pendulum.Period(start, end).range("months"):
             if d_obj not in (x[0] for x in self._full_data):
                 self._full_data.append((d_obj, 0))
     except IndexError:  # pragma: nocover
         pass
     else:
         self._full_data.sort()
Esempio n. 12
0
    def test_split_job_smallest(self, mocker, api):
        """Test that split will correctly downsize edge_object"""
        interval = pendulum.Period(pendulum.Date(2010, 1, 1),
                                   pendulum.Date(2010, 1, 10))
        params = {"time_increment": 1, "breakdowns": []}
        job = InsightAsyncJob(api=api,
                              edge_object=Ad(1),
                              interval=interval,
                              params=params)

        with pytest.raises(
                ValueError,
                match="The job is already splitted to the smallest size."):
            job.split_job()
Esempio n. 13
0
    def weekdays(self):
        now = pendulum.now().at(hour=self.time.hour,
                                minute=self.time.minute,
                                second=self.time.second,
                                microsecond=self.time.microsecond)
        start = now.subtract(days=now.isoweekday()).add(days=self.day)
        period = pendulum.Period(start=start, end=start + self.duration)

        result = set()
        for day in period.xrange('days'):
            weekday = day.isoweekday()
            if weekday in result:
                break
            result.add(weekday)
        return result
Esempio n. 14
0
def job_fixture(api, account):
    params = {
        "level": "ad",
        "action_breakdowns": [],
        "breakdowns": [],
        "fields": ["field1", "field2"],
        "time_increment": 1,
        "action_attribution_windows": [],
    }
    interval = pendulum.Period(pendulum.Date(2019, 1, 1),
                               pendulum.Date(2019, 1, 1))

    return InsightAsyncJob(edge_object=account,
                           api=api,
                           interval=interval,
                           params=params)
Esempio n. 15
0
    def _generate_async_jobs(self, params: Mapping) -> Iterator[AsyncJob]:
        """Generator of async jobs

        :param params:
        :return:
        """

        for ts_start in self._date_intervals():
            if ts_start in self._completed_slices:
                continue
            ts_end = ts_start + pendulum.duration(days=self.time_increment - 1)
            interval = pendulum.Period(ts_start, ts_end)
            yield InsightAsyncJob(api=self._api.api,
                                  edge_object=self._api.account,
                                  interval=interval,
                                  params=params)
def convertPendulum(request, template, resource):
    '''
    Converts request.from request.to and template.period in pendulum
    :param resource: a resource class
    :param request: a request class
    :param template: a template class
    :return: 3 pendulum from from_date,to_date and period
    '''
    expirationtime = None
    print(type(request.from_date))
    startime = pendulum.parse(request.from_date)
    endtime = pendulum.parse(request.to_date)
    if resource.to_date != None:
        expirationtime = pendulum.parse(resource.to_date)
    period = pendulum.Period(startime, startime.add(weeks=template.period))

    return startime, endtime, period, expirationtime
Esempio n. 17
0
def get_graph_data_lap():
    lap_id = request.args.get('lap')
    field = request.args.get('field')

    laps = data_processor.get_laps_raw()
    lap = laps[int(lap_id) if lap_id else -1]
    lap_data = lap['lap_data']
    graph_periods = [
        pendulum.Period(lap_data[0]['date'], item['date']) for item in lap_data
    ]
    graph_labels = [
        f"{raw_value.hours:02d}:{raw_value.minutes:02d}:{raw_value.remaining_seconds:02d}"
        for raw_value in graph_periods
    ]
    graph_data = [
        float(item[field]) if item[field] is not None else None
        for item in lap_data
    ]
    return _jsonify({"labels": graph_labels, "values": graph_data})
Esempio n. 18
0
    def _totals_line(self, metric):
        """Generate Totals for a given metric."""
        total_cells = [TOTAL_TEXT[self.report_type]]
        publishers = {resource.publisher for resource in self.pubs}
        if len(publishers) == 1:
            total_cells.append(publishers.pop())
        else:
            total_cells.append("")
        platforms = {resource.platform for resource in self.pubs}
        if len(platforms) == 1:
            total_cells.append(platforms.pop())
        else:
            total_cells.append("")
        if self.report_type in ("JR1", "BR1", "BR2", "JR2", "BR3"):
            total_cells.extend([""] * 4)
        if self.report_type in ("DB2", "JR2", "BR3"):
            total_cells.append(metric)
        total_usage = 0
        pdf_usage = 0
        html_usage = 0

        start_month_first_day = datetime.date(
            self.period[0].year, self.period[0].month, 1
        )
        months = list(
            pendulum.Period(start_month_first_day, self.period[1]).range("months")
        )
        month_data = [0] * len(months)
        for pub in self.pubs:
            if pub.metric != metric:
                continue
            if self.report_type == "JR1":
                pdf_usage += pub.pdf_total  # pytype: disable=attribute-error
                html_usage += pub.html_total  # pytype: disable=attribute-error
            for data in pub:
                total_usage += data[2]
                month_data[months.index(data[0])] += data[2]
        total_cells.append(str(total_usage))
        if self.report_type == "JR1":
            total_cells.append(str(html_usage))
            total_cells.append(str(pdf_usage))
        total_cells.extend(str(d) for d in month_data)
        return total_cells
Esempio n. 19
0
 def period(self):
     period = pendulum.Period(start=self.start, end=self.end)
     period.closed = self.closed
     return period
Esempio n. 20
0
def schedulePPendulum(request, resource, template, aged):
    errors = {}

    u = generateXMLDoc(aged)
    r = generateXMLDoc(resource)
    c = None  # per ora non usato
    template.message_structure
    templateInfo = {}
    templateInfo['tags'] = template.message_structure
    #todo il tone e' da aggiungere come parametro alla classe template--> template.tone
    #templateInfo['tone'] = template.tone
    templateInfo['tone'] = "Neutral"


    if type(request.from_date) is not Pendulum:
        times = convertPendulum(request, template, resource)
        startime = times[0]
        endtime = times[1]
        period = times[2]
        expirationtime = times[3]
    else:
        startime = request.from_date
        endtime = request.to_date
        period = pendulum.Period(startime, startime.add(weeks=template.period))
        expirationtime = resource.to_date
        if expirationtime == None:
            expirationtime = endtime

    valid_interval = endtime - startime
    if valid_interval > period:
        valid_interval = period

    if template.nmsgmin != template.nmsgmax:
        nmsg = rnd.randrange(template.nmsgmin, template.nmsgmax + 1)
    else:
        nmsg = template.nmsgmax

    miniplan = [Message(count, aged.aged_id, intervention_session_id=1) for count in xrange(nmsg)]

    miniplanID = uuid.uuid4()

    channels = getChannelsAvailable(template, aged)

    with open('csv/prova_import_messages.csv') as csvmessages:
        messages = csv.DictReader(csvmessages)
        msgs_tosend = getListMessages(messages, nmsg, resource, channels)

    er = checkForErrors(errors, endtime, expirationtime, startime, miniplan, nmsg, len(msgs_tosend))
    errors = er[0]
    miniplan = er[1]
    if er[2]:
        endtime = er[3]
    else:
        return errors, miniplan

    day_of_event = mapDay(resource.on_day)
    if day_of_event == None:
        errors['ErrorNoDay'] = 'Error no day specified for periodic messages'
        miniplan = []
        return errors, miniplan

    # length of the loop depending on the msgs found
    if len(msgs_tosend) < nmsg:
        lenloop = len(msgs_tosend)
    else:
        lenloop = nmsg

    c = 0
    i = 0
    for dt in valid_interval.range("days"):
        if dt.day_of_week == day_of_event:
            if c % int(resource.every) == 0:
                if i > lenloop:
                    break
                miniplan[i].miniplan_id = miniplanID
                miniplan[i].date = dt.date()
                miniplan[i].time_1 = dt.date()
                miniplan[i].time_2 = dt.subtract(days=1).date()
                miniplan[i].time = scheduleHour(aged, None)
                miniplan[i].attached_audio = msgs_tosend[i]['Audio']
                miniplan[i].attached_media = msgs_tosend[i]['Media']
                miniplan[i].URL = msgs_tosend[i]['URL']

                miniplan[i].channel = msgs_tosend[i]['Channel']
                #miniplan[i].message_text = generate_message_text(aged, msgs_tosend[i]['Text'],msgs_tosend[i]['URL'])
                message_body = msgs_tosend[i]['Text']
                m = createMessageJson(message_body, templateInfo)
                miniplan[i].message_text = composeMessage(u, r, c, m)

                miniplan[i].intervention_session_id = request.intervention_session_id
                miniplan[i].pilot_id = request.pilot_id

                i += 1
            c += 1

    miniplan = checkMsgsOneDay(miniplan, endtime)

    return errors, miniplan
Esempio n. 21
0
def schedule(request, resource, template, aged):
    print "_______________SCHEDULE_______________"
    errors = {}

    if type(request.from_date) is not Pendulum:
        times = convertPendulum(request, template, resource)
        startime = times[0]
        endtime = times[1]
        period = times[2]
        expirationtime = times[3]
    else:
        startime = request.from_date
        endtime = request.to_date
        period = pendulum.Period(startime, startime.add(weeks=template.period))
        expirationtime = resource.to_date
        if expirationtime == None:
            expirationtime = endtime

    if template.nmsgmin != template.nmsgmax and template.nmsgmax > template.nmsgmin:
        nmsg = rnd.randrange(template.nmsgmin, template.nmsgmax + 1)
    else:
        nmsg = template.nmsgmax

    # creates miniplan that is a list of messages
    miniplan = [Message(count, aged.aged_id, intervention_session_id=1) for count in xrange(nmsg)]

    channels = getChannelsAvailable(template, aged)

    '''
    with open('csv/prova_import_messages.csv') as csvmessages:
        messages = csv.DictReader(csvmessages)
        msgs_tosend = getListMessages(messages, nmsg, resource, channels)
    '''

    messages = getResourceMessages(resource.resource_id)

    msgs_tosend = selectMessages(messages, nmsg, channels)

    er = checkForErrors(errors, endtime, None, startime, miniplan, nmsg, len(msgs_tosend))
    errors = er[0]
    miniplan = er[1]
    if er[2]:
        endtime = er[3]
    else:
        return errors, miniplan

    # length of the loop depending on the msgs found
    if len(msgs_tosend) < nmsg:
        lenloop = len(msgs_tosend)
    else:
        lenloop = nmsg

    for i in range(0, lenloop):
        miniplan[i].message_text = generate_message_text(aged, msgs_tosend[i]['Text'], msgs_tosend[i]['URL'])
        miniplan[i].attached_audio = msgs_tosend[i]['Audio']
        miniplan[i].attached_media = msgs_tosend[i]['Media']
        miniplan[i].URL = msgs_tosend[i]['URL']
        miniplan[i].channel = msgs_tosend[i]['Channel']

    miniplan = ED(miniplan, lenloop, startime, endtime, period, aged)

    miniplan = checkMsgsOneDay(miniplan, endtime)

    return errors, miniplan
Esempio n. 22
0
def scheduleLPendulum(request, resource, template, aged):
    print "_______________SCHEDULEPENDULUM_______________"
    '''
    Returns the miniplan scheduled with more frequency at the end of the interval
    It divides the interval for every msg with logaritmic growth:1 1/2 1/3 1/4
    Check on period(valid weeks): if request interval is larger that period then user period as interval
    Last message always sent the day before the event
    With Pendulum
    :param request: a request class
    :param template: a template class
    :param aged: a user class
    :return: a miniplan that is a list of messages class with all the fields completed
    '''
    errors = {}
    miniplanID = uuid.uuid4()

    u = generateXMLDoc(aged)
    r = generateXMLDoc(resource)
    c = None  # per ora non usato
    # todo: tenuta provvisoria per la demo, bisogna stabilire una struttura standard
    templateInfo = {}
    templateInfo['tags'] = template.message_structure
    templateInfo['tone'] = "Neutral"

    if type(request.from_date) is not Pendulum:
        times = convertPendulum(request, template, resource)
        startime = times[0]
        endtime = times[1]
        period = times[2]
        expirationtime = times[3]
    else:
        startime = request.from_date
        endtime = request.to_date
        period = pendulum.Period(startime, startime.add(weeks=template.period))
        expirationtime = resource.to_date
        if expirationtime == None:
            expirationtime = endtime

    if template.nmsgmin != template.nmsgmax:
        nmsg = rnd.randrange(template.nmsgmin, template.nmsgmax + 1)
    else:
        nmsg = template.nmsgmax

    miniplan = [Message(count, aged.aged_id, intervention_session_id=1) for count in xrange(nmsg)]

    valid_interval = endtime - startime
    if valid_interval > period:
        errors['Interval changed'] = 'Duration of the template(' + str(
            period) + ') less than interval set by the care giver'
        valid_interval = period

    channels = getChannelsAvailable(template, aged)

    messages = getResourceMessages(resource.resource_id)

    if messages is None:
        errors = {'Error': 'Messages not found'}
        miniplan = {}
        return errors, miniplan

    msgs_tosend = selectMessages(messages, nmsg, channels)

    '''
    with open('csv/prova_import_messages.csv') as csvmessages:
        messages = csv.DictReader(csvmessages)
        msgs_tosend = getListMessages(messages, nmsg, resource, channels)
    '''

    er = checkForErrors(errors, endtime, expirationtime, startime, miniplan, nmsg, len(msgs_tosend))
    errors = er[0]
    miniplan = er[1]
    if er[2]:
        endtime = er[3]
    else:
        return errors, miniplan

    # length of the loop depending on the msgs found
    if len(msgs_tosend) < nmsg:
        lenloop = len(msgs_tosend)
    else:
        lenloop = nmsg

    for i in range(0, lenloop):
        date = endtime - valid_interval

        miniplan[i].miniplan_id = miniplanID

        miniplan[i].date = date.date()
        miniplan[i].time_1 = date.date()
        miniplan[i].time_2 = date.add(days=1).date()

        miniplan[i].time = scheduleHourFromDate(aged, date).time()

        # miniplan[i].message_text = buildMessage(aged, msgs_tosend[i])
        message_body = msgs_tosend[i]['Text']
        m = createMessageJson(message_body, templateInfo)
        miniplan[i].message_text = composeMessage(u, r, c, m)

        miniplan[i].attached_audio = msgs_tosend[i].audio
        miniplan[i].attached_media = msgs_tosend[i].media
        miniplan[i].URL = msgs_tosend[i].url
        miniplan[i].message_id = msgs_tosend[i].message_id

        miniplan[i].channel = msgs_tosend[i].channels[0]['channel_name']

        miniplan[i].intervention_session_id = request.intervention_session_id
        miniplan[i].pilot_id = request.pilot_id

        valid_interval = valid_interval / (i + 2)

    miniplan = checkMsgsOneDayPendulum(miniplan, endtime)

    return errors, miniplan
Esempio n. 23
0
def scheduleEDPPendulum(request, resource, template, aged):
    print "_______________SCHEDULEEDPPENDULUM_______________"
    '''
        Returns the miniplan with the temporal interval between the msgs divided equally with Pendulum
        :param request: a request class
        :param template: a template class
        :param aged: a user class
        :return: a miniplan that is a list of messages class with all the fields completed
        '''
    errors = {}
    miniplanID = uuid.uuid4()

    u = generateXMLDoc(aged)
    r = generateXMLDoc(resource)
    c = None  # per ora non usato
    #todo: tenuta provvisoria per la demo, bisogna stabilire una struttura standard
    templateInfo = {}
    templateInfo['tags'] = template.message_structure
    templateInfo['tone'] = "Neutral"


    if type(request.from_date) is not Pendulum:
        times = convertPendulum(request, template, resource)
        startime = times[0]
        endtime = times[1]
        period = times[2]
    else:
        startime = request.from_date
        endtime = request.to_date
        period = pendulum.Period(startime, startime.add(weeks=template.period))

    valid_interval = endtime - startime
    if valid_interval > period:
        errors['Interval changed'] = 'Duration of the template(' + str(
            period) + ') less than interval set by the care giver'
        valid_interval = period

    if template.nmsgmin != template.nmsgmax and template.nmsgmax > template.nmsgmin:
        nmsg = rnd.randrange(template.nmsgmin, template.nmsgmax + 1)
    else:
        nmsg = template.nmsgmax

    # creates miniplan that is a list of messages
    miniplan = [Message(count, aged.aged_id, intervention_session_id=1) for count in xrange(nmsg)]

    channels = getChannelsAvailable(template, aged)

    messages = getResourceMessages(resource.resource_id)

    if messages is None:
        errors = {'Error': 'Messages not found'}
        miniplan = {}
        return errors, miniplan

    msgs_tosend = selectMessages(messages, nmsg, channels)

    er = checkForErrors(errors, endtime, None, startime, miniplan, nmsg, len(msgs_tosend))
    errors = er[0]
    miniplan = er[1]
    if er[2]:
        endtime = er[3]
    else:
        return errors, miniplan

    # length of the loop depending on the msgs found
    if len(msgs_tosend) < nmsg:
        lenloop = len(msgs_tosend)
    else:
        lenloop = nmsg

    step_send_msg = valid_interval / lenloop

    date = startime + (step_send_msg / 2)
    for i in range(0, lenloop):
        miniplan[i].miniplan_id = miniplanID
        miniplan[i].date = date.date()
        miniplan[i].time = scheduleHour(aged, None)

        miniplan[i].message_text = buildMessage(aged, msgs_tosend[i])
        message_body = msgs_tosend[i]['Text']
        m = createMessageJson(message_body, templateInfo)
        miniplan[i].message_text = composeMessage(u, r, c, m)

        miniplan[i].attached_audio = msgs_tosend[i].audio
        miniplan[i].attached_media = msgs_tosend[i].media
        miniplan[i].URL = msgs_tosend[i].url
        miniplan[i].channel = msgs_tosend[i].channels[0]['channel_name']
        miniplan[i].time_1 = date.date()
        miniplan[i].time_2 = date.add(days=1).date()
        miniplan[i].intervention_session_id = request.intervention_session_id
        miniplan[i].pilot_id = request.pilot_id

        date += step_send_msg

    miniplan = checkMsgsOneDay(miniplan, endtime)

    return errors, miniplan
def _update_car_laps():
    global _car_laps_list
    global _car_laps_formatted
    global _get_configuration_func
    global _car_charging_processes

    logger.debug("updating car laps")
    configuration = _get_configuration_func()
    positions = _data_source.get_car_positions(configuration)
    _car_laps_list = lap_analyzer.find_laps(configuration, positions,
                                            configuration.startRadius, 0, 0)
    _car_charging_processes = _data_source.get_charging_processes(
        configuration)

    # load driver names
    dates = [l.startTime for l in _car_laps_list]
    if dates:
        driver_map = _data_source.get_driver_changes(configuration, dates)
        for l in _car_laps_list:
            if l.startTime in driver_map:
                l.driver_name = driver_map[l.startTime].name

    # fill charging data
    for l in _car_laps_list:
        for charging in _car_charging_processes:
            if not charging.end_date:
                continue  # incomplete records - they are visible in the db from time to time
            charging.start_date = charging.start_date.replace(
                tzinfo=timezone.utc)
            charging.end_date = charging.end_date.replace(tzinfo=timezone.utc)
            if l.startTimePit <= charging.start_date and (
                    not l.endTimePit or l.endTimePit > charging.start_date):
                # set the value
                l.chargeStartTime = pendulum.from_timestamp(
                    charging.start_date.timestamp())
                l.chargeEndTime = pendulum.from_timestamp(
                    charging.end_date.timestamp())
                l.chargeEnergyAdded = charging.charge_energy_added
                l.chargeStartSoc = charging.start_battery_level
                l.chargeEndSoc = charging.end_battery_level
                l.chargeStartRangeRated = charging.start_rated_range_km
                l.chargeEndRangeRated = charging.end_rated_range_km
                l.chargeRangeRatedAdded = charging.end_rated_range_km - charging.start_rated_range_km  # the validator doesn't fill it for some reason
                l.chargeSocAdded = charging.end_battery_level - charging.start_battery_level  # the validator doesn't fill it for some reason
                l.chargeDuration = pendulum.Period(charging.start_date,
                                                   charging.end_date)
                break  # load only one charging

    total_lap = _calculate_lap_total(
        _car_laps_list) if _car_laps_list else None
    recent_lap = _car_laps_list[-1] if _car_laps_list else None
    prev_lap_list = _car_laps_list[-configuration.previousLaps -
                                   1:-1] if len(_car_laps_list) > 0 else []
    prev_lap_list.reverse()  # to have newest on top

    total_formatted = generate_labels(_get_configuration_func().lapLabelsTotal,
                                      total_lap.dict())
    previous_formatted = [
        generate_labels(_get_configuration_func().lapLabelsPrevious,
                        lap.dict()) for lap in prev_lap_list
    ]
    recent_formatted = generate_labels(
        _get_configuration_func().lapLabelsRecent, recent_lap.dict())

    _car_laps_formatted = JsonLapsResponse(total=total_formatted,
                                           previous=previous_formatted,
                                           recent=recent_formatted)

    logger.debug("updating car laps done")
def scheduleEDPPendulum(request, resource, template, aged):
    '''
        Returns the miniplan with the temporal interval between the msgs divided equally with Pendulum
        :param request: a request class
        :param template: a template class
        :param aged: a user class
        :return: a miniplan that is a list of messages class with all the fields completed
        '''
    errors = {}
    miniplanID = uuid.uuid4()

    if type(request.from_date) is not Pendulum:
        times = convertPendulum(request, template, resource)
        startime = times[0]
        endtime = times[1]
        period = times[2]
    else:
        startime = request.from_date
        endtime = request.to_date
        period = pendulum.Period(startime, startime.add(weeks=template.period))

    valid_interval = endtime - startime
    if valid_interval > period:
        errors['Interval changed'] = 'Duration of the template(' + str(
            period) + ') less than interval set by the care giver'
        valid_interval = period

    if template.nmsgmin != template.nmsgmax and template.nmsgmax > template.nmsgmin:
        nmsg = rnd.randrange(template.nmsgmin, template.nmsgmax + 1)
    else:
        nmsg = template.nmsgmax

    # creates miniplan that is a list of messages
    miniplan = [
        Message(count, aged.aged_id, intervention_session_id=1)
        for count in xrange(nmsg)
    ]

    channels = getChannelsAvailable(template, aged)
    '''
    with open('csv/prova_import_messages.csv') as csvmessages:
        messages = csv.DictReader(csvmessages)
        msgs_tosend = getListMessages(messages, nmsg, resource, channels)
    '''

    messages = getResourceMessages(resource.resource_id)
    if messages is None:
        errors = {'Error': 'Messages not found'}
        miniplan = {}
        return errors, miniplan

    msgs_tosend = selectMessages(messages, nmsg, channels)

    er = checkForErrors(errors, endtime, None, startime, miniplan, nmsg,
                        len(msgs_tosend))
    errors = er[0]
    miniplan = er[1]
    if er[2]:
        endtime = er[3]
    else:
        return errors, miniplan

    # length of the loop depending on the msgs found
    if len(msgs_tosend) < nmsg:
        lenloop = len(msgs_tosend)
    else:
        lenloop = nmsg

    step_send_msg = valid_interval / lenloop

    date = startime + (step_send_msg / 2)
    for i in range(0, lenloop):
        miniplan[i].miniplan_id = miniplanID
        miniplan[i].date = date.date()
        miniplan[i].time = scheduleHour(aged, None)
        miniplan[i].message_text = buildMessage(aged, msgs_tosend[i])
        miniplan[i].attached_audio = msgs_tosend[i].audio
        miniplan[i].attached_media = msgs_tosend[i].media
        miniplan[i].URL = msgs_tosend[i].url
        miniplan[i].channel = msgs_tosend[i].channels[0]['channel_name']
        miniplan[i].time_1 = date.date()
        miniplan[i].time_2 = date.add(days=1).date()
        miniplan[i].intervention_session_id = request.intervention_session_id
        miniplan[i].pilot_id = request.pilot_id

        date += step_send_msg

    miniplan = checkMsgsOneDay(miniplan, endtime)

    return errors, miniplan
Esempio n. 26
0
 def set_charge_energy_added(cls, v, values) -> pendulum.Duration:
     return values['chargeEndTime'] - values['chargeStartTime'] if values[
         'chargeEndTime'] and values['chargeStartTime'] else pendulum.Period(
             pendulum.now(), pendulum.now())
Esempio n. 27
0
def parent_job_fixture(api, grouped_jobs):
    interval = pendulum.Period(pendulum.Date(2019, 1, 1),
                               pendulum.Date(2019, 1, 1))
    return ParentAsyncJob(api=api, jobs=grouped_jobs, interval=interval)
def add_calculated_fields(*, current_item: Dict[str, Any], initial_status,
                          current_status, position_list, lap_list, total,
                          charging_process_list, forecast,
                          configuration: Configuration,
                          current_item_index: Optional[int],
                          now_dt: pendulum.DateTime):
    """
    Add hardcoded calculated fields into current_item
    Note the prototype is the same for all calculated functions even if all inputs are not used

    :param current_item:
    :param initial_status:
    :param current_status:
    :param position_list:
    :param lap_list:
    :param total:
    :param charging_process_list:
    :param forecast:
    :param configuration:
    :param current_item_index:
    :param now_dt: time to calculate data for.
    :return:
    """
    if not lap_list:
        return

    logger.info(f"{len(lap_list)} laps on forecast input")

    unfinished_lap = lap_list[
        -1] if lap_list and not lap_list[-1]['finished'] else None
    logger.debug(f"unfinished lap: {unfinished_lap is not None}")

    car_laps = lap_list[:-1]
    if not car_laps:
        return None
    logger.info(f"{len(car_laps)} laps to analyze")

    start_time = configuration.start_time
    end_time = configuration.start_time.add(hours=configuration.hours)
    time_since_start = now_dt - start_time if now_dt > start_time else pendulum.period(
        now_dt, now_dt)
    time_to_end = end_time - now_dt if now_dt < end_time else pendulum.period(
        now_dt, now_dt)
    distance_since_start = \
        current_status['distance'] if current_status and 'distance' in current_status and current_status['distance'] is not None else 0.0

    # print(f"from start: {time_since_start.in_hours()}, to end: {time_to_end.in_hours()}, dist: {distance_since_start}")

    avg_lap_time = pendulum.Period(now_dt, now_dt)
    avg_pit_time = pendulum.Period(now_dt, now_dt)
    avg_lap_distance = 0
    for lap in car_laps:
        avg_lap_time += lap['lap_duration']
        avg_pit_time += lap['pit_duration']
        avg_lap_distance += lap['distance']
    logger.info(
        f"sum lap time {avg_lap_time}, sum lap distance {avg_lap_distance}")
    avg_lap_time /= len(car_laps)
    avg_pit_time /= len(car_laps)
    avg_lap_distance /= len(car_laps)
    # print(f"avg lap time {avgLapTime}, avg pit time: {avgPitTime}, avg lap distance {avgLapDistance}")
    # print(f"avg lap time {avgLapTime}, avg lap distance {avgLapDistance}")

    unfinished_lap_remaining_time = pendulum.Period(now_dt, now_dt)
    unfinished_lap_remaining_distance = 0
    # calculate time and dist for the unfinished lap
    # print(f"unfinished lap duration {unfinished_lap.duration} vs avg {avgLapTime}")
    if unfinished_lap and unfinished_lap['lap_duration'] < avg_lap_time:
        unfinished_lap_remaining_time = avg_lap_time - unfinished_lap[
            'lap_duration']
    # print(f"unfinished lap time remaining time: {unfinished_lap_remaining_time}")
    if unfinished_lap and unfinished_lap['distance'] < avg_lap_distance:
        unfinished_lap_remaining_distance = avg_lap_distance - unfinished_lap[
            'distance']
    # print(f"unfinished lap time remaining distance: {unfinished_lap_remaining_time}")

    time_to_forecast = time_to_end
    if unfinished_lap_remaining_time:
        time_to_forecast -= unfinished_lap_remaining_time
    # print(f"time to forecast: {timeToForecast.in_hours()}")
    full_laps_remaining = int(time_to_forecast / (avg_lap_time + avg_pit_time))
    # print(f"laps to go: {fullLapsRemaining}")
    remaining_last_lap_time = time_to_forecast - full_laps_remaining * (
        avg_lap_time + avg_pit_time)  # time left after max possible full laps
    # print(f"last lap time: {remaining_last_lap_time}")
    coef = remaining_last_lap_time / (avg_lap_time + avg_pit_time)
    # print(f"coef: {coef}")
    last_lap_duration = avg_lap_time * coef
    # print(f"last lap duration: {last_lap_duration}")
    last_pit_duration = avg_pit_time * coef
    # print(f"last pit duration : {last_pit_duration}")
    last_lap_distance = avg_lap_distance * coef
    # print(f"last lap distance: {last_lap_distance}")

    total_estimated_distance = distance_since_start + unfinished_lap_remaining_distance + full_laps_remaining * avg_lap_distance + last_lap_distance
    # print(f"total estimated distance: {total_estimated_distance}")

    current_item['avg_lap_duration'] = avg_lap_time
    current_item['avg_pit_duration'] = avg_pit_time
    current_item['avg_full_duration'] = avg_lap_time + avg_pit_time
    current_item['avg_lap_distance'] = avg_lap_distance
    current_item[
        'unfinished_lap_remaining_time'] = unfinished_lap_remaining_time
    current_item[
        'unfinished_lap_remaining_distance'] = unfinished_lap_remaining_distance
    current_item['full_laps_remaining'] = full_laps_remaining
    current_item['last_lap_duration'] = last_lap_duration
    current_item['last_pit_duration'] = last_pit_duration
    current_item['last_full_duration'] = last_lap_duration + last_pit_duration
    current_item['last_lap_distance'] = last_lap_distance
    current_item['total_estimated_distance'] = total_estimated_distance

    # add best lap metric (best full avg speed
    best_lap_id = None
    best_avg_speed = 0
    best_full_duration = time_since_start
    best_lap_distance = 0
    for lap in car_laps:
        if 'full_avg_speed' in lap and lap['full_avg_speed'] > best_avg_speed:
            best_avg_speed = lap['full_avg_speed']
            best_lap_id = lap['lap_id']
            best_full_duration = lap['full_duration']
            best_lap_distance = lap['distance']
    current_item['best_lap'] = best_lap_id

    best_full_laps_remaining = int(time_to_forecast / best_full_duration)
    # print(f"laps to go: {fullLapsRemaining}")
    best_remaining_last_lap_time = time_to_forecast - best_full_laps_remaining * best_full_duration  # time left after max possible full laps
    # print(f"last lap time: {remaining_last_lap_time}")
    best_coef = best_remaining_last_lap_time / best_full_duration
    # print(f"coef: {coef}")
    best_last_lap_distance = best_lap_distance * best_coef
    # print(f"last lap distance: {last_lap_distance}")

    best_estimated_distance = distance_since_start + unfinished_lap_remaining_distance + best_full_laps_remaining * best_lap_distance + best_last_lap_distance
    current_item['best_estimated_distance'] = best_estimated_distance
Esempio n. 29
0
 def period(self, day):
     return pendulum.Period(start=self.start(day), end=self.end(day))