Skip to content

Commit 6e584ad

Browse files
authored
Merge pull request #24 from fact-project/add_missing
Add missing stuff
2 parents 8f7524b + d52f336 commit 6e584ad

5 files changed

Lines changed: 112 additions & 54 deletions

File tree

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
setup(
55
name='smart_fact_crawler',
6-
version='0.4.0',
6+
version='0.4.1',
77
description='acquieres data published on the smartfact web page',
88
url='https://github.com/fact-project/smart_fact_crawler.git',
99
author='Dominik Neise, Sebastian Mueller, Maximilian Nöthe',
@@ -21,7 +21,7 @@
2121
install_requires=[
2222
'requests',
2323
],
24-
tests_require=['pytest>=3.0'],
24+
tests_require=['pytest>=3.0', 'freezegun'],
2525
setup_requires=['pytest-runner'],
2626
zip_safe=True,
2727
)

smart_fact_crawler/__init__.py

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from .tools import str2float as s2f
77
from .tools import smartfact_time2datetime as sft2dt
88
from .tools import smartfact2table
9-
from .tools import extract_run_id_from_system_status
109
from .tools import get_entry
1110

1211
import re
@@ -20,6 +19,17 @@
2019
Quantity = namedtuple('Quantity', ['value', 'unit'])
2120

2221

22+
run_re = re.compile(
23+
'([0-9]{2}:[0-9]{2}:[0-9]{2}) ' # match the time part
24+
'<#[a-z]+>' # html color
25+
'([a-zA-Z\-]+) ' # run type
26+
'\[([a-zA-Z0-9 ]+)\] ' # source name
27+
'\(Run (\d+)\)' # run number
28+
'</#>'
29+
)
30+
Run = namedtuple('Run', ['start', 'type', 'source', 'id'])
31+
32+
2333
def to_namedtuple(name, dictionary):
2434
return namedtuple(name, dictionary.keys())(**dictionary)
2535

@@ -305,14 +315,19 @@ def main_page(url=None, timeout=None, fallback=False):
305315
get = partial(get_entry, fallback=fallback)
306316

307317
system_status = get(table, 1, 1)
318+
power_val, power_unit = get(table, 6, 3, default='nan nan').split()
319+
trigger_val, trigger_unit, _ = get(table, 5, 1, default='nan nan nan').split()
308320
return to_namedtuple('MainPage', {
309321
'timestamp_1': sft2dt(get(table, 0, 0)),
310322
'timestamp_2': sft2dt(get(table, 0, 1)),
311323
'system_status': system_status,
312-
'run_id': extract_run_id_from_system_status(system_status),
313324
'relative_camera_temperature': Quantity(s2f(get(table, 3, 1)), 'deg_C'),
314325
'humidity': Quantity(s2f(get(table, 4, 1)), '%'),
315326
'wind_speed': Quantity(s2f(get(table, 4, 2)), 'km/h'),
327+
'trigger_rate': Quantity(s2f(trigger_val), trigger_unit),
328+
'median_current': Quantity(s2f(get(table, 6, 1)), 'uA'),
329+
'max_current': Quantity(s2f(get(table, 6, 2)), 'uA'),
330+
'power': Quantity(s2f(power_val), power_unit),
316331
})
317332

318333

@@ -335,14 +350,48 @@ def errorhist(url=None, timeout=None, fallback=False):
335350

336351
table = smartfact2table(url, timeout=timeout)
337352
get = partial(get_entry, fallback=fallback)
338-
timestamp = get(table, 0, 0)
339353

