H2Oline.get_sample()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 2
1
"""
2
Get flows (and other parameters) from h2oline.com sites
3
"""
4
import datetime
5
import logging
6
import re
7
8
from bs4 import BeautifulSoup
9
import requests
10
import parsedatetime
11
12
from app.models import Sensor
13
from .base import add_new_sample, RemoteGage
14
15
logger = logging.getLogger(__name__)
16
17
18
class H2Oline(RemoteGage):
19
    @staticmethod
20
    def soup(remote_id):
21
        """
22
        Return a beautiful soup object from h2oline
23
        """
24
        url = 'http://www.h2oline.com/default.aspx?pg=si&op={}'.format(remote_id)
25
        r = requests.get(url)
26
        return BeautifulSoup(r.text, 'html.parser')
27
28
    def river(self, remote_id, soup=None):
29
        """
30
        Return string with river name and location
31
        """
32
        if soup is None:
33
            soup = self.soup(remote_id)
34
        river_strings = soup.body.findAll(text=re.compile(str(remote_id)))
35
        return ' '.join(river_strings[0].split()[1:])
36
37
    def value_strings(self, remote_id, parameter='CFS', soup=None):
38
        """
39
        Return strings containing specified parameter
40
        """
41
        if soup is None:
42
            soup = self.soup(remote_id)
43
        p = re.compile('([\d.]+)+(?= {})'.format(parameter))
44
        return soup.body.findAll(text=p)
45
46
    @staticmethod
47
    def start_end(string, parameter):
48
        """
49
        Return the start and end of the parameter in the string
50
        """
51
        p = re.compile('([\d.]+)+(?= {})'.format(parameter))
52
        result = p.search(string)
53
        return result.start(), result.end()
54
55
    def value(self, remote_id, parameter='CFS', soup=None):
56
        """
57
        Return float of first CFS found
58
        If given a parameter string, it will find that instead
59
        """
60
        if soup is None:
61
            cfs_strings = self.value_strings(remote_id, parameter=parameter)
62
        else:
63
            cfs_strings = self.value_strings(remote_id, parameter=parameter, soup=soup)
64
        start, end = self.start_end(cfs_strings[0], parameter)
65
        return float(cfs_strings[0][start:end])
66
67
68
    def dt_value(self, remote_id, parameter='CFS', soup=None):
69
        """
70
        Returns datetime and float of first CFS (or other parameter) found
71
        """
72
        strings = self.value_strings(remote_id,
73
                                     parameter=parameter,
74
                                     soup=soup)
75
        start, end = self.start_end(strings[0], parameter)
76
        dt = datetime.datetime.now()
77
        return dt, float(strings[0][start:end])
78
79
    def get_sample(self, sensor_id):
80
        """
81
        Takes a sensor id, tries to get the latest sample from the site
82
        """
83
        sensor = self.sensor(sensor_id)
84
        if sensor.remote_parameter is None:
85
            dt, v = self.dt_value(sensor.remote_id)
86
        else:
87
            dt, v = self.dt_value(sensor.remote_id,
88
                                  parameter=sensor.remote_parameter)
89
        add_new_sample(sensor.id, dt, v)
90