This commit is contained in:
2025-12-08 04:51:02 +00:00
parent 1195729d58
commit 35be1d0823
11 changed files with 0 additions and 992 deletions

View File

View File

@@ -1,47 +0,0 @@
import psycopg2
import json
# Connect to your PostgreSQL database
conn = psycopg2.connect(
host="localhost",
database="nws",
user="nws",
password="nws"
)
# Create a cursor object
cur = conn.cursor()
# Execute the SQL query
cur.execute("""
SELECT json_build_object(
'type', 'FeatureCollection',
'features', json_agg(
json_build_object(
'type', 'Feature',
'geometry', ST_AsGeoJSON(geom)::json,
'properties', json_build_object(
'county', countyname,
'state', state,
'lat', lat,
'lon', lon
)
)
)
)
FROM county
WHERE cwa = 'RLX';
""")
# Fetch the result
geojson_result = cur.fetchone()[0]
# Print the GeoJSON result
outfile = open("rlxtest.json", "w")
json.dump(geojson_result,outfile, indent=2)
# Close the cursor and connection
cur.close()
conn.close()

48
geo.py
View File

@@ -1,48 +0,0 @@
#You can convert panoid to lat/lon using a free API call https://maps.googleapis.com/maps/api/streetview/metadata?pano=PANOID&key=YOURAPIKEY
#https://maps.googleapis.com/maps/api/streetview/metadata?pano=onUr8119UohoEeRXfBNArQ&key=AIzaSyDNmQaLwMoVluAJ8PMIZZyMUfp3hlbsndw
import requests
import os
import json
import webbrowser
S = requests.Session()
apikey = 'AIzaSyDNmQaLwMoVluAJ8PMIZZyMUfp3hlbsndw'
def geocheat(panoidurl):
query = requests.utils.urlparse(panoidurl).query
params = dict(x.split('=') for x in query.split('&'))
if 'panoid' in params:
panoid = params['panoid']
url = 'https://maps.googleapis.com/maps/api/streetview/metadata?pano='+panoid+'&key=AIzaSyDNmQaLwMoVluAJ8PMIZZyMUfp3hlbsndw'
dataresponse = json.loads(S.get(url).text)
#r = requests.get(url, timeout=3)
#if r.status_code == 200:
lat = dataresponse['location']['lat']
lon = dataresponse['location']['lng']
#print(lat,lon)
# print(r.content)
#print(dataresponse)
mapurl = "https://maps.google.com/maps?q=loc:" + str(lat) + "+" + str(lon)
#os.system("start \"\" + mapurl)
webbrowser.open(mapurl, new = 1)
poop = True
while poop:
cheatme = input("Enter URL with panoid: ")
geocheat(cheatme)

View File