340354
history = [
341355
h
342356
for h in get(table, 1, 1, default='').split("<->")[1].split("<br/>")
343357
if h
344358
]
345359
return to_namedtuple('ErrorHistPage', {
346-
'timestamp': sft2dt(timestamp) if timestamp else None,
360+
'timestamp': sft2dt(get(table, 0, 0)),
347361
'history': history,
348362
})
363+
364+
365+
def build_run(tup):
366+
start, run_type, source, run_id = tup
367+
run_id = int(run_id)
368+
369+
now = datetime.utcnow()
370+
start = datetime.strptime(start, '%H:%M:%S').replace(
371+
year=now.year, month=now.month, day=now.day
372+
)
373+
374+
if start > now:
375+
start -= timedelta(hours=24)
376+
377+
return Run(start, run_type, source, run_id)
378+
379+
380+
def observations(url=None, timeout=None, fallback=False):
381+
if url is None:
382+
url = os.path.join(smartfacturl, 'observations.data')
383+
384+
table = smartfact2table(url, timeout=timeout)
385+
get = partial(get_entry, fallback=fallback)
386+
387+
run_list = get(table, 1, 1)
388+
if run_list is not None:
389+
runs = list(map(build_run, run_re.findall(table[1][1])))
390+
runs.sort(key=lambda r: r.id)
391+
else:
392+
runs = None
393+
394+
return to_namedtuple('ErrorHistPage', {
395+
'timestamp': sft2dt(get(table, 0, 0)),
396+
'runs': runs,
397+
})
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
from pkg_resources import resource_filename
2+
from freezegun import freeze_time
3+
from datetime import datetime
4+
5+
test_file = resource_filename(
6+
'smart_fact_crawler', 'resources/20160703_233149/observations.data'
7+
)
8+
9+
def test_re():
10+
from smart_fact_crawler import run_re
11+
12+
with open(test_file) as f:
13+
m = run_re.findall(f.read())
14+
15+
assert len(m) == 67
16+
17+
timestamp, run_type, source, run_id = m[0]
18+
19+
assert timestamp == '23:31:27'
20+
assert run_type == 'data'
21+
assert source == 'Mrk 501'
22+
assert run_id == '67'
23+
24+
25+
@freeze_time('2016-07-03 23:32')
26+
def test_build_run():
27+
from smart_fact_crawler import run_re, build_run
28+
29+
with open(test_file) as f:
30+
m = run_re.findall(f.read())
31+
32+
run = build_run(m[0])
33+
34+
assert run.id == 67
35+
assert run.start == datetime(2016, 7, 3, 23, 31, 27)
36+
37+
38+
@freeze_time('2016-07-04 00:32')
39+
def test_build_run_after_midnight():
40+
from smart_fact_crawler import run_re, build_run
41+
42+
with open(test_file) as f:
43+
m = run_re.findall(f.read())
44+
45+
run = build_run(m[0])
46+
47+
assert run.id == 67
48+
assert run.start == datetime(2016, 7, 3, 23, 31, 27)
49+
50+
51+
@freeze_time('2016-07-03 23:32')
52+
def test_observations():
53+
from smart_fact_crawler import observations
54+
55+
obs = observations(url='file:' + test_file)
56+
57+
assert obs.runs[-1].id == len(obs.runs)

smart_fact_crawler/tests/test_unit.py

Lines changed: 0 additions & 26 deletions
This file was deleted.

smart_fact_crawler/tools.py

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
import requests
33
import urllib
44
from datetime import datetime
5-
import re
65

76

87
def str2float(text):
@@ -48,27 +47,6 @@ def smartfact2table(url, timeout=None):
4847
return parse_table(text)
4948

5049

51-
def extract_run_id_from_system_status(system_status):
52-
'''
53-
system_status: string like 'data(47) [1169/279s]' or 'Idle [pedestal]'
54-
returns: integer `run_id`
55-
or None if no number between braces `()` found in system_status.
56-
57-
throws TypeError in case `system_status` is not string like
58-
enough to be used inside re.match()
59-
'''
60-
if system_status is None:
61-
return None
62-
63-
run_id_in_system_status_pattern = r'.*\((\d+)\).*'
64-
match_run_id = re.match(run_id_in_system_status_pattern, system_status)
65-
66-
if match_run_id is None:
67-
return None
68-
69-
return int(match_run_id.groups()[0])
70-
71-
7250
def get_entry(table, row, col, fallback=False, default=None):
7351
'''
7452
Get an element from a two dimensinoal list like the return value

0 commit comments

Comments
 (0)