diff --git a/README.md b/README.md index fb2ea99..7893a38 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ This library supports parsing any valid JSON file using the following schema ver - v0.13 - v14 +- v15 Note: Endpoints using versions 0.12 and older are not supported, they will result in a `ParseError` being thrown. diff --git a/src/main/kotlin/io/spaceapi/types/Area.kt b/src/main/kotlin/io/spaceapi/types/Area.kt new file mode 100644 index 0000000..c830a7a --- /dev/null +++ b/src/main/kotlin/io/spaceapi/types/Area.kt @@ -0,0 +1,31 @@ +/** + * spaceapi-kt + * https://github.com/spaceapi-community/spaceapi-kt/ + * Copyright (C) 2020-2024 Danilo Bargen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.spaceapi.types + +import kotlinx.serialization.Serializable + +@Serializable +data class Area( + @JvmField + var name: String? = null, + @JvmField + var description: String? = null, + @JvmField + var square_meters: Float, +) diff --git a/src/main/kotlin/io/spaceapi/types/LinkedSpace.kt b/src/main/kotlin/io/spaceapi/types/LinkedSpace.kt new file mode 100644 index 0000000..f550d55 --- /dev/null +++ b/src/main/kotlin/io/spaceapi/types/LinkedSpace.kt @@ -0,0 +1,29 @@ +/** + * spaceapi-kt + * https://github.com/spaceapi-community/spaceapi-kt/ + * Copyright (C) 2020-2024 Danilo Bargen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package io.spaceapi.types + +import kotlinx.serialization.Serializable + +@Serializable +data class LinkedSpace( + @JvmField + var website: String? = null, + @JvmField + var endpoint: String? = null, +) diff --git a/src/main/kotlin/io/spaceapi/types/Location.kt b/src/main/kotlin/io/spaceapi/types/Location.kt index 14ab4c4..841dee2 100644 --- a/src/main/kotlin/io/spaceapi/types/Location.kt +++ b/src/main/kotlin/io/spaceapi/types/Location.kt @@ -25,9 +25,15 @@ data class Location( @JvmField var address: String? = null, @JvmField - var lat: Float, + var lat: Float? = null, @JvmField - var lon: Float, + var lon: Float? = null, @JvmField var timezone: String? = null, + @JvmField + var country_code: String? = null, + @JvmField + var areas: Array = emptyArray(), + @JvmField + var hint: String? = null, ) diff --git a/src/main/kotlin/io/spaceapi/types/Sensors.kt b/src/main/kotlin/io/spaceapi/types/Sensors.kt index 538f582..ab6af03 100644 --- a/src/main/kotlin/io/spaceapi/types/Sensors.kt +++ b/src/main/kotlin/io/spaceapi/types/Sensors.kt @@ -52,6 +52,10 @@ data class Sensors( var people_now_present: Array = emptyArray(), @JvmField var network_traffic: Array = emptyArray(), + @JvmField + var power_generation: Array = emptyArray(), + @JvmField + var carbondioxide: Array = emptyArray(), ) @Serializable @@ -66,6 +70,8 @@ data class Temperature( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -78,6 +84,8 @@ data class DoorLocked( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -92,6 +100,8 @@ data class Barometer( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -122,6 +132,8 @@ data class RadiationSensor( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -136,6 +148,8 @@ data class Humidity( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -150,6 +164,8 @@ data class BeverageSupply( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -164,6 +180,8 @@ data class PowerConsumption( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -176,6 +194,8 @@ data class Wind( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -228,6 +248,8 @@ data class NetworkConnection( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -250,6 +272,8 @@ data class AccountBalance( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -262,6 +286,8 @@ data class MemberCount( var name: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -276,6 +302,8 @@ data class PeoplePresent( var names: Array = emptyArray(), @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -288,6 +316,8 @@ data class NetworkTraffic( var location: String? = null, @JvmField var description: String? = null, + @JvmField + var lastchange: Float? = null, ) @Serializable @@ -311,3 +341,35 @@ data class PacketsPerSecond( @JvmField var value: Long, ) + +@Serializable +data class PowerGeneration( + @JvmField + var value: Float, + @JvmField + var unit: String, + @JvmField + var location: String, + @JvmField + var name: String? = null, + @JvmField + var description: String? = null, + @JvmField + var lastchange: Float? = null, +) + +@Serializable +data class CarbonDioxide( + @JvmField + var value: Float, + @JvmField + var unit: String, + @JvmField + var location: String, + @JvmField + var name: String? = null, + @JvmField + var description: String? = null, + @JvmField + var lastchange: Float? = null, +) diff --git a/src/main/kotlin/io/spaceapi/types/Status.kt b/src/main/kotlin/io/spaceapi/types/Status.kt index 9caa82e..0afcaed 100644 --- a/src/main/kotlin/io/spaceapi/types/Status.kt +++ b/src/main/kotlin/io/spaceapi/types/Status.kt @@ -38,7 +38,7 @@ data class Status( @JvmField var url: String, @JvmField - var location: Location, + var location: Location? = null, @JvmField var spacefed: SpaceFed? = null, @JvmField @@ -71,4 +71,6 @@ data class Status( @Deprecated("The 'radio_show' field was removed in API v14") @JvmField var radio_show: Array = emptyArray(), + @JvmField + var linked_spaces: Array = emptyArray(), ) diff --git a/src/test/kotlin/io/spaceapi/ParserTestKotlin.kt b/src/test/kotlin/io/spaceapi/ParserTestKotlin.kt index aa97175..ed3cca6 100644 --- a/src/test/kotlin/io/spaceapi/ParserTestKotlin.kt +++ b/src/test/kotlin/io/spaceapi/ParserTestKotlin.kt @@ -46,9 +46,9 @@ class ParserTestKotlin { assertEquals("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", parsed.logo) assertEquals("https://www.coredump.ch/", parsed.url.toString()) - assertEquals("Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", parsed.location.address) - assertEquals(47.2251f, parsed.location.lon) - assertEquals(8.8339f, parsed.location.lat) + assertEquals("Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", parsed.location!!.address) + assertEquals(47.2251f, parsed.location!!.lon) + assertEquals(8.8339f, parsed.location!!.lat) assertEquals(false, parsed.state!!.open) assertEquals(null, parsed.state!!.lastchange) @@ -96,9 +96,9 @@ class ParserTestKotlin { assertEquals("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", parsed.logo) assertEquals("https://www.coredump.ch/", parsed.url.toString()) - assertEquals("Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", parsed.location.address) - assertEquals(47.2251f, parsed.location.lon) - assertEquals(8.8339f, parsed.location.lat) + assertEquals("Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", parsed.location!!.address) + assertEquals(47.2251f, parsed.location!!.lon) + assertEquals(8.8339f, parsed.location!!.lat) assertEquals(false, parsed.state!!.open) assertEquals(null, parsed.state!!.lastchange) @@ -130,9 +130,9 @@ class ParserTestKotlin { assertEquals("Coredump", parsed.space) assertEquals("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", parsed.logo) assertEquals("https://www.coredump.ch/", parsed.url) - assertEquals(null, parsed.location.address) - assertEquals(47.2251f, parsed.location.lon) - assertEquals(8.8339f, parsed.location.lat) + assertEquals(null, parsed.location!!.address) + assertEquals(47.2251f, parsed.location!!.lon) + assertEquals(8.8339f, parsed.location!!.lat) @Suppress("DEPRECATION") assertEquals(emptySet(), parsed.issue_report_channels) @@ -150,6 +150,89 @@ class ParserTestKotlin { assertEquals(setOf("14"), parsed.api_compatibility) } + @Test + fun testParseV15FromString() { + val parsed = parseString(""" + { + "api": "0.13", + "api_compatibility": ["14", "15"], + "space": "Coredump", + "logo": "https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", + "url": "https://www.coredump.ch/", + "location": { + "address": "Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", + "lon": 47.2251, + "lat": 8.8339, + "country_code": "CH", + "hint": "Ring bell twice" + }, + "contact": { + "email": "vorstand@lists.coredump.ch", + "irc": "irc://freenode.net/#coredump", + "twitter": "@coredump_ch" + }, + "issue_report_channels": ["email", "twitter"], + "state": { + "open": false, + "message": "Open Mondays from 20:00" + }, + "linked_spaces": [ + { + "endpoint": "https://spaceapi.kabelsalat.ch/", + "website": "https://ccc-basel.ch/" + } + ] + } + """) + + assertEquals("Coredump", parsed.space) + assertEquals("0.13", parsed.api) + assertEquals(setOf("14", "15"), parsed.api_compatibility) + assertEquals("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", parsed.logo) + assertEquals("https://www.coredump.ch/", parsed.url.toString()) + + assertEquals("Neue Jonastrasse 107, 8640 Rapperswil, Switzerland", parsed.location!!.address) + assertEquals(47.2251f, parsed.location!!.lon) + assertEquals(8.8339f, parsed.location!!.lat) + assertEquals("CH", parsed.location!!.country_code) + assertEquals("Ring bell twice", parsed.location!!.hint) + + assertEquals(false, parsed.state!!.open) + assertEquals(null, parsed.state!!.lastchange) + assertEquals("Open Mondays from 20:00", parsed.state!!.message) + + assertEquals("vorstand@lists.coredump.ch", parsed.contact.email) + assertEquals("irc://freenode.net/#coredump", parsed.contact.irc) + assertEquals("@coredump_ch", parsed.contact.twitter) + assertEquals(null, parsed.contact.facebook) + + assertEquals(1, parsed.linked_spaces.size) + assertEquals("https://spaceapi.kabelsalat.ch/", parsed.linked_spaces[0].endpoint) + assertEquals("https://ccc-basel.ch/", parsed.linked_spaces[0].website) + + @Suppress("DEPRECATION") + assertEquals(setOf("email", "twitter"), parsed.issue_report_channels) + } + + private val minimalV15Data = """{ + "api_compatibility": ["15"], + "space": "Coredump", + "logo": "https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", + "url": "https://www.coredump.ch/", + "contact": {} + }""" + + @Test + fun testParseV15Minimal() { + val parsed = parseString(minimalV15Data) + + assertEquals(setOf("15"), parsed.api_compatibility) + assertEquals("Coredump", parsed.space) + assertEquals("https://www.coredump.ch/wp-content/uploads/2016/11/logo.png", parsed.logo) + assertEquals("https://www.coredump.ch/", parsed.url) + assertEquals(null, parsed.location) + } + /** * Regression test for #2. */