@@ -1,66 +0,0 @@
import requests
import json
import psycopg2
import psycopg2.extensions
from datetime import datetime, timezone
import re
from shapely import wkt
def generate_gr2_triangle_placefile(filename="power_outages_gr2.txt"):
"""
Generates a GR2Analyst placefile using Triangles and Text for power outages.
Args:
filename (str): The name of the placefile to create.
"""
try:
conn = psycopg2.connect(host='localhost', database='nws', user='nws', password='nws')
cursor = conn.cursor()
cursor.execute("SELECT startguess,outagen,lastchange,st_astext(realareageom),lat,lon,cause, outagen FROM power WHERE cwa = 'RLX' and active = true") # Include outagen in select
outages = cursor.fetchall()
with open(filename, "w") as pf:
pf.write("Refresh: 1\n")
pf.write("Threshold: 999 nautical_miles\n")
pf.write("Title: Power Outages (RLX CWA) - Triangles\n")
pf.write("Font: 1, 11, 0, \"Courier New\"\n")
pf.write("Color: 255 0 0\n") # Red for triangles (outage area)
for outage in outages:
startguess, outagen_num_db, lastchange, realareageom_wkt, lat, lon, cause, outagen_display_num = outage # Get outagen as outagen_display_num
# Format hover text (optional for triangles, but can add later if needed)
hover_text = f"Outage #{outagen_display_num}\\n" # Use outagen_display_num for display
hover_text += f"Cause: {cause}\\n"
hover_text += f"Last Update: {lastchange.strftime('%Y-%m-%d %H:%M:%Z UTC')}"
# Triangle vertices - create a small triangle around the outage point
triangle_lat_offset = 0.02 # Adjust for triangle size (latitude offset)
triangle_lon_offset = 0.03 # Adjust for triangle size (longitude offset)
pf.write("Triangles:\n")
pf.write(f" {lat - triangle_lat_offset}, {lon - triangle_lon_offset}\n") # Vertex 1: Southwest
pf.write(f" {lat + triangle_lat_offset}, {lon - triangle_lon_offset}\n") # Vertex 2: Southeast
pf.write(f" {lat}, {lon + triangle_lon_offset}\n") # Vertex 3: North
pf.write("End:\n")
# Blue text label for outage number
pf.write("Color: 0 0 255\n") # Blue for text
pf.write(f"Text: {lat}, {lon}, 1, \"Outage #{outagen_display_num}\", \"{hover_text}\"\n") # Include hover text
pf.write("End:\n")
print(f"GR2Analyst Triangle placefile '{filename}' generated successfully.")
except psycopg2.Error as db_error:
print(f"Database error: {db_error}")
except IOError as io_error:
print(f"File I/O error: {io_error}")
finally:
if conn:
conn.close()
if __name__ == "__main__":
generate_gr2_triangle_placefile()
# generate_gr2_triangle_placefile("my_outages_triangle.txt")

24
ham.php
View File

@@ -1,24 +0,0 @@
<?php
// Connecting, selecting database
$dbconn = pg_connect("host=localhost dbname=nws user=nws password=nws")
or die('Could not connect: ' . pg_last_error());
// Performing SQL query
//$query = "SELECT distinct on (camid) camid, filepath FROM camdb order by camid,dateutc desc";
$query = "SELECT hour as hour, band as band, freq as freq FROM ham";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
// Printing results in HTML
while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$array[] = $line;
}
echo json_encode($array);
// Free resultset
pg_free_result($result);
// Closing connection
pg_close($dbconn);
?>

View File

@@ -1,62 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>SRD Update</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>
<body>
<p>Form for updating bands that are currently being monitored/worked</p>
<p>Fill out these as pairs then click submit, you need to fill 1 pair as a minimum:</p>
<form action="hamupdate.php" method="post">
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Band / Mode 1</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Freq / Comments 1</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Band / Mode 2</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Freq / Comments 2</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Band / Mode 3</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<label for="band[]" class="col-4 col-form-label">Freq / Comments 3</label>
<div class="col-8">
<input id="band[]" name="band[]" type="text" class="form-control">
</div>
</div>
<div class="form-group row">
<div class="offset-4 col-8">
<button name="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</body>
<script>
</script>
</html>

481
ltg.html
View File

