def get_rule_matches(id):
    """ This route can operate in 3 ways. With no parameters, it looks at yesterday (from the
        second most recent midnight till the most recent midnight). With a `since` parameter, it uses
        the range from `since` until now. With `start_time` and `end_time`, it uses that range.

        It also checks if there are any values at all since the start time, and if there are none,
        this likely means that there's some problem with the Value Pipeline, and today's values
        haven't been imported yet. To just report 0 would be a false negative, so we throw a 404
        instead, so the client knows that there was a failure.
    """
    since = trycast_int(request.values.get("since"))
    start_time = trycast_int(request.values.get("start_time"))
    end_time = trycast_int(request.values.get("end_time"))
    if since is not None:
        start = since
        end = int(dt.datetime.now().timestamp())
    elif None not in (start_time, end_time):
        start = start_time
        end = end_time
    else:
        end = int(dt.datetime.combine(dt.date.today(), dt.time()).timestamp())
        start = end - 60 * 60 * 24

    if not Values.has_any_since(start):
        abort(404, "No values since start time %s" % start)

    (point_search, value_search) = Rules.searches(id)
    point_ids = Points.ids_where(Search.points(point_search))

    return Values.get(point_ids, start, end, Search.values(value_search))
Пример #2
0
    def test_where_tag(self):
        self.assertEqual(
            Rooms.where(Search.rooms("#11")),
            """[{"room_id":3,"room_name":"102","building_id":1,"building_name":"CMC","floor":1,"description":null,"tags":["math_stats","academic","computer_science"]}, 
 {"room_id":2,"room_name":"304","building_id":1,"building_name":"CMC","floor":3,"description":null,"tags":["math_stats","academic","computer_science"]}, 
 {"room_id":1,"room_name":"328","building_id":1,"building_name":"CMC","floor":3,"description":"Fishbowl","tags":["classroom","math_stats","academic","computer_science"]}]"""
        )
Пример #3
0
    def test_where_tag(self):
        self.assertEqual(
            Devices.where(Search.devices("#11")),
            """[{"device_id":2,"device_name":"Fishbowl vav","room_id":1,"room_name":"328","building_id":1,"building_name":"CMC","tags":["classroom","math_stats","academic","computer_science"],"description":null}, 
 {"device_id":1,"device_name":"Fishbowl thermostat","room_id":1,"room_name":"328","building_id":1,"building_name":"CMC","tags":["classroom","math_stats","academic","thermostat","computer_science"],"description":null}, 
 {"device_id":4,"device_name":"102 Lab thermostat","room_id":3,"room_name":"102","building_id":1,"building_name":"CMC","tags":["math_stats","academic","computer_science"],"description":null}]"""
        )
    def test_where_tag(self):
        self.assertEqual(
            Points.where(Search.points("#11")),
            """[{"point_id":2,"point_name":"CMC.328.SP","device_id":1,"device_name":"Fishbowl thermostat","room_id":1,"room_name":"328","building_id":1,"building_name":"CMC","value_type":{"value_type_id":4,"type":["NRML", "FAULT", "OFFNRML", "HIGH", "LOW"]},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["classroom","math_stats","academic","thermostat","computer_science","room_temp","set"],"description":"Thermostat Set Point in CMC 328"}, 
 {"point_id":1,"point_name":"CMC.328.RT","device_id":1,"device_name":"Fishbowl thermostat","room_id":1,"room_name":"328","building_id":1,"building_name":"CMC","value_type":{"value_type_id":2,"type":1},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["classroom","math_stats","academic","thermostat","computer_science","get","room_temp"],"description":"Room Temp in CMC 328"}, 
 {"point_id":5,"point_name":"CMC.102.SP","device_id":4,"device_name":"102 Lab thermostat","room_id":3,"room_name":"102","building_id":1,"building_name":"CMC","value_type":{"value_type_id":2,"type":1},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["math_stats","academic","computer_science","set"],"description":"Thermostat Set Point in CMC 102"}]"""
        )
    def test_where_building_or_device(self):
        self.assertEqual(
            Points.where(Search.points("@2 or %4")),
            """[{"point_id":4,"point_name":"EV.RM107.SP","device_id":3,"device_name":"Thermostat in Evans 107","room_id":4,"room_name":"107","building_id":2,"building_name":"Evans","value_type":{"value_type_id":3,"type":1.0},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["thermostat","residential","single","residence","room_temp","set"],"description":"Thermostat Set Point in Evans 107"}, 
 {"point_id":3,"point_name":"EV.RM107.RT","device_id":3,"device_name":"Thermostat in Evans 107","room_id":4,"room_name":"107","building_id":2,"building_name":"Evans","value_type":{"value_type_id":2,"type":1},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["thermostat","residential","get","single","residence","room_temp"],"description":"Room Temp in Evans 107"}, 
 {"point_id":5,"point_name":"CMC.102.SP","device_id":4,"device_name":"102 Lab thermostat","room_id":3,"room_name":"102","building_id":1,"building_name":"CMC","value_type":{"value_type_id":2,"type":1},"value_unit":{"value_unit_id":1,"measurement":"temperature","unit":"fahrenheit"},"tags":["math_stats","academic","computer_science","set"],"description":"Thermostat Set Point in CMC 102"}]"""
        )
