コード例 #1
0
def test_data_collection_period_relative():
    collection = DataCollectionPeriodRelative(start_offset=3600,
                                              wait_time=10,
                                              end_offset=3600 / 2)

    assert collection.period().start - st.utctime_now() - 3600 < 0.01
    assert collection.period().end - st.utctime_now() - 3600 / 2 < 0.01
コード例 #2
0
    def next(self) -> ty.Dict[str, Number]:
        self.client = st.DtsClient(
            f'{os.environ["DTSS_SERVER"]}:{os.environ["DTSS_PORT_NUM"]}')
        now = st.utctime_now()
        period = st.UtcPeriod(now - self.cal.HOUR, now)
        data = self.client.evaluate(self.tsv, period)

        if self.type == 'temp':
            ts = data[0]
        elif self.type == 'co2':
            ts = data[1]
        else:
            ts = data[2]

        values = ts.values.to_numpy()
        times = ts.time_axis.time_points_double
        out = dict(
            current=values[-1] if len(values) else np.nan,
            time=float(st.utctime_now()) * 1000,
            # time=float(times[0]) * 1000,
            max=max(values),
            min=min(values),
        )
        # print('data fetch success')
        return out
コード例 #3
0
ファイル: rate_limiter.py プロジェクト: tobiasli/weather
    def check_next_rate(self) -> bool:
        """Check if a hypothetical next action (performed right now) would exceed the rate limit."""

        now = utctime_now()
        next_timestamps = list(self.action_timestamps)[1:]
        next_timestamps.append(now)
        return self._check_rate(action_timestamps=next_timestamps,
                                action_limit=self.action_limit,
                                timespan=self.timespan)
コード例 #4
0
    def update():
        # Update dashboard data.
        period = st.UtcPeriod(st.utctime_now() - st.Calendar.DAY,
                              st.utctime_now())
        data = client.evaluate(
            st.TsVector([
                domain.get_measurement(station_name='Eftasåsen',
                                       module_name='Ute',
                                       data_type='Temperature').time_series
            ]), period)
        time, temp = get_xy(cal, data[0])

        new = {
            'temp': [temp[-1]],
            'time': [bokeh_time_from_timestamp(cal, st.utctime_now())],
            'color': ['blue']
        }
        now_source.stream(new, 100)
コード例 #5
0
    def _get_measurements_block(self, *,
                                device_data: lnetatmo.WeatherStationData,
                                device_id: str,
                                module_id: str,
                                measurements: ty.Sequence[str],
                                utc_period: UtcPeriod = None
                                ) -> TsVector:
        """Get data for a specific device and set of measurements. utc_period is the timespan for which we ask for
        data, but it is optional, as utc_period=None asks for the longest possible timespan of data.

        NB: Calls are limited to 1024 values. Must split to get all data in period (50 req pr sec, 500 req pr hour).

        Args:
            device_id: Unique identifier for the netatmo device.
            module_id: Unique identifier for the netatmo module (can be None, '').
            measurements: A ty.Sequence of strings representing the measurements we want to fetch.
            utc_period: Inclusive start/end. The period we want data for (if none, the longest possible period
                        (up to 1024 values).

        Returns:
            A TsVector with timeseries containing data for each measurement type, in the order of the input.
        """

        date_start = float(utc_period.start) if utc_period else None
        date_end = float(utc_period.end) if utc_period else None

        self.wait_for_rate_limiters()
        self.add_action_timestamp_to_rate_limiters(utctime_now())

        measurement_types_str = ','.join([m for m in measurements])

        data = device_data.getMeasure(
            device_id=device_id,
            module_id=module_id,
            scale='max',
            mtype=measurement_types_str,
            date_begin=date_start,
            date_end=date_end)

        if not data['body']:
            # noinspection PyArgumentList
            output = [TimeSeries() for _ in measurements]
        else:
            t = [float(timestamp) for timestamp in data['body'].keys()]
            # Add an additional timestep fmod(dt) forward in time to indicate the validness of the last value.
            dt_list = [t2 - t1 for t1, t2 in zip(t[0:-2], t[1:-1])]
            dt_mode = max(set(dt_list), key=dt_list.count)
            ta = TimeAxisByPoints(t + [t[-1] + dt_mode])

            values_pr_time = [value for value in data['body'].values()]
            values = list(map(list, zip(*values_pr_time)))

            # Remove nan:
            output = [TimeSeries(ta, self.set_none_to_nan(vector), POINT_INSTANT_VALUE) for vector in values]

        return TsVector(output)
コード例 #6
0
ファイル: dtss_serve_test.py プロジェクト: tobiasli/weather
    def refresh_data(self, cal: st.Calendar, hist_length: st.time) -> None:
        """Put new data into datasource for icon and plot."""
        period = st.UtcPeriod(st.utctime_now() - hist_length, st.utctime_now())
        temp = self.dtss_data.get_data(period=period)
        t, v = get_xy(cal, temp)

        points = [(time, value) for time, value in zip(t, v)]
        ideal_number_of_points = 10
        epsilon = (len(points) / (3 * ideal_number_of_points)) * 2  # https://stackoverflow.com/questions/57052434/can-i-guess-the-appropriate-epsilon-for-rdp-ramer-douglas-peucker
        reduced = rdp(points, epsilon=epsilon)
        lists = list(map(list, zip(*reduced)))
        t = lists[0]
        v = lists[1]

        new = {'value': [v],
               'time': [t],
               'color': ['grey']
               # 'color': [self.icon.color_selector(v[-1])]
               }
        self.source.data = new