@@ -1,481 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>RLX Lightning Archive</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.js" integrity="sha512-ozq8xQKq6urvuU6jNgkfqAmT7jKN2XumbrX1JiB3TnF7tI48DPI4Gy1GXKD/V3EExgAs1V+pRO7vwtS1LHg0Gw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw-src.css" integrity="sha512-vJfMKRRm4c4UupyPwGUZI8U651mSzbmmPgR3sdE3LcwBPsdGeARvUM5EcSTg34DK8YIRiIo+oJwNfZPMKEQyug==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw-src.js" integrity="sha512-czICF/Crp0B7QB13iQZG9bYUpd/P1Ona1NeZN52gYsoVFXIpakDmdOUepMCHCMBIBd9Ei5Mlg8Quy4e504IT5A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/jquery/latest/jquery.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/momentjs/latest/moment.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet.draw/1.0.4/leaflet.draw.css" integrity="sha512-gc3xjCmIy673V6MyOAZhIW93xhM9ei1I+gLbmFjUHIjocENRsLX/QUE1htk5q1XV2D/iie/VQ8DXI6Vu8bexvQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
<style type="text/css">
//#mapid { height: 800px; }
body {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width: 100%
}
#mapid {
height: 97%;
}
#bototmbar {
height: 3%;
}
#form {
position: absolute;
width: 250px;
left: 15px;
top: 350px;
z-index: 255555;
}
#inputForm {
background-color: #fff;
width: 250px;
z-index: 255553;
}
.datetimes {
width: 250px;
z-index: 2556557;
}
#current {
z-index: 10000000;
}
#legend {
position: absolute;
right: 30px;
bottom: 40px;
z-index: 55555;
}
</style>
<div id="mapid">
<div id="legend">
<img src="legend.png" alt="Legend">
</div>
<div id="form">
<form id="inputForm">
<label for="datetimes">Time Range (UTC)</label>
<input type="text" name="datetimes" class="datetimes" id="datetimes">
Use the box drawing thing in the top right so you don't have to manually enter these<br>
<label for="nwLon">NE Corner Latitude:</label><br>
<input type="text" id="neLat" name="neLat" required><br>
<label for="nwLon">NE Corner Longitude:</label><br>
<input type="text" id="neLon" name="neLon" required><br>
<label for="seLat">SW Corner Latitude:</label><br>
<input type="text" id="swLat" name="swLat" required><br>
<label for="seLon">SW Corner Longitude:</label><br>
<input type="text" id="swLon" name="swLon" required><br>
<label>Output Format:</label><br>
<input type="radio" id="leafletMap" name="outputFormat" value="Leaflet Map" checked>
<label for="leafletMap">Leaflet Map</label><br>
<input type="radio" id="geoJSON" name="outputFormat" value="geoJSON">
<label for="geoJSON">geoJSON</label><br>
<input type="radio" id="kml" name="outputFormat" value="KML">
<label for="kml">KML</label><br>
<label>Database:</label><br>
<label>Real-time ltg ingest has been disabled</label><br>
<input type="radio" id="main" name="database" value="main" checked>
<label for="main">Main (1986-Present)</label><br>
<input type="radio" id="current" name="database" value="current">
<label for="main">Current (Only new strikes)</label><br>
<!-- <input type="radio" id="csv" name="outputFormat" value="CSV">
<label for="csv">CSV</label><br>-->
<button type="button" onclick="generateOutput()">Generate Output</button>
<button type="button" onclick="clearstrikes()">Clear Strikes</button><br>
<label for="strikecount">Total / Pos / Neg Strikes Displayed:</label><br>
<input type="text" id="strikecount" name="strikecount" value=0 readonly><br>
</form>
</div>
</div>
<div id="bottombar">
<a href="cams.html" class="w3-button w3-black">Cam List</a>
<a href="admin.html" class="w3-button w3-black">Add Camera</a>
<a href="db.html" class="w3-button w3-black">WU obs</a>
<a href="5min.html" class="w3-button w3-black">5m ASOS obs</a>
<a href="outagemap.html" class="w3-button w3-black">Power Outages</a>
<a href="today.html" class="w3-button w3-black">CoCoRaHS Remarks</a>
<a href="https://docs.google.com/forms/d/1-2rTBkNyyBVe08G1vN1hcSOEOvvLUcS1Vs2SmmaudlU" class="w3-button w3-black" target="_blank">Questions? Comments?</a>
<!-- <a href="http://stoat.org/work/db.html" class="w3-button w3-black">Wunderground Obs</a>-->
</div>
<script>
var mymap = L.map('mapid').setView([38.332372, -81.652480], 8);
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri'
});
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles &copy; Esri &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
});
var Stadia_StamenToner = L.tileLayer('https://tiles.stadiamaps.com/tiles/stamen_toner/{z}/{x}/{y}{r}.{ext}', {
minZoom: 0,
maxZoom: 20,
attribution: '&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://www.stamen.com/" target="_blank">Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a> &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
ext: 'png'
});
var USGS_USImageryTopo = L.tileLayer('https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 20,
attribution: 'Tiles courtesy of the <a href="https://usgs.gov/">U.S. Geological Survey</a>'
});
var baselayers = {
"Esri Street Map": Esri_WorldStreetMap,
"Esri Satellite": Esri_WorldImagery,
"Esri Topo": Esri_WorldTopoMap,
"USGS Sat/Topo": USGS_USImageryTopo
}
L.control.layers(baselayers,null,{collapsed: false}).addTo(mymap);
Esri_WorldStreetMap.addTo(mymap);
var counties = 'counties.json'
var exteriorStyle = {
"color": "#000000",
"weight": 1,
"fillOpacity": 0
};
fetch(
counties
).then(
res => res.json()
).then(
data => L.geoJSON(data, {style: exteriorStyle}).addTo(mymap)
)
var LeafIcon = L.Icon.extend({
options: {
shadowUrl:
'http://leafletjs.com/docs/images/leaf-shadow.png',
iconSize: [38, 95],
shadowSize: [50, 64],
iconAnchor: [22, 94],
shadowAnchor: [4, 62],
popupAnchor: [-3, -76]
}
});
var greenIcon = new LeafIcon({
iconUrl: 'http://leafletjs.com/docs/images/leaf-green.png'
});
var drawnItems = new L.FeatureGroup();
mymap.addLayer(drawnItems);
var drawControl = new L.Control.Draw({
position: 'topright',
draw: {
rect: true,
polygon: false,
circle: false,
marker: false,
circlemarker: false,
polyline: false
},
edit: {
featureGroup: drawnItems
}
});
mymap.addControl(drawControl);
mymap.on('draw:created', function (e) {
var type = e.layerType,
layer = e.layer;
document.getElementById('neLat').value = layer._bounds._northEast.lat.toFixed(4);
document.getElementById('neLon').value = layer._bounds._northEast.lng.toFixed(4);
document.getElementById('swLat').value = layer._bounds._southWest.lat.toFixed(4);
document.getElementById('swLon').value = layer._bounds._southWest.lng.toFixed(4);
if (type === 'marker') {
layer.bindPopup('A popup!');
}
drawnItems.addLayer(layer);
});
$(function() {
var date = new Date();
$('input[name="datetimes"]').daterangepicker({
timePicker: true,
timePicker24Hour: true,
showDropdowns: true,
startDate: moment().utc().startOf('hour').add(-23, 'hour'),
endDate: moment().utc().startOf('hour').add(1,'hour'),
maxSpan: { "years": 100 },
linkedCalenders: false,
minDate: new Date(1986,0,1),
maxDate: new Date(date.getFullYear(), date.getMonth() + 1, 0),
opens: 'right',
drops: 'up',
locale: {
format: 'M/DD/YYYY HH:mm'
}
});
});
function generateOutput() {
// Retrieve user inputs
var neLat = (document.getElementById("neLat").value);
var neLon = document.getElementById("neLon").value;
var swLat = document.getElementById("swLat").value;
var swLon = document.getElementById("swLon").value;
var database = document.querySelector('input[name="database"]:checked').value;
var outputFormat = document.querySelector('input[name="outputFormat"]:checked').value;
var startDate = $('#datetimes').data('daterangepicker').startDate._d;
var endDate = $('#datetimes').data('daterangepicker').endDate._d;
if (neLat && neLon && swLat && swLon) {
let data = {swLat: swLat, neLat: neLat, swLon: swLon, neLon: neLon, type: outputFormat, startDate: startDate, endDate: endDate, database: database};
// Perform actions based on the selected output format
switch (outputFormat) {
case "geoJSON":
fetch_geoJSON(data)
// Generate GeoJSON output
// Implement your GeoJSON generation logic here
break;
case "KML":
generate_kml(data)
// Generate KML output
// Implement your KML generation logic here
break;
case "CSV":
// Generate CSV output
// Implement your CSV generation logic here
break;
case "Leaflet Map":
add_leaflet(data);
// Show a Leaflet map with the specified coordinates and date/time
// Implement your Leaflet map rendering logic here
break;
default:
// Handle unsupported format
break;
}
} else {
alert('Please ensure you have selected a bounding box for the data you want')
}
}
function fetch_geoJSON(data) {
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'RLXltg.geojson',
}).click();
});
}
function add_leaflet(data) {
var geojsonMarkerOptions = {
radius: 8,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
};
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.text())
.then(text => (plot_geojson(text)));
}
function plot_geojson(data) {
data = jQuery.parseJSON(data);
if (data.features == null) {
alert("No strikes were returned from the database, try a different time range or bounding box!");
}
var geojsonMarkerOptions = {
radius: 2,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
};
L.geoJson(data, {
pointToLayer: function (feature, latlng) {
mypopup = L.popup().setContent("Time (UTC): " + (feature.properties.time) + "<br> Magnitude (kA) " + feature.properties.mag)
counter = counter + 1;
if (feature.properties.mag > 0) {
poscounter = poscounter + 1;
}
if (feature.properties.mag < 0) {
negcounter = negcounter + 1;
}
return L.circleMarker(latlng, {
radius: 3,
fillColor: styleMarker(feature),
color: styleMarker(feature),
weight: 1,
opacity: 1,
fillOpacity: 0.8
}
).bindPopup(mypopup);
}
}).addTo(layerGroup);
document.getElementById('strikecount').value = counter + " / " + poscounter + " / " + negcounter;
drawnItems.clearLayers();
//document.getElementById("current").innerHTML = 'Total Displayed Strikes: ' + counter;
}
counter = 0;
poscounter = 0;
negcounter = 0;
document.getElementById('strikecount').value = counter + " / " + poscounter + " / " + negcounter;
function generate_kml(data) {
fetch("https://wx.stoat.org/cgi-bin/ltg.py", {
method: "POST",
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(data)
}).then((res) => res.blob())
.then((blob) => URL.createObjectURL(blob))
.then((href) => {
Object.assign(document.createElement('a'), {
href,
download: 'RLXltg.kml',
}).click();
});
}
function styleMarker(feature) {
if (feature.properties.mag > 0) {
return 'red';
}
if (feature.properties.mag < 0) {
return 'blue';
}
}
function clearstrikes() {
layerGroup.clearLayers();
counter = 0;
poscounter = 0;
negcounter = 0;
document.getElementById('strikecount').value = counter;
}
var layerGroup = L.layerGroup().addTo(mymap);
</script>
</body>
</html>

