Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
kowis-projects
deskscreen
Commits
e7b61e6a
Commit
e7b61e6a
authored
Dec 27, 2020
by
David
Browse files
Works on java 11 and openjfx 11
parent
815d20ca
Pipeline
#658
failed with stage
in 27 seconds
Changes
7
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
.java-version
View file @
e7b61e6a
o
racle
64-1
.8
.0.
22
1
o
penjdk
64-1
1
.0.
9.
1
build.gradle
View file @
e7b61e6a
...
...
@@ -8,17 +8,23 @@ buildscript {
}
plugins
{
id
'org.jetbrains.kotlin.jvm'
version
'1.
3
.21'
id
"io.spring.dependency-management"
version
"1.0.7.RELEASE"
id
'org.jetbrains.kotlin.jvm'
version
'1.
4
.21'
id
"io.spring.dependency-management"
version
"1.0.7.RELEASE"
//Bet I don't need this...
id
'com.github.johnrengelman.shadow'
version
'5.0.0'
id
"org.hidetake.ssh"
version
"2.9.0"
id
"application"
id
'org.openjfx.javafxplugin'
version
'0.0.9'
}
apply
plugin:
'org.junit.platform.gradle.plugin'
mainClassName
=
"is.kow.deskscreen.DeskScreenKt"
javafx
{
version
=
"11.0.2"
modules
=
[
'javafx.controls'
,
'javafx.swing'
]
}
wrapper
{
distributionType
=
Wrapper
.
DistributionType
.
ALL
}
...
...
@@ -66,16 +72,16 @@ shadowJar {
dependencies
{
implementation
"org.jetbrains.kotlin:kotlin-stdlib-jdk8"
,
"org.jetbrains.kotlin:kotlin-reflect"
,
"no.tornado:tornadofx:1.7.
16
"
,
'io.reactivex.rxjava2:rxkotlin:2.
2
.0'
,
"no.tornado:tornadofx:1.7.
20
"
,
'io.reactivex.rxjava2:rxkotlin:2.
4
.0'
,
"com.github.thomasnield:rxkotlinfx:2.2.2"
,
'io.github.microutils:kotlin-logging:1.5.4'
,
"io.reactivex.rxjava2:rxjava:2.2.
6
"
,
//have to include it explicitly
"io.reactivex.rxjava2:rxjava:2.2.
20
"
,
//have to include it explicitly
"org.apache.logging.log4j:log4j-api"
,
"org.apache.logging.log4j:log4j-core"
,
"org.apache.logging.log4j:log4j-slf4j-impl"
,
"io.github.microutils:kotlin-logging:
1.5.6
"
,
"io.github.microutils:kotlin-logging:
2.0.4
"
,
'io.github.config4k:config4k:0.4.0'
//V4l4j for the raspberry pi, to get video directly from v4l
...
...
@@ -92,9 +98,10 @@ dependencies {
//Some extra java time classes that are potentially useful
implementation
'org.threeten:threeten-extra:1.5.0'
//Gonna use the DarkSky forecast info
implementation
'tk.plogitech:darksky-forecast-api-jackson:1.3.1'
,
'org.slf4j:jul-to-slf4j:1.7.25'
// Fuckin apple stoleDark sky, so that's dead.
// //Gonna use the DarkSky forecast info
// implementation 'tk.plogitech:darksky-forecast-api-jackson:1.3.1',
// 'org.slf4j:jul-to-slf4j:1.7.25'
implementation
group:
"org.http4k"
,
name:
"http4k-client-apache"
,
version:
"3.38.1"
implementation
group:
"org.http4k"
,
name:
"http4k-format-jackson"
,
version:
"3.38.1"
...
...
@@ -108,12 +115,14 @@ dependencies {
// 'org.glassfish.jaxb:jaxb-runtime:2.3.0.1'
//Using the snapshot version of pi4j, because it's the best
implementation
'com.pi4j:pi4j-core:1.2-SNAPSHOT'
//Maybe I can get away without using the snapshot....
implementation
'com.pi4j:pi4j-core:1.2'
//Trying ikonili, because FontawesomeFX is being a pain
implementation
'org.kordamp.ikonli:ikonli-javafx:2.4.0'
implementation
'org.kordamp.ikonli:ikonli-fontawesome5-pack:2.4.0'
implementation
'org.kordamp.ikonli:ikonli-weathericons-pack:2.4.0'
//TODO: update this to use a version variable
implementation
'org.kordamp.ikonli:ikonli-javafx:12.0.0'
implementation
'org.kordamp.ikonli:ikonli-fontawesome5-pack:12.0.0'
implementation
'org.kordamp.ikonli:ikonli-weathericons-pack:12.0.0'
// implementation 'com.hierynomus:sshj:0.26.0',
// 'com.jcraft:jzlib:1.1.3'
...
...
@@ -156,6 +165,8 @@ task deploy {
}
task
runDesktop
(
type:
JavaExec
)
{
group
=
"Application"
description
=
"Run it on the desktop lol"
classpath
=
sourceSets
.
main
.
runtimeClasspath
environment
+=
[
...
...
@@ -167,6 +178,7 @@ task runDesktop(type: JavaExec) {
"REDDIT_CLIENT_ID"
:
redditClientId
,
"REDDIT_SECRET"
:
redditSecret
]
//jvmArgs = [""]
main
=
"is.kow.deskscreen.DesktopScreen"
}
src/main/kotlin/is/kow/deskscreen/camera/CameraController.kt
View file @
e7b61e6a
...
...
@@ -8,6 +8,7 @@ import com.github.thomasnield.rxkotlinfx.observeOnFx
import
com.hopding.jrpicam.RPiCamera
import
io.reactivex.Observable
import
io.reactivex.schedulers.Schedulers
import
javafx.embed.swing.SwingFXUtils
import
javafx.event.ActionEvent
import
javafx.scene.image.Image
import
mu.KotlinLogging
...
...
@@ -76,8 +77,7 @@ class CameraController : Controller() {
?.
setTimeout
(
timeout
*
1000
)
//This timeout is in milliseconds
?.
setFullPreviewOn
()
?.
takeBufferedStill
()
!!
//lets just convert it directly
Util
.
toFXImage
(
bf
,
null
)
SwingFXUtils
.
toFXImage
(
bf
,
null
)
}
else
{
//load the cat picture WHY WON'T YOU LOAD MY KITTY
val
stream
=
this
.
javaClass
.
getResourceAsStream
(
"/imagery/MaineCoon-cropped.jpeg"
)
...
...
@@ -135,4 +135,4 @@ class CameraController : Controller() {
.
subscribe
()
}
}
\ No newline at end of file
}
src/main/kotlin/is/kow/deskscreen/utils/Util.kt
View file @
e7b61e6a
package
`is`.kow.deskscreen.utils
import
javafx.scene.image.Image
import
javafx.scene.image.PixelFormat
import
javafx.scene.image.WritableImage
import
sun.awt.image.IntegerComponentRaster
import
java.awt.image.BufferedImage
import
java.io.InputStream
import
java.nio.file.Files
import
java.nio.file.Path
...
...
@@ -36,79 +31,4 @@ object Util {
fun
md5File
(
path
:
Path
):
String
{
return
md5Stuff
(
Files
.
newInputStream
(
path
))
}
/**
* Stolen from the JDK, because it's apparently not in the javafx on the rpi. Maybe different versions?
* Snapshots the specified [BufferedImage] and stores a copy of
* its pixels into a JavaFX [Image] object, creating a new
* object if needed.
* The returned `Image` will be a static snapshot of the state
* of the pixels in the `BufferedImage` at the time the method
* completes. Further changes to the `BufferedImage` will not
* be reflected in the `Image`.
*
*
* The optional JavaFX [WritableImage] parameter may be reused
* to store the copy of the pixels.
* A new `Image` will be created if the supplied object is null,
* is too small or of a type which the image pixels cannot be easily
* converted into.
*
* @param bimg the `BufferedImage` object to be converted
* @param wimg an optional `WritableImage` object that can be
* used to store the returned pixel data
* @return an `Image` object representing a snapshot of the
* current pixels in the `BufferedImage`.
* @since JavaFX 2.2
*/
fun
toFXImage
(
bimg
:
BufferedImage
,
wimg
:
WritableImage
?):
WritableImage
{
var
bimg
=
bimg
var
wimg
=
wimg
val
bw
=
bimg
.
width
val
bh
=
bimg
.
height
when
(
bimg
.
type
)
{
BufferedImage
.
TYPE_INT_ARGB
,
BufferedImage
.
TYPE_INT_ARGB_PRE
->
{
}
else
->
{
val
converted
=
BufferedImage
(
bw
,
bh
,
BufferedImage
.
TYPE_INT_ARGB_PRE
)
val
g2d
=
converted
.
createGraphics
()
g2d
.
drawImage
(
bimg
,
0
,
0
,
null
)
g2d
.
dispose
()
bimg
=
converted
}
}
// assert(bimg.getType == TYPE_INT_ARGB[_PRE]);
if
(
wimg
!=
null
)
{
val
iw
=
wimg
.
width
.
toInt
()
val
ih
=
wimg
.
height
.
toInt
()
if
(
iw
<
bw
||
ih
<
bh
)
{
wimg
=
null
}
else
if
(
bw
<
iw
||
bh
<
ih
)
{
val
empty
=
IntArray
(
iw
)
val
pw
=
wimg
.
pixelWriter
val
pf
=
PixelFormat
.
getIntArgbPreInstance
()
if
(
bw
<
iw
)
{
pw
.
setPixels
(
bw
,
0
,
iw
-
bw
,
bh
,
pf
,
empty
,
0
,
0
)
}
if
(
bh
<
ih
)
{
pw
.
setPixels
(
0
,
bh
,
iw
,
ih
-
bh
,
pf
,
empty
,
0
,
0
)
}
}
}
if
(
wimg
==
null
)
{
wimg
=
WritableImage
(
bw
,
bh
)
}
val
pw
=
wimg
.
pixelWriter
val
icr
=
bimg
.
raster
as
IntegerComponentRaster
val
data
=
icr
.
dataStorage
val
offset
=
icr
.
getDataOffset
(
0
)
val
scan
=
icr
.
scanlineStride
val
pf
=
if
(
bimg
.
isAlphaPremultiplied
)
PixelFormat
.
getIntArgbPreInstance
()
else
PixelFormat
.
getIntArgbInstance
()
pw
.
setPixels
(
0
,
0
,
bw
,
bh
,
pf
,
data
,
offset
,
scan
)
return
wimg
}
}
\ No newline at end of file
}
src/main/kotlin/is/kow/deskscreen/views/TimeTempView.kt
View file @
e7b61e6a
...
...
@@ -130,7 +130,7 @@ class TimeTempView : View() {
.
observeOnFx
()
.
doOnNext
{
//Update the label (or the model?!?)
model
.
temp
.
value
=
it
model
.
temp
.
value
=
it
.
toLong
()
}
.
subscribe
()
ticks
.
connect
()
...
...
@@ -139,4 +139,4 @@ class TimeTempView : View() {
private
fun
readTemp
():
Int
{
return
temperatureFile
.
readText
().
trim
().
toInt
()
}
}
\ No newline at end of file
}
src/main/kotlin/is/kow/deskscreen/wx/DarkSkyCurrentConditionsView.kt
deleted
100644 → 0
View file @
815d20ca
package
`is`.kow.deskscreen.wx
import
`is`.kow.deskscreen.TransitionsController
import
com.github.thomasnield.rxkotlinfx.events
import
com.github.thomasnield.rxkotlinfx.toBinding
import
com.github.thomasnield.rxkotlinfx.toObservable
import
javafx.beans.property.*
import
javafx.geometry.Pos
import
javafx.scene.layout.Priority
import
javafx.util.StringConverter
import
mu.KotlinLogging
import
org.kordamp.ikonli.javafx.FontIcon
import
org.kordamp.ikonli.weathericons.WeatherIcons
import
tornadofx.*
import
java.time.LocalDateTime
import
java.time.format.DateTimeFormatter
/*
Add more METAR fields to this, to display the current weather outside.
*/
class
DarkSkyCurrentConditions
(
time
:
LocalDateTime
=
LocalDateTime
.
now
(),
temp
:
Double
=
0.0
)
{
val
timeProperty
=
SimpleObjectProperty
(
this
,
"time"
,
time
)
val
tempProperty
=
SimpleDoubleProperty
(
this
,
"temp"
,
temp
)
val
feelsLikeTempProperty
=
SimpleDoubleProperty
(
this
,
"feelsLikeTemp"
,
0.0
)
val
lowTempProperty
=
SimpleDoubleProperty
(
this
,
"lowTemp"
,
0.0
)
val
highTempProperty
=
SimpleDoubleProperty
(
this
,
"highTemp"
,
0.0
)
val
popsProperty
=
SimpleDoubleProperty
(
this
,
"pops"
,
0.0
)
val
precipitationIntensityProperty
=
SimpleDoubleProperty
(
this
,
"precipitationIntensity"
,
0.0
)
val
ikonProperty
=
SimpleObjectProperty
(
this
,
"ikon"
,
WeatherIcons
.
NA
)
val
pressureProperty
=
SimpleDoubleProperty
(
this
,
"pressure"
,
0.0
)
val
windDirectionProperty
=
SimpleIntegerProperty
(
this
,
"windDirection"
,
0
)
val
windSpeedProperty
=
SimpleDoubleProperty
(
this
,
"windSpeed"
,
0.0
)
val
windGustProperty
=
SimpleDoubleProperty
(
this
,
"windGust"
,
0.0
)
val
humidityProperty
=
SimpleIntegerProperty
(
this
,
"humidity"
,
0
)
val
stormDistanceProperty
=
SimpleDoubleProperty
(
this
,
"stormDistance"
,
0.0
)
val
stormBearingProperty
=
SimpleDoubleProperty
(
this
,
"stormBearing"
,
0.0
)
val
problemProperty
=
SimpleStringProperty
(
this
,
"problem"
,
null
)
val
hasProblemProperty
=
SimpleBooleanProperty
(
this
,
"hasProblemProperty"
,
false
)
val
precipTypeProperty
=
SimpleStringProperty
(
this
,
"precipTypeProperty"
,
""
)
}
class
DarkSkyCurrentConditionsModel
:
ItemViewModel
<
DarkSkyCurrentConditions
>()
{
val
time
=
bind
(
DarkSkyCurrentConditions
::
timeProperty
)
val
temp
=
bind
(
DarkSkyCurrentConditions
::
tempProperty
)
val
feelsLikeTemp
=
bind
(
DarkSkyCurrentConditions
::
feelsLikeTempProperty
)
val
lowTemp
=
bind
(
DarkSkyCurrentConditions
::
lowTempProperty
)
val
highTemp
=
bind
(
DarkSkyCurrentConditions
::
highTempProperty
)
val
pops
=
bind
(
DarkSkyCurrentConditions
::
popsProperty
)
val
precipitationIntensity
=
bind
(
DarkSkyCurrentConditions
::
precipitationIntensityProperty
)
val
ikon
=
bind
(
DarkSkyCurrentConditions
::
ikonProperty
)
val
pressure
=
bind
(
DarkSkyCurrentConditions
::
pressureProperty
)
val
windDirection
=
bind
(
DarkSkyCurrentConditions
::
windDirectionProperty
)
val
windSpeed
=
bind
(
DarkSkyCurrentConditions
::
windSpeedProperty
)
val
windGust
=
bind
(
DarkSkyCurrentConditions
::
windGustProperty
)
val
humidity
=
bind
(
DarkSkyCurrentConditions
::
humidityProperty
)
val
stormDistance
=
bind
(
DarkSkyCurrentConditions
::
stormDistanceProperty
)
val
stormBearing
=
bind
(
DarkSkyCurrentConditions
::
stormBearingProperty
)
val
problem
=
bind
(
DarkSkyCurrentConditions
::
problemProperty
)
val
hasProblem
=
bind
(
DarkSkyCurrentConditions
::
hasProblemProperty
)
val
precipType
=
bind
(
DarkSkyCurrentConditions
::
precipTypeProperty
)
}
class
WxTimeConverter
:
StringConverter
<
LocalDateTime
>()
{
val
formatter
=
DateTimeFormatter
.
ofPattern
(
"HH:mm"
)
override
fun
toString
(
time
:
LocalDateTime
?):
String
{
if
(
time
!=
null
)
{
return
time
.
format
(
formatter
)
}
else
{
return
""
}
}
override
fun
fromString
(
string
:
String
?):
LocalDateTime
{
return
LocalDateTime
.
now
()
}
}
class
RoundedConverter
:
StringConverter
<
Number
>()
{
override
fun
toString
(
temp
:
Number
?):
String
{
return
if
(
temp
!=
null
)
{
"%d"
.
format
(
Math
.
round
(
temp
.
toDouble
()))
}
else
{
""
}
}
override
fun
fromString
(
string
:
String
?):
Number
{
return
if
(
string
!=
null
)
{
string
.
toDouble
()
}
else
{
0.0
}
}
}
class
WxDateConverter
:
StringConverter
<
LocalDateTime
>()
{
val
formatter
=
DateTimeFormatter
.
ofPattern
(
"M/dd/yy"
)
override
fun
toString
(
time
:
LocalDateTime
?):
String
{
if
(
time
!=
null
)
{
return
time
.
format
(
formatter
)
}
else
{
return
""
}
}
override
fun
fromString
(
string
:
String
?):
LocalDateTime
{
return
LocalDateTime
.
now
()
}
}
class
DarkSkyCurrentConditionsView
:
View
()
{
private
val
logger
=
KotlinLogging
.
logger
{}
private
val
weatherController
:
WeatherController
by
inject
()
private
val
transitionsController
:
TransitionsController
by
inject
()
private
val
modelDarkSky
:
DarkSkyCurrentConditionsModel
by
inject
()
override
val
root
=
borderpane
{
style
{
fontSize
=
14
.
px
}
top
=
label
(
"Current Conditions"
)
center
=
borderpane
{
top
=
borderpane
{
//Updated at and Barometric Pressure
hgrow
=
Priority
.
ALWAYS
left
=
vbox
{
label
{
this
.
bind
(
modelDarkSky
.
time
,
converter
=
WxDateConverter
())
alignment
=
Pos
.
BASELINE_CENTER
hgrow
=
Priority
.
ALWAYS
useMaxWidth
=
true
}
label
{
this
.
bind
(
modelDarkSky
.
time
,
converter
=
WxTimeConverter
())
alignment
=
Pos
.
BASELINE_CENTER
hgrow
=
Priority
.
ALWAYS
useMaxWidth
=
true
}
}
right
=
hbox
{
alignment
=
Pos
.
BASELINE_RIGHT
label
{
bind
(
modelDarkSky
.
pressure
)
}
label
(
"in"
)
}
}
left
=
vbox
{
//Probability of Precipitation and Intensity
vgrow
=
Priority
.
ALWAYS
alignment
=
Pos
.
CENTER
hbox
{
alignment
=
Pos
.
CENTER
label
{
bind
(
modelDarkSky
.
pops
)
}
label
{
text
=
"%"
}
}
hbox
{
label
{
bind
(
modelDarkSky
.
precipitationIntensity
)
}
label
(
"in/hr"
)
}
}
right
=
vbox
{
//Wind Direction and Wind Speed
vgrow
=
Priority
.
ALWAYS
alignment
=
Pos
.
CENTER
hbox
{
alignment
=
Pos
.
CENTER
label
{
graphic
=
cache
{
val
icon
=
FontIcon
.
of
(
WeatherIcons
.
DIRECTION_DOWN
)
icon
.
iconSize
=
22
icon
}
rotateProperty
().
bind
(
modelDarkSky
.
windDirection
)
}
}
hbox
{
alignment
=
Pos
.
BASELINE_CENTER
label
{
bind
(
modelDarkSky
.
windSpeed
)
}
label
(
"mph"
)
}
hbox
{
alignment
=
Pos
.
BASELINE_CENTER
label
{
bind
(
modelDarkSky
.
humidity
)
}
label
{
graphic
=
cache
{
val
icon
=
FontIcon
.
of
(
WeatherIcons
.
HUMIDITY
)
icon
.
iconSize
=
14
icon
}
}
}
}
center
=
borderpane
{
//TODO: also needs to be touch evented -- Handled via mouse emulation, it'll be fine
weatherController
.
handleDisplayRadar
(
this
.
events
(
javafx
.
scene
.
input
.
MouseEvent
.
MOUSE_RELEASED
))
style
{
fontSize
=
16
.
px
padding
=
box
(
3
.
px
)
}
center
=
label
{
//Weather Icon!
val
convertToIcon
=
modelDarkSky
.
ikon
.
toObservable
()
.
map
{
val
icon
=
FontIcon
.
of
(
it
)
icon
.
iconSize
=
70
icon
}
graphicProperty
().
bind
(
convertToIcon
.
toBinding
())
}
bottom
=
hbox
{
//Current temp, and low/high
useMaxWidth
=
true
hgrow
=
Priority
.
ALWAYS
alignment
=
Pos
.
BASELINE_CENTER
vbox
{
hbox
{
alignment
=
Pos
.
BASELINE_CENTER
label
{
bind
(
modelDarkSky
.
temp
)
}
label
{
graphic
=
cache
{
val
icon
=
FontIcon
.
of
(
WeatherIcons
.
FAHRENHEIT
)
icon
.
iconSize
=
18
icon
}
}
}
hbox
{
alignment
=
Pos
.
BASELINE_CENTER
style
{
fontSize
=
14
.
px
}
label
{
bind
(
modelDarkSky
.
lowTemp
,
converter
=
RoundedConverter
())
}
label
(
"/"
)
label
{
bind
(
modelDarkSky
.
highTemp
,
converter
=
RoundedConverter
())
}
}
}
}
}
}
}
override
fun
onDock
()
{
logger
.
debug
(
"Current Conditions Polling started"
)
weatherController
.
darkSkyStream
()
}
}
\ No newline at end of file
src/main/kotlin/is/kow/deskscreen/wx/WeatherController.kt
View file @
e7b61e6a
...
...
@@ -20,12 +20,6 @@ import org.http4k.client.ApacheClient
import
org.http4k.core.Method
import
org.http4k.core.Request
import
org.kordamp.ikonli.weathericons.WeatherIcons
import
tk.plogitech.darksky.api.jackson.DarkSkyJacksonClient
import
tk.plogitech.darksky.forecast.APIKey
import
tk.plogitech.darksky.forecast.ForecastRequestBuilder
import
tk.plogitech.darksky.forecast.GeoCoordinates
import
tk.plogitech.darksky.forecast.model.Latitude
import
tk.plogitech.darksky.forecast.model.Longitude
import
tornadofx.*
import
java.net.URI
import
java.nio.file.Files
...
...
@@ -46,7 +40,6 @@ class WeatherController : Controller() {
private
val
displayController
:
DisplayController
by
inject
()
private
val
transitionsController
:
TransitionsController
by
inject
()
private
val
darkSkyCurrentConditionsModel
:
DarkSkyCurrentConditionsModel
by
inject
()
private
val
radarModel
:
RadarModel
by
inject
()
private
val
radarDisplayedSubject
=
PublishSubject
.
create
<
Boolean
>()
...
...
@@ -399,92 +392,6 @@ class WeatherController : Controller() {
}
fun
darkSkyStream
()
{
val
config
=
mainController
.
appConfig
val
darkSkyJacksonClient
=
DarkSkyJacksonClient
()
val
timeZoneId
=
ZoneId
.
of
(
"America/Chicago"
)
//Use a switchMap to determine if we output intervals, or if we don't
displayController
.
displayStateObservable
.
switchMap
{
if
(
it
)
{
logger
.
debug
(
"Display is on!"
)
Observable
.
interval
(
0
,
30
,
TimeUnit
.
MINUTES
)
}
else
{
logger
.
debug
(
"display is not on!"
)
Observable
.
empty
()
}
}
.
subscribeOn
(
Schedulers
.
io
())
.
map
{
//A request only for the KDAL station
val
request
=
ForecastRequestBuilder
()
.
key
(
APIKey
(
config
.
getString
(
"weather.darkSkyApiKey"
)))
.
units
(
ForecastRequestBuilder
.
Units
.
us
)
.
location
(
GeoCoordinates
(
Longitude
(
config
.
getDouble
(
"weather.longitude"
)),
Latitude
(
config
.
getDouble
(
"weather.latitude"
)))).
build
()
darkSkyJacksonClient
.
forecast
(
request
)
}
//TODO: handle an error state
.
doOnNext
{
logger
.
debug
(
"Forecast: ${it}"
)
}
.
retryWhen
{
it
.
observeOnFx
()
.
doOnError
{
fail
->
//Update the model to indicate a prolem
darkSkyCurrentConditionsModel
.
problem
.
value
=
fail
.
message
darkSkyCurrentConditionsModel
.
hasProblem
.
value
=
true
}
.
observeOn
(
Schedulers
.
io
())
.
flatMap
{
Observable
.
timer
(
config
.
getLong
(
"weather.retryDelaySeconds"
),
TimeUnit
.
SECONDS
)
}
}
.
observeOnFx
()
.
doOnNext
{
fcst
->
//No problem detected!
darkSkyCurrentConditionsModel
.
problem
.
value
=
null
darkSkyCurrentConditionsModel
.
hasProblem
.
value
=
false
//Updoot the model
val
model
=
darkSkyCurrentConditionsModel
val
currently
=
fcst
.
currently
model
.
temp
.
value
=
currently
.
temperature
model
.
feelsLikeTemp
.
value
=
currently
.
apparentTemperature
model
.
time
.
value
=
LocalDateTime
.
ofInstant
(
fcst
.
currently
.
time
,
timeZoneId
)
model
.
pressure
.
value
=
currently
.
pressure
*
0.0295301
//Converted to Inches
model
.
windDirection
.
value
=
currently
.
windBearing
model
.
windSpeed
.
value
=
currently
.
windSpeed
//No wind gust in currently
model
.
humidity
.
value
=
currently
.
humidity
*
100