55 "flag"
66 "fmt"
77 "log"
8+ "math"
89 "net/http"
910 "os"
1011 "strconv"
@@ -112,122 +113,94 @@ func main() {
112113 for _ , datum := range vehicleData .Data {
113114 fieldName := datum .Key .String () // Get the field name from the enum
114115 value := datum .Value
115- // Process each value type
116- switch v := value .Value .(type ) {
117- case * protos.Value_DoubleValue :
118- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (v .DoubleValue )
119- case * protos.Value_FloatValue :
120- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .FloatValue ))
121- case * protos.Value_IntValue :
122- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .IntValue ))
123- case * protos.Value_LongValue :
124- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .LongValue ))
125- case * protos.Value_BooleanValue :
126- var numericValue float64
127- if v .BooleanValue {
128- numericValue = 1.0
129- } else {
130- numericValue = 0.0
131- }
132- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (numericValue )
133- case * protos.Value_StringValue :
134- // Check if the string is "<invalid>"
135- if v .StringValue == "\u003c invalid\u003e " || v .StringValue == "<invalid>" {
136- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (0 )
137- log .Printf ("Received invalid string value for field %s" , fieldName )
138- } else {
139- // Try to parse the string value as a float64
140- floatVal , err := strconv .ParseFloat (v .StringValue , 64 )
141- if err == nil {
142- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (floatVal )
143- } else {
144- // Handle non-numeric string values
145- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (0 ) // Placeholder value
146- log .Printf ("Received non-numeric string value for field %s: %s" , fieldName , v .StringValue )
147- }
148- }
149- case * protos.Value_Invalid :
150- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (0 )
151- log .Printf ("Received invalid value for field %s" , fieldName )
152- case * protos.Value_LocationValue :
153- // Handle LocationValue separately
154- vehicleDataGauge .WithLabelValues ("Latitude" , vehicleData .Vin ).Set (v .LocationValue .Latitude )
155- vehicleDataGauge .WithLabelValues ("Longitude" , vehicleData .Vin ).Set (v .LocationValue .Longitude )
156- case * protos.Value_DoorValue :
157- // Handle Doors by setting individual door states
158- doors := v .DoorValue
159- doorFields := map [string ]bool {
160- "DriverFrontDoor" : doors .DriverFront ,
161- "PassengerFrontDoor" : doors .PassengerFront ,
162- "DriverRearDoor" : doors .DriverRear ,
163- "PassengerRearDoor" : doors .PassengerRear ,
164- "TrunkFront" : doors .TrunkFront ,
165- "TrunkRear" : doors .TrunkRear ,
166- }
167- for doorName , state := range doorFields {
168- var numericValue float64
169- if state {
170- numericValue = 1.0
171- } else {
172- numericValue = 0.0
173- }
174- vehicleDataGauge .WithLabelValues (doorName , vehicleData .Vin ).Set (numericValue )
175- }
176- case * protos.Value_TimeValue :
177- // Handle TimeValue by converting to seconds since midnight
178- timeValue := v .TimeValue
179- totalSeconds := float64 (timeValue .Hour * 3600 + timeValue .Minute * 60 + timeValue .Second )
180- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (totalSeconds )
181- // Handle all enum types
182- case * protos.Value_ChargingValue :
183- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ChargingValue .Number ()))
184- case * protos.Value_ShiftStateValue :
185- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ShiftStateValue .Number ()))
186- case * protos.Value_LaneAssistLevelValue :
187- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .LaneAssistLevelValue .Number ()))
188- case * protos.Value_ScheduledChargingModeValue :
189- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ScheduledChargingModeValue .Number ()))
190- case * protos.Value_SentryModeStateValue :
191- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .SentryModeStateValue .Number ()))
192- case * protos.Value_SpeedAssistLevelValue :
193- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .SpeedAssistLevelValue .Number ()))
194- case * protos.Value_BmsStateValue :
195- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .BmsStateValue .Number ()))
196- case * protos.Value_BuckleStatusValue :
197- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .BuckleStatusValue .Number ()))
198- case * protos.Value_CarTypeValue :
199- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .CarTypeValue .Number ()))
200- case * protos.Value_ChargePortValue :
201- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ChargePortValue .Number ()))
202- case * protos.Value_ChargePortLatchValue :
203- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ChargePortLatchValue .Number ()))
204- case * protos.Value_CruiseStateValue :
205- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .CruiseStateValue .Number ()))
206- case * protos.Value_DriveInverterStateValue :
207- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .DriveInverterStateValue .Number ()))
208- case * protos.Value_HvilStatusValue :
209- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .HvilStatusValue .Number ()))
210- case * protos.Value_WindowStateValue :
211- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .WindowStateValue .Number ()))
212- case * protos.Value_SeatFoldPositionValue :
213- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .SeatFoldPositionValue .Number ()))
214- case * protos.Value_TractorAirStatusValue :
215- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .TractorAirStatusValue .Number ()))
216- case * protos.Value_TrailerAirStatusValue :
217- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .TrailerAirStatusValue .Number ()))
218- case * protos.Value_FollowDistanceValue :
219- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .FollowDistanceValue .Number ()))
220- case * protos.Value_ForwardCollisionSensitivityValue :
221- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .ForwardCollisionSensitivityValue .Number ()))
222- case * protos.Value_GuestModeMobileAccessValue :
223- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .GuestModeMobileAccessValue .Number ()))
224- case * protos.Value_DetailedChargeStateValue :
225- vehicleDataGauge .WithLabelValues (fieldName , vehicleData .Vin ).Set (float64 (v .DetailedChargeStateValue .Number ()))
226- default :
227- // Log unhandled types
228- log .Printf ("Unhandled value type for field %s" , fieldName )
229- continue
230- }
116+ processValue (fieldName , value , vehicleDataGauge , vehicleData .Vin )
231117 }
232118 }
119+ }
120+
121+ func processValue (fieldName string , value * protos.Value , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
122+ // Process each value type
123+ switch v := value .Value .(type ) {
124+ case * protos.Value_DoubleValue :
125+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (v .DoubleValue )
126+ case * protos.Value_FloatValue :
127+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (float64 (v .FloatValue ))
128+ case * protos.Value_IntValue :
129+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (float64 (v .IntValue ))
130+ case * protos.Value_LongValue :
131+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (float64 (v .LongValue ))
132+ case * protos.Value_BooleanValue :
133+ handleBooleanValue (v .BooleanValue , fieldName , vehicleDataGauge , vin )
134+ case * protos.Value_StringValue :
135+ handleStringValue (v .StringValue , fieldName , vehicleDataGauge , vin )
136+ case * protos.Value_Invalid :
137+ log .Printf ("Invalid value received for field %s, setting as NaN" , fieldName )
138+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (math .NaN ())
139+ case * protos.Value_LocationValue :
140+ handleLocationValue (v .LocationValue , fieldName , vehicleDataGauge , vin )
141+ case * protos.Value_DoorValue :
142+ handleDoorValues (v .DoorValue , vehicleDataGauge , vin )
143+ case * protos.Value_TimeValue :
144+ handleTimeValue (v .TimeValue , fieldName , vehicleDataGauge , vin )
145+ default :
146+ log .Printf ("Unhandled value type for field %s" , fieldName )
147+ }
148+ }
149+
150+ func handleBooleanValue (booleanValue bool , fieldName string , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
151+ var numericValue float64
152+ if booleanValue {
153+ numericValue = 1.0
154+ } else {
155+ numericValue = 0.0
156+ }
157+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (numericValue )
158+ }
159+
160+ func handleStringValue (stringValue , fieldName string , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
161+ // Handle invalid string values more gracefully
162+ if stringValue == "<invalid>" || stringValue == "\u003c invalid\u003e " {
163+ log .Printf ("Invalid string value received for field %s, setting as NaN" , fieldName )
164+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (math .NaN ())
165+ return
166+ }
167+
168+ // Try to parse the string value as a float64
169+ floatVal , err := strconv .ParseFloat (stringValue , 64 )
170+ if err == nil {
171+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (floatVal )
172+ } else {
173+ log .Printf ("Non-numeric string value received for field %s: %s, setting as NaN" , fieldName , stringValue )
174+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (math .NaN ())
175+ }
176+ }
177+
178+ func handleLocationValue (locationValue * protos.LocationValue , fieldName string , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
179+ vehicleDataGauge .WithLabelValues ("Latitude" , vin ).Set (locationValue .Latitude )
180+ vehicleDataGauge .WithLabelValues ("Longitude" , vin ).Set (locationValue .Longitude )
181+ }
182+
183+ func handleDoorValues (doors * protos.Doors , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
184+ doorFields := map [string ]bool {
185+ "DriverFrontDoor" : doors .DriverFront ,
186+ "PassengerFrontDoor" : doors .PassengerFront ,
187+ "DriverRearDoor" : doors .DriverRear ,
188+ "PassengerRearDoor" : doors .PassengerRear ,
189+ "TrunkFront" : doors .TrunkFront ,
190+ "TrunkRear" : doors .TrunkRear ,
191+ }
192+ for doorName , state := range doorFields {
193+ var numericValue float64
194+ if state {
195+ numericValue = 1.0
196+ } else {
197+ numericValue = 0.0
198+ }
199+ vehicleDataGauge .WithLabelValues (doorName , vin ).Set (numericValue )
200+ }
201+ }
202+
203+ func handleTimeValue (timeValue * protos.Time , fieldName string , vehicleDataGauge * prometheus.GaugeVec , vin string ) {
204+ totalSeconds := float64 (timeValue .Hour * 3600 + timeValue .Minute * 60 + timeValue .Second )
205+ vehicleDataGauge .WithLabelValues (fieldName , vin ).Set (totalSeconds )
233206}
0 commit comments