27
ltg.php
View File

@@ -1,27 +0,0 @@
<?php
ini_set("log_errors", 1);
ini_set("error_log", "/var/www/html/work/php-error.log");
// Connecting, selecting database
$dbconn = pg_connect("host=localhost dbname=nws user=nws password=nws")
or die('Could not connect: ' . pg_last_error());
$name = file_get_contents('php://input');
$arr = json_decode($name,true);
file_put_contents('test1.txt', $arr);
foreach($arr as $item) { //foreach element in $arr
file_put_contents('test3.txt', $item, FILE_APPEND);
$dtg = $item['time']; //etc
$lat = $item['lat'];
$lon = $item['lon'];
$mag = $item['mag'];
pg_query_params($dbconn,
"INSERT INTO ltg (datetime,lat,lon,mag) values ($1, $2, $3, $4) on conflict do nothing",
array($dtg,$lat,$lon,$mag)) or die('Query failed: ' . pg_last_error());
pg_query("COMMIT");
}
pg_close($dbconn);
?>

View File

@@ -1,59 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<title>Wunderground obs</title>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.js" integrity="sha512-WNLxfP/8cVYL9sj8Jnp6et0BkubLP31jhTG9vhL/F5uEZmg5wEzKoXp1kJslzPQWwPT1eyMiSxlKCgzHLOTOTQ==" crossorigin="anonymous"></script>
<link href="https://unpkg.com/tabulator-tables@4.7.2/dist/css/tabulator.min.css" rel="stylesheet">
<script type="text/javascript" src="https://unpkg.com/tabulator-tables@4.7.2/dist/js/tabulator.min.js"></script>
<button onclick="reloadData()">Data autorefreshes every 5 minutes, click to refresh now</button>
<a>QPE 00L is direct from WU, the other QPE are derived and may be off if time settings on the individual PWS are incorrect</a>
<input type="checkbox" id="cwa" name="cwa" value="RLX" onchange="filters()">
<label for="cwa">RLX only</label><br>
<div id="wunderobs"></div>
<script>
function googleMap(cell, formatterParams){
return "http://maps.google.com/maps?t=k&q=loc:" + cell.getData().lat + "+" + cell.getData().lon + "&basemap=satellite";
}
function reloadData() {
table.replaceData("dbone.php");
}
var table = new Tabulator("#wunderobs", {
responsiveLayout:true,
tooltipsHeader:true,
columns:[
{title:"Station", field:"sitename"},
{title:"T", field:"tempf"},
{title:"QPE 00L", field:"preciptotal",formatter:"money",headerTooltip:"Since Midnight"},
{title:"Winddir", field:"winddir"},
{title:"Speed", field:"windspd",headerTooltip:"Mph"},
{title:"Gust", field:"windgust",headerTooltip:"Mph"}
],
});
table.setData("oneraindb.php");
function filters() {
var y = document.getElementById("cwa").checked;
if (y) {
table.addFilter("cwa", "=", 'RLX');
}
if (!y) {
table.removeFilter("cwa", "=", 'RLX');
}
}
// {title:"24hr QPE", field:"rain24", formatterParms:{precision:2}},
var timeout = setInterval(reloadData, 300000);
</script>
</body>
</html>