コード例 #7
0
    def find_callback(self, query: str) -> TsInfoVector:
        """This callback is passed as the default find_callback for a shyft.time_series.DtsServer.

        Args:
            query: The url representing a relevant query for this DataCollectionRepository. Matches the formatting
                   provided by DataCollectionRepository.create_ts_query()

        Returns:
            A sequence of results matching the query.
        """
        ts = create_ts(0)
        tsi = TsInfo(name=query,
                     point_fx=point_interpretation_policy.POINT_INSTANT_VALUE,
                     delta_t=0,
                     olson_tz_id='',
                     data_period=ts.time_axis.total_period(),
                     created=utctime_now(),
                     modified=utctime_now())

        tsiv = TsInfoVector()
        tsiv.append(tsi)
        return tsiv
コード例 #8
0
def dashboard(doc):
    now_source = ColumnDataSource({'temp': [], 'time': [], 'color': []})
    period = st.UtcPeriod(st.utctime_now() - st.Calendar.DAY, st.utctime_now())
    fig = figure(
        title='Show current outdoor temperature!',
        x_axis_type='datetime',
        sizing_mode='scale_both',
        #     y_range=[15, 35],
    )
    fig.circle(source=now_source, x='time', y='temp', color='color', size=10)

    # fig.x_range = Range1d(bokeh_time_from_timestamp(cal, period.start), bokeh_time_from_timestamp(cal, period.end))

    def update():
        # Update dashboard data.
        period = st.UtcPeriod(st.utctime_now() - st.Calendar.DAY,
                              st.utctime_now())
        data = client.evaluate(
            st.TsVector([
                domain.get_measurement(station_name='Eftasåsen',
                                       module_name='Ute',
                                       data_type='Temperature').time_series
            ]), period)
        time, temp = get_xy(cal, data[0])

        new = {
            'temp': [temp[-1]],
            'time': [bokeh_time_from_timestamp(cal, st.utctime_now())],
            'color': ['blue']
        }
        now_source.stream(new, 100)
        # fig.x_range = Range1d(bokeh_time_from_timestamp(cal, period.start), bokeh_time_from_timestamp(cal, period.end))

    update()

    doc.add_periodic_callback(update, 1000)
    doc.title = "Now with live updating!"
    doc.add_root(fig)
コード例 #9
0
ファイル: rate_limiter.py プロジェクト: tobiasli/weather
    def _check_rate(*, action_timestamps: Sequence[TimeType],
                    action_limit: int, timespan: TimeType) -> bool:
        """With a set of timestamps, an action limit and a timespan, check if the performed actions exceed the rate
        limit or not.

        Args:
            action_timestamps: The history of actions represented by their timestamps.
            action_limit: The maximum amount of allowed actions within timestamp.
            timespan: The timespan over which action_limit is allowed.

        Returns:
            True when within rate, False, when rate is exceeded.
        """

        if len(action_timestamps) < action_limit:
            return True

        now = utctime_now()
        # Check if the Nth call happened less than a timespan ago:
        if now - action_timestamps[-action_limit] < timespan:
            return False
        else:
            return True
コード例 #10
0
ファイル: static_plot.py プロジェクト: tobiasli/weather
    {'data': domain.get_measurement(station_name=station, data_type=types.humidity.name, module_name=module),
     'color': '#0F2933'},  # dark green
]
# ('Pressure', 'mbar', point_fx.POINT_INSTANT_VALUE, '#33120F'),  # brown
# ('Noise', 'db', point_fx.POINT_INSTANT_VALUE, '#E39C30'),  # yellow
# ('Rain', 'mm', point_fx.POINT_INSTANT_VALUE, '#448098'),  # light blue
# ('WindStrength', 'km / h', point_fx.POINT_INSTANT_VALUE, '#8816AB'),  # purple

# Get timeseries from measurements:
client = DtsClient(f'{os.environ["DTSS_SERVER"]}:{os.environ["DTSS_PORT_NUM"]}')
# client = DtsClient(f'{socket.gethostname()}:{os.environ["DTSS_PORT_NUM"]}')
tsv = TsVector([meas['data'].time_series for meas in plot_data])
cal = Calendar('Europe/Oslo')
epsilon = 0.1

now = utctime_now()
period = UtcPeriod(now - cal.DAY*3, now)
data = client.evaluate(tsv, period)

try:
    fig = figure(title=f'Demo plot {cal.to_string(now)}', height=400, width=1400, x_axis_type='datetime')
    fig.line([1, 2, 3, 4, 5], [5, 3, 4, 2, 1])

    fig.yaxis.visible = False
    fig.xaxis.formatter = DatetimeTickFormatter(
        months=["%Y %b"],
        days=["%F %H:%M"],
        hours=["%a %H:%M"],
        minutes=["%H:%M"]
    )
コード例 #11
0
    def __init__(self, start: TimeType, wait_time: TimeType, end: Optional[TimeType] = st.utctime_now()):
        """DataCollectionPeriods are used to define the period query pattern for a DataCollectionSerive. The
        DataCollectionPeriod defines the start, stop of every individual period, and the wait time between each query.

        Args:
            start_offset: The offset in seconds from now that defines the start of the queried data period.
            end_offset: The offset in seconds from now that defines the end of the queried data period. Default=0.
            wait_time: The wait time in seconds between individual queries.
        """
        self.wait_time = wait_time
        self.start = start
        self.end = end
コード例 #12
0
 def period(self) -> st.UtcPeriod:
     """Return a UtcPeriod correctly defined for a data query right now."""
     now = st.utctime_now()
     return st.UtcPeriod(now - self.start_offset, now - self.end_offset)
コード例 #13
0
ファイル: rate_limiter.py プロジェクト: tobiasli/weather
 def perform_action(self) -> None:
     """Add now timestamp indicating an action to historical action timestamps."""
     self.action_timestamps.append(utctime_now())