Skip to content

Commit

Permalink
added pressure, weather code, fixed minor bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
nizienko committed Jun 19, 2024
1 parent 5a66daf commit b6cb479
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 22 deletions.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "com.guthub.nizienko"
version = "1.0.1"
version = "1.0.3"

repositories {
mavenCentral()
Expand Down
35 changes: 35 additions & 0 deletions src/main/kotlin/services/WeatherCode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package services

object WeatherCode {
fun get(code: Int): String = when (code) {
0 -> "Clear sky"
1 -> "Mainly clear"
2 -> "Partly cloudy"
3 -> "Overcast"
45 -> "Fog"
48 -> "Depositing rime fog"
51 -> "Light drizzle"
53 -> "Moderate drizzle"
55 -> "Dense intensity drizzle"
56 -> "Light freezing drizzle"
57 -> "Dense freezing drizzle"
61 -> "Slight rain"
63 -> "Moderate rain"
65 -> "Heavy rain"
66 -> "Light freezing rain"
67 -> "Heavy freezing rain"
71 -> "Slight snow fall"
73 -> "Moderate snow fall"
75 -> "Heavy snow fall"
77 -> "Snow grains"
80 -> "Slight rain showers"
81 -> "Moderate rain showers"
82 -> "Violent rain showers"
85 -> "Slight Snow showers"
86 -> "Heavy Snow showers"
95 -> "Thunderstorm"
96 -> "Thunderstorm with slight hail"
99 -> "Thunderstorm with heavy hail"
else -> "___"
}
}
35 changes: 25 additions & 10 deletions src/main/kotlin/services/WeatherService.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package services

import com.intellij.openapi.application.invokeLater
import com.intellij.openapi.components.Service
import com.intellij.openapi.components.service
import com.openmeteo.api.Forecast
Expand Down Expand Up @@ -44,8 +45,10 @@ class WeatherService(coroutineScope: CoroutineScope) {
fun update() {
activeWidget?.let {
cachedRainData = loadWeather()
activeWidget?.repaint()
activeWidget?.revalidate()
invokeLater {
activeWidget?.revalidate()
activeWidget?.repaint()
}
}
}

Expand All @@ -55,11 +58,11 @@ class WeatherService(coroutineScope: CoroutineScope) {
private var lastAttempt: Long = 0L
private fun loadWeather(): WeatherData {
return try {
WeatherData.Present(WeatherClient(settings).getRainData())
.also {
lastUpdate = System.currentTimeMillis()
lastAttempt = System.currentTimeMillis()
}
val data = WeatherClient(settings).getRainData()
WeatherData.Present(data).also {
lastUpdate = System.currentTimeMillis()
lastAttempt = System.currentTimeMillis()
}
} catch (e: Throwable) {
lastAttempt = System.currentTimeMillis()
val error = buildString {
Expand All @@ -78,15 +81,23 @@ sealed interface WeatherData {
class Error(val message: String) : WeatherData
}

data class HourData(val rain: Double, val temperature: Double, val wind: Double, val windDirection: Double)
data class HourData(
val rain: Double,
val temperature: Double,
val wind: Double,
val windDirection: Double,
val weatherCode: Int,
val surfacePressure: Double,
)

class WeatherClient(private val settings: WeatherWidgetSettingsState) {
private val client = OpenMeteo(settings.latitude, settings.longitude)

@OptIn(Response.ExperimentalGluedUnitTimeStepValues::class)
fun getRainData(): List<Pair<Time, HourData>> {
val forecast = client.forecast {
hourly = Forecast.Hourly {
listOf(precipitation, temperature2m, windspeed10m, winddirection10m)
listOf(precipitation, temperature2m, windspeed10m, winddirection10m, weathercode, surfacePressure)
}
forecastDays = 2
temperatureUnit = settings.temperatureUnit
Expand All @@ -99,12 +110,16 @@ class WeatherClient(private val settings: WeatherWidgetSettingsState) {
val temperature = forecast.hourly.getValue(temperature2m).values.filter { (t, _) -> t.time > now }
val wind = forecast.hourly.getValue(windspeed10m).values.filter { (t, _) -> t.time > now }
val windDirection = forecast.hourly.getValue(winddirection10m).values.filter { (t, _) -> t.time > now }
val weatherCode = forecast.hourly.getValue(weathercode).values.filter { (t, _) -> t.time > now }
val surfacePressure = forecast.hourly.getValue(surfacePressure).values.filter { (t, _) -> t.time > now }
val merged = precipitationData.map {
it.key to HourData(
it.value!!,
temperature[it.key] ?: 0.0,
wind[it.key] ?: 0.0,
windDirection[it.key] ?: 0.0
windDirection[it.key] ?: 0.0,
weatherCode[it.key]?.toInt() ?: 0,
surfacePressure[it.key] ?: 0.0
)
}
forecast.hourly.getValue(precipitation).run {
Expand Down
13 changes: 10 additions & 3 deletions src/main/kotlin/settings/WeatherWidgetConfigurable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@ import com.intellij.openapi.options.Configurable
import com.intellij.openapi.ui.MessageType
import com.intellij.openapi.ui.popup.util.PopupUtil
import com.intellij.ui.ColorPanel
import com.intellij.ui.ColorPicker
import com.intellij.ui.components.JBCheckBox
import com.intellij.ui.components.JBLabel
import com.intellij.ui.components.JBTextField
import com.intellij.ui.tabs.ColorSelectionComponent
import com.intellij.ui.util.preferredWidth
import com.intellij.util.ui.FormBuilder
import com.intellij.util.ui.components.BorderLayoutPanel
import com.openmeteo.api.common.units.TemperatureUnit
Expand Down Expand Up @@ -40,6 +38,7 @@ class WeatherWidgetConfigurable : Configurable {
|| ui.colorPicker.selectedColor != settings.rainBarColor
|| ui.temperatureUnit.selectedItem != settings.temperatureUnit
|| ui.windSpeedUnit.selectedItem != settings.windSpeedUnit
|| ui.pressureUnit.selectedItem != settings.pressureUnit
}

override fun apply() {
Expand All @@ -53,6 +52,7 @@ class WeatherWidgetConfigurable : Configurable {
settings.rainBarColor = ui.colorPicker.selectedColor ?: settings.rainBarColor
settings.temperatureUnit = ui.temperatureUnit.selectedItem as TemperatureUnit
settings.windSpeedUnit = ui.windSpeedUnit.selectedItem as WindSpeedUnit
settings.pressureUnit = ui.pressureUnit.selectedItem as PressureUnit
service<WeatherService>().update()
}

Expand Down Expand Up @@ -132,6 +132,12 @@ private class SettingsComponent(settingsState: WeatherWidgetSettingsState) : Dis
selectedItem = settingsState.windSpeedUnit
}

val pressureUnit = JComboBox<PressureUnit>().apply {
PressureUnit.entries.forEach { addItem(it) }
selectedItem = settingsState.pressureUnit
setRenderer { _, value, _, _, _ -> JBLabel(value.value) }
}

val cityName = JBTextField(settingsState.cityName)

fun getHours(): Int = hours.value as Int
Expand All @@ -148,6 +154,7 @@ private class SettingsComponent(settingsState: WeatherWidgetSettingsState) : Dis
.addSeparator()
.addLabeledComponent("Show temperature", showTemperature)
.addLabeledComponent("Temperature unit", temperatureUnit)
.addLabeledComponent("Pressure unit", pressureUnit)
.addSeparator()
.addLabeledComponent("Precipitation bars color", colorPicker)
.panel.let {
Expand Down
17 changes: 16 additions & 1 deletion src/main/kotlin/settings/WeatherWidgetSettingsState.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ class WeatherWidgetSettingsState : PersistentStateComponent<WeatherWidgetSetting
@OptionTag(converter = ColorConverter::class)
var rainBarColor: Color = Color(66, 135, 245)

@OptionTag(converter = PressureUnitConverter::class)
var pressureUnit: PressureUnit = PressureUnit.MMHG

companion object {
fun getInstance() = service<WeatherWidgetSettingsState>()
}
Expand Down Expand Up @@ -74,4 +77,16 @@ internal class WindSpeedUnitConverter : Converter<WindSpeedUnit>() {
override fun toString(value: WindSpeedUnit): String {
return value.name
}
}
}

internal class PressureUnitConverter : Converter<PressureUnit>() {
override fun fromString(value: String): PressureUnit {
return PressureUnit.valueOf(value)
}

override fun toString(value: PressureUnit): String {
return value.name
}
}

enum class PressureUnit(val value: String, val multiplier: Double) { MMHG("mmHg", 0.75006375541921), HPA("hPa", 1.0)}
32 changes: 25 additions & 7 deletions src/main/kotlin/widget/Widget.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import com.intellij.openapi.wm.StatusBarWidgetFactory
import com.intellij.openapi.wm.impl.status.TextPanel
import com.intellij.ui.InplaceButton
import com.intellij.ui.NewUI
import com.intellij.ui.awt.RelativePoint
import com.intellij.ui.awt.AnchoredPoint
import com.intellij.ui.components.JBLabel
import com.intellij.util.ui.JBUI
import com.intellij.util.ui.UIUtil
Expand All @@ -27,8 +27,10 @@ import com.openmeteo.api.common.time.Time
import com.openmeteo.api.common.units.TemperatureUnit
import com.openmeteo.api.common.units.WindSpeedUnit
import services.HourData
import services.WeatherCode
import services.WeatherData
import services.WeatherService
import settings.PressureUnit
import settings.WeatherWidgetConfigurable
import settings.WeatherWidgetSettingsState
import java.awt.*
Expand Down Expand Up @@ -95,7 +97,7 @@ class WidgetComponent(private val model: WidgetModel) : JPanel(), Disposable {
append("<html><table align=\"center\" cellpadding=\"5\">")
append("<tr><th>Time</th><th>Temp</th>")
if (isPrecipitationExpected) append("<th>Precipitation</th>")
append("<th>Wind</th><th></th></tr>")
append("<th>Pressure</th><th>Wind</th><th></th><th></th></tr>")
weatherData.forEach { (time, hourData) ->
append("<tr>")
append("<td>")
Expand All @@ -109,10 +111,17 @@ class WidgetComponent(private val model: WidgetModel) : JPanel(), Disposable {
append("</td>")
if (isPrecipitationExpected) {
append("<td>")
append(hourData.rain)
append(" mm</td>")
if (hourData.weatherCode > 3) append(WeatherCode.get(hourData.weatherCode) + " ")
if (hourData.rain > 0.0) {
append(hourData.rain)
append(" mm")
}
append("</td>")
}
append("<td>")
append(hourData.surfacePressure.recalculate(model.pressureUnit).roundToInt().toString() + " " + model.pressureUnit.value)
append("</td>")
append("<td>")
append(hourData.wind.roundToInt())
append(" " + windSpeedUnitText(model.windSpeedUnit))
append("</td>")
Expand Down Expand Up @@ -144,7 +153,11 @@ class WidgetComponent(private val model: WidgetModel) : JPanel(), Disposable {
is WeatherData.Present -> JBUI.CurrentTheme.GotItTooltip.foreground(true)
}
val panel = BorderLayoutPanel()
val title = JBLabel("<html><h2>${model.city}</h2></html>", UIUtil.ComponentStyle.LARGE)
val weather = when(val rainData = model.rainData) {
is WeatherData.Error -> ""
is WeatherData.Present -> rainData.data[0].second.weatherCode.let { WeatherCode.get(it.toInt()) }
}
val title = JBLabel("<html><h2>$weather in ${model.city}</h2></html>", UIUtil.ComponentStyle.LARGE)
val settingsButton = InplaceButton(
IconButton(
"Settings",
Expand Down Expand Up @@ -172,7 +185,7 @@ class WidgetComponent(private val model: WidgetModel) : JPanel(), Disposable {
.setCornerRadius(JBUI.scale(8))
.setFadeoutTime(10_000)
.createBalloon()
.show(RelativePoint.getCenterOf(this@WidgetComponent), Balloon.Position.above)
.show(AnchoredPoint(AnchoredPoint.Anchor.TOP, this@WidgetComponent), Balloon.Position.above)
}
}

Expand All @@ -194,6 +207,7 @@ class WidgetComponent(private val model: WidgetModel) : JPanel(), Disposable {
}

override fun paint(g: Graphics) {
g.clearRect(0, 0, width, height)
g.font = TextPanel.getFont()
super.paintComponents(g)
setupAntialiasing(g)
Expand Down Expand Up @@ -313,4 +327,8 @@ class WidgetModel {
get() = settings.temperatureUnit
val windSpeedUnit
get() = settings.windSpeedUnit
}
val pressureUnit
get() = settings.pressureUnit
}

private fun Double.recalculate(unit: PressureUnit) = this * unit.multiplier

0 comments on commit b6cb479

Please sign in to comment.