View File

@@ -1,152 +0,0 @@
import time
import requests
import json
import geojson
import psycopg2
import psycopg2.extensions
from psycopg2.extras import Json
conn = psycopg2.connect(host='localhost', database='nws', user='nws', password='nws')
cursor = conn.cursor()
#one rain sensor database with last obs and metadata
#one rain sensor database with all obs
#metsensor = [30,53,11,10,50,44,40,41]
metsensor = [(3,'tempf'),(2,'raintotal'),(8,'humidity'),(7,'winddir'),(4,'windspd'),(5,'windgust')]
rainsensor = [(2,'raintotal')]
features = []
alldata = []
S = requests.Session()
cursor.execute("SELECT siteid, sitetype from onerainsites")
#WHERE (Active = True) and ((EXTRACT(EPOCH FROM (current_timestamp - lastob ))/60) > 8 or (lastob ISNULL))"
allonerainsites = cursor.fetchall()
def getData(siteid,sensorid):
apiget = 'https://wvdhsem.onerain.com/export/flot/?method=sensor&site_id=' + str(siteid) + '&device_id=' + str(sensorid)
#print(apiget)
dataresponse = json.loads(S.get(apiget).text)
#print(dataresponse)
return dataresponse
# sql = 'INSERT INTO wuobs (stationid, dateutc, winddir, windspd, windgust, tempf, dewpt, humidity, pressure, preciptotal) VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s) ON CONFLICT (stationid,dateutc) DO NOTHING'
# sql2 = 'UPDATE wusites SET lastob = %s, winddir = %s, windspd = %s, windgust= %s, tempf = %s, dewpt = %s, humidity = %s, pressure = %s, preciptotal = %s WHERE stationid = %s'
# cursor.execute(sql,ob)
# cursor.execute(sql2,ob2)
# conn.commit()
# setDerived(stationid)
def setDerived(stationid):
data1 = (stationid,)
data = (stationid,stationid)
ago24 = "UPDATE wusites set ago24 = subquery.preciptotal, ago24time = subquery.dateutc from (select preciptotal,stationid,dateutc from wuobs WHERE (dateutc < timezone('utc',current_timestamp) - interval '23 hours') and (dateutc > timezone('utc',current_timestamp) - interval '24 hours') and stationid = %s order by dateutc desc limit 1) as subquery where wusites.stationid = %s"
ago3 = "UPDATE wusites set ago3 = subquery.preciptotal, ago3time = subquery.dateutc from (select preciptotal,stationid,dateutc from wuobs WHERE (dateutc < timezone('utc',current_timestamp) - interval '2.5 hours') and (dateutc > timezone('utc',current_timestamp) - interval '3 hours') and stationid = %s order by dateutc desc limit 1) as subquery where wusites.stationid = %s"
ago6 = "UPDATE wusites set ago6 = subquery.preciptotal, ago6time = subquery.dateutc from (select preciptotal,stationid,dateutc from wuobs WHERE (dateutc < timezone('utc',current_timestamp) - interval '5.2 hours') and (dateutc > timezone('utc',current_timestamp) - interval '6 hours') and stationid = %s order by dateutc desc limit 1) as subquery where wusites.stationid = %s"
midnight = "UPDATE wusites set lastmidnight = subquery.preciptotal from (select preciptotal,stationid from wuobs WHERE (dateutc < timezone('UTC', current_date::timestamp at time zone 'US/Eastern')) and (dateutc > timezone('UTC', current_date::timestamp at time zone 'US/Eastern' - interval '40 minutes')) and stationid = %s order by dateutc desc limit 1) as subquery where wusites.stationid = %s"
windmax = "UPDATE wusites set windmax = subquery.windmax from (SELECT MAX(windgust) as windmax FROM wuobs where (dateutc > timezone('utc',current_timestamp) - interval '24 hours') and stationid = %s) as subquery where wusites.stationid = %s"
maxt = "UPDATE wusites set maxt = subquery.maxt from (SELECT MAX(tempf) as maxt FROM wuobs where (dateutc > timezone('utc',current_timestamp) - interval '24 hours') and stationid = %s) as subquery where wusites.stationid = %s"
mint = "UPDATE wusites set mint = subquery.mint from (SELECT MIN(tempf) as mint FROM wuobs where (dateutc > timezone('utc',current_timestamp) - interval '24 hours') and stationid = %s) as subquery where wusites.stationid = %s"
cursor.execute(ago24,data)
cursor.execute(ago6,data)
cursor.execute(ago3,data)
cursor.execute(windmax,data)
cursor.execute(midnight,data)
cursor.execute(maxt,data)
cursor.execute(mint,data)
conn.commit()
rain3 = "update wusites set rain3 = (case when (wusites.ago3time < timezone('UTC', current_date::timestamp at time zone 'US/Eastern') and wusites.stationid = %s) then (wusites.preciptotal + wusites.lastmidnight - wusites.ago3) when (wusites.ago3time > timezone('UTC', current_date::timestamp at time zone 'US/Eastern') and wusites.stationid = %s) then (wusites.preciptotal - wusites.ago3) end) where wusites.stationid = %s"
rain6 = "update wusites set rain6 = (case when (wusites.ago6time < timezone('UTC', current_date::timestamp at time zone 'US/Eastern') and wusites.stationid = %s) then (wusites.preciptotal + wusites.lastmidnight - wusites.ago6) when (wusites.ago6time > timezone('UTC', current_date::timestamp at time zone 'US/Eastern') and wusites.stationid = %s) then (wusites.preciptotal - wusites.ago6) end) where wusites.stationid = %s"
rain24 = "update wusites set rain24 = (wusites.preciptotal + wusites.lastmidnight - wusites.ago24) where wusites.stationid = %s"
data2 = (stationid,stationid,stationid)
cursor.execute(rain3,data2)
cursor.execute(rain6,data2)
cursor.execute(rain24,data1)
conn.commit()
for i in allonerainsites:
if i[1] == 'MET':
for j in metsensor:
tempdata = getData(i[0],j[0])
for p in tempdata['data']:
datafield = p[1]
datefield = int(p[0])/1000
ob = (i[0],datefield,int(j[0]),datafield)
sql = 'INSERT INTO onerainobs (siteid, dateutc, sensorid, data1) VALUES (%s,to_timestamp(%s),%s,%s) ON CONFLICT (siteid,sensorid,dateutc,data1) DO NOTHING'
cursor.execute(sql,ob)
conn.commit()
if i[1] == 'Rain':
for j in rainsensor:
tempdata = getData(i[0],j[0])
for p in tempdata['data']:
datafield = p[1]
datefield = int(p[0])/1000
ob = (i[0],datefield,int(j[0]),datafield)
sql = 'INSERT INTO onerainobs (siteid, dateutc, sensorid, data1) VALUES (%s,to_timestamp(%s),%s,%s) ON CONFLICT (siteid,sensorid,dateutc,data1) DO NOTHING'
cursor.execute(sql,ob)
conn.commit()
for i in allonerainsites:
if i[1] == 'MET':
for j in metsensor:
sql = 'SELECT data1,dateutc from onerainobs where siteid = %s and sensorid = %s order by dateutc desc limit 1'
getob = (i[0],j[0])
cursor.execute(sql,getob)
#WHERE (Active = True) and ((EXTRACT(EPOCH FROM (current_timestamp - lastob ))/60) > 8 or (lastob ISNULL))"
obdata = cursor.fetchall()
if len(obdata) == 1:
for l in obdata:
sensor = str(j[1])
sensortime = str(j[1])+'time'
sql = 'UPDATE onerainsites set ' + sensor + ' = %s, ' + sensortime + ' = %s where siteid = %s'
updateob = (l[0],l[1],i[0])
cursor.execute(sql,updateob)
conn.commit()
if i[1] == 'Rain':
for j in rainsensor:
sql = 'SELECT data1,dateutc from onerainobs where siteid = %s and sensorid = %s order by dateutc desc limit 1'
getob = (i[0],j[0])
cursor.execute(sql,getob)
#WHERE (Active = True) and ((EXTRACT(EPOCH FROM (current_timestamp - lastob ))/60) > 8 or (lastob ISNULL))"
obdata = cursor.fetchall()
if len(obdata) == 1:
for l in obdata:
sensor = str(j[1])
sensortime = str(j[1])+'time'
sql = 'UPDATE onerainsites set ' + sensor + ' = %s, ' + sensortime + ' = %s where siteid = %s'
updateob = (l[0],l[1],i[0])
cursor.execute(sql,updateob)
conn.commit()

View File

@@ -1,26 +0,0 @@
<?php
// Connecting, selecting database
$dbconn = pg_connect("host=localhost dbname=nws user=nws password=nws")
or die('Could not connect: ' . pg_last_error());
// Performing SQL query
$query = "SELECT sitename, lat, lon, tempf, humidity,raintotal,winddir,windspd,windgust,tempftime, humiditytime,raintotaltime,winddirtime,windspdtime,windgusttime FROM onerainsites where sitetype = 'MET';";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
// Printing results in HTML
while ($line = pg_fetch_array($result, null, PGSQL_ASSOC)) {
$array[] = $line;
}
echo json_encode($array);
// Free resultset
pg_free_result($result);
// Closing connection
pg_close($dbconn);
?>