mirror of
https://github.com/netbymatt/ws4kp.git
synced 2026-04-18 09:39:30 -07:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ecf0999675 | ||
|
|
6a49b7b6ce | ||
|
|
5ffff03db9 | ||
|
|
c8a25e5d9a | ||
|
|
ea58b5a9c8 | ||
|
|
4bf725413b | ||
|
|
75eb81887f |
@@ -335,6 +335,10 @@ Before reporting an issue or requesting a feature please consider that this is n
|
|||||||
|
|
||||||
Note: not all units are converted to metric, if selected. Some text-based products such as warnings are simple text strings provided from the national weather service and thus have baked-in units such as "gusts up to 60 mph." These values will not be converted.
|
Note: not all units are converted to metric, if selected. Some text-based products such as warnings are simple text strings provided from the national weather service and thus have baked-in units such as "gusts up to 60 mph." These values will not be converted.
|
||||||
|
|
||||||
|
## The full moon icon is broken
|
||||||
|
|
||||||
|
This is a known problem with the Ws4kp as it ages. It was a problem with the [actual Weatherstar hardware](https://youtu.be/rcUwlZ4pqh0?feature=shared&t=116) as well.
|
||||||
|
|
||||||
## Related Projects
|
## Related Projects
|
||||||
|
|
||||||
Not retro enough? Try the [Weatherstar 3000+](https://github.com/netbymatt/ws3kp)
|
Not retro enough? Try the [Weatherstar 3000+](https://github.com/netbymatt/ws3kp)
|
||||||
|
|||||||
@@ -84,8 +84,8 @@
|
|||||||
"lat": 29.7633,
|
"lat": 29.7633,
|
||||||
"lon": -95.3633,
|
"lon": -95.3633,
|
||||||
"point": {
|
"point": {
|
||||||
"x": 65,
|
"x": 63,
|
||||||
"y": 97,
|
"y": 95,
|
||||||
"wfo": "HGX"
|
"wfo": "HGX"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -230,7 +230,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"city": "Washington DC",
|
"city": "Washington",
|
||||||
"lat": 38.8951,
|
"lat": 38.8951,
|
||||||
"lon": -77.0364,
|
"lon": -77.0364,
|
||||||
"point": {
|
"point": {
|
||||||
@@ -274,7 +274,7 @@
|
|||||||
"lat": 61.2181,
|
"lat": 61.2181,
|
||||||
"lon": -149.9003,
|
"lon": -149.9003,
|
||||||
"point": {
|
"point": {
|
||||||
"x": 125,
|
"x": 143,
|
||||||
"y": 236,
|
"y": 236,
|
||||||
"wfo": "AER"
|
"wfo": "AER"
|
||||||
}
|
}
|
||||||
@@ -734,8 +734,8 @@
|
|||||||
"lat": 42.9956,
|
"lat": 42.9956,
|
||||||
"lon": -71.4548,
|
"lon": -71.4548,
|
||||||
"point": {
|
"point": {
|
||||||
"x": 42,
|
"x": 38,
|
||||||
"y": 21,
|
"y": 20,
|
||||||
"wfo": "GYX"
|
"wfo": "GYX"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -884,8 +884,8 @@
|
|||||||
"lat": 43.6615,
|
"lat": 43.6615,
|
||||||
"lon": -70.2553,
|
"lon": -70.2553,
|
||||||
"point": {
|
"point": {
|
||||||
"x": 76,
|
"x": 72,
|
||||||
"y": 59,
|
"y": 58,
|
||||||
"wfo": "GYX"
|
"wfo": "GYX"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -115,7 +115,7 @@
|
|||||||
"lon": -82.5329
|
"lon": -82.5329
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"city": "Washington DC",
|
"city": "Washington",
|
||||||
"lat": 38.8951,
|
"lat": 38.8951,
|
||||||
"lon": -77.0364
|
"lon": -77.0364
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
import 'dotenv/config';
|
import 'dotenv/config';
|
||||||
import {
|
import {
|
||||||
src, dest, series, parallel,
|
src, dest, series, parallel,
|
||||||
@@ -58,15 +57,6 @@ const jsVendorSources = [
|
|||||||
'server/scripts/vendor/auto/suncalc.js',
|
'server/scripts/vendor/auto/suncalc.js',
|
||||||
];
|
];
|
||||||
|
|
||||||
// Copy metar-taf-parser separately since it's an ES module with locale dependencies
|
|
||||||
const metarVendorSources = [
|
|
||||||
'server/scripts/vendor/auto/metar-taf-parser.mjs',
|
|
||||||
'server/scripts/vendor/auto/locale/en.js',
|
|
||||||
];
|
|
||||||
|
|
||||||
const copyMetarVendor = () => src(metarVendorSources, { base: 'server/scripts/vendor/auto' })
|
|
||||||
.pipe(dest(`${RESOURCES_PATH}/vendor/auto`));
|
|
||||||
|
|
||||||
const compressJsVendor = () => src(jsVendorSources)
|
const compressJsVendor = () => src(jsVendorSources)
|
||||||
.pipe(concat('vendor.min.js'))
|
.pipe(concat('vendor.min.js'))
|
||||||
.pipe(terser())
|
.pipe(terser())
|
||||||
@@ -210,7 +200,7 @@ const buildPlaylist = async () => {
|
|||||||
return file('playlist.json', JSON.stringify(playlist)).pipe(dest('./dist'));
|
return file('playlist.json', JSON.stringify(playlist)).pipe(dest('./dist'));
|
||||||
};
|
};
|
||||||
|
|
||||||
const buildDist = series(clean, parallel(buildJs, compressJsVendor, copyMetarVendor, copyCss, compressHtml, copyOtherFiles, copyDataFiles, copyImageSources, buildPlaylist));
|
const buildDist = series(clean, parallel(buildJs, compressJsVendor, copyCss, compressHtml, copyOtherFiles, copyDataFiles, copyImageSources, buildPlaylist));
|
||||||
|
|
||||||
// upload_images could be in parallel with upload, but _images logs a lot and has little changes
|
// upload_images could be in parallel with upload, but _images logs a lot and has little changes
|
||||||
// by running upload last the majority of the changes will be at the bottom of the log for easy viewing
|
// by running upload last the majority of the changes will be at the bottom of the log for easy viewing
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable import/no-extraneous-dependencies */
|
|
||||||
import { src, series, dest } from 'gulp';
|
import { src, series, dest } from 'gulp';
|
||||||
import { deleteAsync } from 'del';
|
import { deleteAsync } from 'del';
|
||||||
import rename from 'gulp-rename';
|
import rename from 'gulp-rename';
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ws4kp",
|
"name": "ws4kp",
|
||||||
"version": "6.0.0",
|
"version": "6.1.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ws4kp",
|
"name": "ws4kp",
|
||||||
"version": "6.0.0",
|
"version": "6.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dotenv": "^17.0.1",
|
"dotenv": "^17.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "ws4kp",
|
"name": "ws4kp",
|
||||||
"version": "6.0.0",
|
"version": "6.1.1",
|
||||||
"description": "Welcome to the WeatherStar 4000+ project page!",
|
"description": "Welcome to the WeatherStar 4000+ project page!",
|
||||||
"main": "index.mjs",
|
"main": "index.mjs",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
BIN
server/images/gimp/Full-Moon-Degraded.xcf
Normal file
BIN
server/images/gimp/Full-Moon-Degraded.xcf
Normal file
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
BIN
server/images/gimp/No-Data.xcf
Normal file
BIN
server/images/gimp/No-Data.xcf
Normal file
Binary file not shown.
BIN
server/images/icons/current-conditions/No-Data.gif
Normal file
BIN
server/images/icons/current-conditions/No-Data.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
server/images/icons/moon-phases/Full-Moon-Degraded.gif
Normal file
BIN
server/images/icons/moon-phases/Full-Moon-Degraded.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1009 B |
@@ -9,11 +9,19 @@ class Almanac extends WeatherDisplay {
|
|||||||
constructor(navId, elemId) {
|
constructor(navId, elemId) {
|
||||||
super(navId, elemId, 'Almanac', true);
|
super(navId, elemId, 'Almanac', true);
|
||||||
|
|
||||||
|
// occasional degraded moon icon
|
||||||
|
this.iconPaths = {
|
||||||
|
Full: imageName(Math.random() > 0.995 ? 'Degraded' : 'Full'),
|
||||||
|
Last: imageName('Last'),
|
||||||
|
New: imageName('New'),
|
||||||
|
First: imageName('First'),
|
||||||
|
};
|
||||||
|
|
||||||
// preload the moon images
|
// preload the moon images
|
||||||
preloadImg(imageName('Full'));
|
preloadImg(this.iconPaths.Full);
|
||||||
preloadImg(imageName('Last'));
|
preloadImg(this.iconPaths.Last);
|
||||||
preloadImg(imageName('New'));
|
preloadImg(this.iconPaths.New);
|
||||||
preloadImg(imageName('First'));
|
preloadImg(this.iconPaths.First);
|
||||||
|
|
||||||
this.timing.totalScreens = 1;
|
this.timing.totalScreens = 1;
|
||||||
}
|
}
|
||||||
@@ -142,7 +150,7 @@ class Almanac extends WeatherDisplay {
|
|||||||
|
|
||||||
fill.date = date;
|
fill.date = date;
|
||||||
fill.type = MoonPhase.phase;
|
fill.type = MoonPhase.phase;
|
||||||
fill.icon = { type: 'img', src: imageName(MoonPhase.phase) };
|
fill.icon = { type: 'img', src: this.iconPaths[MoonPhase.phase] };
|
||||||
|
|
||||||
return this.fillTemplate('day', fill);
|
return this.fillTemplate('day', fill);
|
||||||
});
|
});
|
||||||
@@ -169,6 +177,8 @@ const imageName = (type) => {
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case 'Full':
|
case 'Full':
|
||||||
return 'images/icons/moon-phases/Full-Moon.gif';
|
return 'images/icons/moon-phases/Full-Moon.gif';
|
||||||
|
case 'Degraded':
|
||||||
|
return 'images/icons/moon-phases/Full-Moon-Degraded.gif';
|
||||||
case 'Last':
|
case 'Last':
|
||||||
return 'images/icons/moon-phases/Last-Quarter.gif';
|
return 'images/icons/moon-phases/Last-Quarter.gif';
|
||||||
case 'New':
|
case 'New':
|
||||||
|
|||||||
@@ -85,7 +85,6 @@ class CurrentWeather extends WeatherDisplay {
|
|||||||
const requiredFields = [
|
const requiredFields = [
|
||||||
{ name: 'temperature', check: (props) => props.temperature?.value === null, required: true },
|
{ name: 'temperature', check: (props) => props.temperature?.value === null, required: true },
|
||||||
{ name: 'textDescription', check: (props) => props.textDescription === null || props.textDescription === '', required: true },
|
{ name: 'textDescription', check: (props) => props.textDescription === null || props.textDescription === '', required: true },
|
||||||
{ name: 'icon', check: (props) => props.icon === null, required: true },
|
|
||||||
{ name: 'windSpeed', check: (props) => props.windSpeed?.value === null, required: false },
|
{ name: 'windSpeed', check: (props) => props.windSpeed?.value === null, required: false },
|
||||||
{ name: 'dewpoint', check: (props) => props.dewpoint?.value === null, required: false },
|
{ name: 'dewpoint', check: (props) => props.dewpoint?.value === null, required: false },
|
||||||
{ name: 'barometricPressure', check: (props) => props.barometricPressure?.value === null, required: false },
|
{ name: 'barometricPressure', check: (props) => props.barometricPressure?.value === null, required: false },
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ const largeIcon = (link, _isNightTime) => {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`largeIcon: ${error.message}`);
|
console.warn(`largeIcon: ${error.message}`);
|
||||||
// Return a fallback icon to prevent downstream errors
|
// Return a fallback icon to prevent downstream errors
|
||||||
return addPath(_isNightTime ? 'Clear.gif' : 'Sunny.gif');
|
return addPath(`No-Data.gif?${conditionIcon}${isNightTime ? '-n' : ''}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// find the icon
|
// find the icon
|
||||||
@@ -169,7 +169,7 @@ const largeIcon = (link, _isNightTime) => {
|
|||||||
default: {
|
default: {
|
||||||
console.warn(`Unknown weather condition '${conditionIcon}' from ${link}; using fallback icon`);
|
console.warn(`Unknown weather condition '${conditionIcon}' from ${link}; using fallback icon`);
|
||||||
// Return a reasonable fallback instead of false to prevent downstream errors
|
// Return a reasonable fallback instead of false to prevent downstream errors
|
||||||
return addPath(isNightTime ? 'Clear.gif' : 'Sunny.gif');
|
return addPath(`No-Data.gif?${conditionIcon}${isNightTime ? '-n' : ''}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
// METAR parsing utilities using metar-taf-parser library
|
// METAR parsing utilities using metar-taf-parser library
|
||||||
import { parseMetar } from '../../vendor/auto/metar-taf-parser.mjs';
|
import { parseMetar } from '../../vendor/auto/metar-taf-parser.mjs';
|
||||||
|
// eslint-disable-next-line import/extensions
|
||||||
|
import en from '../../vendor/auto/locale/en.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Augment observation data by parsing METAR when API fields are missing
|
* Augment observation data by parsing METAR when API fields are missing
|
||||||
@@ -14,7 +16,7 @@ const augmentObservationWithMetar = (observation) => {
|
|||||||
const metar = { ...observation };
|
const metar = { ...observation };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const metarData = parseMetar(observation.rawMessage);
|
const metarData = parseMetar(observation.rawMessage, { locale: en });
|
||||||
|
|
||||||
if (observation.windSpeed?.value === null && metarData.wind?.speed !== undefined) {
|
if (observation.windSpeed?.value === null && metarData.wind?.speed !== undefined) {
|
||||||
metar.windSpeed = {
|
metar.windSpeed = {
|
||||||
|
|||||||
@@ -44,7 +44,8 @@
|
|||||||
"mwood",
|
"mwood",
|
||||||
"unmuted",
|
"unmuted",
|
||||||
"dumpio",
|
"dumpio",
|
||||||
"mesonet"
|
"mesonet",
|
||||||
|
"metar"
|
||||||
],
|
],
|
||||||
"cSpell.ignorePaths": [
|
"cSpell.ignorePaths": [
|
||||||
"**/package-lock.json",
|
"**/package-lock.json",
|
||||||
@@ -82,4 +83,4 @@
|
|||||||
"j69.ejs-beautify",
|
"j69.ejs-beautify",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user