Author: Adam <git@apiote.xyz>
Enums in Vehicle and Alert
app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt | 6 app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt | 119 ++++++- app/src/main/java/xyz/apiote/bimba/czwek/repo/Departure.kt | 55 +++ app/src/main/java/xyz/apiote/bimba/czwek/repo/Vehicle.kt | 121 +++++--
diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt b/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt index dfa1fb1659a435ec02e450071088b1b5b8233f97..f32fbfbb49ce718e677036fbd07d223fb01f1f35 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/Bimba.kt @@ -3,12 +3,6 @@ import org.osmdroid.config.Configuration import java.io.File -/* todo - api.AlertV1 enums (Structs.kt) - repo.Alert enums (Departure.kt) - ErrorResponseError - repo.Vehicle enums (Vehicle.kt) -*/ class Bimba : android.app.Application() { override fun onCreate() { super.onCreate() diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt b/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt index ad2f2ca2147befaa516f905eb052878bfa4293e7..2761f6ac89092ffcc5218e8b2efcabfe2f249297 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/api/Structs.kt @@ -135,22 +135,72 @@ ) } } +enum class AlertCauseV1 { + UNKNOWN, OTHER, TECHNICAL_PROBLEM, STRIKE, DEMONSTRATION, ACCIDENT, HOLIDAY, WEATHER, MAINTENANCE, + CONSTRUCTION, POLICE_ACTIVITY, MEDICAL_EMERGENCY; + + companion object { + fun of(type: UInt): AlertCauseV1 { + return when (type) { + 0u -> valueOf("UNKNOWN") + 1u -> valueOf("OTHER") + 2u -> valueOf("TECHNICAL_PROBLEM") + 3u -> valueOf("STRIKE") + 4u -> valueOf("DEMONSTRATION") + 5u -> valueOf("ACCIDENT") + 6u -> valueOf("HOLIDAY") + 7u -> valueOf("WEATHER") + 8u -> valueOf("MAINTENANCE") + 9u -> valueOf("CONSTRUCTION") + 10u -> valueOf("POLICE_ACTIVITY") + 11u -> valueOf("MEDICAL_EMERGENCY") + else -> throw UnknownResourceVersionException("AlertCause/$type", 1u) + } + } + } +} + +enum class AlertEffectV1 { + UNKNOWN, OTHER, NO_SERVICE, REDUCED_SERVICE, SIGNIFICANT_DELAYS, DETOUR, ADDITIONAL_SERVICE, + MODIFIED_SERVICE, STOP_MOVED, NONE, ACCESSIBILITY_ISSUE; + + companion object { + fun of(type: UInt): AlertEffectV1 { + return when (type) { + 0u -> valueOf("UNKNOWN") + 1u -> valueOf("OTHER") + 2u -> valueOf("NO_SERVICE") + 3u -> valueOf("REDUCED_SERVICE") + 4u -> valueOf("SIGNIFICANT_DELAYS") + 5u -> valueOf("DETOUR") + 6u -> valueOf("ADDITIONAL_SERVICE") + 7u -> valueOf("MODIFIED_SERVICE") + 8u -> valueOf("STOP_MOVED") + 9u -> valueOf("NONE") + 10u -> valueOf("ACCESSIBILITY_ISSUE") + else -> throw UnknownResourceVersionException("AlertEffect/$type", 1u) + } + } + } +} + data class AlertV1( val header: String, val Description: String, val Url: String, - val Cause: ULong, // todo [3.1] enum - val Effect: ULong // todo [3.1] enum + val Cause: AlertCauseV1, + val Effect: AlertEffectV1 ) { companion object { fun unmarshal(stream: InputStream): AlertV1 { val reader = Reader(stream) - val header = reader.readString() - val description = reader.readString() - val url = reader.readString() - val cause = reader.readUInt().toULong() - val effect = reader.readUInt().toULong() - return AlertV1(header, description, url, cause, effect) + return AlertV1( + reader.readString(), + reader.readString(), + reader.readString(), + AlertCauseV1.of(reader.readUInt().toULong().toUInt()), + AlertEffectV1.of(reader.readUInt().toULong().toUInt()) + ) } } } @@ -183,6 +233,43 @@ } } } +enum class CongestionLevelV1 { + UNKNOWN, SMOOTH, STOP_AND_GO, SIGNIFICANT, SEVERE; + + companion object { + fun of(type: UInt): CongestionLevelV1 { + return when (type) { + 0u -> valueOf("UNKNOWN") + 1u -> valueOf("SMOOTH") + 2u -> valueOf("STOP_AND_GO") + 3u -> valueOf("SIGNIFICANT") + 4u -> valueOf("SEVERE") + else -> throw UnknownResourceVersionException("CongestionLevel/$type", 1u) + } + } + } +} + +enum class OccupancyStatusV1 { + UNKNOWN, EMPTY, MANY_AVAILABLE, FEW_AVAILABLE, STANDING_ONLY, CRUSHED, FULL, NOT_ACCEPTING; + + companion object { + fun of(type: UInt): OccupancyStatusV1 { + return when (type) { + 0u -> valueOf("UNKNOWN") + 1u -> valueOf("EMPTY") + 2u -> valueOf("MANY_AVAILABLE") + 3u -> valueOf("FEW_AVAILABLE") + 4u -> valueOf("STANDING_ONLY") + 5u -> valueOf("CRUSHED") + 6u -> valueOf("FULL") + 7u -> valueOf("NOT_ACCEPTING") + else -> throw UnknownResourceVersionException("OccupancyStatus/$type", 1u) + } + } + } +} + data class VehicleV1( val ID: String, val Position: PositionV1, @@ -190,8 +277,8 @@ val Capabilities: UShort, val Speed: Float, val Line: LineStubV1, val Headsign: String, - val CongestionLevel: ULong, - val OccupancyStatus: ULong + val CongestionLevel: CongestionLevelV1, + val OccupancyStatus: OccupancyStatusV1 ) : LocatableV1 { companion object { fun unmarshal(stream: InputStream): VehicleV1 { @@ -203,8 +290,8 @@ reader.readU16(), reader.readFloat32(), LineStubV1.unmarshal(stream), reader.readString(), - reader.readUInt().toULong(), - reader.readUInt().toULong() + CongestionLevelV1.of(reader.readUInt().toULong().toUInt()), + OccupancyStatusV1.of(reader.readUInt().toULong().toUInt()) ) } } @@ -217,8 +304,8 @@ val Capabilities: UShort, val Speed: Float, val Line: LineStubV2, val Headsign: String, - val CongestionLevel: ULong, - val OccupancyStatus: ULong + val CongestionLevel: CongestionLevelV1, + val OccupancyStatus: OccupancyStatusV1 ) : LocatableV2 { companion object { fun unmarshal(stream: InputStream): VehicleV2 { @@ -230,8 +317,8 @@ reader.readU16(), reader.readFloat32(), LineStubV2.unmarshal(stream), reader.readString(), - reader.readUInt().toULong(), - reader.readUInt().toULong() + CongestionLevelV1.of(reader.readUInt().toULong().toUInt()), + OccupancyStatusV1.of(reader.readUInt().toULong().toUInt()) ) } } diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Departure.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Departure.kt index d3259e6e5df6c5c5e0755f12ca47d48ede9e0c18..92cee3af3c4ee80616516019a22c6818e07d17b9 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Departure.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Departure.kt @@ -3,6 +3,8 @@ import android.content.Context import android.text.format.DateUtils import xyz.apiote.bimba.czwek.R +import xyz.apiote.bimba.czwek.api.AlertCauseV1 +import xyz.apiote.bimba.czwek.api.AlertEffectV1 import xyz.apiote.bimba.czwek.api.AlertV1 import xyz.apiote.bimba.czwek.api.DepartureV1 import xyz.apiote.bimba.czwek.api.DepartureV2 @@ -13,14 +15,61 @@ import java.time.ZoneId import java.time.ZonedDateTime import java.time.temporal.ChronoUnit +enum class AlertCause { + UNKNOWN, OTHER, TECHNICAL_PROBLEM, STRIKE, DEMONSTRATION, ACCIDENT, HOLIDAY, WEATHER, MAINTENANCE, + CONSTRUCTION, POLICE_ACTIVITY, MEDICAL_EMERGENCY; + + companion object { + fun of(type: AlertCauseV1): AlertCause { + return when (type) { + AlertCauseV1.UNKNOWN -> valueOf("UNKNOWN") + AlertCauseV1.OTHER -> valueOf("OTHER") + AlertCauseV1.TECHNICAL_PROBLEM -> valueOf("TECHNICAL_PROBLEM") + AlertCauseV1.STRIKE -> valueOf("STRIKE") + AlertCauseV1.DEMONSTRATION -> valueOf("DEMONSTRATION") + AlertCauseV1.ACCIDENT -> valueOf("ACCIDENT") + AlertCauseV1.HOLIDAY -> valueOf("HOLIDAY") + AlertCauseV1.WEATHER -> valueOf("WEATHER") + AlertCauseV1.MAINTENANCE -> valueOf("MAINTENANCE") + AlertCauseV1.CONSTRUCTION -> valueOf("CONSTRUCTION") + AlertCauseV1.POLICE_ACTIVITY -> valueOf("POLICE_ACTIVITY") + AlertCauseV1.MEDICAL_EMERGENCY -> valueOf("MEDICAL_EMERGENCY") + } + } + } +} + +enum class AlertEffect { + UNKNOWN, OTHER, NO_SERVICE, REDUCED_SERVICE, SIGNIFICANT_DELAYS, DETOUR, ADDITIONAL_SERVICE, + MODIFIED_SERVICE, STOP_MOVED, NONE, ACCESSIBILITY_ISSUE; + + companion object { + fun of(type: AlertEffectV1): AlertEffect { + return when (type) { + AlertEffectV1.UNKNOWN -> valueOf("UNKNOWN") + AlertEffectV1.OTHER -> valueOf("OTHER") + AlertEffectV1.NO_SERVICE -> valueOf("NO_SERVICE") + AlertEffectV1.REDUCED_SERVICE -> valueOf("REDUCED_SERVICE") + AlertEffectV1.SIGNIFICANT_DELAYS -> valueOf("SIGNIFICANT_DELAYS") + AlertEffectV1.DETOUR -> valueOf("DETOUR") + AlertEffectV1.ADDITIONAL_SERVICE -> valueOf("ADDITIONAL_SERVICE") + AlertEffectV1.MODIFIED_SERVICE -> valueOf("MODIFIED_SERVICE") + AlertEffectV1.STOP_MOVED -> valueOf("STOP_MOVED") + AlertEffectV1.NONE -> valueOf("NONE") + AlertEffectV1.ACCESSIBILITY_ISSUE -> valueOf("ACCESSIBILITY_ISSUE") + } + } + } +} + data class Alert( val header: String, val description: String, val url: String, - val cause: ULong, // todo [3.1] enum - val effect: ULong // todo [3.1] enum + val cause: AlertCause, + val effect: AlertEffect ) { - constructor(a: AlertV1) : this(a.header, a.Description, a.Url, a.Cause, a.Effect) + constructor(a: AlertV1) : this(a.header, a.Description, a.Url, AlertCause.of(a.Cause), AlertEffect.of(a.Effect)) } data class StopDepartures( diff --git a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Vehicle.kt b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Vehicle.kt index 4e7e795de8c92c2fdc69f1d3b01bbd391433ae37..509e4819d6b6826c07323c71425f0f1928549319 100644 --- a/app/src/main/java/xyz/apiote/bimba/czwek/repo/Vehicle.kt +++ b/app/src/main/java/xyz/apiote/bimba/czwek/repo/Vehicle.kt @@ -1,11 +1,68 @@ package xyz.apiote.bimba.czwek.repo import android.content.Context -import android.graphics.drawable.Drawable import xyz.apiote.bimba.czwek.R -import xyz.apiote.bimba.czwek.api.UnknownResourceVersion +import xyz.apiote.bimba.czwek.api.CongestionLevelV1 +import xyz.apiote.bimba.czwek.api.OccupancyStatusV1 import xyz.apiote.bimba.czwek.api.VehicleV1 import xyz.apiote.bimba.czwek.api.VehicleV2 + +enum class CongestionLevel { + UNKNOWN, SMOOTH, STOP_AND_GO, SIGNIFICANT, SEVERE; + + fun toString(context: Context): String { + return when (this) { + UNKNOWN -> context.getString(R.string.congestion_unknown) + SMOOTH -> context.getString(R.string.congestion_smooth) + STOP_AND_GO -> context.getString(R.string.congestion_stop_and_go) + SIGNIFICANT -> context.getString(R.string.congestion_congestion) + SEVERE -> context.getString(R.string.congestion_jams) + } + } + + companion object { + fun of(type: CongestionLevelV1): CongestionLevel { + return when (type) { + CongestionLevelV1.UNKNOWN -> valueOf("UNKNOWN") + CongestionLevelV1.SMOOTH -> valueOf("SMOOTH") + CongestionLevelV1.STOP_AND_GO -> valueOf("STOP_AND_GO") + CongestionLevelV1.SIGNIFICANT -> valueOf("SIGNIFICANT") + CongestionLevelV1.SEVERE -> valueOf("SEVERE") + } + } + } +} + +enum class OccupancyStatus { + UNKNOWN, EMPTY, MANY_AVAILABLE, FEW_AVAILABLE, STANDING_ONLY, CRUSHED, FULL, NOT_ACCEPTING; + + fun toString(context: Context):String { + return when (this) { + UNKNOWN -> context.getString(R.string.occupancy_unknown) + EMPTY -> context.getString(R.string.occupancy_empty) + MANY_AVAILABLE -> context.getString(R.string.occupancy_many_seats) + FEW_AVAILABLE -> context.getString(R.string.occupancy_few_seats) + STANDING_ONLY -> context.getString(R.string.occupancy_standing_only) + CRUSHED -> context.getString(R.string.occupancy_crowded) + FULL -> context.getString(R.string.occupancy_full) + NOT_ACCEPTING -> context.getString(R.string.occupancy_wont_let) + } + } + companion object { + fun of(type: OccupancyStatusV1): OccupancyStatus { + return when (type) { + OccupancyStatusV1.UNKNOWN -> valueOf("UNKNOWN") + OccupancyStatusV1.EMPTY -> valueOf("EMPTY") + OccupancyStatusV1.MANY_AVAILABLE -> valueOf("MANY_AVAILABLE") + OccupancyStatusV1.FEW_AVAILABLE -> valueOf("FEW_AVAILABLE") + OccupancyStatusV1.STANDING_ONLY -> valueOf("STANDING_ONLY") + OccupancyStatusV1.CRUSHED -> valueOf("CRUSHED") + OccupancyStatusV1.FULL -> valueOf("FULL") + OccupancyStatusV1.NOT_ACCEPTING -> valueOf("NOT_ACCEPTING") + } + } + } +} data class Vehicle( val ID: String, @@ -14,15 +71,31 @@ val Capabilities: UShort, val Speed: Float, val Line: LineStub, val Headsign: String, - val CongestionLevel: ULong, - val OccupancyStatus: ULong + val congestionLevel: CongestionLevel, + val occupancyStatus: OccupancyStatus ) : Locatable { - constructor(v: VehicleV1):this(v.ID, - Position(v.Position), v.Capabilities, v.Speed, - LineStub(v.Line), v.Headsign, v.CongestionLevel, v.OccupancyStatus) - constructor(v: VehicleV2):this(v.ID, - Position(v.Position), v.Capabilities, v.Speed, - LineStub(v.Line), v.Headsign, v.CongestionLevel, v.OccupancyStatus) + constructor(v: VehicleV1) : this( + v.ID, + Position(v.Position), + v.Capabilities, + v.Speed, + LineStub(v.Line), + v.Headsign, + CongestionLevel.of(v.CongestionLevel), + OccupancyStatus.of(v.OccupancyStatus) + ) + + constructor(v: VehicleV2) : this( + v.ID, + Position(v.Position), + v.Capabilities, + v.Speed, + LineStub(v.Line), + v.Headsign, + CongestionLevel.of(v.CongestionLevel), + OccupancyStatus.of(v.OccupancyStatus) + ) + enum class Capability(val bit: UShort) { RAMP(0b0001u), LOW_FLOOR(0b0010u), LOW_ENTRY(0b0001_0000_0000u), AC(0b0100u), BIKE(0b1000u), VOICE( 0b0001_0000u @@ -30,37 +103,15 @@ ), TICKET_MACHINE(0b0010_0000u), TICKET_DRIVER(0b0100_0000u), USB_CHARGING(0b1000_0000u) } - override fun icon(context: Context, scale: Float): Drawable = Line.icon(context, scale) + override fun icon(context: Context, scale: Float) = Line.icon(context, scale) override fun location(): Position = Position override fun id(): String = ID - fun congestion(context: Context): String { - return when (val r = CongestionLevel.toUInt()) { // todo [3.1] enum - 0u -> context.getString(R.string.congestion_unknown) - 1u -> context.getString(R.string.congestion_smooth) - 2u -> context.getString(R.string.congestion_stop_and_go) - 3u -> context.getString(R.string.congestion_congestion) - 4u -> context.getString(R.string.congestion_jams) - else -> throw UnknownResourceVersion("Congestion/$r", 1u) - } - } - - fun occupancy(context: Context): String { - return when (val r = OccupancyStatus.toUInt()) { // todo [3.1] enum - 0u -> context.getString(R.string.occupancy_unknown) - 1u -> context.getString(R.string.occupancy_empty) - 2u -> context.getString(R.string.occupancy_many_seats) - 3u -> context.getString(R.string.occupancy_few_seats) - 4u -> context.getString(R.string.occupancy_standing_only) - 5u -> context.getString(R.string.occupancy_crowded) - 6u -> context.getString(R.string.occupancy_full) - 7u -> context.getString(R.string.occupancy_wont_let) - else -> throw UnknownResourceVersion("Occupancy/$r", 1u) + fun congestion(context: Context) = congestionLevel.toString(context) - } - } + fun occupancy(context: Context)= occupancyStatus.toString(context) fun getCapability(field: Capability): Boolean { return Capabilities.and(field.bit) != (0).toUShort()