def search_verify():
    search_query = request.values.get('search')
    if not search_query:
        abort(400, "Request must include a `search` argument")
    try:
        return Points.counts_where(Search.points(search_query)) or "[]"
    except psycopg2.Error as e:  # Any InvalidSearchException will be thrown and result in a 500.
        return "Invalid Point Search: " + str(e.pgerror)
def get_buildings():
    search_query = request.values.get('search')
    if search_query:
        try:
            return Buildings.where(Search.buildings(search_query)) or "[]"
        except InvalidSearchException as e:
            abort(400, e)
    else:
        return Buildings.all() or "[]"
def get_points_ids():
    search_query = request.values.get('search')
    if not search_query:
        abort(400, "Must include search parameter")

    try:
        return jsonify(Points.ids_where(Search.points(search_query))) or "[]"
    except InvalidSearchException as e:
        abort(400, e)
def get_values():
    # Some clients put `[]` at the end of array parameters. We can handle either case.
    point_ids = request.values.getlist('point_ids') or request.values.getlist(
        'point_ids[]')
    start_time = request.values.get('start_time')
    end_time = request.values.get('end_time')
    search = request.values.get('search')

    if None in (point_ids, start_time, end_time):
        abort(400, "Missing required parameter")

    search_sql = Search.values(search)

    return Values.get(tuple(point_ids), start_time, end_time,
                      search_sql) or "[]"
Пример #10
0
def values_verify():
    try:
        point_ids = request.values.getlist(
            'point_ids') or request.values.getlist('point_ids[]')
        start_time = request.values.get('start_time')
        end_time = request.values.get('end_time')
        search = request.values.get('search')

        if search is None:
            abort(400, "Request must include a `search` argument")
        search_sql = Search.values(search)

        return "%s values found" % Values.get_count(
            tuple(point_ids), start_time, end_time, search_sql)
    except InvalidSearchException:
        return "Invalid Value Search Syntax"
    except psycopg2.Error as e:  # Any InvalidSearchException will be thrown and result in a 500.
        return "Invalid Value Search: " + str(e.pgerror)
Пример #11
0
 def test_ids_where_tag(self):
     self.assertEqual(set(Rooms.ids_where(Search.rooms("#11"))), {1, 2, 3})
Пример #12
0
 def test_simple_tag(self):
     self.assertEqual(
         Search.rooms("#1"),
         " (rooms_tags.tag_id = 1 OR buildings_tags.tag_id = 1)")
Пример #13
0
 def test_ids_where_building_or_device(self):
     with self.assertRaises(Exception):
         Rooms.ids_where(Search.rooms("@2 or %4"))
Пример #14
0
 def test_simple_unit(self):
     with self.assertRaises(Exception):
         Search.rooms(":unit 5")
Пример #15
0
 def test_simple_or(self):
     self.assertEqual(Search.rooms("or"), " OR")
Пример #16
0
 def test_parenthesis_building_room_device(self):
     self.assertEqual(
         Search.rooms("(:floor = 2 or @3) and $2"),
         "( rooms.floor = 2 OR buildings.building_id = 3) AND rooms.room_id = 2"
     )
Пример #17
0
 def test_simple_building(self):
     self.assertEqual(Search.rooms("@12"), " buildings.building_id = 12")
Пример #18
0
 def test_building_room_device(self):
     self.assertEqual(Search.rooms("@3 and $2"),
                      " buildings.building_id = 3 AND rooms.room_id = 2")
Пример #19
0
 def test_device_point(self):
     with self.assertRaises(Exception):
         Search.rooms("%310 or *78")
Пример #20
0
 def test_building_room(self):
     self.assertEqual(Search.rooms("@3 and $7"),
                      " buildings.building_id = 3 AND rooms.room_id = 7")
Пример #21
0
 def test_simple_measurement(self):
     with self.assertRaises(Exception):
         Search.rooms(":measurement 'temperature'")
Пример #22
0
 def test_ids_where_building_and_tag(self):
     self.assertEqual(set(Rooms.ids_where(Search.rooms("@1 and #2"))),
                      set())
Пример #23
0
 def test_ids_where_tag_not_building(self):
     self.assertEqual(set(Rooms.ids_where(Search.rooms("#7 and not @1"))),
                      {4})
Пример #24
0
 def test_simple_floor(self):
     self.assertEqual(Search.rooms(":floor = 3"), " rooms.floor = 3")
Пример #25
0
 def test_simple_not(self):
     self.assertEqual(Search.rooms("not"), " NOT")
Пример #26
0
 def test_building_floor(self):
     self.assertEqual(Search.rooms("@3 and :floor > 2"),
                      " buildings.building_id = 3 AND rooms.floor > 2")
Пример #27
0
 def test_ids_where_building(self):
     self.assertEqual(set(Rooms.ids_where(Search.rooms("@2"))), {4})
Пример #28
0
 def test_ids_where_building_floor(self):
     self.assertEqual(
         set(Rooms.ids_where(Search.rooms("@1 and :floor > 2"))), {1, 2})
Пример #29
0
 def test_nested_parenthesis_building_room_device(self):
     self.assertEqual(
         Search.rooms(":floor = 2 or (@3 or $2)"),
         " rooms.floor = 2 OR( buildings.building_id = 3 OR rooms.room_id = 2)"
     )
Пример #30
0
 def test_simple_type(self):
     with self.assertRaises(Exception):
         Search.rooms(":type 4")