Skip to content

Commit

Permalink
Merge aad4f1e into 455af3e
Browse files Browse the repository at this point in the history
  • Loading branch information
adybbroe committed Aug 30, 2022
2 parents 455af3e + aad4f1e commit 8524bb9
Show file tree
Hide file tree
Showing 4 changed files with 343 additions and 43 deletions.
2 changes: 1 addition & 1 deletion .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

- [ ] Closes #xxxx <!-- remove if there is no corresponding issue, which should only be the case for minor changes -->
- [ ] Tests added <!-- for all bug fixes or enhancements -->
- [ ] Tests passed: Passes ``pytest pyspectral`` <!-- for all non-documentation changes) -->
- [ ] Tests passed: Passes ``pytest`` <!-- for all non-documentation changes) -->
- [ ] Passes ``flake8`` <!-- remove if you did not edit any Python files -->
- [ ] Fully documented <!-- remove if this change should not be visible to users, e.g., if it is an internal clean-up, or if this is part of a larger project that will be documented later -->
34 changes: 28 additions & 6 deletions activefires_pp/api_posting.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Copyright (c) 2022 Adam.Dybbroe
# Copyright (c) 2022 Adam Dybbroe

# Author(s):

# Adam.Dybbroe <a000680@c21856.ad.smhi.se>
# Adam Dybbroe <Firstname.Lastname@smhi.se>

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
Expand All @@ -20,10 +20,32 @@
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

"""Post geojson formatted Alarms to a ReST-API
"""
"""Post geojson formatted Alarms to a ReST-API."""

import logging
import requests

def post_alarm(geojson_data, url):
# Data payload to be posted - Example:
# {"type": "Feature", "geometry": {"type": "Point", "coordinates": [15.860621, 61.403141]},
# "properties": {"power": 3.09576535, "tb": 328.81933594, "confidence": 8,
# "observation_time": "2022-08-02T03:27:43.850000",
# "platform_name": "NOAA-20", "related_detection": false}}

LOG = logging.getLogger(__name__)


def post_alarm(geojson_data, api_url, xauth=None):
"""Post an Alarm to a rest-api stored as a geojson file."""
pass
if xauth is None:
headers = {"Content-Type": "application/json; charset=utf-8"}
else:
headers = {"Content-Type": "application/json; charset=utf-8",
"x-auth-satellite-alarm": xauth}

response = requests.post(api_url,
headers=headers,
json=geojson_data)

LOG.info("Alarm posted: Response = %s", str(response))
LOG.debug("Status code = %d", response.status_code)
response.raise_for_status()
35 changes: 30 additions & 5 deletions activefires_pp/spatiotemporal_alarm_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
"""

import os
import logging
import signal
from queue import Empty
from threading import Thread
from requests.exceptions import HTTPError
from posttroll.listener import ListenerContainer
from posttroll.message import Message
from posttroll.publisher import NoisyPublisher
Expand Down Expand Up @@ -84,6 +86,9 @@ def __init__(self, configfile):

self.sos_alarms_file_pattern = self.options['geojson_file_pattern_alarms']
self.restapi_url = self.options['restapi_url']
_xauth_filepath = get_xauthentication_filepath_from_environment()
self._xauth_token = _get_xauthentication_token(_xauth_filepath)

self.fire_alarms_dir = Path(self.options['fire_alarms_dir'])

self.listener = None
Expand All @@ -102,7 +107,6 @@ def _setup_and_start_communication(self):

def _set_options_from_config(self, config):
"""From the configuration on disk set the option dictionary with all metadata for real-time processing."""

for item in config:
self.options[item] = config[item]

Expand Down Expand Up @@ -180,7 +184,13 @@ def send_alarms(self, geojson_alarms, msg):
# 1) Create the filename
# 2) Wite to a file
output_filename = store_geojson_alarm(self.fire_alarms_dir, p__, idx, alarm)
post_alarm(alarm, self.restapi_url)
try:
post_alarm(alarm['features'], self.restapi_url, self._xauth_token)
LOG.info('Alarm sent - status OK')
except HTTPError:
LOG.exception('Failed sending alarm!')
LOG.error('Data: %s', str(alarm['features']))

output_message = _create_output_message(msg, self.output_topic, alarm, output_filename)
LOG.debug("Sending message: %s", str(output_message))
self.publisher.send(str(output_message))
Expand All @@ -200,6 +210,23 @@ def close(self):
LOG.exception("Couldn't stop publisher.")


def get_xauthentication_filepath_from_environment():
"""Get the filename with the X-Authentication-token from environment."""
xauth_filepath = os.environ.get('FIREALARMS_XAUTH_FILEPATH')
if xauth_filepath is None:
raise OSError("Environment variable FIREALARMS_XAUTH_FILEPATH not set!")

return xauth_filepath


def _get_xauthentication_token(xauth_filepath):
"""Get the X-Authentication-token needed for posting to the API."""
with open(xauth_filepath, 'r') as fpt:
xauth_token = fpt.readline()

return xauth_token


def dump_collection(idx, features):
"""Dump the list of features as a Geojson Feature Collection."""
tmpdir = Path(DIR_SPATIAL_FILTER)
Expand All @@ -219,7 +246,7 @@ def create_alarms_from_fire_detections(fire_data, past_detections_dir, sos_alarm
# detections in smaller parts, and create potential alarms:

alarms_list = []
for idx, key in enumerate(gathered_fires):
for key in gathered_fires:
LOG.debug("Key: %s" % key)
fire_alarms = get_single_point_fires_as_collections(gathered_fires[key], long_fires_threshold)

Expand Down Expand Up @@ -255,7 +282,6 @@ def find_neighbours(feature, other_features, thr_dist=0.8):

def gather_neighbours_to_new_collection(start_id, features, feature_collections, thr_dist=None):
"""Go through all features and gather into groups of neighbouring detections."""

first_point = features[start_id]
features.pop(start_id)
neighbour_ids = find_neighbours(first_point, features)
Expand Down Expand Up @@ -306,7 +332,6 @@ def join_fire_detections(gdata):

def split_large_fire_clusters(features, km_threshold):
"""Take a list of fire detection features and split in smaller clusters/chains."""

num_features = len(features)
LOG.debug("Split large fire clusters - Number of features: %d" % num_features)
features = dict(zip(range(num_features), features))
Expand Down
Loading

0 comments on commit 8524bb9

Please sign in to comment.