Add morning and evening broadcast forecasts

This commit is contained in:
Guntis Smaukstelis
2025-03-15 21:34:44 +02:00
parent 89fa9224fe
commit cb2a75d5fd
4 changed files with 89 additions and 72 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

+26 -28
View File
@@ -1,6 +1,4 @@
import { Component } from 'solid-js' import { Accessor, Component, createEffect } from 'solid-js'
import { fetchText } from '../../helpers/fetch'
import { apiHost } from '../../consts'
import { codeToIcon } from '../weatherIcons/iconConsts' import { codeToIcon } from '../weatherIcons/iconConsts'
import rigaBgUrl from '../../assets/bg-riga.webp' import rigaBgUrl from '../../assets/bg-riga.webp'
import arrowUrl from '../../assets/arrow.webp' import arrowUrl from '../../assets/arrow.webp'
@@ -15,9 +13,9 @@ type TableWeather = {
} }
export const Table: Component<{ export const Table: Component<{
csvUrl: string, getCsvLines: Accessor<string[]>,
}> = ({ }> = ({
csvUrl, getCsvLines,
}) => { }) => {
let canvas: HTMLCanvasElement | undefined let canvas: HTMLCanvasElement | undefined
const rigaBg = new Image() const rigaBg = new Image()
@@ -25,29 +23,29 @@ export const Table: Component<{
const arrowImg = new Image() const arrowImg = new Image()
arrowImg.src = arrowUrl arrowImg.src = arrowUrl
fetchText(`${apiHost}/api/show/lvgmc-forecast/${csvUrl}`) createEffect(() => {
.then(csv => { const csvLines = getCsvLines()
const csvLines = csv.split('\n') if (csvLines.length <= 0) return;
const dateStr = csvLines[2].split(';')[0].split('.').reverse().join('.') const dateStr = csvLines[2].split(';')[0].split('.').reverse().join('.')
const weekDay = new Date(dateStr).getDay() const weekDay = new Date(dateStr).getDay()
const weekDayLV = weekDaysLV.get(weekDay)?.toUpperCase() ?? '' const weekDayLV = weekDaysLV.get(weekDay)?.toUpperCase() ?? ''
const dayOrNight = csvLines[2].split(';')[1] const dayOrNight = csvLines[2].split(';')[1]
const rigaOffset = dayOrNight === 'DIENA' ? 24 : 51 const rigaOffset = dayOrNight === 'DIENA' ? 24 : 51
const data: TableWeather[] = csvLines const data: TableWeather[] = csvLines
.slice(rigaOffset, rigaOffset+4) .slice(rigaOffset, rigaOffset+4)
.map((line): TableWeather => { .map((line): TableWeather => {
const parts = line.split(';') const parts = line.split(';')
const hour = parts[0].slice(6, 11).replace(':', '.') const hour = parts[0].slice(6, 11).replace(':', '.')
const temperature = parts[1] const temperature = parts[1]
const windDirection = parts[3] const windDirection = parts[3]
const windSpeed = parts[5] const windSpeed = parts[5]
const iconCode = Number(parts[7]) const iconCode = Number(parts[7])
const icon = codeToIcon(iconCode) const icon = codeToIcon(iconCode)
return { hour, temperature, windDirection, windSpeed, icon } return { hour, temperature, windDirection, windSpeed, icon }
}) })
drawTable(canvas!, rigaBg, arrowImg, data, weekDayLV) drawTable(canvas!, rigaBg, arrowImg, data, weekDayLV)
}) })
return <> return <>
<canvas ref={canvas} width='1040px' height='530px' /> <canvas ref={canvas} width='1040px' height='530px' />
@@ -104,11 +102,11 @@ function drawTable(
} }
const weekDaysLV = new Map([ const weekDaysLV = new Map([
[0, 'svētdiena'],
[1, 'pirmdiena'], [1, 'pirmdiena'],
[2, 'otrdiena'], [2, 'otrdiena'],
[3, 'trešdiena'], [3, 'trešdiena'],
[4, 'ceturtdiena'], [4, 'ceturtdiena'],
[5, 'piektdiena'], [5, 'piektdiena'],
[6, 'sestdiena'], [6, 'sestdiena'],
[7, 'svētdiena'],
]) ])
+26 -29
View File
@@ -1,4 +1,4 @@
import { Component, createSignal, onMount } from 'solid-js' import { Accessor, Component, createEffect, createSignal, onMount } from 'solid-js'
import { apiHost } from '../../consts' import { apiHost } from '../../consts'
import { fetchText } from '../../helpers/fetch' import { fetchText } from '../../helpers/fetch'
import { codeToIcon } from '../../components/weatherIcons/iconConsts' import { codeToIcon } from '../../components/weatherIcons/iconConsts'
@@ -10,43 +10,40 @@ import arrowUrl from '../../assets/arrow.webp'
import { resolutionProps, windProps, WindProps } from '../../components/map/mapConsts' import { resolutionProps, windProps, WindProps } from '../../components/map/mapConsts'
export const CsvMapData: Component<{ export const CsvMapData: Component<{
csvUrl: string, getCityLines: Accessor<string[]>,
getWindLine: Accessor<string>,
bgImgUrl: string, bgImgUrl: string,
}> = ({ }> = ({
csvUrl, getCityLines,
getWindLine,
bgImgUrl, bgImgUrl,
}) => { }) => {
const [getCityData, setCityData] = createSignal<CityData[]>([]) const [getCityData, setCityData] = createSignal<CityData[]>([])
const [getWindData, setWindData] = createSignal<[string, string, string]>(['', '', '']) const [getWindData, setWindData] = createSignal<[string, string, string]>(['', '', ''])
fetchText(`${apiHost}/api/show/lvgmc-forecast/${csvUrl}`) createEffect(() => {
.then(csv => { if (getCityLines().length <= 0) return;
const csvLines = csv.split('\n') const cityData: CityData[] = csvCityListInOrder
const dayOrNight = csvLines[2].split(';')[1] .map((city, i): CityData => {
// console.log(csvLines) const parts = getCityLines()[i].split(';')
const citiesOffset = 4 const temperature = Number(parts[1])
const cityData: CityData[] = csvCityListInOrder const iconCode = Number(parts[2])
.map((city, i): CityData => { const icon = codeToIcon(iconCode)
const parts = csvLines[i + citiesOffset].split(';') const coord = cityCoords[city]
const temperature = Number(parts[1]) if (!coord) throw new Error(`No coord found for city: ${city}`)
const iconCode = Number(parts[2]) return [city, coord, temperature, icon]
const icon = codeToIcon(iconCode) })
const coord = cityCoords[city] .filter(([city]) => citiesToShow.includes(city))
if (!coord) throw new Error(`No coord found for city: ${city}`)
return [city, coord, temperature, icon]
})
.filter(([city]) => citiesToShow.includes(city))
const windOffset = dayOrNight === 'DIENA' ? 30 : 26 const windParts = getWindLine().split(';')
const windParts = csvLines[windOffset].split(';') const windSpped = windParts[1]
const windSpped = windParts[1] const windGusts = windParts[3]
const windGusts = windParts[3] const windDirection = windParts[5]
const windDirection = windParts[5] setWindData([windDirection, windSpped, windGusts])
setWindData([windDirection, windSpped, windGusts]) setCityData(cityData)
setCityData(cityData) draw()
draw() })
})
const arrowImg = new Image() const arrowImg = new Image()
arrowImg.src = arrowUrl arrowImg.src = arrowUrl
+35 -13
View File
@@ -1,9 +1,11 @@
import { Component } from 'solid-js' import { Component, createEffect, createSignal, Setter } from 'solid-js'
import dayBgMap from '../../assets/map_3840x1440_wind.webp' import dayBgMap from '../../assets/map_3840x1440_wind.webp'
import nightBgMap from '../../assets/map_night_3840x1440_wind.webp' import nightBgMap from '../../assets/map_night_3840x1440_wind.webp'
import { CsvMapData } from './CsvMapData' import { CsvMapData } from './CsvMapData'
import { Table } from '../../components/table/Table' import { Table } from '../../components/table/Table'
import { apiHost } from '../../consts'
import { fetchText } from '../../helpers/fetch'
// Eiropa_LTV_pilsetas_nakama_dn.csv // Eiropa_LTV_pilsetas_nakama_dn.csv
// Eiropa_LTV_pilsetas_tekosa_dn.csv // Eiropa_LTV_pilsetas_tekosa_dn.csv
@@ -12,24 +14,44 @@ import { Table } from '../../components/table/Table'
// Latvija_faktiskais_laiks.csv // Latvija_faktiskais_laiks.csv
export const LvgmcForecast: Component<{}> = () => { export const LvgmcForecast: Component<{}> = () => {
return <> const [getEveningLines, setEveningLines] = createSignal<string[]>([])
<Table const [getMorningLines, setMorningLines] = createSignal<string[]>([])
csvUrl='Latvija_LTV_pilsetas_nakama_dnn.csv'
/>
<Table
csvUrl='Latvija_LTV_pilsetas_tekosa_dn.csv'
/>
<p>Night</p> const urlsAndSignals: [string, Setter<string[]>][] = [
['Latvija_LTV_pilsetas_nakama_dnn.csv', setEveningLines],
['Latvija_LTV_pilsetas_tekosa_dn.csv', setMorningLines],
]
urlsAndSignals.forEach(([csvUrl, setLines]) =>
fetchText(`${apiHost}/api/show/lvgmc-forecast/${csvUrl}`)
.then(csv => setLines(csv.split('\n')))
.catch(console.warn)
)
createEffect(() => {
console.log(getMorningLines())
})
return <>
<p>Vakara ēters</p>
<CsvMapData <CsvMapData
csvUrl='Latvija_LTV_pilsetas_nakama_dnn.csv' getCityLines={() => getEveningLines().slice(4, 22)}
getWindLine={() => getEveningLines()[26]}
bgImgUrl={nightBgMap} bgImgUrl={nightBgMap}
/> />
<p>Day</p>
<CsvMapData <CsvMapData
csvUrl='Latvija_LTV_pilsetas_tekosa_dn.csv' getCityLines={() => getEveningLines().slice(31, 49)}
getWindLine={() => getEveningLines()[57]}
bgImgUrl={dayBgMap} bgImgUrl={dayBgMap}
/> />
<Table getCsvLines={() => getEveningLines()} />
<p>Rīta ēters</p>
<CsvMapData
getCityLines={() => getMorningLines().slice(4, 22)}
getWindLine={() => getMorningLines()[23]}
bgImgUrl={dayBgMap}
/>
<Table getCsvLines={() => getMorningLines()} />
</> </>
} }