// generated by gen_skylab.go at 2023-06-27 20:32:07.43630691 -0500 CDT m=+0.003975675 DO NOT EDIT! package skylab import ( "errors" "encoding/binary" "encoding/json" ) type SkylabId uint32 const ( BmsMeasurementId SkylabId = 0x10 BatteryStatusId SkylabId = 0x11 BmsKillReasonId SkylabId = 0x12 BmsModuleMinMaxId SkylabId = 0x13 BmsSocId SkylabId = 0x14 BmsCapacityId SkylabId = 0x15 BmsCurrentlimitId SkylabId = 0x18 BmsFanInfoId SkylabId = 0x19 BmsSetMinFanSpeedId SkylabId = 0x1B BmsModuleId SkylabId = 0x1C BmsChargerResponseId SkylabId = 0x75 DashboardPedalPercentagesId SkylabId = 0x290 CarStateId SkylabId = 0x291 DashboardPedalFaultId SkylabId = 0x292 DashboardSystemTimeoutTestId SkylabId = 0x299 CarSpeedId SkylabId = 0x29A FlightComputerLvBoardDisconnectCountsId SkylabId = 0x29B FlightComputerHvBoardDisconnectCountsId SkylabId = 0x29C FlightComputerInternalStateId SkylabId = 0x29D PowerToDriveId SkylabId = 0x19E ArrayPowerId SkylabId = 0x19F VisionTurnSignalsCommandId SkylabId = 0x2B0 VisionBrakeLightsCommandId SkylabId = 0x2B1 VisionHeadlightsCommandId SkylabId = 0x2B2 VisionHornCommandId SkylabId = 0x2B3 VisionArrayLatchesCommandId SkylabId = 0x2B4 VisionRearviewCommandId SkylabId = 0x2B5 TrackerEnableId SkylabId = 0x610 DistanceTraveledId SkylabId = 0x200 ChargerStateId SkylabId = 0x573 ChargerBmsRequestId SkylabId = 0x74 ChargerCurrentVoltageId SkylabId = 0x576 ChargerPowerId SkylabId = 0x577 ThunderstruckControlMessageId SkylabId = 0x18E54024 VisionStatusFrontId SkylabId = 0x2B6 VisionStatusRearId SkylabId = 0x2B7 LightsFrontIdId SkylabId = 0x300 LightsBackIdId SkylabId = 0x301 VisionIdId SkylabId = 0x302 SteeringPressCount1Id SkylabId = 0x240 SteeringPressCount2Id SkylabId = 0x250 SteeringButtonColors1Id SkylabId = 0x241 SteeringButtonColors2Id SkylabId = 0x251 SteeringHornId SkylabId = 0x242 ThunderstruckStatusMessageId SkylabId = 0x18EB2440 TrackerDataId SkylabId = 0x600 TritiumMotorDriveId SkylabId = 0x121 TritiumMotorPowerId SkylabId = 0x122 TritiumResetId SkylabId = 0x123 BmsAhSetId SkylabId = 0x16 BmsWhSetId SkylabId = 0x17 BmsKillId SkylabId = 0x1A TelemetryRtcResetId SkylabId = 0x700 WsrIdentificationId SkylabId = 0x140 WsrStatusInformationId SkylabId = 0x141 WsrBusMeasurementId SkylabId = 0x142 WsrVelocityId SkylabId = 0x143 WsrPhaseCurrentId SkylabId = 0x144 WsrMotorVoltageVectorId SkylabId = 0x145 WsrMotorCurrentVectorId SkylabId = 0x146 WsrMotorBackemfId SkylabId = 0x147 Wsr15165VoltageRailId SkylabId = 0x148 Wsr2512VoltageRailId SkylabId = 0x149 WsrHeatsinkMotorTempId SkylabId = 0x14B WsrDspBoardTempId SkylabId = 0x14C WsrReservedId SkylabId = 0x14D WsrOdometerBusAmphoursMeasurementId SkylabId = 0x14E WsrSlipSpeedMeasurementId SkylabId = 0x157 WslIdentificationId SkylabId = 0x100 WslStatusInformationId SkylabId = 0x101 WslBusMeasurementId SkylabId = 0x102 WslVelocityId SkylabId = 0x103 WslPhaseCurrentId SkylabId = 0x104 WslMotorVoltageVectorId SkylabId = 0x105 WslMotorCurrentVectorId SkylabId = 0x106 WslMotorBackemfId SkylabId = 0x107 Wsl15165VoltageRailId SkylabId = 0x108 Wsl2512VoltageRailId SkylabId = 0x109 WslHeatsinkMotorTempId SkylabId = 0x10B WslDspBoardTempId SkylabId = 0x10C WslOdometerBusAmphoursMeasurementId SkylabId = 0x10E WslReservedId SkylabId = 0x10D WslSlipSpeedMeasurementId SkylabId = 0x117 ) // list of every packet ID. can be used for O(1) checks. var idMap = map[uint32]bool{ 0x10: true, 0x11: true, 0x12: true, 0x13: true, 0x14: true, 0x15: true, 0x18: true, 0x19: true, 0x1B: true, 0x1C: true, 0x1D: true, 0x1E: true, 0x1F: true, 0x20: true, 0x21: true, 0x22: true, 0x23: true, 0x24: true, 0x25: true, 0x26: true, 0x27: true, 0x28: true, 0x29: true, 0x2A: true, 0x2B: true, 0x2C: true, 0x2D: true, 0x2E: true, 0x2F: true, 0x30: true, 0x31: true, 0x32: true, 0x33: true, 0x34: true, 0x35: true, 0x36: true, 0x37: true, 0x38: true, 0x39: true, 0x3A: true, 0x3B: true, 0x3C: true, 0x3D: true, 0x3E: true, 0x3F: true, 0x75: true, 0x290: true, 0x291: true, 0x292: true, 0x299: true, 0x29A: true, 0x29B: true, 0x29C: true, 0x29D: true, 0x19E: true, 0x19F: true, 0x2B0: true, 0x2B1: true, 0x2B2: true, 0x2B3: true, 0x2B4: true, 0x2B5: true, 0x610: true, 0x611: true, 0x612: true, 0x613: true, 0x614: true, 0x615: true, 0x200: true, 0x573: true, 0x74: true, 0x576: true, 0x577: true, 0x18E54024: true, 0x2B6: true, 0x2B7: true, 0x300: true, 0x301: true, 0x302: true, 0x240: true, 0x250: true, 0x241: true, 0x251: true, 0x242: true, 0x18EB2440: true, 0x600: true, 0x601: true, 0x602: true, 0x603: true, 0x604: true, 0x605: true, 0x121: true, 0x122: true, 0x123: true, 0x16: true, 0x17: true, 0x1A: true, 0x700: true, 0x140: true, 0x141: true, 0x142: true, 0x143: true, 0x144: true, 0x145: true, 0x146: true, 0x147: true, 0x148: true, 0x149: true, 0x14B: true, 0x14C: true, 0x14D: true, 0x14E: true, 0x157: true, 0x100: true, 0x101: true, 0x102: true, 0x103: true, 0x104: true, 0x105: true, 0x106: true, 0x107: true, 0x108: true, 0x109: true, 0x10B: true, 0x10C: true, 0x10E: true, 0x10D: true, 0x117: true, } // FromCanFrame creates a Packet from a given CAN ID and data payload. // If the CAN ID is unknown, it will return an error. func FromCanFrame(id uint32, data []byte) (Packet, error) { if !idMap[id] { return nil, &UnknownIdError{ id } } switch id { case 0x10: var res = &BmsMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x11: var res = &BatteryStatus{} res.UnmarshalPacket(data) return res, nil case 0x12: var res = &BmsKillReason{} res.UnmarshalPacket(data) return res, nil case 0x13: var res = &BmsModuleMinMax{} res.UnmarshalPacket(data) return res, nil case 0x14: var res = &BmsSoc{} res.UnmarshalPacket(data) return res, nil case 0x15: var res = &BmsCapacity{} res.UnmarshalPacket(data) return res, nil case 0x18: var res = &BmsCurrentlimit{} res.UnmarshalPacket(data) return res, nil case 0x19: var res = &BmsFanInfo{} res.UnmarshalPacket(data) return res, nil case 0x1B: var res = &BmsSetMinFanSpeed{} res.UnmarshalPacket(data) return res, nil case 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F: var res = &BmsModule{} res.UnmarshalPacket(data) res.Idx = id - 0x1C return res, nil case 0x75: var res = &BmsChargerResponse{} res.UnmarshalPacket(data) return res, nil case 0x290: var res = &DashboardPedalPercentages{} res.UnmarshalPacket(data) return res, nil case 0x291: var res = &CarState{} res.UnmarshalPacket(data) return res, nil case 0x292: var res = &DashboardPedalFault{} res.UnmarshalPacket(data) return res, nil case 0x299: var res = &DashboardSystemTimeoutTest{} res.UnmarshalPacket(data) return res, nil case 0x29A: var res = &CarSpeed{} res.UnmarshalPacket(data) return res, nil case 0x29B: var res = &FlightComputerLvBoardDisconnectCounts{} res.UnmarshalPacket(data) return res, nil case 0x29C: var res = &FlightComputerHvBoardDisconnectCounts{} res.UnmarshalPacket(data) return res, nil case 0x29D: var res = &FlightComputerInternalState{} res.UnmarshalPacket(data) return res, nil case 0x19E: var res = &PowerToDrive{} res.UnmarshalPacket(data) return res, nil case 0x19F: var res = &ArrayPower{} res.UnmarshalPacket(data) return res, nil case 0x2B0: var res = &VisionTurnSignalsCommand{} res.UnmarshalPacket(data) return res, nil case 0x2B1: var res = &VisionBrakeLightsCommand{} res.UnmarshalPacket(data) return res, nil case 0x2B2: var res = &VisionHeadlightsCommand{} res.UnmarshalPacket(data) return res, nil case 0x2B3: var res = &VisionHornCommand{} res.UnmarshalPacket(data) return res, nil case 0x2B4: var res = &VisionArrayLatchesCommand{} res.UnmarshalPacket(data) return res, nil case 0x2B5: var res = &VisionRearviewCommand{} res.UnmarshalPacket(data) return res, nil case 0x610, 0x611, 0x612, 0x613, 0x614, 0x615: var res = &TrackerEnable{} res.UnmarshalPacket(data) res.Idx = id - 0x610 return res, nil case 0x200: var res = &DistanceTraveled{} res.UnmarshalPacket(data) return res, nil case 0x573: var res = &ChargerState{} res.UnmarshalPacket(data) return res, nil case 0x74: var res = &ChargerBmsRequest{} res.UnmarshalPacket(data) return res, nil case 0x576: var res = &ChargerCurrentVoltage{} res.UnmarshalPacket(data) return res, nil case 0x577: var res = &ChargerPower{} res.UnmarshalPacket(data) return res, nil case 0x18E54024: var res = &ThunderstruckControlMessage{} res.UnmarshalPacket(data) return res, nil case 0x2B6: var res = &VisionStatusFront{} res.UnmarshalPacket(data) return res, nil case 0x2B7: var res = &VisionStatusRear{} res.UnmarshalPacket(data) return res, nil case 0x300: var res = &LightsFrontId{} res.UnmarshalPacket(data) return res, nil case 0x301: var res = &LightsBackId{} res.UnmarshalPacket(data) return res, nil case 0x302: var res = &VisionId{} res.UnmarshalPacket(data) return res, nil case 0x240: var res = &SteeringPressCount1{} res.UnmarshalPacket(data) return res, nil case 0x250: var res = &SteeringPressCount2{} res.UnmarshalPacket(data) return res, nil case 0x241: var res = &SteeringButtonColors1{} res.UnmarshalPacket(data) return res, nil case 0x251: var res = &SteeringButtonColors2{} res.UnmarshalPacket(data) return res, nil case 0x242: var res = &SteeringHorn{} res.UnmarshalPacket(data) return res, nil case 0x18EB2440: var res = &ThunderstruckStatusMessage{} res.UnmarshalPacket(data) return res, nil case 0x600, 0x601, 0x602, 0x603, 0x604, 0x605: var res = &TrackerData{} res.UnmarshalPacket(data) res.Idx = id - 0x600 return res, nil case 0x121: var res = &TritiumMotorDrive{} res.UnmarshalPacket(data) return res, nil case 0x122: var res = &TritiumMotorPower{} res.UnmarshalPacket(data) return res, nil case 0x123: var res = &TritiumReset{} res.UnmarshalPacket(data) return res, nil case 0x16: var res = &BmsAhSet{} res.UnmarshalPacket(data) return res, nil case 0x17: var res = &BmsWhSet{} res.UnmarshalPacket(data) return res, nil case 0x1A: var res = &BmsKill{} res.UnmarshalPacket(data) return res, nil case 0x700: var res = &TelemetryRtcReset{} res.UnmarshalPacket(data) return res, nil case 0x140: var res = &WsrIdentification{} res.UnmarshalPacket(data) return res, nil case 0x141: var res = &WsrStatusInformation{} res.UnmarshalPacket(data) return res, nil case 0x142: var res = &WsrBusMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x143: var res = &WsrVelocity{} res.UnmarshalPacket(data) return res, nil case 0x144: var res = &WsrPhaseCurrent{} res.UnmarshalPacket(data) return res, nil case 0x145: var res = &WsrMotorVoltageVector{} res.UnmarshalPacket(data) return res, nil case 0x146: var res = &WsrMotorCurrentVector{} res.UnmarshalPacket(data) return res, nil case 0x147: var res = &WsrMotorBackemf{} res.UnmarshalPacket(data) return res, nil case 0x148: var res = &Wsr15165VoltageRail{} res.UnmarshalPacket(data) return res, nil case 0x149: var res = &Wsr2512VoltageRail{} res.UnmarshalPacket(data) return res, nil case 0x14B: var res = &WsrHeatsinkMotorTemp{} res.UnmarshalPacket(data) return res, nil case 0x14C: var res = &WsrDspBoardTemp{} res.UnmarshalPacket(data) return res, nil case 0x14D: var res = &WsrReserved{} res.UnmarshalPacket(data) return res, nil case 0x14E: var res = &WsrOdometerBusAmphoursMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x157: var res = &WsrSlipSpeedMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x100: var res = &WslIdentification{} res.UnmarshalPacket(data) return res, nil case 0x101: var res = &WslStatusInformation{} res.UnmarshalPacket(data) return res, nil case 0x102: var res = &WslBusMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x103: var res = &WslVelocity{} res.UnmarshalPacket(data) return res, nil case 0x104: var res = &WslPhaseCurrent{} res.UnmarshalPacket(data) return res, nil case 0x105: var res = &WslMotorVoltageVector{} res.UnmarshalPacket(data) return res, nil case 0x106: var res = &WslMotorCurrentVector{} res.UnmarshalPacket(data) return res, nil case 0x107: var res = &WslMotorBackemf{} res.UnmarshalPacket(data) return res, nil case 0x108: var res = &Wsl15165VoltageRail{} res.UnmarshalPacket(data) return res, nil case 0x109: var res = &Wsl2512VoltageRail{} res.UnmarshalPacket(data) return res, nil case 0x10B: var res = &WslHeatsinkMotorTemp{} res.UnmarshalPacket(data) return res, nil case 0x10C: var res = &WslDspBoardTemp{} res.UnmarshalPacket(data) return res, nil case 0x10E: var res = &WslOdometerBusAmphoursMeasurement{} res.UnmarshalPacket(data) return res, nil case 0x10D: var res = &WslReserved{} res.UnmarshalPacket(data) return res, nil case 0x117: var res = &WslSlipSpeedMeasurement{} res.UnmarshalPacket(data) return res, nil } return nil, errors.New("failed to match Id, something is really wrong") } func FromJson (id uint32, raw []byte) (Packet, error) { if !idMap[id] { return nil, errors.New("unknown id") } switch id { case 0x10: var res = &BmsMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x11: var res = &BatteryStatus{} err := json.Unmarshal(raw, res) return res, err case 0x12: var res = &BmsKillReason{} err := json.Unmarshal(raw, res) return res, err case 0x13: var res = &BmsModuleMinMax{} err := json.Unmarshal(raw, res) return res, err case 0x14: var res = &BmsSoc{} err := json.Unmarshal(raw, res) return res, err case 0x15: var res = &BmsCapacity{} err := json.Unmarshal(raw, res) return res, err case 0x18: var res = &BmsCurrentlimit{} err := json.Unmarshal(raw, res) return res, err case 0x19: var res = &BmsFanInfo{} err := json.Unmarshal(raw, res) return res, err case 0x1B: var res = &BmsSetMinFanSpeed{} err := json.Unmarshal(raw, res) return res, err case 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F: var res = &BmsModule{} err := json.Unmarshal(raw, res) res.Idx = id - 0x1C return res, err case 0x75: var res = &BmsChargerResponse{} err := json.Unmarshal(raw, res) return res, err case 0x290: var res = &DashboardPedalPercentages{} err := json.Unmarshal(raw, res) return res, err case 0x291: var res = &CarState{} err := json.Unmarshal(raw, res) return res, err case 0x292: var res = &DashboardPedalFault{} err := json.Unmarshal(raw, res) return res, err case 0x299: var res = &DashboardSystemTimeoutTest{} err := json.Unmarshal(raw, res) return res, err case 0x29A: var res = &CarSpeed{} err := json.Unmarshal(raw, res) return res, err case 0x29B: var res = &FlightComputerLvBoardDisconnectCounts{} err := json.Unmarshal(raw, res) return res, err case 0x29C: var res = &FlightComputerHvBoardDisconnectCounts{} err := json.Unmarshal(raw, res) return res, err case 0x29D: var res = &FlightComputerInternalState{} err := json.Unmarshal(raw, res) return res, err case 0x19E: var res = &PowerToDrive{} err := json.Unmarshal(raw, res) return res, err case 0x19F: var res = &ArrayPower{} err := json.Unmarshal(raw, res) return res, err case 0x2B0: var res = &VisionTurnSignalsCommand{} err := json.Unmarshal(raw, res) return res, err case 0x2B1: var res = &VisionBrakeLightsCommand{} err := json.Unmarshal(raw, res) return res, err case 0x2B2: var res = &VisionHeadlightsCommand{} err := json.Unmarshal(raw, res) return res, err case 0x2B3: var res = &VisionHornCommand{} err := json.Unmarshal(raw, res) return res, err case 0x2B4: var res = &VisionArrayLatchesCommand{} err := json.Unmarshal(raw, res) return res, err case 0x2B5: var res = &VisionRearviewCommand{} err := json.Unmarshal(raw, res) return res, err case 0x610, 0x611, 0x612, 0x613, 0x614, 0x615: var res = &TrackerEnable{} err := json.Unmarshal(raw, res) res.Idx = id - 0x610 return res, err case 0x200: var res = &DistanceTraveled{} err := json.Unmarshal(raw, res) return res, err case 0x573: var res = &ChargerState{} err := json.Unmarshal(raw, res) return res, err case 0x74: var res = &ChargerBmsRequest{} err := json.Unmarshal(raw, res) return res, err case 0x576: var res = &ChargerCurrentVoltage{} err := json.Unmarshal(raw, res) return res, err case 0x577: var res = &ChargerPower{} err := json.Unmarshal(raw, res) return res, err case 0x18E54024: var res = &ThunderstruckControlMessage{} err := json.Unmarshal(raw, res) return res, err case 0x2B6: var res = &VisionStatusFront{} err := json.Unmarshal(raw, res) return res, err case 0x2B7: var res = &VisionStatusRear{} err := json.Unmarshal(raw, res) return res, err case 0x300: var res = &LightsFrontId{} err := json.Unmarshal(raw, res) return res, err case 0x301: var res = &LightsBackId{} err := json.Unmarshal(raw, res) return res, err case 0x302: var res = &VisionId{} err := json.Unmarshal(raw, res) return res, err case 0x240: var res = &SteeringPressCount1{} err := json.Unmarshal(raw, res) return res, err case 0x250: var res = &SteeringPressCount2{} err := json.Unmarshal(raw, res) return res, err case 0x241: var res = &SteeringButtonColors1{} err := json.Unmarshal(raw, res) return res, err case 0x251: var res = &SteeringButtonColors2{} err := json.Unmarshal(raw, res) return res, err case 0x242: var res = &SteeringHorn{} err := json.Unmarshal(raw, res) return res, err case 0x18EB2440: var res = &ThunderstruckStatusMessage{} err := json.Unmarshal(raw, res) return res, err case 0x600, 0x601, 0x602, 0x603, 0x604, 0x605: var res = &TrackerData{} err := json.Unmarshal(raw, res) res.Idx = id - 0x600 return res, err case 0x121: var res = &TritiumMotorDrive{} err := json.Unmarshal(raw, res) return res, err case 0x122: var res = &TritiumMotorPower{} err := json.Unmarshal(raw, res) return res, err case 0x123: var res = &TritiumReset{} err := json.Unmarshal(raw, res) return res, err case 0x16: var res = &BmsAhSet{} err := json.Unmarshal(raw, res) return res, err case 0x17: var res = &BmsWhSet{} err := json.Unmarshal(raw, res) return res, err case 0x1A: var res = &BmsKill{} err := json.Unmarshal(raw, res) return res, err case 0x700: var res = &TelemetryRtcReset{} err := json.Unmarshal(raw, res) return res, err case 0x140: var res = &WsrIdentification{} err := json.Unmarshal(raw, res) return res, err case 0x141: var res = &WsrStatusInformation{} err := json.Unmarshal(raw, res) return res, err case 0x142: var res = &WsrBusMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x143: var res = &WsrVelocity{} err := json.Unmarshal(raw, res) return res, err case 0x144: var res = &WsrPhaseCurrent{} err := json.Unmarshal(raw, res) return res, err case 0x145: var res = &WsrMotorVoltageVector{} err := json.Unmarshal(raw, res) return res, err case 0x146: var res = &WsrMotorCurrentVector{} err := json.Unmarshal(raw, res) return res, err case 0x147: var res = &WsrMotorBackemf{} err := json.Unmarshal(raw, res) return res, err case 0x148: var res = &Wsr15165VoltageRail{} err := json.Unmarshal(raw, res) return res, err case 0x149: var res = &Wsr2512VoltageRail{} err := json.Unmarshal(raw, res) return res, err case 0x14B: var res = &WsrHeatsinkMotorTemp{} err := json.Unmarshal(raw, res) return res, err case 0x14C: var res = &WsrDspBoardTemp{} err := json.Unmarshal(raw, res) return res, err case 0x14D: var res = &WsrReserved{} err := json.Unmarshal(raw, res) return res, err case 0x14E: var res = &WsrOdometerBusAmphoursMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x157: var res = &WsrSlipSpeedMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x100: var res = &WslIdentification{} err := json.Unmarshal(raw, res) return res, err case 0x101: var res = &WslStatusInformation{} err := json.Unmarshal(raw, res) return res, err case 0x102: var res = &WslBusMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x103: var res = &WslVelocity{} err := json.Unmarshal(raw, res) return res, err case 0x104: var res = &WslPhaseCurrent{} err := json.Unmarshal(raw, res) return res, err case 0x105: var res = &WslMotorVoltageVector{} err := json.Unmarshal(raw, res) return res, err case 0x106: var res = &WslMotorCurrentVector{} err := json.Unmarshal(raw, res) return res, err case 0x107: var res = &WslMotorBackemf{} err := json.Unmarshal(raw, res) return res, err case 0x108: var res = &Wsl15165VoltageRail{} err := json.Unmarshal(raw, res) return res, err case 0x109: var res = &Wsl2512VoltageRail{} err := json.Unmarshal(raw, res) return res, err case 0x10B: var res = &WslHeatsinkMotorTemp{} err := json.Unmarshal(raw, res) return res, err case 0x10C: var res = &WslDspBoardTemp{} err := json.Unmarshal(raw, res) return res, err case 0x10E: var res = &WslOdometerBusAmphoursMeasurement{} err := json.Unmarshal(raw, res) return res, err case 0x10D: var res = &WslReserved{} err := json.Unmarshal(raw, res) return res, err case 0x117: var res = &WslSlipSpeedMeasurement{} err := json.Unmarshal(raw, res) return res, err } return nil, errors.New("failed to match id") } // BmsMeasurement is Voltages for main battery and aux pack type BmsMeasurement struct { // 0.01 V BatteryVoltage uint16 `json:"battery_voltage"` // 0.001 V AuxVoltage uint16 `json:"aux_voltage"` // 1 A Current float32 `json:"current"` } func (p *BmsMeasurement) CANId() (uint32, error) { return 0x10, nil } func (p *BmsMeasurement) Size() uint { return 8 } func (p *BmsMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.BatteryVoltage) binary.LittleEndian.PutUint16(b[2:], p.AuxVoltage) float32ToBytes(b[4:], p.Current, false) return b, nil } func (p *BmsMeasurement) UnmarshalPacket(b []byte) error { p.BatteryVoltage = binary.LittleEndian.Uint16(b[0:]) p.AuxVoltage = binary.LittleEndian.Uint16(b[2:]) p.Current = float32FromBytes(b[4:], false) return nil } func (p *BmsMeasurement) String() string { return "bms_measurement" } type BatteryStatusBatteryState struct { Startup bool `json:"startup"` Precharge bool `json:"precharge"` Discharging bool `json:"discharging"` LvOnly bool `json:"lv_only"` Charging bool `json:"charging"` WallCharging bool `json:"wall_charging"` Killed bool `json:"killed"` } func (p *BatteryStatusBatteryState) MarshalByte() byte { var b byte if p.Startup { b |= 1 << 0 } if p.Precharge { b |= 1 << 1 } if p.Discharging { b |= 1 << 2 } if p.LvOnly { b |= 1 << 3 } if p.Charging { b |= 1 << 4 } if p.WallCharging { b |= 1 << 5 } if p.Killed { b |= 1 << 6 } return b } func (p *BatteryStatusBatteryState) UnmarshalByte(b byte) { p.Startup = (b & (1 << 0)) != 0 p.Precharge = (b & (1 << 1)) != 0 p.Discharging = (b & (1 << 2)) != 0 p.LvOnly = (b & (1 << 3)) != 0 p.Charging = (b & (1 << 4)) != 0 p.WallCharging = (b & (1 << 5)) != 0 p.Killed = (b & (1 << 6)) != 0 } type BatteryStatusContactorState struct { BatteryHighContactor bool `json:"battery_high_contactor"` BatteryLowContactor bool `json:"battery_low_contactor"` BatteryVicorContactor bool `json:"battery_vicor_contactor"` BatteryPreContactor bool `json:"battery_pre_contactor"` BatteryHigh2Contactor bool `json:"battery_high2_contactor"` BatteryLow2Contactor bool `json:"battery_low2_contactor"` ChargerHighContactor bool `json:"charger_high_contactor"` ChargerPreContactor bool `json:"charger_pre_contactor"` } func (p *BatteryStatusContactorState) MarshalByte() byte { var b byte if p.BatteryHighContactor { b |= 1 << 0 } if p.BatteryLowContactor { b |= 1 << 1 } if p.BatteryVicorContactor { b |= 1 << 2 } if p.BatteryPreContactor { b |= 1 << 3 } if p.BatteryHigh2Contactor { b |= 1 << 4 } if p.BatteryLow2Contactor { b |= 1 << 5 } if p.ChargerHighContactor { b |= 1 << 6 } if p.ChargerPreContactor { b |= 1 << 7 } return b } func (p *BatteryStatusContactorState) UnmarshalByte(b byte) { p.BatteryHighContactor = (b & (1 << 0)) != 0 p.BatteryLowContactor = (b & (1 << 1)) != 0 p.BatteryVicorContactor = (b & (1 << 2)) != 0 p.BatteryPreContactor = (b & (1 << 3)) != 0 p.BatteryHigh2Contactor = (b & (1 << 4)) != 0 p.BatteryLow2Contactor = (b & (1 << 5)) != 0 p.ChargerHighContactor = (b & (1 << 6)) != 0 p.ChargerPreContactor = (b & (1 << 7)) != 0 } type BatteryStatusLvChannelStatus struct { AuxFault bool `json:"aux_fault"` MainFault bool `json:"main_fault"` AuxPowerValid bool `json:"aux_power_valid"` MainPowerValid bool `json:"main_power_valid"` AuxPowerActive bool `json:"aux_power_active"` MainPowerActive bool `json:"main_power_active"` } func (p *BatteryStatusLvChannelStatus) MarshalByte() byte { var b byte if p.AuxFault { b |= 1 << 0 } if p.MainFault { b |= 1 << 1 } if p.AuxPowerValid { b |= 1 << 2 } if p.MainPowerValid { b |= 1 << 3 } if p.AuxPowerActive { b |= 1 << 4 } if p.MainPowerActive { b |= 1 << 5 } return b } func (p *BatteryStatusLvChannelStatus) UnmarshalByte(b byte) { p.AuxFault = (b & (1 << 0)) != 0 p.MainFault = (b & (1 << 1)) != 0 p.AuxPowerValid = (b & (1 << 2)) != 0 p.MainPowerValid = (b & (1 << 3)) != 0 p.AuxPowerActive = (b & (1 << 4)) != 0 p.MainPowerActive = (b & (1 << 5)) != 0 } type BatteryStatusLvControlStatus struct { AuxVicorEnable bool `json:"aux_vicor_enable"` BatVicorEnable bool `json:"bat_vicor_enable"` AuxRelayHeld bool `json:"aux_relay_held"` AuxRefEnable bool `json:"aux_ref_enable"` AuxChargingEnable bool `json:"aux_charging_enable"` KillHv bool `json:"kill_hv"` KillLv bool `json:"kill_lv"` StartButton bool `json:"start_button"` } func (p *BatteryStatusLvControlStatus) MarshalByte() byte { var b byte if p.AuxVicorEnable { b |= 1 << 0 } if p.BatVicorEnable { b |= 1 << 1 } if p.AuxRelayHeld { b |= 1 << 2 } if p.AuxRefEnable { b |= 1 << 3 } if p.AuxChargingEnable { b |= 1 << 4 } if p.KillHv { b |= 1 << 5 } if p.KillLv { b |= 1 << 6 } if p.StartButton { b |= 1 << 7 } return b } func (p *BatteryStatusLvControlStatus) UnmarshalByte(b byte) { p.AuxVicorEnable = (b & (1 << 0)) != 0 p.BatVicorEnable = (b & (1 << 1)) != 0 p.AuxRelayHeld = (b & (1 << 2)) != 0 p.AuxRefEnable = (b & (1 << 3)) != 0 p.AuxChargingEnable = (b & (1 << 4)) != 0 p.KillHv = (b & (1 << 5)) != 0 p.KillLv = (b & (1 << 6)) != 0 p.StartButton = (b & (1 << 7)) != 0 } // BatteryStatus is Status bits for the battery type BatteryStatus struct { BatteryState BatteryStatusBatteryState `json:"battery_state"` ContactorState BatteryStatusContactorState `json:"contactor_state"` LvChannelStatus BatteryStatusLvChannelStatus `json:"lv_channel_status"` LvControlStatus BatteryStatusLvControlStatus `json:"lv_control_status"` } func (p *BatteryStatus) CANId() (uint32, error) { return 0x11, nil } func (p *BatteryStatus) Size() uint { return 4 } func (p *BatteryStatus) MarshalPacket() ([]byte, error) { b := make([]byte, 4) b[0] = p.BatteryState.MarshalByte() b[1] = p.ContactorState.MarshalByte() b[2] = p.LvChannelStatus.MarshalByte() b[3] = p.LvControlStatus.MarshalByte() return b, nil } func (p *BatteryStatus) UnmarshalPacket(b []byte) error { p.BatteryState.UnmarshalByte(b[0]) p.ContactorState.UnmarshalByte(b[1]) p.LvChannelStatus.UnmarshalByte(b[2]) p.LvControlStatus.UnmarshalByte(b[3]) return nil } func (p *BatteryStatus) String() string { return "battery_status" } type BmsKillReasonReason1 struct { OVERVOLT bool `json:"OVERVOLT"` UNDERVOLT bool `json:"UNDERVOLT"` OVERTEMP bool `json:"OVERTEMP"` TEMPDISCONNECT bool `json:"TEMP_DISCONNECT"` COMMFAIL bool `json:"COMM_FAIL"` } func (p *BmsKillReasonReason1) MarshalByte() byte { var b byte if p.OVERVOLT { b |= 1 << 0 } if p.UNDERVOLT { b |= 1 << 1 } if p.OVERTEMP { b |= 1 << 2 } if p.TEMPDISCONNECT { b |= 1 << 3 } if p.COMMFAIL { b |= 1 << 4 } return b } func (p *BmsKillReasonReason1) UnmarshalByte(b byte) { p.OVERVOLT = (b & (1 << 0)) != 0 p.UNDERVOLT = (b & (1 << 1)) != 0 p.OVERTEMP = (b & (1 << 2)) != 0 p.TEMPDISCONNECT = (b & (1 << 3)) != 0 p.COMMFAIL = (b & (1 << 4)) != 0 } type BmsKillReasonReason2 struct { HARDWARE bool `json:"HARDWARE"` KILLPACKET bool `json:"KILL_PACKET"` UKNOWN bool `json:"UKNOWN"` OVERCURRENT bool `json:"OVERCURRENT"` PRECHARGEFAIL bool `json:"PRECHARGE_FAIL"` AUXOVERUNDER bool `json:"AUX_OVER_UNDER"` } func (p *BmsKillReasonReason2) MarshalByte() byte { var b byte if p.HARDWARE { b |= 1 << 0 } if p.KILLPACKET { b |= 1 << 1 } if p.UKNOWN { b |= 1 << 2 } if p.OVERCURRENT { b |= 1 << 3 } if p.PRECHARGEFAIL { b |= 1 << 4 } if p.AUXOVERUNDER { b |= 1 << 5 } return b } func (p *BmsKillReasonReason2) UnmarshalByte(b byte) { p.HARDWARE = (b & (1 << 0)) != 0 p.KILLPACKET = (b & (1 << 1)) != 0 p.UKNOWN = (b & (1 << 2)) != 0 p.OVERCURRENT = (b & (1 << 3)) != 0 p.PRECHARGEFAIL = (b & (1 << 4)) != 0 p.AUXOVERUNDER = (b & (1 << 5)) != 0 } // BmsKillReason is Information for when the car kills type BmsKillReason struct { Reason1 BmsKillReasonReason1 `json:"reason1"` Reason2 BmsKillReasonReason2 `json:"reason2"` Module uint16 `json:"module"` Value float32 `json:"value"` } func (p *BmsKillReason) CANId() (uint32, error) { return 0x12, nil } func (p *BmsKillReason) Size() uint { return 8 } func (p *BmsKillReason) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.Reason1.MarshalByte() b[1] = p.Reason2.MarshalByte() binary.LittleEndian.PutUint16(b[2:], p.Module) float32ToBytes(b[4:], p.Value, false) return b, nil } func (p *BmsKillReason) UnmarshalPacket(b []byte) error { p.Reason1.UnmarshalByte(b[0]) p.Reason2.UnmarshalByte(b[1]) p.Module = binary.LittleEndian.Uint16(b[2:]) p.Value = float32FromBytes(b[4:], false) return nil } func (p *BmsKillReason) String() string { return "bms_kill_reason" } // BmsModuleMinMax is min and max cell voltages and temperatures type BmsModuleMinMax struct { // 0.01 C ModuleMaxTemp int16 `json:"module_max_temp"` // 0.01 C ModuleMinTemp int16 `json:"module_min_temp"` // 0.001 V ModuleMaxVoltage uint16 `json:"module_max_voltage"` // 0.001 V ModuleMinVoltage uint16 `json:"module_min_voltage"` } func (p *BmsModuleMinMax) CANId() (uint32, error) { return 0x13, nil } func (p *BmsModuleMinMax) Size() uint { return 8 } func (p *BmsModuleMinMax) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], uint16(p.ModuleMaxTemp)) binary.LittleEndian.PutUint16(b[2:], uint16(p.ModuleMinTemp)) binary.LittleEndian.PutUint16(b[4:], p.ModuleMaxVoltage) binary.LittleEndian.PutUint16(b[6:], p.ModuleMinVoltage) return b, nil } func (p *BmsModuleMinMax) UnmarshalPacket(b []byte) error { p.ModuleMaxTemp = int16(binary.LittleEndian.Uint16(b[0:])) p.ModuleMinTemp = int16(binary.LittleEndian.Uint16(b[2:])) p.ModuleMaxVoltage = binary.LittleEndian.Uint16(b[4:]) p.ModuleMinVoltage = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *BmsModuleMinMax) String() string { return "bms_module_min_max" } // BmsSoc is State of charge type BmsSoc struct { Soc float32 `json:"soc"` } func (p *BmsSoc) CANId() (uint32, error) { return 0x14, nil } func (p *BmsSoc) Size() uint { return 4 } func (p *BmsSoc) MarshalPacket() ([]byte, error) { b := make([]byte, 4) float32ToBytes(b[0:], p.Soc, false) return b, nil } func (p *BmsSoc) UnmarshalPacket(b []byte) error { p.Soc = float32FromBytes(b[0:], false) return nil } func (p *BmsSoc) String() string { return "bms_soc" } // BmsCapacity is State of charge type BmsCapacity struct { Ah float32 `json:"Ah"` Wh float32 `json:"Wh"` } func (p *BmsCapacity) CANId() (uint32, error) { return 0x15, nil } func (p *BmsCapacity) Size() uint { return 8 } func (p *BmsCapacity) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Ah, false) float32ToBytes(b[4:], p.Wh, false) return b, nil } func (p *BmsCapacity) UnmarshalPacket(b []byte) error { p.Ah = float32FromBytes(b[0:], false) p.Wh = float32FromBytes(b[4:], false) return nil } func (p *BmsCapacity) String() string { return "bms_capacity" } // BmsCurrentlimit is reports BP params for current type BmsCurrentlimit struct { // 0.01 A CurrentMax int16 `json:"current_max"` // 0.01 A CurrentMin int16 `json:"current_min"` } func (p *BmsCurrentlimit) CANId() (uint32, error) { return 0x18, nil } func (p *BmsCurrentlimit) Size() uint { return 4 } func (p *BmsCurrentlimit) MarshalPacket() ([]byte, error) { b := make([]byte, 4) binary.LittleEndian.PutUint16(b[0:], uint16(p.CurrentMax)) binary.LittleEndian.PutUint16(b[2:], uint16(p.CurrentMin)) return b, nil } func (p *BmsCurrentlimit) UnmarshalPacket(b []byte) error { p.CurrentMax = int16(binary.LittleEndian.Uint16(b[0:])) p.CurrentMin = int16(binary.LittleEndian.Uint16(b[2:])) return nil } func (p *BmsCurrentlimit) String() string { return "bms_currentlimit" } // BmsFanInfo is BP Fans type BmsFanInfo struct { // 1 RPM Fan1 uint16 `json:"fan1"` // 1 RPM Fan2 uint16 `json:"fan2"` // 1 RPM Fan3 uint16 `json:"fan3"` // 1 RPM Fan4 uint16 `json:"fan4"` } func (p *BmsFanInfo) CANId() (uint32, error) { return 0x19, nil } func (p *BmsFanInfo) Size() uint { return 8 } func (p *BmsFanInfo) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.Fan1) binary.LittleEndian.PutUint16(b[2:], p.Fan2) binary.LittleEndian.PutUint16(b[4:], p.Fan3) binary.LittleEndian.PutUint16(b[6:], p.Fan4) return b, nil } func (p *BmsFanInfo) UnmarshalPacket(b []byte) error { p.Fan1 = binary.LittleEndian.Uint16(b[0:]) p.Fan2 = binary.LittleEndian.Uint16(b[2:]) p.Fan3 = binary.LittleEndian.Uint16(b[4:]) p.Fan4 = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *BmsFanInfo) String() string { return "bms_fan_info" } // BmsSetMinFanSpeed is packet which sets a minimum fan speed of BMS for a specific time frame in seconds type BmsSetMinFanSpeed struct { // 0 percent FanPercentage float32 `json:"fan_percentage"` // 0 s Time uint16 `json:"time"` } func (p *BmsSetMinFanSpeed) CANId() (uint32, error) { return 0x1B, nil } func (p *BmsSetMinFanSpeed) Size() uint { return 6 } func (p *BmsSetMinFanSpeed) MarshalPacket() ([]byte, error) { b := make([]byte, 6) float32ToBytes(b[0:], p.FanPercentage, false) binary.LittleEndian.PutUint16(b[4:], p.Time) return b, nil } func (p *BmsSetMinFanSpeed) UnmarshalPacket(b []byte) error { p.FanPercentage = float32FromBytes(b[0:], false) p.Time = binary.LittleEndian.Uint16(b[4:]) return nil } func (p *BmsSetMinFanSpeed) String() string { return "bms_set_min_fan_speed" } // BmsModule is Voltage and temperature for a single module type BmsModule struct { // 1 V Voltage float32 `json:"voltage"` // 1 C Temperature float32 `json:"temperature"` // Idx is the packet index. The accepted range is 0-36 Idx uint32 `json:"idx"` } func (p *BmsModule) CANId() (uint32, error) { if p.Idx >= 36 { return 0, &UnknownIdError{ 0x1C } } return 0x1C + p.Idx, nil } func (p *BmsModule) Size() uint { return 8 } func (p *BmsModule) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Voltage, false) float32ToBytes(b[4:], p.Temperature, false) return b, nil } func (p *BmsModule) UnmarshalPacket(b []byte) error { p.Voltage = float32FromBytes(b[0:], false) p.Temperature = float32FromBytes(b[4:], false) return nil } func (p *BmsModule) String() string { return "bms_module" } type BmsChargerResponseResponseFlags struct { ChargingReady bool `json:"charging_ready"` } func (p *BmsChargerResponseResponseFlags) MarshalByte() byte { var b byte if p.ChargingReady { b |= 1 << 0 } return b } func (p *BmsChargerResponseResponseFlags) UnmarshalByte(b byte) { p.ChargingReady = (b & (1 << 0)) != 0 } // BmsChargerResponse is Response packet from BMS for indicating whether BMS is ready for charging type BmsChargerResponse struct { ResponseFlags BmsChargerResponseResponseFlags `json:"response_flags"` } func (p *BmsChargerResponse) CANId() (uint32, error) { return 0x75, nil } func (p *BmsChargerResponse) Size() uint { return 1 } func (p *BmsChargerResponse) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.ResponseFlags.MarshalByte() return b, nil } func (p *BmsChargerResponse) UnmarshalPacket(b []byte) error { p.ResponseFlags.UnmarshalByte(b[0]) return nil } func (p *BmsChargerResponse) String() string { return "bms_charger_response" } // DashboardPedalPercentages is ADC values from the brake and accelerator pedals. type DashboardPedalPercentages struct { AccelPedalValue uint8 `json:"accel_pedal_value"` BrakePedalValue uint8 `json:"brake_pedal_value"` } func (p *DashboardPedalPercentages) CANId() (uint32, error) { return 0x290, nil } func (p *DashboardPedalPercentages) Size() uint { return 2 } func (p *DashboardPedalPercentages) MarshalPacket() ([]byte, error) { b := make([]byte, 2) b[0] = p.AccelPedalValue b[1] = p.BrakePedalValue return b, nil } func (p *DashboardPedalPercentages) UnmarshalPacket(b []byte) error { p.AccelPedalValue = b[0] p.BrakePedalValue = b[1] return nil } func (p *DashboardPedalPercentages) String() string { return "dashboard_pedal_percentages" } // CarState is Car gear. Forward, neutral, reverse, etc. type CarState struct { State uint8 `json:"state"` } func (p *CarState) CANId() (uint32, error) { return 0x291, nil } func (p *CarState) Size() uint { return 1 } func (p *CarState) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.State return b, nil } func (p *CarState) UnmarshalPacket(b []byte) error { p.State = b[0] return nil } func (p *CarState) String() string { return "car_state" } // DashboardPedalFault is Target speed that the driver should maintain. type DashboardPedalFault struct { BrakeFaultCount uint8 `json:"brake_fault_count"` AccelFaultCount uint8 `json:"accel_fault_count"` } func (p *DashboardPedalFault) CANId() (uint32, error) { return 0x292, nil } func (p *DashboardPedalFault) Size() uint { return 2 } func (p *DashboardPedalFault) MarshalPacket() ([]byte, error) { b := make([]byte, 2) b[0] = p.BrakeFaultCount b[1] = p.AccelFaultCount return b, nil } func (p *DashboardPedalFault) UnmarshalPacket(b []byte) error { p.BrakeFaultCount = b[0] p.AccelFaultCount = b[1] return nil } func (p *DashboardPedalFault) String() string { return "dashboard_pedal_fault" } type DashboardSystemTimeoutTestFlagSet0 struct { SteeringDisconnected bool `json:"steering_disconnected"` VisionFrontDisconnected bool `json:"vision_front_disconnected"` VisionRearDisconnected bool `json:"vision_rear_disconnected"` TelemetryDisconnected bool `json:"telemetry_disconnected"` WslDisconnected bool `json:"wsl_disconnected"` WsrDisconnected bool `json:"wsr_disconnected"` FrontMpptDisconnected bool `json:"front_mppt_disconnected"` RearMpptDisconnected bool `json:"rear_mppt_disconnected"` } func (p *DashboardSystemTimeoutTestFlagSet0) MarshalByte() byte { var b byte if p.SteeringDisconnected { b |= 1 << 0 } if p.VisionFrontDisconnected { b |= 1 << 1 } if p.VisionRearDisconnected { b |= 1 << 2 } if p.TelemetryDisconnected { b |= 1 << 3 } if p.WslDisconnected { b |= 1 << 4 } if p.WsrDisconnected { b |= 1 << 5 } if p.FrontMpptDisconnected { b |= 1 << 6 } if p.RearMpptDisconnected { b |= 1 << 7 } return b } func (p *DashboardSystemTimeoutTestFlagSet0) UnmarshalByte(b byte) { p.SteeringDisconnected = (b & (1 << 0)) != 0 p.VisionFrontDisconnected = (b & (1 << 1)) != 0 p.VisionRearDisconnected = (b & (1 << 2)) != 0 p.TelemetryDisconnected = (b & (1 << 3)) != 0 p.WslDisconnected = (b & (1 << 4)) != 0 p.WsrDisconnected = (b & (1 << 5)) != 0 p.FrontMpptDisconnected = (b & (1 << 6)) != 0 p.RearMpptDisconnected = (b & (1 << 7)) != 0 } // DashboardSystemTimeoutTest is Exposes whether each system that dashboard is supposed to listen for packets from has sent a packet. Used for testing. type DashboardSystemTimeoutTest struct { FlagSet0 DashboardSystemTimeoutTestFlagSet0 `json:"flag_set_0"` } func (p *DashboardSystemTimeoutTest) CANId() (uint32, error) { return 0x299, nil } func (p *DashboardSystemTimeoutTest) Size() uint { return 1 } func (p *DashboardSystemTimeoutTest) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.FlagSet0.MarshalByte() return b, nil } func (p *DashboardSystemTimeoutTest) UnmarshalPacket(b []byte) error { p.FlagSet0.UnmarshalByte(b[0]) return nil } func (p *DashboardSystemTimeoutTest) String() string { return "dashboard_system_timeout_test" } // CarSpeed is speed of car in meters per second type CarSpeed struct { Speed float32 `json:"speed"` } func (p *CarSpeed) CANId() (uint32, error) { return 0x29A, nil } func (p *CarSpeed) Size() uint { return 4 } func (p *CarSpeed) MarshalPacket() ([]byte, error) { b := make([]byte, 4) float32ToBytes(b[0:], p.Speed, false) return b, nil } func (p *CarSpeed) UnmarshalPacket(b []byte) error { p.Speed = float32FromBytes(b[0:], false) return nil } func (p *CarSpeed) String() string { return "car_speed" } // FlightComputerLvBoardDisconnectCounts is Number of times a board hasn't been heard from within the allowed timeout. type FlightComputerLvBoardDisconnectCounts struct { FrontLights uint8 `json:"front_lights"` RearLights uint8 `json:"rear_lights"` Steering uint8 `json:"steering"` Vision uint8 `json:"vision"` DriverDisplay uint8 `json:"driver_display"` CenterConsole uint8 `json:"center_console"` } func (p *FlightComputerLvBoardDisconnectCounts) CANId() (uint32, error) { return 0x29B, nil } func (p *FlightComputerLvBoardDisconnectCounts) Size() uint { return 6 } func (p *FlightComputerLvBoardDisconnectCounts) MarshalPacket() ([]byte, error) { b := make([]byte, 6) b[0] = p.FrontLights b[1] = p.RearLights b[2] = p.Steering b[3] = p.Vision b[4] = p.DriverDisplay b[5] = p.CenterConsole return b, nil } func (p *FlightComputerLvBoardDisconnectCounts) UnmarshalPacket(b []byte) error { p.FrontLights = b[0] p.RearLights = b[1] p.Steering = b[2] p.Vision = b[3] p.DriverDisplay = b[4] p.CenterConsole = b[5] return nil } func (p *FlightComputerLvBoardDisconnectCounts) String() string { return "flight_computer_lv_board_disconnect_counts" } // FlightComputerHvBoardDisconnectCounts is Number of times a board hasn't been heard from within the allowed timeout. type FlightComputerHvBoardDisconnectCounts struct { Bms uint8 `json:"bms"` Charger uint8 `json:"charger"` Wsl uint8 `json:"wsl"` Wsr uint8 `json:"wsr"` MpptFront uint8 `json:"mppt_front"` MpptRear uint8 `json:"mppt_rear"` } func (p *FlightComputerHvBoardDisconnectCounts) CANId() (uint32, error) { return 0x29C, nil } func (p *FlightComputerHvBoardDisconnectCounts) Size() uint { return 6 } func (p *FlightComputerHvBoardDisconnectCounts) MarshalPacket() ([]byte, error) { b := make([]byte, 6) b[0] = p.Bms b[1] = p.Charger b[2] = p.Wsl b[3] = p.Wsr b[4] = p.MpptFront b[5] = p.MpptRear return b, nil } func (p *FlightComputerHvBoardDisconnectCounts) UnmarshalPacket(b []byte) error { p.Bms = b[0] p.Charger = b[1] p.Wsl = b[2] p.Wsr = b[3] p.MpptFront = b[4] p.MpptRear = b[5] return nil } func (p *FlightComputerHvBoardDisconnectCounts) String() string { return "flight_computer_hv_board_disconnect_counts" } type FlightComputerInternalStateBms struct { BatteryKill bool `json:"battery_kill"` CellsInChargingThreshold bool `json:"cells_in_charging_threshold"` FirstPacketReceived bool `json:"first_packet_received"` } func (p *FlightComputerInternalStateBms) MarshalByte() byte { var b byte if p.BatteryKill { b |= 1 << 0 } if p.CellsInChargingThreshold { b |= 1 << 1 } if p.FirstPacketReceived { b |= 1 << 2 } return b } func (p *FlightComputerInternalStateBms) UnmarshalByte(b byte) { p.BatteryKill = (b & (1 << 0)) != 0 p.CellsInChargingThreshold = (b & (1 << 1)) != 0 p.FirstPacketReceived = (b & (1 << 2)) != 0 } type FlightComputerInternalStateCharger struct { ProximityDetected bool `json:"proximity_detected"` } func (p *FlightComputerInternalStateCharger) MarshalByte() byte { var b byte if p.ProximityDetected { b |= 1 << 0 } return b } func (p *FlightComputerInternalStateCharger) UnmarshalByte(b byte) { p.ProximityDetected = (b & (1 << 0)) != 0 } type FlightComputerInternalStatePhoton3 struct { Enable bool `json:"enable"` } func (p *FlightComputerInternalStatePhoton3) MarshalByte() byte { var b byte if p.Enable { b |= 1 << 0 } return b } func (p *FlightComputerInternalStatePhoton3) UnmarshalByte(b byte) { p.Enable = (b & (1 << 0)) != 0 } type FlightComputerInternalStateWavesculptor struct { SendingReset bool `json:"sending_reset"` RegenEnable bool `json:"regen_enable"` } func (p *FlightComputerInternalStateWavesculptor) MarshalByte() byte { var b byte if p.SendingReset { b |= 1 << 0 } if p.RegenEnable { b |= 1 << 1 } return b } func (p *FlightComputerInternalStateWavesculptor) UnmarshalByte(b byte) { p.SendingReset = (b & (1 << 0)) != 0 p.RegenEnable = (b & (1 << 1)) != 0 } type FlightComputerInternalStateInternal struct { AccelPedalDisconnect bool `json:"accel_pedal_disconnect"` BrakePedalDisconnect bool `json:"brake_pedal_disconnect"` } func (p *FlightComputerInternalStateInternal) MarshalByte() byte { var b byte if p.AccelPedalDisconnect { b |= 1 << 0 } if p.BrakePedalDisconnect { b |= 1 << 1 } return b } func (p *FlightComputerInternalStateInternal) UnmarshalByte(b byte) { p.AccelPedalDisconnect = (b & (1 << 0)) != 0 p.BrakePedalDisconnect = (b & (1 << 1)) != 0 } // FlightComputerInternalState is internal bools type FlightComputerInternalState struct { Bms FlightComputerInternalStateBms `json:"bms"` Charger FlightComputerInternalStateCharger `json:"charger"` Photon3 FlightComputerInternalStatePhoton3 `json:"photon3"` Wavesculptor FlightComputerInternalStateWavesculptor `json:"wavesculptor"` Internal FlightComputerInternalStateInternal `json:"internal"` } func (p *FlightComputerInternalState) CANId() (uint32, error) { return 0x29D, nil } func (p *FlightComputerInternalState) Size() uint { return 5 } func (p *FlightComputerInternalState) MarshalPacket() ([]byte, error) { b := make([]byte, 5) b[0] = p.Bms.MarshalByte() b[1] = p.Charger.MarshalByte() b[2] = p.Photon3.MarshalByte() b[3] = p.Wavesculptor.MarshalByte() b[4] = p.Internal.MarshalByte() return b, nil } func (p *FlightComputerInternalState) UnmarshalPacket(b []byte) error { p.Bms.UnmarshalByte(b[0]) p.Charger.UnmarshalByte(b[1]) p.Photon3.UnmarshalByte(b[2]) p.Wavesculptor.UnmarshalByte(b[3]) p.Internal.UnmarshalByte(b[4]) return nil } func (p *FlightComputerInternalState) String() string { return "flight_computer_internal_state" } // PowerToDrive is calculated power required to drive the vehicle type PowerToDrive struct { MovingAverage100 int16 `json:"moving_average_100"` MovingAverage1K int16 `json:"moving_average_1k"` MovingAverage10K int16 `json:"moving_average_10k"` } func (p *PowerToDrive) CANId() (uint32, error) { return 0x19E, nil } func (p *PowerToDrive) Size() uint { return 6 } func (p *PowerToDrive) MarshalPacket() ([]byte, error) { b := make([]byte, 6) binary.LittleEndian.PutUint16(b[0:], uint16(p.MovingAverage100)) binary.LittleEndian.PutUint16(b[2:], uint16(p.MovingAverage1K)) binary.LittleEndian.PutUint16(b[4:], uint16(p.MovingAverage10K)) return b, nil } func (p *PowerToDrive) UnmarshalPacket(b []byte) error { p.MovingAverage100 = int16(binary.LittleEndian.Uint16(b[0:])) p.MovingAverage1K = int16(binary.LittleEndian.Uint16(b[2:])) p.MovingAverage10K = int16(binary.LittleEndian.Uint16(b[4:])) return nil } func (p *PowerToDrive) String() string { return "power_to_drive" } // ArrayPower is array power calculated from current and voltage measurements type ArrayPower struct { FrontArrayChannel0 uint16 `json:"front_array_channel_0"` FrontArrayChannel1 uint16 `json:"front_array_channel_1"` RearArrayChannel0 uint16 `json:"rear_array_channel_0"` RearArrayChannel1 uint16 `json:"rear_array_channel_1"` } func (p *ArrayPower) CANId() (uint32, error) { return 0x19F, nil } func (p *ArrayPower) Size() uint { return 8 } func (p *ArrayPower) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.FrontArrayChannel0) binary.LittleEndian.PutUint16(b[2:], p.FrontArrayChannel1) binary.LittleEndian.PutUint16(b[4:], p.RearArrayChannel0) binary.LittleEndian.PutUint16(b[6:], p.RearArrayChannel1) return b, nil } func (p *ArrayPower) UnmarshalPacket(b []byte) error { p.FrontArrayChannel0 = binary.LittleEndian.Uint16(b[0:]) p.FrontArrayChannel1 = binary.LittleEndian.Uint16(b[2:]) p.RearArrayChannel0 = binary.LittleEndian.Uint16(b[4:]) p.RearArrayChannel1 = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *ArrayPower) String() string { return "array_power" } type VisionTurnSignalsCommandLights struct { LeftTurnSignal bool `json:"left_turn_signal"` RightTurnSignal bool `json:"right_turn_signal"` Spare1 bool `json:"spare_1"` Spare2 bool `json:"spare_2"` Spare3 bool `json:"spare_3"` } func (p *VisionTurnSignalsCommandLights) MarshalByte() byte { var b byte if p.LeftTurnSignal { b |= 1 << 0 } if p.RightTurnSignal { b |= 1 << 1 } if p.Spare1 { b |= 1 << 2 } if p.Spare2 { b |= 1 << 3 } if p.Spare3 { b |= 1 << 4 } return b } func (p *VisionTurnSignalsCommandLights) UnmarshalByte(b byte) { p.LeftTurnSignal = (b & (1 << 0)) != 0 p.RightTurnSignal = (b & (1 << 1)) != 0 p.Spare1 = (b & (1 << 2)) != 0 p.Spare2 = (b & (1 << 3)) != 0 p.Spare3 = (b & (1 << 4)) != 0 } // VisionTurnSignalsCommand is Command to have the vision board illuminate or turn off left, right, or both turn signals type VisionTurnSignalsCommand struct { Lights VisionTurnSignalsCommandLights `json:"lights"` } func (p *VisionTurnSignalsCommand) CANId() (uint32, error) { return 0x2B0, nil } func (p *VisionTurnSignalsCommand) Size() uint { return 1 } func (p *VisionTurnSignalsCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Lights.MarshalByte() return b, nil } func (p *VisionTurnSignalsCommand) UnmarshalPacket(b []byte) error { p.Lights.UnmarshalByte(b[0]) return nil } func (p *VisionTurnSignalsCommand) String() string { return "vision_turn_signals_command" } type VisionBrakeLightsCommandLights struct { BrakeLights bool `json:"brake_lights"` Spare1 bool `json:"spare_1"` Spare2 bool `json:"spare_2"` Spare3 bool `json:"spare_3"` } func (p *VisionBrakeLightsCommandLights) MarshalByte() byte { var b byte if p.BrakeLights { b |= 1 << 0 } if p.Spare1 { b |= 1 << 1 } if p.Spare2 { b |= 1 << 2 } if p.Spare3 { b |= 1 << 3 } return b } func (p *VisionBrakeLightsCommandLights) UnmarshalByte(b byte) { p.BrakeLights = (b & (1 << 0)) != 0 p.Spare1 = (b & (1 << 1)) != 0 p.Spare2 = (b & (1 << 2)) != 0 p.Spare3 = (b & (1 << 3)) != 0 } // VisionBrakeLightsCommand is Command to have the vision board illuminate or turn off the brake lights type VisionBrakeLightsCommand struct { Lights VisionBrakeLightsCommandLights `json:"lights"` } func (p *VisionBrakeLightsCommand) CANId() (uint32, error) { return 0x2B1, nil } func (p *VisionBrakeLightsCommand) Size() uint { return 1 } func (p *VisionBrakeLightsCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Lights.MarshalByte() return b, nil } func (p *VisionBrakeLightsCommand) UnmarshalPacket(b []byte) error { p.Lights.UnmarshalByte(b[0]) return nil } func (p *VisionBrakeLightsCommand) String() string { return "vision_brake_lights_command" } type VisionHeadlightsCommandLights struct { Headlights bool `json:"headlights"` HighBeams bool `json:"high_beams"` Spare1 bool `json:"spare_1"` Spare2 bool `json:"spare_2"` Spare3 bool `json:"spare_3"` } func (p *VisionHeadlightsCommandLights) MarshalByte() byte { var b byte if p.Headlights { b |= 1 << 0 } if p.HighBeams { b |= 1 << 1 } if p.Spare1 { b |= 1 << 2 } if p.Spare2 { b |= 1 << 3 } if p.Spare3 { b |= 1 << 4 } return b } func (p *VisionHeadlightsCommandLights) UnmarshalByte(b byte) { p.Headlights = (b & (1 << 0)) != 0 p.HighBeams = (b & (1 << 1)) != 0 p.Spare1 = (b & (1 << 2)) != 0 p.Spare2 = (b & (1 << 3)) != 0 p.Spare3 = (b & (1 << 4)) != 0 } // VisionHeadlightsCommand is Command to have the vision board illuminate or turn off the headlights and high beams type VisionHeadlightsCommand struct { Lights VisionHeadlightsCommandLights `json:"lights"` Brightness float32 `json:"brightness"` } func (p *VisionHeadlightsCommand) CANId() (uint32, error) { return 0x2B2, nil } func (p *VisionHeadlightsCommand) Size() uint { return 5 } func (p *VisionHeadlightsCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 5) b[0] = p.Lights.MarshalByte() float32ToBytes(b[1:], p.Brightness, false) return b, nil } func (p *VisionHeadlightsCommand) UnmarshalPacket(b []byte) error { p.Lights.UnmarshalByte(b[0]) p.Brightness = float32FromBytes(b[1:], false) return nil } func (p *VisionHeadlightsCommand) String() string { return "vision_headlights_command" } type VisionHornCommandHorn struct { Horn bool `json:"horn"` Spare bool `json:"spare"` } func (p *VisionHornCommandHorn) MarshalByte() byte { var b byte if p.Horn { b |= 1 << 0 } if p.Spare { b |= 1 << 1 } return b } func (p *VisionHornCommandHorn) UnmarshalByte(b byte) { p.Horn = (b & (1 << 0)) != 0 p.Spare = (b & (1 << 1)) != 0 } // VisionHornCommand is Command the vision board honk the horn, must be repeatedly sent otherwise the vision board will stop honking after a bit. See high_power.h for details. type VisionHornCommand struct { Horn VisionHornCommandHorn `json:"horn"` } func (p *VisionHornCommand) CANId() (uint32, error) { return 0x2B3, nil } func (p *VisionHornCommand) Size() uint { return 1 } func (p *VisionHornCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Horn.MarshalByte() return b, nil } func (p *VisionHornCommand) UnmarshalPacket(b []byte) error { p.Horn.UnmarshalByte(b[0]) return nil } func (p *VisionHornCommand) String() string { return "vision_horn_command" } type VisionArrayLatchesCommandArrayLatches struct { ArrayFront bool `json:"array_front"` ArrayRear bool `json:"array_rear"` } func (p *VisionArrayLatchesCommandArrayLatches) MarshalByte() byte { var b byte if p.ArrayFront { b |= 1 << 0 } if p.ArrayRear { b |= 1 << 1 } return b } func (p *VisionArrayLatchesCommandArrayLatches) UnmarshalByte(b byte) { p.ArrayFront = (b & (1 << 0)) != 0 p.ArrayRear = (b & (1 << 1)) != 0 } // VisionArrayLatchesCommand is Command the vision board to open the array latches type VisionArrayLatchesCommand struct { ArrayLatches VisionArrayLatchesCommandArrayLatches `json:"array_latches"` } func (p *VisionArrayLatchesCommand) CANId() (uint32, error) { return 0x2B4, nil } func (p *VisionArrayLatchesCommand) Size() uint { return 1 } func (p *VisionArrayLatchesCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.ArrayLatches.MarshalByte() return b, nil } func (p *VisionArrayLatchesCommand) UnmarshalPacket(b []byte) error { p.ArrayLatches.UnmarshalByte(b[0]) return nil } func (p *VisionArrayLatchesCommand) String() string { return "vision_array_latches_command" } type VisionRearviewCommandCameras struct { Left bool `json:"left"` Right bool `json:"right"` Rear bool `json:"rear"` } func (p *VisionRearviewCommandCameras) MarshalByte() byte { var b byte if p.Left { b |= 1 << 0 } if p.Right { b |= 1 << 1 } if p.Rear { b |= 1 << 2 } return b } func (p *VisionRearviewCommandCameras) UnmarshalByte(b byte) { p.Left = (b & (1 << 0)) != 0 p.Right = (b & (1 << 1)) != 0 p.Rear = (b & (1 << 2)) != 0 } // VisionRearviewCommand is Command the vision board turn on the rear view cameras type VisionRearviewCommand struct { Cameras VisionRearviewCommandCameras `json:"cameras"` } func (p *VisionRearviewCommand) CANId() (uint32, error) { return 0x2B5, nil } func (p *VisionRearviewCommand) Size() uint { return 1 } func (p *VisionRearviewCommand) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Cameras.MarshalByte() return b, nil } func (p *VisionRearviewCommand) UnmarshalPacket(b []byte) error { p.Cameras.UnmarshalByte(b[0]) return nil } func (p *VisionRearviewCommand) String() string { return "vision_rearview_command" } // TrackerEnable is Enables/disables power trackers. Use 0x610 for the channel transmitting the data packet on 0x600, 0x611 for 0x601, et cetera. Sending 1 in the enable byte turns the tracker on; sending 0 turns it off. type TrackerEnable struct { Enable uint8 `json:"enable"` // Idx is the packet index. The accepted range is 0-6 Idx uint32 `json:"idx"` } func (p *TrackerEnable) CANId() (uint32, error) { if p.Idx >= 6 { return 0, &UnknownIdError{ 0x610 } } return 0x610 + p.Idx, nil } func (p *TrackerEnable) Size() uint { return 1 } func (p *TrackerEnable) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Enable return b, nil } func (p *TrackerEnable) UnmarshalPacket(b []byte) error { p.Enable = b[0] return nil } func (p *TrackerEnable) String() string { return "tracker_enable" } // DistanceTraveled is distance of wavesculptor odometer type DistanceTraveled struct { // 0 m TripDistance float32 `json:"trip_distance"` } func (p *DistanceTraveled) CANId() (uint32, error) { return 0x200, nil } func (p *DistanceTraveled) Size() uint { return 4 } func (p *DistanceTraveled) MarshalPacket() ([]byte, error) { b := make([]byte, 4) float32ToBytes(b[0:], p.TripDistance, false) return b, nil } func (p *DistanceTraveled) UnmarshalPacket(b []byte) error { p.TripDistance = float32FromBytes(b[0:], false) return nil } func (p *DistanceTraveled) String() string { return "distance_traveled" } type ChargerStateStateFlags struct { ChargerPlugged bool `json:"charger_plugged"` } func (p *ChargerStateStateFlags) MarshalByte() byte { var b byte if p.ChargerPlugged { b |= 1 << 0 } return b } func (p *ChargerStateStateFlags) UnmarshalByte(b byte) { p.ChargerPlugged = (b & (1 << 0)) != 0 } type ChargerStateFault struct { CHARGEROVERVOLT bool `json:"CHARGER_OVERVOLT"` CHARGEROVERTEMP bool `json:"CHARGER_OVERTEMP"` CHARGERCANTIMEOUT bool `json:"CHARGER_CAN_TIMEOUT"` BATTERYHVKILL bool `json:"BATTERY_HV_KILL"` BATTERYUNDERVOLT bool `json:"BATTERY_UNDERVOLT"` BATTERYOVERVOLT bool `json:"BATTERY_OVERVOLT"` BATTERYCELLOVERTEMP bool `json:"BATTERY_CELL_OVERTEMP"` BATTERYCANTIMEOUT bool `json:"BATTERY_CAN_TIMEOUT"` } func (p *ChargerStateFault) MarshalByte() byte { var b byte if p.CHARGEROVERVOLT { b |= 1 << 0 } if p.CHARGEROVERTEMP { b |= 1 << 1 } if p.CHARGERCANTIMEOUT { b |= 1 << 2 } if p.BATTERYHVKILL { b |= 1 << 3 } if p.BATTERYUNDERVOLT { b |= 1 << 4 } if p.BATTERYOVERVOLT { b |= 1 << 5 } if p.BATTERYCELLOVERTEMP { b |= 1 << 6 } if p.BATTERYCANTIMEOUT { b |= 1 << 7 } return b } func (p *ChargerStateFault) UnmarshalByte(b byte) { p.CHARGEROVERVOLT = (b & (1 << 0)) != 0 p.CHARGEROVERTEMP = (b & (1 << 1)) != 0 p.CHARGERCANTIMEOUT = (b & (1 << 2)) != 0 p.BATTERYHVKILL = (b & (1 << 3)) != 0 p.BATTERYUNDERVOLT = (b & (1 << 4)) != 0 p.BATTERYOVERVOLT = (b & (1 << 5)) != 0 p.BATTERYCELLOVERTEMP = (b & (1 << 6)) != 0 p.BATTERYCANTIMEOUT = (b & (1 << 7)) != 0 } // ChargerState is Notifies whether the J1772 cable is plugged. type ChargerState struct { StateFlags ChargerStateStateFlags `json:"state_flags"` // 0.001 C ChargerMaxTemp uint16 `json:"charger_max_temp"` Fault ChargerStateFault `json:"fault"` // 0 A ChargingCurrent float32 `json:"charging_current"` } func (p *ChargerState) CANId() (uint32, error) { return 0x573, nil } func (p *ChargerState) Size() uint { return 8 } func (p *ChargerState) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.StateFlags.MarshalByte() binary.LittleEndian.PutUint16(b[1:], p.ChargerMaxTemp) b[3] = p.Fault.MarshalByte() float32ToBytes(b[4:], p.ChargingCurrent, false) return b, nil } func (p *ChargerState) UnmarshalPacket(b []byte) error { p.StateFlags.UnmarshalByte(b[0]) p.ChargerMaxTemp = binary.LittleEndian.Uint16(b[1:]) p.Fault.UnmarshalByte(b[3]) p.ChargingCurrent = float32FromBytes(b[4:], false) return nil } func (p *ChargerState) String() string { return "charger_state" } type ChargerBmsRequestRequestFlags struct { ChargingRequested bool `json:"charging_requested"` } func (p *ChargerBmsRequestRequestFlags) MarshalByte() byte { var b byte if p.ChargingRequested { b |= 1 << 0 } return b } func (p *ChargerBmsRequestRequestFlags) UnmarshalByte(b byte) { p.ChargingRequested = (b & (1 << 0)) != 0 } // ChargerBmsRequest is Request packet for sending contactor commands from the charger to BP. type ChargerBmsRequest struct { RequestFlags ChargerBmsRequestRequestFlags `json:"request_flags"` } func (p *ChargerBmsRequest) CANId() (uint32, error) { return 0x74, nil } func (p *ChargerBmsRequest) Size() uint { return 1 } func (p *ChargerBmsRequest) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.RequestFlags.MarshalByte() return b, nil } func (p *ChargerBmsRequest) UnmarshalPacket(b []byte) error { p.RequestFlags.UnmarshalByte(b[0]) return nil } func (p *ChargerBmsRequest) String() string { return "charger_bms_request" } // ChargerCurrentVoltage is Packet to request charging current/voltage set type ChargerCurrentVoltage struct { // 0 A MaxCurrent float32 `json:"max_current"` // 0 kWh MaxCapacity float32 `json:"max_capacity"` } func (p *ChargerCurrentVoltage) CANId() (uint32, error) { return 0x576, nil } func (p *ChargerCurrentVoltage) Size() uint { return 8 } func (p *ChargerCurrentVoltage) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MaxCurrent, false) float32ToBytes(b[4:], p.MaxCapacity, false) return b, nil } func (p *ChargerCurrentVoltage) UnmarshalPacket(b []byte) error { p.MaxCurrent = float32FromBytes(b[0:], false) p.MaxCapacity = float32FromBytes(b[4:], false) return nil } func (p *ChargerCurrentVoltage) String() string { return "charger_current_voltage" } // ChargerPower is Outputs the amount of power that the chargers are delivering. type ChargerPower struct { // 0 W Power float32 `json:"power"` } func (p *ChargerPower) CANId() (uint32, error) { return 0x577, nil } func (p *ChargerPower) Size() uint { return 4 } func (p *ChargerPower) MarshalPacket() ([]byte, error) { b := make([]byte, 4) float32ToBytes(b[0:], p.Power, false) return b, nil } func (p *ChargerPower) UnmarshalPacket(b []byte) error { p.Power = float32FromBytes(b[0:], false) return nil } func (p *ChargerPower) String() string { return "charger_power" } // ThunderstruckControlMessage is Control packet for thunderstruck chargers type ThunderstruckControlMessage struct { // 1 V Enable uint8 `json:"Enable"` // 1 V CHARGEVOLTAGE uint16 `json:"CHARGE_VOLTAGE"` // 1 V CHARGECURRENT uint16 `json:"CHARGE_CURRENT"` // 1 V LEDBLINKPATTERN uint8 `json:"LED_BLINK_PATTERN"` // 1 V RESERVED uint16 `json:"RESERVED"` } func (p *ThunderstruckControlMessage) CANId() (uint32, error) { return 0x18E54024, nil } func (p *ThunderstruckControlMessage) Size() uint { return 8 } func (p *ThunderstruckControlMessage) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.Enable binary.LittleEndian.PutUint16(b[1:], p.CHARGEVOLTAGE) binary.LittleEndian.PutUint16(b[3:], p.CHARGECURRENT) b[5] = p.LEDBLINKPATTERN binary.LittleEndian.PutUint16(b[6:], p.RESERVED) return b, nil } func (p *ThunderstruckControlMessage) UnmarshalPacket(b []byte) error { p.Enable = b[0] p.CHARGEVOLTAGE = binary.LittleEndian.Uint16(b[1:]) p.CHARGECURRENT = binary.LittleEndian.Uint16(b[3:]) p.LEDBLINKPATTERN = b[5] p.RESERVED = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *ThunderstruckControlMessage) String() string { return "thunderstruck_control_message" } type VisionStatusFrontLights struct { LeftTurnSignal bool `json:"left_turn_signal"` RightTurnSignal bool `json:"right_turn_signal"` BrakeLights bool `json:"brake_lights"` Headlights bool `json:"headlights"` HighBeams bool `json:"high_beams"` Spare1 bool `json:"spare_1"` Spare2 bool `json:"spare_2"` Spare3 bool `json:"spare_3"` } func (p *VisionStatusFrontLights) MarshalByte() byte { var b byte if p.LeftTurnSignal { b |= 1 << 0 } if p.RightTurnSignal { b |= 1 << 1 } if p.BrakeLights { b |= 1 << 2 } if p.Headlights { b |= 1 << 3 } if p.HighBeams { b |= 1 << 4 } if p.Spare1 { b |= 1 << 5 } if p.Spare2 { b |= 1 << 6 } if p.Spare3 { b |= 1 << 7 } return b } func (p *VisionStatusFrontLights) UnmarshalByte(b byte) { p.LeftTurnSignal = (b & (1 << 0)) != 0 p.RightTurnSignal = (b & (1 << 1)) != 0 p.BrakeLights = (b & (1 << 2)) != 0 p.Headlights = (b & (1 << 3)) != 0 p.HighBeams = (b & (1 << 4)) != 0 p.Spare1 = (b & (1 << 5)) != 0 p.Spare2 = (b & (1 << 6)) != 0 p.Spare3 = (b & (1 << 7)) != 0 } type VisionStatusFrontHorn struct { Horn bool `json:"horn"` Spare bool `json:"spare"` } func (p *VisionStatusFrontHorn) MarshalByte() byte { var b byte if p.Horn { b |= 1 << 0 } if p.Spare { b |= 1 << 1 } return b } func (p *VisionStatusFrontHorn) UnmarshalByte(b byte) { p.Horn = (b & (1 << 0)) != 0 p.Spare = (b & (1 << 1)) != 0 } type VisionStatusFrontCameras struct { Left bool `json:"left"` Right bool `json:"right"` Rear bool `json:"rear"` } func (p *VisionStatusFrontCameras) MarshalByte() byte { var b byte if p.Left { b |= 1 << 0 } if p.Right { b |= 1 << 1 } if p.Rear { b |= 1 << 2 } return b } func (p *VisionStatusFrontCameras) UnmarshalByte(b byte) { p.Left = (b & (1 << 0)) != 0 p.Right = (b & (1 << 1)) != 0 p.Rear = (b & (1 << 2)) != 0 } type VisionStatusFrontArrayLatches struct { ArrayFront0 bool `json:"array_front_0"` ArrayFront1 bool `json:"array_front_1"` ArrayRear0 bool `json:"array_rear_0"` ArrayRear1 bool `json:"array_rear_1"` } func (p *VisionStatusFrontArrayLatches) MarshalByte() byte { var b byte if p.ArrayFront0 { b |= 1 << 0 } if p.ArrayFront1 { b |= 1 << 1 } if p.ArrayRear0 { b |= 1 << 2 } if p.ArrayRear1 { b |= 1 << 3 } return b } func (p *VisionStatusFrontArrayLatches) UnmarshalByte(b byte) { p.ArrayFront0 = (b & (1 << 0)) != 0 p.ArrayFront1 = (b & (1 << 1)) != 0 p.ArrayRear0 = (b & (1 << 2)) != 0 p.ArrayRear1 = (b & (1 << 3)) != 0 } // VisionStatusFront is Status of the front vision board outputs type VisionStatusFront struct { Lights VisionStatusFrontLights `json:"lights"` Horn VisionStatusFrontHorn `json:"horn"` Cameras VisionStatusFrontCameras `json:"cameras"` ArrayLatches VisionStatusFrontArrayLatches `json:"array_latches"` } func (p *VisionStatusFront) CANId() (uint32, error) { return 0x2B6, nil } func (p *VisionStatusFront) Size() uint { return 4 } func (p *VisionStatusFront) MarshalPacket() ([]byte, error) { b := make([]byte, 4) b[0] = p.Lights.MarshalByte() b[1] = p.Horn.MarshalByte() b[2] = p.Cameras.MarshalByte() b[3] = p.ArrayLatches.MarshalByte() return b, nil } func (p *VisionStatusFront) UnmarshalPacket(b []byte) error { p.Lights.UnmarshalByte(b[0]) p.Horn.UnmarshalByte(b[1]) p.Cameras.UnmarshalByte(b[2]) p.ArrayLatches.UnmarshalByte(b[3]) return nil } func (p *VisionStatusFront) String() string { return "vision_status_front" } type VisionStatusRearLights struct { LeftTurnSignal bool `json:"left_turn_signal"` RightTurnSignal bool `json:"right_turn_signal"` BrakeLights bool `json:"brake_lights"` Headlights bool `json:"headlights"` HighBeams bool `json:"high_beams"` Spare1 bool `json:"spare_1"` Spare2 bool `json:"spare_2"` Spare3 bool `json:"spare_3"` } func (p *VisionStatusRearLights) MarshalByte() byte { var b byte if p.LeftTurnSignal { b |= 1 << 0 } if p.RightTurnSignal { b |= 1 << 1 } if p.BrakeLights { b |= 1 << 2 } if p.Headlights { b |= 1 << 3 } if p.HighBeams { b |= 1 << 4 } if p.Spare1 { b |= 1 << 5 } if p.Spare2 { b |= 1 << 6 } if p.Spare3 { b |= 1 << 7 } return b } func (p *VisionStatusRearLights) UnmarshalByte(b byte) { p.LeftTurnSignal = (b & (1 << 0)) != 0 p.RightTurnSignal = (b & (1 << 1)) != 0 p.BrakeLights = (b & (1 << 2)) != 0 p.Headlights = (b & (1 << 3)) != 0 p.HighBeams = (b & (1 << 4)) != 0 p.Spare1 = (b & (1 << 5)) != 0 p.Spare2 = (b & (1 << 6)) != 0 p.Spare3 = (b & (1 << 7)) != 0 } type VisionStatusRearHorn struct { Horn bool `json:"horn"` Spare bool `json:"spare"` } func (p *VisionStatusRearHorn) MarshalByte() byte { var b byte if p.Horn { b |= 1 << 0 } if p.Spare { b |= 1 << 1 } return b } func (p *VisionStatusRearHorn) UnmarshalByte(b byte) { p.Horn = (b & (1 << 0)) != 0 p.Spare = (b & (1 << 1)) != 0 } type VisionStatusRearCameras struct { Left bool `json:"left"` Right bool `json:"right"` Rear bool `json:"rear"` } func (p *VisionStatusRearCameras) MarshalByte() byte { var b byte if p.Left { b |= 1 << 0 } if p.Right { b |= 1 << 1 } if p.Rear { b |= 1 << 2 } return b } func (p *VisionStatusRearCameras) UnmarshalByte(b byte) { p.Left = (b & (1 << 0)) != 0 p.Right = (b & (1 << 1)) != 0 p.Rear = (b & (1 << 2)) != 0 } type VisionStatusRearArrayLatches struct { ArrayFront0 bool `json:"array_front_0"` ArrayFront1 bool `json:"array_front_1"` ArrayRear0 bool `json:"array_rear_0"` ArrayRear1 bool `json:"array_rear_1"` } func (p *VisionStatusRearArrayLatches) MarshalByte() byte { var b byte if p.ArrayFront0 { b |= 1 << 0 } if p.ArrayFront1 { b |= 1 << 1 } if p.ArrayRear0 { b |= 1 << 2 } if p.ArrayRear1 { b |= 1 << 3 } return b } func (p *VisionStatusRearArrayLatches) UnmarshalByte(b byte) { p.ArrayFront0 = (b & (1 << 0)) != 0 p.ArrayFront1 = (b & (1 << 1)) != 0 p.ArrayRear0 = (b & (1 << 2)) != 0 p.ArrayRear1 = (b & (1 << 3)) != 0 } // VisionStatusRear is Status of the rear vision board outputs type VisionStatusRear struct { Lights VisionStatusRearLights `json:"lights"` Horn VisionStatusRearHorn `json:"horn"` Cameras VisionStatusRearCameras `json:"cameras"` ArrayLatches VisionStatusRearArrayLatches `json:"array_latches"` } func (p *VisionStatusRear) CANId() (uint32, error) { return 0x2B7, nil } func (p *VisionStatusRear) Size() uint { return 4 } func (p *VisionStatusRear) MarshalPacket() ([]byte, error) { b := make([]byte, 4) b[0] = p.Lights.MarshalByte() b[1] = p.Horn.MarshalByte() b[2] = p.Cameras.MarshalByte() b[3] = p.ArrayLatches.MarshalByte() return b, nil } func (p *VisionStatusRear) UnmarshalPacket(b []byte) error { p.Lights.UnmarshalByte(b[0]) p.Horn.UnmarshalByte(b[1]) p.Cameras.UnmarshalByte(b[2]) p.ArrayLatches.UnmarshalByte(b[3]) return nil } func (p *VisionStatusRear) String() string { return "vision_status_rear" } // LightsFrontId is Unique identification packet for front lights board type LightsFrontId struct { BoardId uint16 `json:"board_id"` // 0.01 C McuTemp int16 `json:"mcu_temp"` // 0.001 V BusVoltage uint16 `json:"bus_voltage"` FaultCode uint16 `json:"fault_code"` } func (p *LightsFrontId) CANId() (uint32, error) { return 0x300, nil } func (p *LightsFrontId) Size() uint { return 8 } func (p *LightsFrontId) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.BoardId) binary.LittleEndian.PutUint16(b[2:], uint16(p.McuTemp)) binary.LittleEndian.PutUint16(b[4:], p.BusVoltage) binary.LittleEndian.PutUint16(b[6:], p.FaultCode) return b, nil } func (p *LightsFrontId) UnmarshalPacket(b []byte) error { p.BoardId = binary.LittleEndian.Uint16(b[0:]) p.McuTemp = int16(binary.LittleEndian.Uint16(b[2:])) p.BusVoltage = binary.LittleEndian.Uint16(b[4:]) p.FaultCode = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *LightsFrontId) String() string { return "lights_front_id" } // LightsBackId is Unique identification packet for back lights board type LightsBackId struct { BoardId uint16 `json:"board_id"` // 0.01 C McuTemp int16 `json:"mcu_temp"` // 0.001 V BusVoltage uint16 `json:"bus_voltage"` FaultCode uint16 `json:"fault_code"` } func (p *LightsBackId) CANId() (uint32, error) { return 0x301, nil } func (p *LightsBackId) Size() uint { return 8 } func (p *LightsBackId) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.BoardId) binary.LittleEndian.PutUint16(b[2:], uint16(p.McuTemp)) binary.LittleEndian.PutUint16(b[4:], p.BusVoltage) binary.LittleEndian.PutUint16(b[6:], p.FaultCode) return b, nil } func (p *LightsBackId) UnmarshalPacket(b []byte) error { p.BoardId = binary.LittleEndian.Uint16(b[0:]) p.McuTemp = int16(binary.LittleEndian.Uint16(b[2:])) p.BusVoltage = binary.LittleEndian.Uint16(b[4:]) p.FaultCode = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *LightsBackId) String() string { return "lights_back_id" } // VisionId is Unique identification packet for vision type VisionId struct { BoardId uint16 `json:"board_id"` // 0.01 C McuTemp int16 `json:"mcu_temp"` // 0.001 V BusVoltage uint16 `json:"bus_voltage"` FaultCode uint16 `json:"fault_code"` } func (p *VisionId) CANId() (uint32, error) { return 0x302, nil } func (p *VisionId) Size() uint { return 8 } func (p *VisionId) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.BoardId) binary.LittleEndian.PutUint16(b[2:], uint16(p.McuTemp)) binary.LittleEndian.PutUint16(b[4:], p.BusVoltage) binary.LittleEndian.PutUint16(b[6:], p.FaultCode) return b, nil } func (p *VisionId) UnmarshalPacket(b []byte) error { p.BoardId = binary.LittleEndian.Uint16(b[0:]) p.McuTemp = int16(binary.LittleEndian.Uint16(b[2:])) p.BusVoltage = binary.LittleEndian.Uint16(b[4:]) p.FaultCode = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *VisionId) String() string { return "vision_id" } // SteeringPressCount1 is Shows whether each button has been toggled an even ("on") or odd ("off") number of times. type SteeringPressCount1 struct { Button0 uint8 `json:"button0"` Button1 uint8 `json:"button1"` Button2 uint8 `json:"button2"` Button3 uint8 `json:"button3"` Button4 uint8 `json:"button4"` Button5 uint8 `json:"button5"` Button6 uint8 `json:"button6"` } func (p *SteeringPressCount1) CANId() (uint32, error) { return 0x240, nil } func (p *SteeringPressCount1) Size() uint { return 7 } func (p *SteeringPressCount1) MarshalPacket() ([]byte, error) { b := make([]byte, 7) b[0] = p.Button0 b[1] = p.Button1 b[2] = p.Button2 b[3] = p.Button3 b[4] = p.Button4 b[5] = p.Button5 b[6] = p.Button6 return b, nil } func (p *SteeringPressCount1) UnmarshalPacket(b []byte) error { p.Button0 = b[0] p.Button1 = b[1] p.Button2 = b[2] p.Button3 = b[3] p.Button4 = b[4] p.Button5 = b[5] p.Button6 = b[6] return nil } func (p *SteeringPressCount1) String() string { return "steering_press_count_1" } // SteeringPressCount2 is Shows whether each button has been toggled an even ("on") or odd ("off") number of times. type SteeringPressCount2 struct { Button7 uint8 `json:"button7"` Button8 uint8 `json:"button8"` Button9 uint8 `json:"button9"` Button10 uint8 `json:"button10"` } func (p *SteeringPressCount2) CANId() (uint32, error) { return 0x250, nil } func (p *SteeringPressCount2) Size() uint { return 4 } func (p *SteeringPressCount2) MarshalPacket() ([]byte, error) { b := make([]byte, 4) b[0] = p.Button7 b[1] = p.Button8 b[2] = p.Button9 b[3] = p.Button10 return b, nil } func (p *SteeringPressCount2) UnmarshalPacket(b []byte) error { p.Button7 = b[0] p.Button8 = b[1] p.Button9 = b[2] p.Button10 = b[3] return nil } func (p *SteeringPressCount2) String() string { return "steering_press_count_2" } // SteeringButtonColors1 is This packet controls each button's color. Each byte is a hex color code. type SteeringButtonColors1 struct { Button0 uint8 `json:"button0"` Button1 uint8 `json:"button1"` Button2 uint8 `json:"button2"` Button3 uint8 `json:"button3"` Button4 uint8 `json:"button4"` Button5 uint8 `json:"button5"` Button6 uint8 `json:"button6"` } func (p *SteeringButtonColors1) CANId() (uint32, error) { return 0x241, nil } func (p *SteeringButtonColors1) Size() uint { return 7 } func (p *SteeringButtonColors1) MarshalPacket() ([]byte, error) { b := make([]byte, 7) b[0] = p.Button0 b[1] = p.Button1 b[2] = p.Button2 b[3] = p.Button3 b[4] = p.Button4 b[5] = p.Button5 b[6] = p.Button6 return b, nil } func (p *SteeringButtonColors1) UnmarshalPacket(b []byte) error { p.Button0 = b[0] p.Button1 = b[1] p.Button2 = b[2] p.Button3 = b[3] p.Button4 = b[4] p.Button5 = b[5] p.Button6 = b[6] return nil } func (p *SteeringButtonColors1) String() string { return "steering_button_colors_1" } // SteeringButtonColors2 is This packet controls each button's color. Each byte is a hex color code. type SteeringButtonColors2 struct { Button7 uint8 `json:"button7"` Button8 uint8 `json:"button8"` Button9 uint8 `json:"button9"` Button10 uint8 `json:"button10"` } func (p *SteeringButtonColors2) CANId() (uint32, error) { return 0x251, nil } func (p *SteeringButtonColors2) Size() uint { return 4 } func (p *SteeringButtonColors2) MarshalPacket() ([]byte, error) { b := make([]byte, 4) b[0] = p.Button7 b[1] = p.Button8 b[2] = p.Button9 b[3] = p.Button10 return b, nil } func (p *SteeringButtonColors2) UnmarshalPacket(b []byte) error { p.Button7 = b[0] p.Button8 = b[1] p.Button9 = b[2] p.Button10 = b[3] return nil } func (p *SteeringButtonColors2) String() string { return "steering_button_colors_2" } // SteeringHorn is This packet controls the state of the horn. type SteeringHorn struct { Horn uint8 `json:"horn"` } func (p *SteeringHorn) CANId() (uint32, error) { return 0x242, nil } func (p *SteeringHorn) Size() uint { return 1 } func (p *SteeringHorn) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.Horn return b, nil } func (p *SteeringHorn) UnmarshalPacket(b []byte) error { p.Horn = b[0] return nil } func (p *SteeringHorn) String() string { return "steering_horn" } // ThunderstruckStatusMessage is Status packet for thunderstruck chargers type ThunderstruckStatusMessage struct { // 1 V STATUSFLAGS uint8 `json:"STATUS_FLAGS"` // 1 V CHARGEFLAGS uint8 `json:"CHARGE_FLAGS"` // 1 V OUTPUTVOLTAGE uint16 `json:"OUTPUT_VOLTAGE"` // 1 V OUTPUTCURRENT uint16 `json:"OUTPUT_CURRENT"` // 1 V CHARGERTEMP uint8 `json:"CHARGER_TEMP"` // 1 V RESERVED uint8 `json:"RESERVED"` } func (p *ThunderstruckStatusMessage) CANId() (uint32, error) { return 0x18EB2440, nil } func (p *ThunderstruckStatusMessage) Size() uint { return 8 } func (p *ThunderstruckStatusMessage) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.STATUSFLAGS b[1] = p.CHARGEFLAGS binary.LittleEndian.PutUint16(b[2:], p.OUTPUTVOLTAGE) binary.LittleEndian.PutUint16(b[4:], p.OUTPUTCURRENT) b[6] = p.CHARGERTEMP b[7] = p.RESERVED return b, nil } func (p *ThunderstruckStatusMessage) UnmarshalPacket(b []byte) error { p.STATUSFLAGS = b[0] p.CHARGEFLAGS = b[1] p.OUTPUTVOLTAGE = binary.LittleEndian.Uint16(b[2:]) p.OUTPUTCURRENT = binary.LittleEndian.Uint16(b[4:]) p.CHARGERTEMP = b[6] p.RESERVED = b[7] return nil } func (p *ThunderstruckStatusMessage) String() string { return "thunderstruck_status_message" } // TrackerData is Tracker data. Each channel transmits on a specific ID, which should be specified along with the tracker, most likely 0x600-0x603. type TrackerData struct { // 0.01 V ArrayVoltage uint16 `json:"array_voltage"` // 0.001 A ArrayCurrent uint16 `json:"array_current"` // 0.01 V BatteryVoltage uint16 `json:"battery_voltage"` // 0.01 C Temperature uint16 `json:"temperature"` // Idx is the packet index. The accepted range is 0-6 Idx uint32 `json:"idx"` } func (p *TrackerData) CANId() (uint32, error) { if p.Idx >= 6 { return 0, &UnknownIdError{ 0x600 } } return 0x600 + p.Idx, nil } func (p *TrackerData) Size() uint { return 8 } func (p *TrackerData) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint16(b[0:], p.ArrayVoltage) binary.LittleEndian.PutUint16(b[2:], p.ArrayCurrent) binary.LittleEndian.PutUint16(b[4:], p.BatteryVoltage) binary.LittleEndian.PutUint16(b[6:], p.Temperature) return b, nil } func (p *TrackerData) UnmarshalPacket(b []byte) error { p.ArrayVoltage = binary.LittleEndian.Uint16(b[0:]) p.ArrayCurrent = binary.LittleEndian.Uint16(b[2:]) p.BatteryVoltage = binary.LittleEndian.Uint16(b[4:]) p.Temperature = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *TrackerData) String() string { return "tracker_data" } // TritiumMotorDrive is Tritium Motor Drive Command type TritiumMotorDrive struct { MotorVelocity float32 `json:"motor_velocity"` MotorCurrent float32 `json:"motor_current"` } func (p *TritiumMotorDrive) CANId() (uint32, error) { return 0x121, nil } func (p *TritiumMotorDrive) Size() uint { return 8 } func (p *TritiumMotorDrive) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MotorVelocity, false) float32ToBytes(b[4:], p.MotorCurrent, false) return b, nil } func (p *TritiumMotorDrive) UnmarshalPacket(b []byte) error { p.MotorVelocity = float32FromBytes(b[0:], false) p.MotorCurrent = float32FromBytes(b[4:], false) return nil } func (p *TritiumMotorDrive) String() string { return "tritium_motor_drive" } // TritiumMotorPower is Tritium Motor Power Command type TritiumMotorPower struct { Reserved float32 `json:"reserved"` BusCurrent float32 `json:"bus_current"` } func (p *TritiumMotorPower) CANId() (uint32, error) { return 0x122, nil } func (p *TritiumMotorPower) Size() uint { return 8 } func (p *TritiumMotorPower) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reserved, false) float32ToBytes(b[4:], p.BusCurrent, false) return b, nil } func (p *TritiumMotorPower) UnmarshalPacket(b []byte) error { p.Reserved = float32FromBytes(b[0:], false) p.BusCurrent = float32FromBytes(b[4:], false) return nil } func (p *TritiumMotorPower) String() string { return "tritium_motor_power" } // TritiumReset is Tritium Reset Command type TritiumReset struct { Unused1 float32 `json:"unused1"` Unused2 float32 `json:"unused2"` } func (p *TritiumReset) CANId() (uint32, error) { return 0x123, nil } func (p *TritiumReset) Size() uint { return 8 } func (p *TritiumReset) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Unused1, false) float32ToBytes(b[4:], p.Unused2, false) return b, nil } func (p *TritiumReset) UnmarshalPacket(b []byte) error { p.Unused1 = float32FromBytes(b[0:], false) p.Unused2 = float32FromBytes(b[4:], false) return nil } func (p *TritiumReset) String() string { return "tritium_reset" } // BmsAhSet is write state of charge, use with caution type BmsAhSet struct { Ah uint32 `json:"ah"` } func (p *BmsAhSet) CANId() (uint32, error) { return 0x16, nil } func (p *BmsAhSet) Size() uint { return 4 } func (p *BmsAhSet) MarshalPacket() ([]byte, error) { b := make([]byte, 4) binary.LittleEndian.PutUint32(b[0:], p.Ah) return b, nil } func (p *BmsAhSet) UnmarshalPacket(b []byte) error { p.Ah = binary.LittleEndian.Uint32(b[0:]) return nil } func (p *BmsAhSet) String() string { return "bms_ah_set" } // BmsWhSet is write state of charge, use with caution type BmsWhSet struct { Wh uint32 `json:"wh"` } func (p *BmsWhSet) CANId() (uint32, error) { return 0x17, nil } func (p *BmsWhSet) Size() uint { return 4 } func (p *BmsWhSet) MarshalPacket() ([]byte, error) { b := make([]byte, 4) binary.LittleEndian.PutUint32(b[0:], p.Wh) return b, nil } func (p *BmsWhSet) UnmarshalPacket(b []byte) error { p.Wh = binary.LittleEndian.Uint32(b[0:]) return nil } func (p *BmsWhSet) String() string { return "bms_wh_set" } type BmsKillKillType struct { KILLHARD bool `json:"KILL_HARD"` } func (p *BmsKillKillType) MarshalByte() byte { var b byte if p.KILLHARD { b |= 1 << 0 } return b } func (p *BmsKillKillType) UnmarshalByte(b byte) { p.KILLHARD = (b & (1 << 0)) != 0 } // BmsKill is packet to cause BMS kill type BmsKill struct { KillType BmsKillKillType `json:"kill_type"` } func (p *BmsKill) CANId() (uint32, error) { return 0x1A, nil } func (p *BmsKill) Size() uint { return 1 } func (p *BmsKill) MarshalPacket() ([]byte, error) { b := make([]byte, 1) b[0] = p.KillType.MarshalByte() return b, nil } func (p *BmsKill) UnmarshalPacket(b []byte) error { p.KillType.UnmarshalByte(b[0]) return nil } func (p *BmsKill) String() string { return "bms_kill" } // TelemetryRtcReset is Reset telemetry's real-time clock (RTC). type TelemetryRtcReset struct { Year uint8 `json:"year"` Month uint8 `json:"month"` Day uint8 `json:"day"` Hour uint8 `json:"hour"` Minute uint8 `json:"minute"` Second uint8 `json:"second"` } func (p *TelemetryRtcReset) CANId() (uint32, error) { return 0x700, nil } func (p *TelemetryRtcReset) Size() uint { return 6 } func (p *TelemetryRtcReset) MarshalPacket() ([]byte, error) { b := make([]byte, 6) b[0] = p.Year b[1] = p.Month b[2] = p.Day b[3] = p.Hour b[4] = p.Minute b[5] = p.Second return b, nil } func (p *TelemetryRtcReset) UnmarshalPacket(b []byte) error { p.Year = b[0] p.Month = b[1] p.Day = b[2] p.Hour = b[3] p.Minute = b[4] p.Second = b[5] return nil } func (p *TelemetryRtcReset) String() string { return "telemetry_rtc_reset" } // WsrIdentification is WS RIGHT Identification Information type WsrIdentification struct { TritiumId uint32 `json:"tritium_id"` SerialNumber uint32 `json:"serial_number"` } func (p *WsrIdentification) CANId() (uint32, error) { return 0x140, nil } func (p *WsrIdentification) Size() uint { return 8 } func (p *WsrIdentification) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint32(b[0:], p.TritiumId) binary.LittleEndian.PutUint32(b[4:], p.SerialNumber) return b, nil } func (p *WsrIdentification) UnmarshalPacket(b []byte) error { p.TritiumId = binary.LittleEndian.Uint32(b[0:]) p.SerialNumber = binary.LittleEndian.Uint32(b[4:]) return nil } func (p *WsrIdentification) String() string { return "wsr_identification" } type WsrStatusInformationLimitFlags struct { OutputVoltagePwm bool `json:"output_voltage_pwm"` MotorCurrent bool `json:"motor_current"` Velocity bool `json:"velocity"` BusCurrent bool `json:"bus_current"` BusVoltageUpperLimit bool `json:"bus_voltage_upper_limit"` BusVoltageLowerLimit bool `json:"bus_voltage_lower_limit"` IpmTemperatureOrMotorTemperature bool `json:"ipm_temperature_or_motor_temperature"` Reserved bool `json:"reserved"` } func (p *WsrStatusInformationLimitFlags) MarshalByte() byte { var b byte if p.OutputVoltagePwm { b |= 1 << 0 } if p.MotorCurrent { b |= 1 << 1 } if p.Velocity { b |= 1 << 2 } if p.BusCurrent { b |= 1 << 3 } if p.BusVoltageUpperLimit { b |= 1 << 4 } if p.BusVoltageLowerLimit { b |= 1 << 5 } if p.IpmTemperatureOrMotorTemperature { b |= 1 << 6 } if p.Reserved { b |= 1 << 7 } return b } func (p *WsrStatusInformationLimitFlags) UnmarshalByte(b byte) { p.OutputVoltagePwm = (b & (1 << 0)) != 0 p.MotorCurrent = (b & (1 << 1)) != 0 p.Velocity = (b & (1 << 2)) != 0 p.BusCurrent = (b & (1 << 3)) != 0 p.BusVoltageUpperLimit = (b & (1 << 4)) != 0 p.BusVoltageLowerLimit = (b & (1 << 5)) != 0 p.IpmTemperatureOrMotorTemperature = (b & (1 << 6)) != 0 p.Reserved = (b & (1 << 7)) != 0 } type WsrStatusInformationErrorFlags0 struct { HardwareOverCurrent bool `json:"hardware_over_current"` SoftwareOverCurrent bool `json:"software_over_current"` DcBusOverVoltage bool `json:"dc_bus_over_voltage"` BadMotorPositionHallSequence bool `json:"bad_motor_position_hall_sequence"` WatchdogCausedLastReset bool `json:"watchdog_caused_last_reset"` ConfigReadError bool `json:"config_read_error"` LvRailUnderVoltageLockOut bool `json:"lv_rail_under_voltage_lock_out"` DesaturationFault bool `json:"desaturation_fault"` } func (p *WsrStatusInformationErrorFlags0) MarshalByte() byte { var b byte if p.HardwareOverCurrent { b |= 1 << 0 } if p.SoftwareOverCurrent { b |= 1 << 1 } if p.DcBusOverVoltage { b |= 1 << 2 } if p.BadMotorPositionHallSequence { b |= 1 << 3 } if p.WatchdogCausedLastReset { b |= 1 << 4 } if p.ConfigReadError { b |= 1 << 5 } if p.LvRailUnderVoltageLockOut { b |= 1 << 6 } if p.DesaturationFault { b |= 1 << 7 } return b } func (p *WsrStatusInformationErrorFlags0) UnmarshalByte(b byte) { p.HardwareOverCurrent = (b & (1 << 0)) != 0 p.SoftwareOverCurrent = (b & (1 << 1)) != 0 p.DcBusOverVoltage = (b & (1 << 2)) != 0 p.BadMotorPositionHallSequence = (b & (1 << 3)) != 0 p.WatchdogCausedLastReset = (b & (1 << 4)) != 0 p.ConfigReadError = (b & (1 << 5)) != 0 p.LvRailUnderVoltageLockOut = (b & (1 << 6)) != 0 p.DesaturationFault = (b & (1 << 7)) != 0 } type WsrStatusInformationErrorFlags1 struct { MotorOverSpeed bool `json:"motor_over_speed"` Reserved9 bool `json:"reserved_9"` Reserved10 bool `json:"reserved_10"` Reserved11 bool `json:"reserved_11"` Reserved12 bool `json:"reserved_12"` Reserved13 bool `json:"reserved_13"` Reserved14 bool `json:"reserved_14"` Reserved15 bool `json:"reserved_15"` } func (p *WsrStatusInformationErrorFlags1) MarshalByte() byte { var b byte if p.MotorOverSpeed { b |= 1 << 0 } if p.Reserved9 { b |= 1 << 1 } if p.Reserved10 { b |= 1 << 2 } if p.Reserved11 { b |= 1 << 3 } if p.Reserved12 { b |= 1 << 4 } if p.Reserved13 { b |= 1 << 5 } if p.Reserved14 { b |= 1 << 6 } if p.Reserved15 { b |= 1 << 7 } return b } func (p *WsrStatusInformationErrorFlags1) UnmarshalByte(b byte) { p.MotorOverSpeed = (b & (1 << 0)) != 0 p.Reserved9 = (b & (1 << 1)) != 0 p.Reserved10 = (b & (1 << 2)) != 0 p.Reserved11 = (b & (1 << 3)) != 0 p.Reserved12 = (b & (1 << 4)) != 0 p.Reserved13 = (b & (1 << 5)) != 0 p.Reserved14 = (b & (1 << 6)) != 0 p.Reserved15 = (b & (1 << 7)) != 0 } // WsrStatusInformation is WS RIGHT Status Information type WsrStatusInformation struct { LimitFlags WsrStatusInformationLimitFlags `json:"limit_flags"` LimitFlagsReserved uint8 `json:"limit_flags_reserved"` ErrorFlags0 WsrStatusInformationErrorFlags0 `json:"error_flags_0"` ErrorFlags1 WsrStatusInformationErrorFlags1 `json:"error_flags_1"` ActiveMotor uint16 `json:"active_motor"` Reserved uint16 `json:"reserved"` } func (p *WsrStatusInformation) CANId() (uint32, error) { return 0x141, nil } func (p *WsrStatusInformation) Size() uint { return 8 } func (p *WsrStatusInformation) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.LimitFlags.MarshalByte() b[1] = p.LimitFlagsReserved b[2] = p.ErrorFlags0.MarshalByte() b[3] = p.ErrorFlags1.MarshalByte() binary.LittleEndian.PutUint16(b[4:], p.ActiveMotor) binary.LittleEndian.PutUint16(b[6:], p.Reserved) return b, nil } func (p *WsrStatusInformation) UnmarshalPacket(b []byte) error { p.LimitFlags.UnmarshalByte(b[0]) p.LimitFlagsReserved = b[1] p.ErrorFlags0.UnmarshalByte(b[2]) p.ErrorFlags1.UnmarshalByte(b[3]) p.ActiveMotor = binary.LittleEndian.Uint16(b[4:]) p.Reserved = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *WsrStatusInformation) String() string { return "wsr_status_information" } // WsrBusMeasurement is WS RIGHT Bus Measurement type WsrBusMeasurement struct { // 0 V BusVoltage float32 `json:"bus_voltage"` // 0 A BusCurrent float32 `json:"bus_current"` } func (p *WsrBusMeasurement) CANId() (uint32, error) { return 0x142, nil } func (p *WsrBusMeasurement) Size() uint { return 8 } func (p *WsrBusMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.BusVoltage, false) float32ToBytes(b[4:], p.BusCurrent, false) return b, nil } func (p *WsrBusMeasurement) UnmarshalPacket(b []byte) error { p.BusVoltage = float32FromBytes(b[0:], false) p.BusCurrent = float32FromBytes(b[4:], false) return nil } func (p *WsrBusMeasurement) String() string { return "wsr_bus_measurement" } // WsrVelocity is WS RIGHT Velocity Measurement type WsrVelocity struct { // 0 rpm MotorVelocity float32 `json:"motor_velocity"` // 0 m/s VehicleVelocity float32 `json:"vehicle_velocity"` } func (p *WsrVelocity) CANId() (uint32, error) { return 0x143, nil } func (p *WsrVelocity) Size() uint { return 8 } func (p *WsrVelocity) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MotorVelocity, false) float32ToBytes(b[4:], p.VehicleVelocity, false) return b, nil } func (p *WsrVelocity) UnmarshalPacket(b []byte) error { p.MotorVelocity = float32FromBytes(b[0:], false) p.VehicleVelocity = float32FromBytes(b[4:], false) return nil } func (p *WsrVelocity) String() string { return "wsr_velocity" } // WsrPhaseCurrent is WS RIGHT Phase Current Measurement type WsrPhaseCurrent struct { // 0 A rms PhaseBCurrent float32 `json:"phase_b_current"` // 0 A rms PhaseCCurrent float32 `json:"phase_c_current"` } func (p *WsrPhaseCurrent) CANId() (uint32, error) { return 0x144, nil } func (p *WsrPhaseCurrent) Size() uint { return 8 } func (p *WsrPhaseCurrent) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.PhaseBCurrent, false) float32ToBytes(b[4:], p.PhaseCCurrent, false) return b, nil } func (p *WsrPhaseCurrent) UnmarshalPacket(b []byte) error { p.PhaseBCurrent = float32FromBytes(b[0:], false) p.PhaseCCurrent = float32FromBytes(b[4:], false) return nil } func (p *WsrPhaseCurrent) String() string { return "wsr_phase_current" } // WsrMotorVoltageVector is WS RIGHT Motor Voltage Vector Measurement type WsrMotorVoltageVector struct { // 0 V Vq float32 `json:"vq"` // 0 V Vd float32 `json:"vd"` } func (p *WsrMotorVoltageVector) CANId() (uint32, error) { return 0x145, nil } func (p *WsrMotorVoltageVector) Size() uint { return 8 } func (p *WsrMotorVoltageVector) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Vq, false) float32ToBytes(b[4:], p.Vd, false) return b, nil } func (p *WsrMotorVoltageVector) UnmarshalPacket(b []byte) error { p.Vq = float32FromBytes(b[0:], false) p.Vd = float32FromBytes(b[4:], false) return nil } func (p *WsrMotorVoltageVector) String() string { return "wsr_motor_voltage_vector" } // WsrMotorCurrentVector is WS RIGHT Motor Current Vector Measurement type WsrMotorCurrentVector struct { // 0 A Iq float32 `json:"iq"` // 0 A Id float32 `json:"id"` } func (p *WsrMotorCurrentVector) CANId() (uint32, error) { return 0x146, nil } func (p *WsrMotorCurrentVector) Size() uint { return 8 } func (p *WsrMotorCurrentVector) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Iq, false) float32ToBytes(b[4:], p.Id, false) return b, nil } func (p *WsrMotorCurrentVector) UnmarshalPacket(b []byte) error { p.Iq = float32FromBytes(b[0:], false) p.Id = float32FromBytes(b[4:], false) return nil } func (p *WsrMotorCurrentVector) String() string { return "wsr_motor_current_vector" } // WsrMotorBackemf is WS RIGHT Motor BackEMF Measurement / Prediction type WsrMotorBackemf struct { // 0 V Bemfq float32 `json:"bemfq"` // 0 V Bemfd float32 `json:"bemfd"` } func (p *WsrMotorBackemf) CANId() (uint32, error) { return 0x147, nil } func (p *WsrMotorBackemf) Size() uint { return 8 } func (p *WsrMotorBackemf) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Bemfq, false) float32ToBytes(b[4:], p.Bemfd, false) return b, nil } func (p *WsrMotorBackemf) UnmarshalPacket(b []byte) error { p.Bemfq = float32FromBytes(b[0:], false) p.Bemfd = float32FromBytes(b[4:], false) return nil } func (p *WsrMotorBackemf) String() string { return "wsr_motor_backemf" } // Wsr15165VoltageRail is WS RIGHT 15 and 1.65 Voltage Rail Measurement type Wsr15165VoltageRail struct { // 0 V Reference165V float32 `json:"reference_165v"` // 0 V Supply15V float32 `json:"supply_15v"` } func (p *Wsr15165VoltageRail) CANId() (uint32, error) { return 0x148, nil } func (p *Wsr15165VoltageRail) Size() uint { return 8 } func (p *Wsr15165VoltageRail) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reference165V, false) float32ToBytes(b[4:], p.Supply15V, false) return b, nil } func (p *Wsr15165VoltageRail) UnmarshalPacket(b []byte) error { p.Reference165V = float32FromBytes(b[0:], false) p.Supply15V = float32FromBytes(b[4:], false) return nil } func (p *Wsr15165VoltageRail) String() string { return "wsr_15_165_voltage_rail" } // Wsr2512VoltageRail is WS RIGHT 2.5V and 1.2V Voltage Rail Measurement type Wsr2512VoltageRail struct { // 0 V Supply12V float32 `json:"supply_12v"` // 0 V Supply25V float32 `json:"supply_25v"` } func (p *Wsr2512VoltageRail) CANId() (uint32, error) { return 0x149, nil } func (p *Wsr2512VoltageRail) Size() uint { return 8 } func (p *Wsr2512VoltageRail) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Supply12V, false) float32ToBytes(b[4:], p.Supply25V, false) return b, nil } func (p *Wsr2512VoltageRail) UnmarshalPacket(b []byte) error { p.Supply12V = float32FromBytes(b[0:], false) p.Supply25V = float32FromBytes(b[4:], false) return nil } func (p *Wsr2512VoltageRail) String() string { return "wsr_25_12_voltage_rail" } // WsrHeatsinkMotorTemp is WS RIGHT Heat-sink & Motor Temperature Measurement type WsrHeatsinkMotorTemp struct { // 0 C MotorTemp float32 `json:"motor_temp"` // 0 C HeatsinkTemp float32 `json:"heatsink_temp"` } func (p *WsrHeatsinkMotorTemp) CANId() (uint32, error) { return 0x14B, nil } func (p *WsrHeatsinkMotorTemp) Size() uint { return 8 } func (p *WsrHeatsinkMotorTemp) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MotorTemp, false) float32ToBytes(b[4:], p.HeatsinkTemp, false) return b, nil } func (p *WsrHeatsinkMotorTemp) UnmarshalPacket(b []byte) error { p.MotorTemp = float32FromBytes(b[0:], false) p.HeatsinkTemp = float32FromBytes(b[4:], false) return nil } func (p *WsrHeatsinkMotorTemp) String() string { return "wsr_heatsink_motor_temp" } // WsrDspBoardTemp is WS RIGHT DPS Board Temperature Measurement type WsrDspBoardTemp struct { // 0 C DspBoardTemp float32 `json:"dsp_board_temp"` // 0 C Reserved float32 `json:"reserved"` } func (p *WsrDspBoardTemp) CANId() (uint32, error) { return 0x14C, nil } func (p *WsrDspBoardTemp) Size() uint { return 8 } func (p *WsrDspBoardTemp) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.DspBoardTemp, false) float32ToBytes(b[4:], p.Reserved, false) return b, nil } func (p *WsrDspBoardTemp) UnmarshalPacket(b []byte) error { p.DspBoardTemp = float32FromBytes(b[0:], false) p.Reserved = float32FromBytes(b[4:], false) return nil } func (p *WsrDspBoardTemp) String() string { return "wsr_dsp_board_temp" } // WsrReserved is WS RIGHT Reserved type WsrReserved struct { Reserved0 float32 `json:"reserved0"` Reserved1 float32 `json:"reserved1"` } func (p *WsrReserved) CANId() (uint32, error) { return 0x14D, nil } func (p *WsrReserved) Size() uint { return 8 } func (p *WsrReserved) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reserved0, false) float32ToBytes(b[4:], p.Reserved1, false) return b, nil } func (p *WsrReserved) UnmarshalPacket(b []byte) error { p.Reserved0 = float32FromBytes(b[0:], false) p.Reserved1 = float32FromBytes(b[4:], false) return nil } func (p *WsrReserved) String() string { return "wsr_reserved" } // WsrOdometerBusAmphoursMeasurement is WS RIGHT Odometer and Bus AmpHours Measurement type WsrOdometerBusAmphoursMeasurement struct { // 0 m Odometer float32 `json:"odometer"` // 0 Ah DcBusAmphours float32 `json:"dc_bus_amphours"` } func (p *WsrOdometerBusAmphoursMeasurement) CANId() (uint32, error) { return 0x14E, nil } func (p *WsrOdometerBusAmphoursMeasurement) Size() uint { return 8 } func (p *WsrOdometerBusAmphoursMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Odometer, false) float32ToBytes(b[4:], p.DcBusAmphours, false) return b, nil } func (p *WsrOdometerBusAmphoursMeasurement) UnmarshalPacket(b []byte) error { p.Odometer = float32FromBytes(b[0:], false) p.DcBusAmphours = float32FromBytes(b[4:], false) return nil } func (p *WsrOdometerBusAmphoursMeasurement) String() string { return "wsr_odometer_bus_amphours_measurement" } // WsrSlipSpeedMeasurement is WS RIGHT Slip Speed Measurement type WsrSlipSpeedMeasurement struct { // 0 C Reserved float32 `json:"reserved"` // 0 Hz SlipSpeed float32 `json:"slip_speed"` } func (p *WsrSlipSpeedMeasurement) CANId() (uint32, error) { return 0x157, nil } func (p *WsrSlipSpeedMeasurement) Size() uint { return 8 } func (p *WsrSlipSpeedMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reserved, false) float32ToBytes(b[4:], p.SlipSpeed, false) return b, nil } func (p *WsrSlipSpeedMeasurement) UnmarshalPacket(b []byte) error { p.Reserved = float32FromBytes(b[0:], false) p.SlipSpeed = float32FromBytes(b[4:], false) return nil } func (p *WsrSlipSpeedMeasurement) String() string { return "wsr_slip_speed_measurement" } // WslIdentification is WS LEFT Identification Information type WslIdentification struct { TritiumId uint32 `json:"tritium_id"` SerialNumber uint32 `json:"serial_number"` } func (p *WslIdentification) CANId() (uint32, error) { return 0x100, nil } func (p *WslIdentification) Size() uint { return 8 } func (p *WslIdentification) MarshalPacket() ([]byte, error) { b := make([]byte, 8) binary.LittleEndian.PutUint32(b[0:], p.TritiumId) binary.LittleEndian.PutUint32(b[4:], p.SerialNumber) return b, nil } func (p *WslIdentification) UnmarshalPacket(b []byte) error { p.TritiumId = binary.LittleEndian.Uint32(b[0:]) p.SerialNumber = binary.LittleEndian.Uint32(b[4:]) return nil } func (p *WslIdentification) String() string { return "wsl_identification" } type WslStatusInformationLimitFlags struct { OutputVoltagePwm bool `json:"output_voltage_pwm"` MotorCurrent bool `json:"motor_current"` Velocity bool `json:"velocity"` BusCurrent bool `json:"bus_current"` BusVoltageUpperLimit bool `json:"bus_voltage_upper_limit"` BusVoltageLowerLimit bool `json:"bus_voltage_lower_limit"` IpmTemperatureOrMotorTemperature bool `json:"ipm_temperature_or_motor_temperature"` Reserved bool `json:"reserved"` } func (p *WslStatusInformationLimitFlags) MarshalByte() byte { var b byte if p.OutputVoltagePwm { b |= 1 << 0 } if p.MotorCurrent { b |= 1 << 1 } if p.Velocity { b |= 1 << 2 } if p.BusCurrent { b |= 1 << 3 } if p.BusVoltageUpperLimit { b |= 1 << 4 } if p.BusVoltageLowerLimit { b |= 1 << 5 } if p.IpmTemperatureOrMotorTemperature { b |= 1 << 6 } if p.Reserved { b |= 1 << 7 } return b } func (p *WslStatusInformationLimitFlags) UnmarshalByte(b byte) { p.OutputVoltagePwm = (b & (1 << 0)) != 0 p.MotorCurrent = (b & (1 << 1)) != 0 p.Velocity = (b & (1 << 2)) != 0 p.BusCurrent = (b & (1 << 3)) != 0 p.BusVoltageUpperLimit = (b & (1 << 4)) != 0 p.BusVoltageLowerLimit = (b & (1 << 5)) != 0 p.IpmTemperatureOrMotorTemperature = (b & (1 << 6)) != 0 p.Reserved = (b & (1 << 7)) != 0 } type WslStatusInformationErrorFlags0 struct { HardwareOverCurrent bool `json:"hardware_over_current"` SoftwareOverCurrent bool `json:"software_over_current"` DcBusOverVoltage bool `json:"dc_bus_over_voltage"` BadMotorPositionHallSequence bool `json:"bad_motor_position_hall_sequence"` WatchdogCausedLastReset bool `json:"watchdog_caused_last_reset"` ConfigReadError bool `json:"config_read_error"` LvRailUnderVoltageLockOut bool `json:"lv_rail_under_voltage_lock_out"` DesaturationFault bool `json:"desaturation_fault"` } func (p *WslStatusInformationErrorFlags0) MarshalByte() byte { var b byte if p.HardwareOverCurrent { b |= 1 << 0 } if p.SoftwareOverCurrent { b |= 1 << 1 } if p.DcBusOverVoltage { b |= 1 << 2 } if p.BadMotorPositionHallSequence { b |= 1 << 3 } if p.WatchdogCausedLastReset { b |= 1 << 4 } if p.ConfigReadError { b |= 1 << 5 } if p.LvRailUnderVoltageLockOut { b |= 1 << 6 } if p.DesaturationFault { b |= 1 << 7 } return b } func (p *WslStatusInformationErrorFlags0) UnmarshalByte(b byte) { p.HardwareOverCurrent = (b & (1 << 0)) != 0 p.SoftwareOverCurrent = (b & (1 << 1)) != 0 p.DcBusOverVoltage = (b & (1 << 2)) != 0 p.BadMotorPositionHallSequence = (b & (1 << 3)) != 0 p.WatchdogCausedLastReset = (b & (1 << 4)) != 0 p.ConfigReadError = (b & (1 << 5)) != 0 p.LvRailUnderVoltageLockOut = (b & (1 << 6)) != 0 p.DesaturationFault = (b & (1 << 7)) != 0 } type WslStatusInformationErrorFlags1 struct { MotorOverSpeed bool `json:"motor_over_speed"` Reserved9 bool `json:"reserved_9"` Reserved10 bool `json:"reserved_10"` Reserved11 bool `json:"reserved_11"` Reserved12 bool `json:"reserved_12"` Reserved13 bool `json:"reserved_13"` Reserved14 bool `json:"reserved_14"` Reserved15 bool `json:"reserved_15"` } func (p *WslStatusInformationErrorFlags1) MarshalByte() byte { var b byte if p.MotorOverSpeed { b |= 1 << 0 } if p.Reserved9 { b |= 1 << 1 } if p.Reserved10 { b |= 1 << 2 } if p.Reserved11 { b |= 1 << 3 } if p.Reserved12 { b |= 1 << 4 } if p.Reserved13 { b |= 1 << 5 } if p.Reserved14 { b |= 1 << 6 } if p.Reserved15 { b |= 1 << 7 } return b } func (p *WslStatusInformationErrorFlags1) UnmarshalByte(b byte) { p.MotorOverSpeed = (b & (1 << 0)) != 0 p.Reserved9 = (b & (1 << 1)) != 0 p.Reserved10 = (b & (1 << 2)) != 0 p.Reserved11 = (b & (1 << 3)) != 0 p.Reserved12 = (b & (1 << 4)) != 0 p.Reserved13 = (b & (1 << 5)) != 0 p.Reserved14 = (b & (1 << 6)) != 0 p.Reserved15 = (b & (1 << 7)) != 0 } // WslStatusInformation is WS LEFT Status Information type WslStatusInformation struct { LimitFlags WslStatusInformationLimitFlags `json:"limit_flags"` LimitFlagsReserved uint8 `json:"limit_flags_reserved"` ErrorFlags0 WslStatusInformationErrorFlags0 `json:"error_flags_0"` ErrorFlags1 WslStatusInformationErrorFlags1 `json:"error_flags_1"` ActiveMotor uint16 `json:"active_motor"` Reserved uint16 `json:"reserved"` } func (p *WslStatusInformation) CANId() (uint32, error) { return 0x101, nil } func (p *WslStatusInformation) Size() uint { return 8 } func (p *WslStatusInformation) MarshalPacket() ([]byte, error) { b := make([]byte, 8) b[0] = p.LimitFlags.MarshalByte() b[1] = p.LimitFlagsReserved b[2] = p.ErrorFlags0.MarshalByte() b[3] = p.ErrorFlags1.MarshalByte() binary.LittleEndian.PutUint16(b[4:], p.ActiveMotor) binary.LittleEndian.PutUint16(b[6:], p.Reserved) return b, nil } func (p *WslStatusInformation) UnmarshalPacket(b []byte) error { p.LimitFlags.UnmarshalByte(b[0]) p.LimitFlagsReserved = b[1] p.ErrorFlags0.UnmarshalByte(b[2]) p.ErrorFlags1.UnmarshalByte(b[3]) p.ActiveMotor = binary.LittleEndian.Uint16(b[4:]) p.Reserved = binary.LittleEndian.Uint16(b[6:]) return nil } func (p *WslStatusInformation) String() string { return "wsl_status_information" } // WslBusMeasurement is WS LEFT Bus Measurement type WslBusMeasurement struct { // 0 V BusVoltage float32 `json:"bus_voltage"` // 0 A BusCurrent float32 `json:"bus_current"` } func (p *WslBusMeasurement) CANId() (uint32, error) { return 0x102, nil } func (p *WslBusMeasurement) Size() uint { return 8 } func (p *WslBusMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.BusVoltage, false) float32ToBytes(b[4:], p.BusCurrent, false) return b, nil } func (p *WslBusMeasurement) UnmarshalPacket(b []byte) error { p.BusVoltage = float32FromBytes(b[0:], false) p.BusCurrent = float32FromBytes(b[4:], false) return nil } func (p *WslBusMeasurement) String() string { return "wsl_bus_measurement" } // WslVelocity is WS LEFT Velocity Measurement type WslVelocity struct { // 0 rpm MotorVelocity float32 `json:"motor_velocity"` // 0 m/s VehicleVelocity float32 `json:"vehicle_velocity"` } func (p *WslVelocity) CANId() (uint32, error) { return 0x103, nil } func (p *WslVelocity) Size() uint { return 8 } func (p *WslVelocity) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MotorVelocity, false) float32ToBytes(b[4:], p.VehicleVelocity, false) return b, nil } func (p *WslVelocity) UnmarshalPacket(b []byte) error { p.MotorVelocity = float32FromBytes(b[0:], false) p.VehicleVelocity = float32FromBytes(b[4:], false) return nil } func (p *WslVelocity) String() string { return "wsl_velocity" } // WslPhaseCurrent is WS LEFT Phase Current Measurement type WslPhaseCurrent struct { // 0 A rms PhaseBCurrent float32 `json:"phase_b_current"` // 0 A rms PhaseCCurrent float32 `json:"phase_c_current"` } func (p *WslPhaseCurrent) CANId() (uint32, error) { return 0x104, nil } func (p *WslPhaseCurrent) Size() uint { return 8 } func (p *WslPhaseCurrent) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.PhaseBCurrent, false) float32ToBytes(b[4:], p.PhaseCCurrent, false) return b, nil } func (p *WslPhaseCurrent) UnmarshalPacket(b []byte) error { p.PhaseBCurrent = float32FromBytes(b[0:], false) p.PhaseCCurrent = float32FromBytes(b[4:], false) return nil } func (p *WslPhaseCurrent) String() string { return "wsl_phase_current" } // WslMotorVoltageVector is WS LEFT Motor Voltage Vector Measurement type WslMotorVoltageVector struct { // 0 V Vq float32 `json:"vq"` // 0 V Vd float32 `json:"vd"` } func (p *WslMotorVoltageVector) CANId() (uint32, error) { return 0x105, nil } func (p *WslMotorVoltageVector) Size() uint { return 8 } func (p *WslMotorVoltageVector) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Vq, false) float32ToBytes(b[4:], p.Vd, false) return b, nil } func (p *WslMotorVoltageVector) UnmarshalPacket(b []byte) error { p.Vq = float32FromBytes(b[0:], false) p.Vd = float32FromBytes(b[4:], false) return nil } func (p *WslMotorVoltageVector) String() string { return "wsl_motor_voltage_vector" } // WslMotorCurrentVector is WS LEFT Motor Current Vector Measurement type WslMotorCurrentVector struct { // 0 A Iq float32 `json:"iq"` // 0 A Id float32 `json:"id"` } func (p *WslMotorCurrentVector) CANId() (uint32, error) { return 0x106, nil } func (p *WslMotorCurrentVector) Size() uint { return 8 } func (p *WslMotorCurrentVector) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Iq, false) float32ToBytes(b[4:], p.Id, false) return b, nil } func (p *WslMotorCurrentVector) UnmarshalPacket(b []byte) error { p.Iq = float32FromBytes(b[0:], false) p.Id = float32FromBytes(b[4:], false) return nil } func (p *WslMotorCurrentVector) String() string { return "wsl_motor_current_vector" } // WslMotorBackemf is WS LEFT Motor BackEMF Measurement / Prediction type WslMotorBackemf struct { // 0 V Bemfq float32 `json:"bemfq"` // 0 V Bemfd float32 `json:"bemfd"` } func (p *WslMotorBackemf) CANId() (uint32, error) { return 0x107, nil } func (p *WslMotorBackemf) Size() uint { return 8 } func (p *WslMotorBackemf) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Bemfq, false) float32ToBytes(b[4:], p.Bemfd, false) return b, nil } func (p *WslMotorBackemf) UnmarshalPacket(b []byte) error { p.Bemfq = float32FromBytes(b[0:], false) p.Bemfd = float32FromBytes(b[4:], false) return nil } func (p *WslMotorBackemf) String() string { return "wsl_motor_backemf" } // Wsl15165VoltageRail is WS LEFT 15 and 1.65 Voltage Rail Measurement type Wsl15165VoltageRail struct { // 0 V Reference165V float32 `json:"reference_165v"` // 0 V Supply15V float32 `json:"supply_15v"` } func (p *Wsl15165VoltageRail) CANId() (uint32, error) { return 0x108, nil } func (p *Wsl15165VoltageRail) Size() uint { return 8 } func (p *Wsl15165VoltageRail) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reference165V, false) float32ToBytes(b[4:], p.Supply15V, false) return b, nil } func (p *Wsl15165VoltageRail) UnmarshalPacket(b []byte) error { p.Reference165V = float32FromBytes(b[0:], false) p.Supply15V = float32FromBytes(b[4:], false) return nil } func (p *Wsl15165VoltageRail) String() string { return "wsl_15_165_voltage_rail" } // Wsl2512VoltageRail is WS LEFT 2.5V and 1.2V Voltage Rail Measurement type Wsl2512VoltageRail struct { // 0 V Supply12V float32 `json:"supply_12v"` // 0 V Supply25V float32 `json:"supply_25v"` } func (p *Wsl2512VoltageRail) CANId() (uint32, error) { return 0x109, nil } func (p *Wsl2512VoltageRail) Size() uint { return 8 } func (p *Wsl2512VoltageRail) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Supply12V, false) float32ToBytes(b[4:], p.Supply25V, false) return b, nil } func (p *Wsl2512VoltageRail) UnmarshalPacket(b []byte) error { p.Supply12V = float32FromBytes(b[0:], false) p.Supply25V = float32FromBytes(b[4:], false) return nil } func (p *Wsl2512VoltageRail) String() string { return "wsl_25_12_voltage_rail" } // WslHeatsinkMotorTemp is WS LEFT Heat-sink & Motor Temperature Measurement type WslHeatsinkMotorTemp struct { // 0 C MotorTemp float32 `json:"motor_temp"` // 0 C HeatsinkTemp float32 `json:"heatsink_temp"` } func (p *WslHeatsinkMotorTemp) CANId() (uint32, error) { return 0x10B, nil } func (p *WslHeatsinkMotorTemp) Size() uint { return 8 } func (p *WslHeatsinkMotorTemp) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.MotorTemp, false) float32ToBytes(b[4:], p.HeatsinkTemp, false) return b, nil } func (p *WslHeatsinkMotorTemp) UnmarshalPacket(b []byte) error { p.MotorTemp = float32FromBytes(b[0:], false) p.HeatsinkTemp = float32FromBytes(b[4:], false) return nil } func (p *WslHeatsinkMotorTemp) String() string { return "wsl_heatsink_motor_temp" } // WslDspBoardTemp is WS LEFT DPS Board Temperature Measurement type WslDspBoardTemp struct { // 0 C DspBoardTemp float32 `json:"dsp_board_temp"` // 0 C Reserved float32 `json:"reserved"` } func (p *WslDspBoardTemp) CANId() (uint32, error) { return 0x10C, nil } func (p *WslDspBoardTemp) Size() uint { return 8 } func (p *WslDspBoardTemp) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.DspBoardTemp, false) float32ToBytes(b[4:], p.Reserved, false) return b, nil } func (p *WslDspBoardTemp) UnmarshalPacket(b []byte) error { p.DspBoardTemp = float32FromBytes(b[0:], false) p.Reserved = float32FromBytes(b[4:], false) return nil } func (p *WslDspBoardTemp) String() string { return "wsl_dsp_board_temp" } // WslOdometerBusAmphoursMeasurement is WS LEFT Odometer and Bus AmpHours Measurement type WslOdometerBusAmphoursMeasurement struct { // 0 m Odometer float32 `json:"odometer"` // 0 Ah DcBusAmphours float32 `json:"dc_bus_amphours"` } func (p *WslOdometerBusAmphoursMeasurement) CANId() (uint32, error) { return 0x10E, nil } func (p *WslOdometerBusAmphoursMeasurement) Size() uint { return 8 } func (p *WslOdometerBusAmphoursMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Odometer, false) float32ToBytes(b[4:], p.DcBusAmphours, false) return b, nil } func (p *WslOdometerBusAmphoursMeasurement) UnmarshalPacket(b []byte) error { p.Odometer = float32FromBytes(b[0:], false) p.DcBusAmphours = float32FromBytes(b[4:], false) return nil } func (p *WslOdometerBusAmphoursMeasurement) String() string { return "wsl_odometer_bus_amphours_measurement" } // WslReserved is WS LEFT Reserved type WslReserved struct { Reserved0 float32 `json:"reserved0"` Reserved1 float32 `json:"reserved1"` } func (p *WslReserved) CANId() (uint32, error) { return 0x10D, nil } func (p *WslReserved) Size() uint { return 8 } func (p *WslReserved) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reserved0, false) float32ToBytes(b[4:], p.Reserved1, false) return b, nil } func (p *WslReserved) UnmarshalPacket(b []byte) error { p.Reserved0 = float32FromBytes(b[0:], false) p.Reserved1 = float32FromBytes(b[4:], false) return nil } func (p *WslReserved) String() string { return "wsl_reserved" } // WslSlipSpeedMeasurement is WS LEFT Slip Speed Measurement type WslSlipSpeedMeasurement struct { // 0 C Reserved float32 `json:"reserved"` // 0 Hz SlipSpeed float32 `json:"slip_speed"` } func (p *WslSlipSpeedMeasurement) CANId() (uint32, error) { return 0x117, nil } func (p *WslSlipSpeedMeasurement) Size() uint { return 8 } func (p *WslSlipSpeedMeasurement) MarshalPacket() ([]byte, error) { b := make([]byte, 8) float32ToBytes(b[0:], p.Reserved, false) float32ToBytes(b[4:], p.SlipSpeed, false) return b, nil } func (p *WslSlipSpeedMeasurement) UnmarshalPacket(b []byte) error { p.Reserved = float32FromBytes(b[0:], false) p.SlipSpeed = float32FromBytes(b[4:], false) return nil } func (p *WslSlipSpeedMeasurement) String() string { return "wsl_slip_speed_measurement" } // The json representation that was used to generate this data. // can be used to share the parsing data for i.e dynamic python gui. const SkylabDefinitions = `{"packets":[{"name":"bms_measurement","description":"Voltages for main battery and aux pack","id":16,"endian":"little","repeat":0,"offset":0,"data":[{"name":"battery_voltage","type":"uint16_t","units":"V","conversion":0.01,"bits":null},{"name":"aux_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null},{"name":"current","type":"float","units":"A","conversion":1,"bits":null}]},{"name":"battery_status","description":"Status bits for the battery","id":17,"endian":"little","repeat":0,"offset":0,"data":[{"name":"battery_state","type":"bitfield","units":"","conversion":0,"bits":[{"name":"startup"},{"name":"precharge"},{"name":"discharging"},{"name":"lv_only"},{"name":"charging"},{"name":"wall_charging"},{"name":"killed"}]},{"name":"contactor_state","type":"bitfield","units":"","conversion":0,"bits":[{"name":"battery_high_contactor"},{"name":"battery_low_contactor"},{"name":"battery_vicor_contactor"},{"name":"battery_pre_contactor"},{"name":"battery_high2_contactor"},{"name":"battery_low2_contactor"},{"name":"charger_high_contactor"},{"name":"charger_pre_contactor"}]},{"name":"lv_channel_status","type":"bitfield","units":"","conversion":0,"bits":[{"name":"aux_fault"},{"name":"main_fault"},{"name":"aux_power_valid"},{"name":"main_power_valid"},{"name":"aux_power_active"},{"name":"main_power_active"}]},{"name":"lv_control_status","type":"bitfield","units":"","conversion":0,"bits":[{"name":"aux_vicor_enable"},{"name":"bat_vicor_enable"},{"name":"aux_relay_held"},{"name":"aux_ref_enable"},{"name":"aux_charging_enable"},{"name":"kill_hv"},{"name":"kill_lv"},{"name":"start_button"}]}]},{"name":"bms_kill_reason","description":"Information for when the car kills","id":18,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reason1","type":"bitfield","units":"","conversion":0,"bits":[{"name":"OVERVOLT"},{"name":"UNDERVOLT"},{"name":"OVERTEMP"},{"name":"TEMP_DISCONNECT"},{"name":"COMM_FAIL"}]},{"name":"reason2","type":"bitfield","units":"","conversion":0,"bits":[{"name":"HARDWARE"},{"name":"KILL_PACKET"},{"name":"UKNOWN"},{"name":"OVERCURRENT"},{"name":"PRECHARGE_FAIL"},{"name":"AUX_OVER_UNDER"}]},{"name":"module","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"value","type":"float","units":"","conversion":0,"bits":null}]},{"name":"bms_module_min_max","description":"min and max cell voltages and temperatures","id":19,"endian":"little","repeat":0,"offset":0,"data":[{"name":"module_max_temp","type":"int16_t","units":"C","conversion":0.01,"bits":null},{"name":"module_min_temp","type":"int16_t","units":"C","conversion":0.01,"bits":null},{"name":"module_max_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null},{"name":"module_min_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null}]},{"name":"bms_soc","description":"State of charge","id":20,"endian":"little","repeat":0,"offset":0,"data":[{"name":"soc","type":"float","units":"","conversion":1,"bits":null}]},{"name":"bms_capacity","description":"State of charge","id":21,"endian":"little","repeat":0,"offset":0,"data":[{"name":"Ah","type":"float","units":"","conversion":1,"bits":null},{"name":"Wh","type":"float","units":"","conversion":1,"bits":null}]},{"name":"bms_currentlimit","description":"reports BP params for current","id":24,"endian":"little","repeat":0,"offset":0,"data":[{"name":"current_max","type":"int16_t","units":"A","conversion":0.01,"bits":null},{"name":"current_min","type":"int16_t","units":"A","conversion":0.01,"bits":null}]},{"name":"bms_fan_info","description":"BP Fans","id":25,"endian":"little","repeat":0,"offset":0,"data":[{"name":"fan1","type":"uint16_t","units":"RPM","conversion":1,"bits":null},{"name":"fan2","type":"uint16_t","units":"RPM","conversion":1,"bits":null},{"name":"fan3","type":"uint16_t","units":"RPM","conversion":1,"bits":null},{"name":"fan4","type":"uint16_t","units":"RPM","conversion":1,"bits":null}]},{"name":"bms_set_min_fan_speed","description":"packet which sets a minimum fan speed of BMS for a specific time frame in seconds","id":27,"endian":"little","repeat":0,"offset":0,"data":[{"name":"fan_percentage","type":"float","units":"percent","conversion":0,"bits":null},{"name":"time","type":"uint16_t","units":"s","conversion":0,"bits":null}]},{"name":"bms_module","description":"Voltage and temperature for a single module","id":28,"endian":"little","repeat":36,"offset":1,"data":[{"name":"voltage","type":"float","units":"V","conversion":1,"bits":null},{"name":"temperature","type":"float","units":"C","conversion":1,"bits":null}]},{"name":"bms_charger_response","description":"Response packet from BMS for indicating whether BMS is ready for charging","id":117,"endian":"","repeat":0,"offset":0,"data":[{"name":"response_flags","type":"bitfield","units":"","conversion":0,"bits":[{"name":"charging_ready"}]}]},{"name":"dashboard_pedal_percentages","description":"ADC values from the brake and accelerator pedals.","id":656,"endian":"little","repeat":0,"offset":0,"data":[{"name":"accel_pedal_value","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"brake_pedal_value","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"car_state","description":"Car gear. Forward, neutral, reverse, etc.","id":657,"endian":"little","repeat":0,"offset":0,"data":[{"name":"state","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"dashboard_pedal_fault","description":"Target speed that the driver should maintain.","id":658,"endian":"little","repeat":0,"offset":0,"data":[{"name":"brake_fault_count","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"accel_fault_count","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"dashboard_system_timeout_test","description":"Exposes whether each system that dashboard is supposed to listen for packets from has sent a packet. Used for testing.","id":665,"endian":"little","repeat":0,"offset":0,"data":[{"name":"flag_set_0","type":"bitfield","units":"","conversion":0,"bits":[{"name":"steering_disconnected"},{"name":"vision_front_disconnected"},{"name":"vision_rear_disconnected"},{"name":"telemetry_disconnected"},{"name":"wsl_disconnected"},{"name":"wsr_disconnected"},{"name":"front_mppt_disconnected"},{"name":"rear_mppt_disconnected"}]}]},{"name":"car_speed","description":"speed of car in meters per second","id":666,"endian":"little","repeat":0,"offset":0,"data":[{"name":"speed","type":"float","units":"","conversion":0,"bits":null}]},{"name":"flight_computer_lv_board_disconnect_counts","description":"Number of times a board hasn't been heard from within the allowed timeout.","id":667,"endian":"little","repeat":0,"offset":0,"data":[{"name":"front_lights","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"rear_lights","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"steering","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"vision","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"driver_display","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"center_console","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"flight_computer_hv_board_disconnect_counts","description":"Number of times a board hasn't been heard from within the allowed timeout.","id":668,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bms","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"charger","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"wsl","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"wsr","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"mppt_front","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"mppt_rear","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"flight_computer_internal_state","description":"internal bools","id":669,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bms","type":"bitfield","units":"","conversion":0,"bits":[{"name":"battery_kill"},{"name":"cells_in_charging_threshold"},{"name":"first_packet_received"}]},{"name":"charger","type":"bitfield","units":"","conversion":0,"bits":[{"name":"proximity_detected"}]},{"name":"photon3","type":"bitfield","units":"","conversion":0,"bits":[{"name":"enable"}]},{"name":"wavesculptor","type":"bitfield","units":"","conversion":0,"bits":[{"name":"sending_reset"},{"name":"regen_enable"}]},{"name":"internal","type":"bitfield","units":"","conversion":0,"bits":[{"name":"accel_pedal_disconnect"},{"name":"brake_pedal_disconnect"}]}]},{"name":"power_to_drive","description":"calculated power required to drive the vehicle","id":414,"endian":"little","repeat":0,"offset":0,"data":[{"name":"moving_average_100","type":"int16_t","units":"","conversion":0,"bits":null},{"name":"moving_average_1k","type":"int16_t","units":"","conversion":0,"bits":null},{"name":"moving_average_10k","type":"int16_t","units":"","conversion":0,"bits":null}]},{"name":"array_power","description":"array power calculated from current and voltage measurements","id":415,"endian":"little","repeat":0,"offset":0,"data":[{"name":"front_array_channel_0","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"front_array_channel_1","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"rear_array_channel_0","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"rear_array_channel_1","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"vision_turn_signals_command","description":"Command to have the vision board illuminate or turn off left, right, or both turn signals","id":688,"endian":"","repeat":0,"offset":0,"data":[{"name":"lights","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left_turn_signal"},{"name":"right_turn_signal"},{"name":"spare_1"},{"name":"spare_2"},{"name":"spare_3"}]}]},{"name":"vision_brake_lights_command","description":"Command to have the vision board illuminate or turn off the brake lights","id":689,"endian":"","repeat":0,"offset":0,"data":[{"name":"lights","type":"bitfield","units":"","conversion":0,"bits":[{"name":"brake_lights"},{"name":"spare_1"},{"name":"spare_2"},{"name":"spare_3"}]}]},{"name":"vision_headlights_command","description":"Command to have the vision board illuminate or turn off the headlights and high beams","id":690,"endian":"","repeat":0,"offset":0,"data":[{"name":"lights","type":"bitfield","units":"","conversion":0,"bits":[{"name":"headlights"},{"name":"high_beams"},{"name":"spare_1"},{"name":"spare_2"},{"name":"spare_3"}]},{"name":"brightness","type":"float","units":"","conversion":0,"bits":null}]},{"name":"vision_horn_command","description":"Command the vision board honk the horn, must be repeatedly sent otherwise the vision board will stop honking after a bit. See high_power.h for details.","id":691,"endian":"","repeat":0,"offset":0,"data":[{"name":"horn","type":"bitfield","units":"","conversion":0,"bits":[{"name":"horn"},{"name":"spare"}]}]},{"name":"vision_array_latches_command","description":"Command the vision board to open the array latches","id":692,"endian":"","repeat":0,"offset":0,"data":[{"name":"array_latches","type":"bitfield","units":"","conversion":0,"bits":[{"name":"array_front"},{"name":"array_rear"}]}]},{"name":"vision_rearview_command","description":"Command the vision board turn on the rear view cameras","id":693,"endian":"","repeat":0,"offset":0,"data":[{"name":"cameras","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left"},{"name":"right"},{"name":"rear"}]}]},{"name":"tracker_enable","description":"Enables/disables power trackers. Use 0x610 for the channel transmitting the data packet on 0x600, 0x611 for 0x601, et cetera. Sending 1 in the enable byte turns the tracker on; sending 0 turns it off.","id":1552,"endian":"little","repeat":6,"offset":1,"data":[{"name":"enable","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"distance_traveled","description":"distance of wavesculptor odometer","id":512,"endian":"little","repeat":0,"offset":0,"data":[{"name":"trip_distance","type":"float","units":"m","conversion":0,"bits":null}]},{"name":"charger_state","description":"Notifies whether the J1772 cable is plugged.","id":1395,"endian":"","repeat":0,"offset":0,"data":[{"name":"state_flags","type":"bitfield","units":"","conversion":0,"bits":[{"name":"charger_plugged"}]},{"name":"charger_max_temp","type":"uint16_t","units":"C","conversion":0.001,"bits":null},{"name":"fault","type":"bitfield","units":"","conversion":0,"bits":[{"name":"CHARGER_OVERVOLT"},{"name":"CHARGER_OVERTEMP"},{"name":"CHARGER_CAN_TIMEOUT"},{"name":"BATTERY_HV_KILL"},{"name":"BATTERY_UNDERVOLT"},{"name":"BATTERY_OVERVOLT"},{"name":"BATTERY_CELL_OVERTEMP"},{"name":"BATTERY_CAN_TIMEOUT"}]},{"name":"charging_current","type":"float","units":"A","conversion":0,"bits":null}]},{"name":"charger_bms_request","description":"Request packet for sending contactor commands from the charger to BP.","id":116,"endian":"","repeat":0,"offset":0,"data":[{"name":"request_flags","type":"bitfield","units":"","conversion":0,"bits":[{"name":"charging_requested"}]}]},{"name":"charger_current_voltage","description":"Packet to request charging current/voltage set","id":1398,"endian":"","repeat":0,"offset":0,"data":[{"name":"max_current","type":"float","units":"A","conversion":0,"bits":null},{"name":"max_capacity","type":"float","units":"kWh","conversion":0,"bits":null}]},{"name":"charger_power","description":"Outputs the amount of power that the chargers are delivering.","id":1399,"endian":"","repeat":0,"offset":0,"data":[{"name":"power","type":"float","units":"W","conversion":0,"bits":null}]},{"name":"thunderstruck_control_message","description":"Control packet for thunderstruck chargers","id":417677348,"endian":"little","repeat":0,"offset":0,"data":[{"name":"Enable","type":"uint8_t","units":"V","conversion":1,"bits":null},{"name":"CHARGE_VOLTAGE","type":"uint16_t","units":"V","conversion":1,"bits":null},{"name":"CHARGE_CURRENT","type":"uint16_t","units":"V","conversion":1,"bits":null},{"name":"LED_BLINK_PATTERN","type":"uint8_t","units":"V","conversion":1,"bits":null},{"name":"RESERVED","type":"uint16_t","units":"V","conversion":1,"bits":null}]},{"name":"vision_status_front","description":"Status of the front vision board outputs","id":694,"endian":"","repeat":0,"offset":0,"data":[{"name":"lights","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left_turn_signal"},{"name":"right_turn_signal"},{"name":"brake_lights"},{"name":"headlights"},{"name":"high_beams"},{"name":"spare_1"},{"name":"spare_2"},{"name":"spare_3"}]},{"name":"horn","type":"bitfield","units":"","conversion":0,"bits":[{"name":"horn"},{"name":"spare"}]},{"name":"cameras","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left"},{"name":"right"},{"name":"rear"}]},{"name":"array_latches","type":"bitfield","units":"","conversion":0,"bits":[{"name":"array_front_0"},{"name":"array_front_1"},{"name":"array_rear_0"},{"name":"array_rear_1"}]}]},{"name":"vision_status_rear","description":"Status of the rear vision board outputs","id":695,"endian":"","repeat":0,"offset":0,"data":[{"name":"lights","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left_turn_signal"},{"name":"right_turn_signal"},{"name":"brake_lights"},{"name":"headlights"},{"name":"high_beams"},{"name":"spare_1"},{"name":"spare_2"},{"name":"spare_3"}]},{"name":"horn","type":"bitfield","units":"","conversion":0,"bits":[{"name":"horn"},{"name":"spare"}]},{"name":"cameras","type":"bitfield","units":"","conversion":0,"bits":[{"name":"left"},{"name":"right"},{"name":"rear"}]},{"name":"array_latches","type":"bitfield","units":"","conversion":0,"bits":[{"name":"array_front_0"},{"name":"array_front_1"},{"name":"array_rear_0"},{"name":"array_rear_1"}]}]},{"name":"lights_front_id","description":"Unique identification packet for front lights board","id":768,"endian":"","repeat":0,"offset":0,"data":[{"name":"board_id","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"mcu_temp","type":"int16_t","units":"C","conversion":0.01,"bits":null},{"name":"bus_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null},{"name":"fault_code","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"lights_back_id","description":"Unique identification packet for back lights board","id":769,"endian":"","repeat":0,"offset":0,"data":[{"name":"board_id","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"mcu_temp","type":"int16_t","units":"C","conversion":0.01,"bits":null},{"name":"bus_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null},{"name":"fault_code","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"vision_id","description":"Unique identification packet for vision","id":770,"endian":"","repeat":0,"offset":0,"data":[{"name":"board_id","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"mcu_temp","type":"int16_t","units":"C","conversion":0.01,"bits":null},{"name":"bus_voltage","type":"uint16_t","units":"V","conversion":0.001,"bits":null},{"name":"fault_code","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"steering_press_count_1","description":"Shows whether each button has been toggled an even (\"on\") or odd (\"off\") number of times.","id":576,"endian":"","repeat":0,"offset":0,"data":[{"name":"button0","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button1","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button2","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button3","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button4","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button5","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button6","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"steering_press_count_2","description":"Shows whether each button has been toggled an even (\"on\") or odd (\"off\") number of times.","id":592,"endian":"","repeat":0,"offset":0,"data":[{"name":"button7","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button8","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button9","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button10","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"steering_button_colors_1","description":"This packet controls each button's color. Each byte is a hex color code.","id":577,"endian":"","repeat":0,"offset":0,"data":[{"name":"button0","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button1","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button2","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button3","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button4","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button5","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button6","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"steering_button_colors_2","description":"This packet controls each button's color. Each byte is a hex color code.","id":593,"endian":"","repeat":0,"offset":0,"data":[{"name":"button7","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button8","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button9","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"button10","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"steering_horn","description":"This packet controls the state of the horn.","id":578,"endian":"","repeat":0,"offset":0,"data":[{"name":"horn","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"thunderstruck_status_message","description":"Status packet for thunderstruck chargers","id":418063424,"endian":"little","repeat":0,"offset":0,"data":[{"name":"STATUS_FLAGS","type":"uint8_t","units":"V","conversion":1,"bits":null},{"name":"CHARGE_FLAGS","type":"uint8_t","units":"V","conversion":1,"bits":null},{"name":"OUTPUT_VOLTAGE","type":"uint16_t","units":"V","conversion":1,"bits":null},{"name":"OUTPUT_CURRENT","type":"uint16_t","units":"V","conversion":1,"bits":null},{"name":"CHARGER_TEMP","type":"uint8_t","units":"V","conversion":1,"bits":null},{"name":"RESERVED","type":"uint8_t","units":"V","conversion":1,"bits":null}]},{"name":"tracker_data","description":"Tracker data. Each channel transmits on a specific ID, which should be specified along with the tracker, most likely 0x600-0x603.","id":1536,"endian":"little","repeat":6,"offset":1,"data":[{"name":"array_voltage","type":"uint16_t","units":"V","conversion":0.01,"bits":null},{"name":"array_current","type":"uint16_t","units":"A","conversion":0.001,"bits":null},{"name":"battery_voltage","type":"uint16_t","units":"V","conversion":0.01,"bits":null},{"name":"temperature","type":"uint16_t","units":"C","conversion":0.01,"bits":null}]},{"name":"tritium_motor_drive","description":"Tritium Motor Drive Command","id":289,"endian":"little","repeat":0,"offset":0,"data":[{"name":"motor_velocity","type":"float","units":"","conversion":0,"bits":null},{"name":"motor_current","type":"float","units":"","conversion":0,"bits":null}]},{"name":"tritium_motor_power","description":"Tritium Motor Power Command","id":290,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reserved","type":"float","units":"","conversion":0,"bits":null},{"name":"bus_current","type":"float","units":"","conversion":0,"bits":null}]},{"name":"tritium_reset","description":"Tritium Reset Command","id":291,"endian":"little","repeat":0,"offset":0,"data":[{"name":"unused1","type":"float","units":"","conversion":0,"bits":null},{"name":"unused2","type":"float","units":"","conversion":0,"bits":null}]},{"name":"bms_ah_set","description":"write state of charge, use with caution","id":22,"endian":"little","repeat":0,"offset":0,"data":[{"name":"ah","type":"uint32_t","units":"","conversion":0.00001,"bits":null}]},{"name":"bms_wh_set","description":"write state of charge, use with caution","id":23,"endian":"little","repeat":0,"offset":0,"data":[{"name":"wh","type":"uint32_t","units":"","conversion":0.00001,"bits":null}]},{"name":"bms_kill","description":"packet to cause BMS kill","id":26,"endian":"little","repeat":0,"offset":0,"data":[{"name":"kill_type","type":"bitfield","units":"","conversion":0,"bits":[{"name":"KILL_HARD"}]}]},{"name":"telemetry_rtc_reset","description":"Reset telemetry's real-time clock (RTC).","id":1792,"endian":"","repeat":0,"offset":0,"data":[{"name":"year","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"month","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"day","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"hour","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"minute","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"second","type":"uint8_t","units":"","conversion":0,"bits":null}]},{"name":"wsr_identification","description":"WS RIGHT Identification Information","id":320,"endian":"little","repeat":0,"offset":0,"data":[{"name":"tritium_id","type":"uint32_t","units":"","conversion":0,"bits":null},{"name":"serial_number","type":"uint32_t","units":"","conversion":0,"bits":null}]},{"name":"wsr_status_information","description":"WS RIGHT Status Information","id":321,"endian":"little","repeat":0,"offset":0,"data":[{"name":"limit_flags","type":"bitfield","units":"","conversion":0,"bits":[{"name":"output_voltage_pwm"},{"name":"motor_current"},{"name":"velocity"},{"name":"bus_current"},{"name":"bus_voltage_upper_limit"},{"name":"bus_voltage_lower_limit"},{"name":"ipm_temperature_or_motor_temperature"},{"name":"reserved"}]},{"name":"limit_flags_reserved","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"error_flags_0","type":"bitfield","units":"","conversion":0,"bits":[{"name":"hardware_over_current"},{"name":"software_over_current"},{"name":"dc_bus_over_voltage"},{"name":"bad_motor_position_hall_sequence"},{"name":"watchdog_caused_last_reset"},{"name":"config_read_error"},{"name":"lv_rail_under_voltage_lock_out"},{"name":"desaturation_fault"}]},{"name":"error_flags_1","type":"bitfield","units":"","conversion":0,"bits":[{"name":"motor_over_speed"},{"name":"reserved_9"},{"name":"reserved_10"},{"name":"reserved_11"},{"name":"reserved_12"},{"name":"reserved_13"},{"name":"reserved_14"},{"name":"reserved_15"}]},{"name":"active_motor","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"reserved","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"wsr_bus_measurement","description":"WS RIGHT Bus Measurement","id":322,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bus_voltage","type":"float","units":"V","conversion":0,"bits":null},{"name":"bus_current","type":"float","units":"A","conversion":0,"bits":null}]},{"name":"wsr_velocity","description":"WS RIGHT Velocity Measurement","id":323,"endian":"little","repeat":0,"offset":0,"data":[{"name":"motor_velocity","type":"float","units":"rpm","conversion":0,"bits":null},{"name":"vehicle_velocity","type":"float","units":"m/s","conversion":0,"bits":null}]},{"name":"wsr_phase_current","description":"WS RIGHT Phase Current Measurement","id":324,"endian":"little","repeat":0,"offset":0,"data":[{"name":"phase_b_current","type":"float","units":"A rms","conversion":0,"bits":null},{"name":"phase_c_current","type":"float","units":"A rms","conversion":0,"bits":null}]},{"name":"wsr_motor_voltage_vector","description":"WS RIGHT Motor Voltage Vector Measurement","id":325,"endian":"little","repeat":0,"offset":0,"data":[{"name":"vq","type":"float","units":"V","conversion":0,"bits":null},{"name":"vd","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsr_motor_current_vector","description":"WS RIGHT Motor Current Vector Measurement","id":326,"endian":"little","repeat":0,"offset":0,"data":[{"name":"iq","type":"float","units":"A","conversion":0,"bits":null},{"name":"id","type":"float","units":"A","conversion":0,"bits":null}]},{"name":"wsr_motor_backemf","description":"WS RIGHT Motor BackEMF Measurement / Prediction","id":327,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bemfq","type":"float","units":"V","conversion":0,"bits":null},{"name":"bemfd","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsr_15_165_voltage_rail","description":"WS RIGHT 15 and 1.65 Voltage Rail Measurement","id":328,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reference_165v","type":"float","units":"V","conversion":0,"bits":null},{"name":"supply_15v","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsr_25_12_voltage_rail","description":"WS RIGHT 2.5V and 1.2V Voltage Rail Measurement","id":329,"endian":"little","repeat":0,"offset":0,"data":[{"name":"supply_12v","type":"float","units":"V","conversion":0,"bits":null},{"name":"supply_25v","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsr_heatsink_motor_temp","description":"WS RIGHT Heat-sink \u0026 Motor Temperature Measurement","id":331,"endian":"little","repeat":0,"offset":0,"data":[{"name":"motor_temp","type":"float","units":"C","conversion":0,"bits":null},{"name":"heatsink_temp","type":"float","units":"C","conversion":0,"bits":null}]},{"name":"wsr_dsp_board_temp","description":"WS RIGHT DPS Board Temperature Measurement","id":332,"endian":"little","repeat":0,"offset":0,"data":[{"name":"dsp_board_temp","type":"float","units":"C","conversion":0,"bits":null},{"name":"reserved","type":"float","units":"C","conversion":0,"bits":null}]},{"name":"wsr_reserved","description":"WS RIGHT Reserved","id":333,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reserved0","type":"float","units":"","conversion":0,"bits":null},{"name":"reserved1","type":"float","units":"","conversion":0,"bits":null}]},{"name":"wsr_odometer_bus_amphours_measurement","description":"WS RIGHT Odometer and Bus AmpHours Measurement","id":334,"endian":"little","repeat":0,"offset":0,"data":[{"name":"odometer","type":"float","units":"m","conversion":0,"bits":null},{"name":"dc_bus_amphours","type":"float","units":"Ah","conversion":0,"bits":null}]},{"name":"wsr_slip_speed_measurement","description":"WS RIGHT Slip Speed Measurement","id":343,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reserved","type":"float","units":"C","conversion":0,"bits":null},{"name":"slip_speed","type":"float","units":"Hz","conversion":0,"bits":null}]},{"name":"wsl_identification","description":"WS LEFT Identification Information","id":256,"endian":"little","repeat":0,"offset":0,"data":[{"name":"tritium_id","type":"uint32_t","units":"","conversion":0,"bits":null},{"name":"serial_number","type":"uint32_t","units":"","conversion":0,"bits":null}]},{"name":"wsl_status_information","description":"WS LEFT Status Information","id":257,"endian":"little","repeat":0,"offset":0,"data":[{"name":"limit_flags","type":"bitfield","units":"","conversion":0,"bits":[{"name":"output_voltage_pwm"},{"name":"motor_current"},{"name":"velocity"},{"name":"bus_current"},{"name":"bus_voltage_upper_limit"},{"name":"bus_voltage_lower_limit"},{"name":"ipm_temperature_or_motor_temperature"},{"name":"reserved"}]},{"name":"limit_flags_reserved","type":"uint8_t","units":"","conversion":0,"bits":null},{"name":"error_flags_0","type":"bitfield","units":"","conversion":0,"bits":[{"name":"hardware_over_current"},{"name":"software_over_current"},{"name":"dc_bus_over_voltage"},{"name":"bad_motor_position_hall_sequence"},{"name":"watchdog_caused_last_reset"},{"name":"config_read_error"},{"name":"lv_rail_under_voltage_lock_out"},{"name":"desaturation_fault"}]},{"name":"error_flags_1","type":"bitfield","units":"","conversion":0,"bits":[{"name":"motor_over_speed"},{"name":"reserved_9"},{"name":"reserved_10"},{"name":"reserved_11"},{"name":"reserved_12"},{"name":"reserved_13"},{"name":"reserved_14"},{"name":"reserved_15"}]},{"name":"active_motor","type":"uint16_t","units":"","conversion":0,"bits":null},{"name":"reserved","type":"uint16_t","units":"","conversion":0,"bits":null}]},{"name":"wsl_bus_measurement","description":"WS LEFT Bus Measurement","id":258,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bus_voltage","type":"float","units":"V","conversion":0,"bits":null},{"name":"bus_current","type":"float","units":"A","conversion":0,"bits":null}]},{"name":"wsl_velocity","description":"WS LEFT Velocity Measurement","id":259,"endian":"little","repeat":0,"offset":0,"data":[{"name":"motor_velocity","type":"float","units":"rpm","conversion":0,"bits":null},{"name":"vehicle_velocity","type":"float","units":"m/s","conversion":0,"bits":null}]},{"name":"wsl_phase_current","description":"WS LEFT Phase Current Measurement","id":260,"endian":"little","repeat":0,"offset":0,"data":[{"name":"phase_b_current","type":"float","units":"A rms","conversion":0,"bits":null},{"name":"phase_c_current","type":"float","units":"A rms","conversion":0,"bits":null}]},{"name":"wsl_motor_voltage_vector","description":"WS LEFT Motor Voltage Vector Measurement","id":261,"endian":"little","repeat":0,"offset":0,"data":[{"name":"vq","type":"float","units":"V","conversion":0,"bits":null},{"name":"vd","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsl_motor_current_vector","description":"WS LEFT Motor Current Vector Measurement","id":262,"endian":"little","repeat":0,"offset":0,"data":[{"name":"iq","type":"float","units":"A","conversion":0,"bits":null},{"name":"id","type":"float","units":"A","conversion":0,"bits":null}]},{"name":"wsl_motor_backemf","description":"WS LEFT Motor BackEMF Measurement / Prediction","id":263,"endian":"little","repeat":0,"offset":0,"data":[{"name":"bemfq","type":"float","units":"V","conversion":0,"bits":null},{"name":"bemfd","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsl_15_165_voltage_rail","description":"WS LEFT 15 and 1.65 Voltage Rail Measurement","id":264,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reference_165v","type":"float","units":"V","conversion":0,"bits":null},{"name":"supply_15v","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsl_25_12_voltage_rail","description":"WS LEFT 2.5V and 1.2V Voltage Rail Measurement","id":265,"endian":"little","repeat":0,"offset":0,"data":[{"name":"supply_12v","type":"float","units":"V","conversion":0,"bits":null},{"name":"supply_25v","type":"float","units":"V","conversion":0,"bits":null}]},{"name":"wsl_heatsink_motor_temp","description":"WS LEFT Heat-sink \u0026 Motor Temperature Measurement","id":267,"endian":"little","repeat":0,"offset":0,"data":[{"name":"motor_temp","type":"float","units":"C","conversion":0,"bits":null},{"name":"heatsink_temp","type":"float","units":"C","conversion":0,"bits":null}]},{"name":"wsl_dsp_board_temp","description":"WS LEFT DPS Board Temperature Measurement","id":268,"endian":"little","repeat":0,"offset":0,"data":[{"name":"dsp_board_temp","type":"float","units":"C","conversion":0,"bits":null},{"name":"reserved","type":"float","units":"C","conversion":0,"bits":null}]},{"name":"wsl_odometer_bus_amphours_measurement","description":"WS LEFT Odometer and Bus AmpHours Measurement","id":270,"endian":"little","repeat":0,"offset":0,"data":[{"name":"odometer","type":"float","units":"m","conversion":0,"bits":null},{"name":"dc_bus_amphours","type":"float","units":"Ah","conversion":0,"bits":null}]},{"name":"wsl_reserved","description":"WS LEFT Reserved","id":269,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reserved0","type":"float","units":"","conversion":0,"bits":null},{"name":"reserved1","type":"float","units":"","conversion":0,"bits":null}]},{"name":"wsl_slip_speed_measurement","description":"WS LEFT Slip Speed Measurement","id":279,"endian":"little","repeat":0,"offset":0,"data":[{"name":"reserved","type":"float","units":"C","conversion":0,"bits":null},{"name":"slip_speed","type":"float","units":"Hz","conversion":0,"bits":null}]}],"boards":[{"name":"bms","transmit":["bms_measurement","bms_capacity","bms_charger_response","battery_status","bms_kill_reason","bms_module_min_max","bms_soc","bms_currentlimit","bms_fan_info","bms_module"],"receive":["bms_kill","bms_wh_set","bms_ah_set","bms_set_min_fan_speed","charger_bms_request"]},{"name":"charger","transmit":["charger_state","charger_bms_request","charger_power"],"receive":["bms_charger_response","battery_status","bms_module_min_max","bms_measurement","charger_current_voltage","bms_capacity"]},{"name":"flight_computer","transmit":["tracker_enable","vision_turn_signals_command","vision_brake_lights_command","vision_headlights_command","vision_horn_command","tritium_motor_drive","steering_button_colors_1","steering_button_colors_2","tritium_reset","dashboard_pedal_percentages","car_state","car_speed","dashboard_pedal_fault","flight_computer_hv_board_disconnect_counts","flight_computer_lv_board_disconnect_counts","flight_computer_internal_state","power_to_drive","array_power","distance_traveled"],"receive":["bms_module_min_max","charger_state","steering_press_count_1","steering_press_count_2","wsl_velocity","wsr_velocity","steering_horn","bms_kill_reason","bms_measurement","tracker_data","vision_status_front","vision_status_rear","wsl_odometer_bus_amphours_measurement","wsr_odometer_bus_amphours_measurement"]},{"name":"g4_example","transmit":["vision_status_front","vision_headlights_command","tracker_data","demo_packet"],"receive":["vision_turn_signals_command","vision_brake_lights_command","vision_headlights_command","vision_horn_command","demo_packet"]},{"name":"lights","transmit":["vision_status_front","vision_status_rear","lights_front_id","lights_back_id"],"receive":["vision_turn_signals_command","vision_brake_lights_command","vision_headlights_command","bms_kill_reason"]},{"name":"skylab2_demo","transmit":["vision_status_front","vision_headlights_command","tracker_data"],"receive":["vision_turn_signals_command","vision_brake_lights_command","vision_headlights_command","vision_horn_command"]},{"name":"steering","transmit":["steering_press_count_1","steering_press_count_2","steering_horn"],"receive":["steering_button_colors_1","steering_button_colors_2"]},{"name":"vision","transmit":["vision_status_front","vision_id"],"receive":["vision_turn_signals_command","vision_brake_lights_command","vision_headlights_command","vision_horn_command","vision_array_latches_command","vision_rearview_command"]}]}`