Skip to content

Commit d18551a

Browse files
committed
Convert Measure enum to data class
1 parent 3df8fb6 commit d18551a

File tree

17 files changed

+419
-485
lines changed

17 files changed

+419
-485
lines changed

gradle.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
githubUrl=https://github.com/strykeforce/thirdcoast
2+
kotlin.code.style=official

telemetry/src/main/kotlin/org/strykeforce/thirdcoast/telemetry/AbstractInventory.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ private fun JsonWriter.writeItems(items: List<Measurable>): JsonWriter {
4343

4444
private fun JsonWriter.writeMeasures(items: List<Measurable>): JsonWriter {
4545
beginArray()
46-
items.associateBy({ it.type }, { it.measures }).forEach { type, measures ->
46+
items.associateBy({ it.type }, { it.measures }).forEach { (type, measures) ->
4747
beginObject()
4848
name("deviceType").value(type)
4949
name("deviceMeasures")

telemetry/src/main/kotlin/org/strykeforce/thirdcoast/telemetry/TelemetryService.kt

Lines changed: 104 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -11,124 +11,126 @@ import java.util.function.Function
1111
private val logger = KotlinLogging.logger {}
1212

1313
/**
14-
* The Telemetry service registers [Measurable] instances for data collection and controls the
15-
* starting and stopping of the service. When active, the services listens for incoming config
16-
* messages via a HTTP REST service and sends data over UDP.
14+
* The Telemetry service is the main interface for client applications that are telemetry-enabled. It registers
15+
* [Measurable] instances for data collection and controls the starting and stopping of the service. When active,
16+
* the services listens for incoming control messages via a HTTP REST-like service and sends data over UDP.
17+
*
18+
* The constructor takes a factory function to create a [TelemetryController] instance with a given [Inventory].
19+
* The default [TelemetryController] has a constructor that serves this purpose, for example:
20+
* ```
21+
* TelemetryService ts = new TelemetryService(TelemetryController::new);
22+
* ts.register(talon);
23+
* ts.start();
24+
* ```
1725
*/
1826
class TelemetryService(private val telemetryControllerFactory: Function<Inventory, TelemetryController>) {
1927

20-
// current implementation passes this list to the inventory as a collection via component binding
21-
// when start is called. The inventory copies this collection into a List, using its index in
22-
// this list as the inventory id.
28+
// Current implementation passes the `items` list to the inventory as a collection when start is called. The inventory
29+
// sorts and copies this collection into a List, using its index in this list as the inventory id. This should provide
30+
// a stable order of measurable items that assists the Grapher client when saving its configuration.
2331

24-
private val items = LinkedHashSet<Measurable>()
25-
private var telemetryController: TelemetryController? = null
32+
private val items = LinkedHashSet<Measurable>()
33+
private var telemetryController: TelemetryController? = null
2634

27-
/** Start the Telemetry service and listen for client connections. */
28-
fun start() {
29-
if (telemetryController != null) {
30-
logger.info("already started")
31-
return
32-
}
33-
telemetryController = telemetryControllerFactory.apply(RobotInventory(items)).also { it.start() }
34-
logger.info("started telemetry controller")
35+
/**
36+
* Start the Telemetry service and listen for client connections. A new instance of [TelemetryController] is created
37+
* that reflects the current list of [Measurable] items.
38+
*/
39+
fun start() {
40+
if (telemetryController != null) {
41+
logger.info("already started")
42+
return
3543
}
44+
telemetryController = telemetryControllerFactory.apply(RobotInventory(items)).also { it.start() }
45+
logger.info("started telemetry controller")
46+
}
3647

37-
/** Stop the Telemetry service. */
38-
fun stop() {
39-
if (telemetryController == null) {
40-
logger.info("already stopped")
41-
return
42-
}
43-
telemetryController?.shutdown()
44-
telemetryController = null
45-
logger.info("stopped")
48+
/** Stop the Telemetry service. */
49+
fun stop() {
50+
if (telemetryController == null) {
51+
logger.info("already stopped")
52+
return
4653
}
54+
telemetryController?.shutdown()
55+
telemetryController = null
56+
logger.info("stopped")
57+
}
4758

48-
/**
49-
* Un-register all Items.
50-
*
51-
* @throws IllegalStateException if TelemetryService is running.
52-
*/
53-
fun clear() {
54-
checkNotStarted()
55-
items.clear()
56-
logger.info("item set was cleared")
57-
}
59+
/**
60+
* Un-register all [Measurable] items.
61+
*
62+
* @throws IllegalStateException if TelemetryService is running.
63+
*/
64+
fun clear() {
65+
check(telemetryController == null) { "TelemetryService must be stopped to clear registered items." }
66+
items.clear()
67+
logger.info("item set was cleared")
68+
}
5869

59-
/**
60-
* Registers an Item for telemetry sending.
61-
*
62-
* @param item the Item to register for data collection
63-
* @throws IllegalStateException if TelemetryService is running.
64-
*/
65-
fun register(item: Measurable) {
66-
checkNotStarted()
67-
if (items.add(item)) {
68-
logger.info { "registered item ${item.description}" }
69-
return
70-
}
71-
logger.info { "item ${item.description} was already registered" }
70+
/**
71+
* Registers an Item for telemetry sending.
72+
*
73+
* @param item the [Measurable] to register for data collection
74+
* @throws IllegalStateException if TelemetryService is running.
75+
*/
76+
fun register(item: Measurable) {
77+
check(telemetryController == null) { "TelemetryService must be stopped to register an item." }
78+
if (items.add(item)) {
79+
logger.info { "registered item ${item.description}" }
80+
return
7281
}
82+
logger.info { "item ${item.description} was already registered" }
83+
}
7384

74-
/**
75-
* Register a collection for telemetry sending.
76-
*
77-
* @param collection the collection of Items to register for data collection
78-
* @throws IllegalStateException if TelemetryService is running.
79-
*/
80-
fun registerAll(collection: Collection<Measurable>) {
81-
checkNotStarted()
82-
items.addAll(collection)
83-
logger.info { "registered all: $collection" }
84-
}
85+
/**
86+
* Register a collection of [Measurable] items for telemetry sending.
87+
*
88+
* @param collection the collection of Items to register for data collection
89+
* @throws IllegalStateException if TelemetryService is running.
90+
*/
91+
fun registerAll(collection: Collection<Measurable>) = collection.forEach(this::register)
8592

86-
/**
87-
* Convenience method to register a `TalonSRX` for telemetry sending.
88-
*
89-
* @param talon the TalonSRX to register for data collection
90-
* @throws IllegalStateException if TelemetryService is running.
91-
*/
92-
fun register(talon: TalonSRX) {
93-
register(TalonItem(talon))
94-
}
93+
/**
94+
* Convenience method to register a `TalonSRX` for telemetry sending.
95+
*
96+
* @param talon the TalonSRX to register for data collection
97+
* @throws IllegalStateException if TelemetryService is running.
98+
*/
99+
fun register(talon: TalonSRX) {
100+
register(TalonItem(talon))
101+
}
95102

96-
/**
97-
* Convenience method to register a [SwerveDrive] for telemetry sending.
98-
*
99-
* @throws IllegalStateException if TelemetryService is running.
100-
*/
101-
fun register(swerveDrive: SwerveDrive) = swerveDrive.wheels.forEach {
102-
register(TalonItem(it.azimuthTalon))
103-
register(TalonItem(it.driveTalon))
104-
}
103+
/**
104+
* Convenience method to register a [SwerveDrive] for telemetry sending.
105+
*
106+
* @throws IllegalStateException if TelemetryService is running.
107+
*/
108+
fun register(swerveDrive: SwerveDrive) = swerveDrive.wheels.forEach {
109+
register(TalonItem(it.azimuthTalon))
110+
register(TalonItem(it.driveTalon))
111+
}
105112

106-
/**
107-
* Get an unmodifiable view of the registered items.
108-
*
109-
* @return an unmodifiable Set of Items.
110-
*/
111-
fun getItems(): Set<Measurable> {
112-
return Collections.unmodifiableSet(items)
113-
}
113+
/**
114+
* Get an unmodifiable view of the registered items.
115+
*
116+
* @return an unmodifiable Set of Items.
117+
*/
118+
fun getItems(): Set<Measurable> {
119+
return Collections.unmodifiableSet(items)
120+
}
114121

115-
/**
116-
* Unregister [item] from a stopped `TelemetryService`.
117-
*
118-
* @throws AssertionError if TelemetryService is running.
119-
*/
120-
fun remove(item: Measurable) {
121-
checkNotStarted()
122-
if (items.remove(item)) {
123-
logger.info { "removed $item" }
124-
return
125-
}
126-
throw AssertionError(item.toString())
122+
/**
123+
* Unregister a [Measurable] item. This service must be stopped first.
124+
*
125+
* @throws AssertionError if TelemetryService is running.
126+
*/
127+
fun remove(item: Measurable) {
128+
check(telemetryController == null) { "TelemetryService must be stopped to remove an item." }
129+
if (items.remove(item)) {
130+
logger.info { "removed $item" }
131+
return
127132
}
133+
throw AssertionError(item.toString())
134+
}
128135

129-
private fun checkNotStarted() {
130-
if (telemetryController != null) {
131-
throw IllegalStateException("TelemetryService must be stopped.")
132-
}
133-
}
134136
}

telemetry/src/main/kotlin/org/strykeforce/thirdcoast/telemetry/grapher/Measure.kt

Lines changed: 0 additions & 94 deletions
This file was deleted.

telemetry/src/main/kotlin/org/strykeforce/thirdcoast/telemetry/grapher/Subscription.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.squareup.moshi.Moshi
55
import mu.KotlinLogging
66
import okio.BufferedSink
77
import org.strykeforce.thirdcoast.telemetry.Inventory
8+
import org.strykeforce.thirdcoast.telemetry.item.Measure
89
import java.io.IOException
910
import java.util.*
1011
import java.util.function.DoubleSupplier
@@ -20,12 +21,7 @@ class Subscription(inventory: Inventory, val client: String, requestJson: String
2021
val request: RequestJson = RequestJson.fromJson(requestJson) ?: RequestJson.EMPTY
2122
request.subscription.forEach {
2223
val item = inventory.itemForId(it.itemId)
23-
val measure = try {
24-
Measure.valueOf(it.measurementId)
25-
} catch (e: IllegalArgumentException) {
26-
logger.error { "no such measure \"${it.measurementId}\", request JSON = \n$requestJson" }
27-
Measure.UNKNOWN
28-
}
24+
val measure = Measure(it.measurementId, it.measurementId)
2925
measurements += item.measurementFor(measure)
3026
descriptions += "${item.description}: ${measure.description}"
3127
}

0 commit comments

Comments
 (0)