Forza Horizon 5 telemetry to InfluxDB

This node setups a UDP server that Forza Horizon 5 Telemetry can connect to. From what I understand the telemetry in Forza Horizon 5 could not connect to the same IP-address as the game is running on. So if that is true, you'll have to run Node-Red on a different PC/server/IP-address than the game runs on. According to what I could find this should work on Forza Horizon 4 aswell, but I cannot confirm since I don't have Forza Horizon 4.

The game sends 60 messages per second, which could be overwhelming, therefore use the throttle node to limit the number of messages. Grafana is struggling with anything less than 150-200ms refresh rate.

In the parser node you could change the element name, that is used as field in InfluxDB, and scale them to fit the preferable unit.

Only tested on InfluxDB 1.x.

This is what it could look like in Grafana: image

[{"id":"16679a3dcc0f0177","type":"tab","label":"Forza","disabled":false,"info":"","env":[]},{"id":"3489eba8b6ea3f72","type":"udp in","z":"16679a3dcc0f0177","name":"Forza","iface":"","port":"1050","ipv":"udp4","multicast":"false","group":"","datatype":"buffer","x":130,"y":100,"wires":[["efa1fb6baaa3c43b"]]},{"id":"efa1fb6baaa3c43b","type":"buffer-parser","z":"16679a3dcc0f0177","name":"Forza parser","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"uint32le","name":"IsRaceOn","offset":0,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"EngineMaxRpm","offset":8,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"EngineIdleRpm","offset":12,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"CurrentEngineRpm","offset":16,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AccelerationX","offset":20,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AccelerationY","offset":24,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AccelerationZ","offset":28,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"VelocityX","offset":32,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"VelocityY","offset":36,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"VelocityZ","offset":40,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AngularVelocityX","offset":44,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AngularVelocityY","offset":48,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"AngularVelocityZ","offset":52,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Yaw","offset":56,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Pitch","offset":60,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Roll","offset":64,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"NormalizedSuspensionTravelFrontLeft","offset":68,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"NormalizedSuspensionTravelFrontRight","offset":72,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"NormalizedSuspensionTravelRearLeft","offset":76,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"NormalizedSuspensionTravelRearRight","offset":80,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipRatioFrontLeft","offset":84,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipRatioFrontRight","offset":88,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipRatioRearLeft","offset":92,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipRatioRearRight","offset":96,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelRotationSpeedFrontLeft","offset":100,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelRotationSpeedFrontRight","offset":104,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelRotationSpeedRearLeft","offset":108,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelRotationSpeedRearRight","offset":112,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelOnRumbleStripFrontLeft","offset":116,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelOnRumbleStripFrontRight","offset":120,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelOnRumbleStripRearLeft","offset":124,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelOnRumbleStripRearRight","offset":128,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelInPuddleDepthFrontLeft","offset":132,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelInPuddleDepthFrontRight","offset":136,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelInPuddleDepthRearLeft","offset":140,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"WheelInPuddleDepthRearRight","offset":144,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SurfaceRumbleFrontLeft","offset":148,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SurfaceRumbleFrontRight","offset":152,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SurfaceRumbleRearLeft","offset":156,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SurfaceRumbleRearRight","offset":160,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipAngleFrontLeft","offset":164,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipAngleFrontRight","offset":168,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipAngleRearLeft","offset":172,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireSlipAngleRearRight","offset":176,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireCombinedSlipFrontLeft","offset":180,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireCombinedSlipFrontRight","offset":184,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireCombinedSlipRearLeft","offset":188,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireCombinedSlipRearRight","offset":192,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SuspensionTravelMetersFrontLeft","offset":196,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SuspensionTravelMetersFrontRight","offset":200,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SuspensionTravelMetersRearLeft","offset":204,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"SuspensionTravelMetersRearRight","offset":208,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"CarOrdinal","offset":212,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"CarClass","offset":216,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"CarPerformanceIndex","offset":220,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"DrivetrainType","offset":224,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"NumCylinders","offset":228,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"PositionX","offset":244,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"PositionY","offset":248,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"PositionZ","offset":252,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Speed","offset":256,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Speed km/t","offset":256,"length":1,"offsetbit":0,"scale":"3.6","mask":""},{"type":"floatle","name":"Power","offset":260,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Torque","offset":264,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireTempFrontLeft","offset":268,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireTempFrontRight","offset":272,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireTempRearLeft","offset":276,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"TireTempRearRight","offset":280,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Boost","offset":284,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"Fuel","offset":288,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"DistanceTraveled","offset":292,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"BestLap","offset":296,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"LastLap","offset":300,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"CurrentLap","offset":304,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"floatle","name":"CurrentRaceTime","offset":308,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int16le","name":"LapNumber","offset":312,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"RacePosition","offset":314,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"Accel","offset":315,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"Brake","offset":316,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"Clutch","offset":317,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"HandBrake","offset":318,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"uint8","name":"Gear","offset":319,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int8","name":"Steer","offset":320,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int8","name":"NormalizedDrivingLine","offset":321,"length":1,"offsetbit":0,"scale":"1","mask":""},{"type":"int8","name":"NormalizedAIBrakeDifference","offset":322,"length":1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"keyvalue","resultTypeType":"output","multipleResult":false,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":330,"y":100,"wires":[["4fe8767cf540c1a4"]]},{"id":"f4cfb1e70481edd1","type":"influxdb out","z":"16679a3dcc0f0177","influxdb":"71105ad8b036bf76","name":"","measurement":"forza","precision":"","retentionPolicy":"","database":"database","precisionV18FluxV20":"ms","retentionPolicyV18Flux":"","org":"organisation","bucket":"bucket","x":740,"y":100,"wires":[]},{"id":"4fe8767cf540c1a4","type":"throttle","z":"16679a3dcc0f0177","name":"","throttleType":"time","timeLimit":"100","timeLimitType":"milliseconds","countLimit":0,"blockSize":0,"locked":false,"x":560,"y":100,"wires":[["f4cfb1e70481edd1"]]},{"id":"ca756d09424e693b","type":"comment","z":"16679a3dcc0f0177","name":"","info":"Forza sends 60 messages per second, so if you would like to have less messages use this node.\nGrafana have hard time with refresh rate quicker than 150-200ms, so messages with 16,67ms is perhaps not needed.","x":560,"y":60,"wires":[]},{"id":"71105ad8b036bf76","type":"influxdb","hostname":"127.0.0.1","port":"8086","protocol":"http","database":"forza","name":"forza","usetls":false,"tls":"","influxdbVersion":"1.x","url":"http://localhost:8086","rejectUnauthorized":true}]

Flow Info

Created 3 years, 9 months ago
Rating: 5 2

Owner

Actions

Rate:

Node Types

Core
  • comment (x1)
  • udp in (x1)
Other
  • buffer-parser (x1)
  • influxdb (x1)
  • influxdb out (x1)
  • tab (x1)
  • throttle (x1)

Tags

  • Forza Horizon 5
  • Forza
  • InfluxDB
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option