553 lines
15 KiB
Go
553 lines
15 KiB
Go
package common
|
|
|
|
import (
|
|
"encoding/json"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type CarState struct {
|
|
Online bool `json:"online"`
|
|
OnlineHMI bool `json:"online_hmi"`
|
|
Battery *Battery `json:"battery,omitempty"`
|
|
MaxRange *MaxRange `json:"max_range,omitempty"`
|
|
Doors *Doors `json:"doors,omitempty"`
|
|
Location *Location `json:"location,omitempty"`
|
|
Locks *Locks `json:"door_locks,omitempty"`
|
|
Windows *Windows `json:"windows,omitempty"`
|
|
MiscWindows *MiscWindows `json:"misc_windows,omitempty"`
|
|
Sunroof *Sunroof `json:"sunroof,omitempty"`
|
|
CabinClimate *CabinClimate `json:"cabin_climate,omitempty"`
|
|
RearDefrost *RearDefrost `json:"rear_defrost,omitempty"`
|
|
DriverSeatHeat *DriverSeatHeat `json:"driver_seat_heat,omitempty"`
|
|
PassengerSeatHeat *PassengerSeatHeat `json:"passenger_seat_heat,omitempty"`
|
|
SteeringWheelHeat *SteeringWheelHeat `json:"steering_wheel_heat,omitempty"`
|
|
AmbientTemperature *AmbientTemperature `json:"ambient_temperature,omitempty"`
|
|
CellTemperature *CellTemperature `json:"cell_temp,omitempty"`
|
|
VehicleSpeed *VehicleSpeed `json:"vehicle_speed,omitempty"`
|
|
VCU0x260 *VCU0x260Descriptor `json:"vcu0x260,omitempty"`
|
|
ChargingMetrics *VCUChargingMetrics `json:"charging_metrics,omitempty"`
|
|
Gear *Gear `json:"gear,omitempty"`
|
|
StateOfCharge *StateOfCharge `json:"state_of_charge,omitempty"`
|
|
TRexVersion string `json:"trex_version,omitempty"`
|
|
DBCVersion string `json:"dbc_version,omitempty"`
|
|
IP string `json:"ip,omitempty"`
|
|
UpdatedAt *time.Time `json:"updated,omitempty"`
|
|
SafeState *SafeState `json:"safe_state,omitempty"`
|
|
DriverOccupySeatState *int `json:"driver_occupy_seat_state,omitempty"`
|
|
PowerMode *int `json:"power_mode,omitempty"`
|
|
ChargingStatus *int `json:"charging_status,omitempty"`
|
|
VehicleReadyState *VehicleReadyState `json:"vehicle_ready_state,omitempty"`
|
|
Battery12V *Battery12V `json:"battery_12v,omitempty"` // maybe make it Battery12v
|
|
ExpandedSignals *ExpandedSignals `json:"expanded_signals,omitempty"`
|
|
}
|
|
|
|
func (c *CarState) GetBattery() *Battery {
|
|
if c.Battery == nil {
|
|
c.Battery = &Battery{}
|
|
}
|
|
|
|
return c.Battery
|
|
}
|
|
|
|
func (c *CarState) GetMaxRange() *MaxRange {
|
|
if c.MaxRange == nil {
|
|
c.MaxRange = &MaxRange{}
|
|
}
|
|
|
|
return c.MaxRange
|
|
}
|
|
|
|
func (c *CarState) GetDoors() *Doors {
|
|
if c.Doors == nil {
|
|
c.Doors = &Doors{}
|
|
}
|
|
|
|
return c.Doors
|
|
}
|
|
|
|
func (c *CarState) UpdateLocation(value []byte) error {
|
|
loc := Location{}
|
|
err := loc.Unmarshal(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
location := c.GetLocation()
|
|
location.Latitude = loc.Latitude
|
|
location.Longitude = loc.Longitude
|
|
|
|
// Altitude could have already been set from GPS_ALTITUDE so do not overwrite unless it is a non-zero
|
|
if loc.Altitude != 0 {
|
|
location.Altitude = loc.Altitude
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (c *CarState) GetLocation() *Location {
|
|
if c.Location == nil {
|
|
c.Location = &Location{}
|
|
}
|
|
|
|
return c.Location
|
|
}
|
|
|
|
func (c *CarState) GetLocks() *Locks {
|
|
if c.Locks == nil {
|
|
c.Locks = &Locks{}
|
|
}
|
|
|
|
return c.Locks
|
|
}
|
|
|
|
func (c *CarState) GetWindows() *Windows {
|
|
if c.Windows == nil {
|
|
c.Windows = &Windows{}
|
|
}
|
|
|
|
return c.Windows
|
|
}
|
|
|
|
func (c *CarState) GetMiscWindows() *MiscWindows {
|
|
if c.MiscWindows == nil {
|
|
c.MiscWindows = &MiscWindows{}
|
|
}
|
|
|
|
return c.MiscWindows
|
|
}
|
|
|
|
func (c *CarState) GetSunroof() *Sunroof {
|
|
if c.Sunroof == nil {
|
|
c.Sunroof = &Sunroof{}
|
|
}
|
|
|
|
return c.Sunroof
|
|
}
|
|
|
|
func (c *CarState) GetCabinClimate() *CabinClimate {
|
|
if c.CabinClimate == nil {
|
|
c.CabinClimate = &CabinClimate{}
|
|
}
|
|
|
|
return c.CabinClimate
|
|
}
|
|
|
|
func (c *CarState) GetRearDefrost() *RearDefrost {
|
|
if c.RearDefrost == nil {
|
|
c.RearDefrost = &RearDefrost{}
|
|
}
|
|
|
|
return c.RearDefrost
|
|
}
|
|
|
|
func (c *CarState) GetDriverSeatHeat() *DriverSeatHeat {
|
|
if c.DriverSeatHeat == nil {
|
|
c.DriverSeatHeat = &DriverSeatHeat{}
|
|
}
|
|
|
|
return c.DriverSeatHeat
|
|
}
|
|
|
|
func (c *CarState) GetPassengerSeatHeat() *PassengerSeatHeat {
|
|
if c.PassengerSeatHeat == nil {
|
|
c.PassengerSeatHeat = &PassengerSeatHeat{}
|
|
}
|
|
|
|
return c.PassengerSeatHeat
|
|
}
|
|
|
|
func (c *CarState) GetSteeringWheelHeat() *SteeringWheelHeat {
|
|
if c.SteeringWheelHeat == nil {
|
|
c.SteeringWheelHeat = &SteeringWheelHeat{}
|
|
}
|
|
|
|
return c.SteeringWheelHeat
|
|
}
|
|
|
|
func (c *CarState) GetAmbientTemperature() *AmbientTemperature {
|
|
if c.AmbientTemperature == nil {
|
|
c.AmbientTemperature = &AmbientTemperature{}
|
|
}
|
|
|
|
return c.AmbientTemperature
|
|
}
|
|
|
|
func (c *CarState) GetCellTemperature() *CellTemperature {
|
|
if c.CellTemperature == nil {
|
|
c.CellTemperature = &CellTemperature{}
|
|
}
|
|
|
|
return c.CellTemperature
|
|
}
|
|
|
|
func (c *CarState) GetVCU0x260() *VCU0x260Descriptor {
|
|
if c.VCU0x260 == nil {
|
|
c.VCU0x260 = &VCU0x260Descriptor{}
|
|
}
|
|
|
|
return c.VCU0x260
|
|
}
|
|
|
|
func (c *CarState) GetChargingMetrics() *VCUChargingMetrics {
|
|
if c.ChargingMetrics == nil {
|
|
c.ChargingMetrics = &VCUChargingMetrics{}
|
|
}
|
|
|
|
return c.ChargingMetrics
|
|
}
|
|
|
|
func (c *CarState) GetGear() *Gear {
|
|
if c.Gear == nil {
|
|
c.Gear = &Gear{}
|
|
}
|
|
|
|
return c.Gear
|
|
}
|
|
|
|
func (c *CarState) GetStateOfCharge() *StateOfCharge {
|
|
if c.StateOfCharge == nil {
|
|
c.StateOfCharge = &StateOfCharge{}
|
|
}
|
|
|
|
return c.StateOfCharge
|
|
}
|
|
|
|
func (c *CarState) GetVehicleSpeed() *VehicleSpeed {
|
|
if c.VehicleSpeed == nil {
|
|
c.VehicleSpeed = &VehicleSpeed{}
|
|
}
|
|
|
|
return c.VehicleSpeed
|
|
}
|
|
|
|
// Battery represents the battery state of the car
|
|
type Battery struct {
|
|
Percent int `json:"percent" redis:"percent"`
|
|
TotalMileageOdometer int `json:"total_mileage_odometer"`
|
|
BatteryVoltage float64 `json:"battery_voltage"` // The fact that this is called battery voltage is really dumb. Its the 12 volt battery, not the high voltage one
|
|
}
|
|
|
|
func (b *Battery) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*b)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (b *Battery) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, b)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// StateOfCharge represents the battery state of charge
|
|
type StateOfCharge struct {
|
|
Usable int `json:"usable"`
|
|
Health int `json:"health"`
|
|
}
|
|
|
|
type SafeState struct {
|
|
VehicleSafeState bool `json:"vehicle_safe_state" redis:"vehicle_safe_state"`
|
|
VCUSafeState bool `json:"vcu_safe_state" redis:"vcu_safe_state"`
|
|
MCUFrontSafeState bool `json:"mcu_front_safe_state" redis:"mcu_front_safe_state"`
|
|
MCURearSafeState bool `json:"mcu_rear_safe_state" redis:"mcu_rear_safe_state"`
|
|
MCURearDecoupState bool `json:"mcu_rear_decoup_state" redis:"mcu_rear_decoup_state"`
|
|
MCUFrontInverterError bool `json:"mcu_front_inverter_error" redis:"mcu_front_inverter_error"`
|
|
MCURearInverterError bool `json:"mcu_rear_inverter_error" redis:"mcu_rear_inverter_error"`
|
|
}
|
|
|
|
func (s *SafeState) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*s)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (s *SafeState) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, s)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
func (c *CarState) GetSafeState() *SafeState {
|
|
if c.SafeState == nil {
|
|
c.SafeState = &SafeState{}
|
|
}
|
|
|
|
return c.SafeState
|
|
}
|
|
|
|
// MaxRange represents the predicted max range of the car
|
|
type MaxRange struct {
|
|
MaxMiles int `json:"max_miles" redis:"max_miles"`
|
|
}
|
|
|
|
type VehicleReadyState struct {
|
|
IsVehicleReady bool `json:"is_vehicle_ready" redis:"is_vehicle_ready"`
|
|
}
|
|
|
|
func (c *CarState) GetVehicleReadyState() *VehicleReadyState {
|
|
if c.VehicleReadyState == nil {
|
|
c.VehicleReadyState = &VehicleReadyState{}
|
|
}
|
|
return c.VehicleReadyState
|
|
}
|
|
|
|
func (b *MaxRange) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*b)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (b *MaxRange) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, b)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// Doors represents the doors state of the car
|
|
// false means closed, true means open
|
|
type Doors struct {
|
|
Hood bool `json:"hood" redis:"hood"`
|
|
LeftFront bool `json:"left_front" redis:"left_front"`
|
|
LeftRear bool `json:"left_rear" redis:"left_rear"`
|
|
RightFront bool `json:"right_front" redis:"right_front"`
|
|
RightRear bool `json:"right_rear" redis:"right_rear"`
|
|
Trunk bool `json:"trunk" redis:"trunk"`
|
|
}
|
|
|
|
func (d *Doors) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*d)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (d *Doors) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, d)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// Locks represents the lock state of the car
|
|
type Locks struct {
|
|
Driver bool `json:"driver" redis:"driver"`
|
|
All bool `json:"all" redis:"all"`
|
|
}
|
|
|
|
func (l *Locks) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*l)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (l *Locks) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, l)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// Windows represents the windows state of the car
|
|
//
|
|
// value is a percentage 0-100 in increments of 0.5
|
|
type Windows struct {
|
|
LeftFront int `json:"left_front" redis:"left_front"`
|
|
LeftRear int `json:"left_rear" redis:"left_rear"`
|
|
RightFront int `json:"right_front" redis:"right_front"`
|
|
RightRear int `json:"right_rear" redis:"right_rear"`
|
|
}
|
|
|
|
func (w *Windows) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *Windows) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// MiscWindows represents the windows state of the car for misc windows (left / right rear quarter and rear windshield)
|
|
// value is a percentage 0-100 in increments of 0.5
|
|
type MiscWindows struct {
|
|
LeftRearQuarter int `json:"left_rear_quarter" redis:"left_rear_quarter"`
|
|
RightRearQuarter int `json:"right_rear_quarter" redis:"right_rear_quarter"`
|
|
RearWindshield int `json:"rear_windshield" redis:"rear_windshield"`
|
|
}
|
|
|
|
func (w *MiscWindows) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *MiscWindows) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type Sunroof struct {
|
|
Sunroof int `json:"sunroof" redis:"sunroof"`
|
|
}
|
|
|
|
func (s *Sunroof) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*s)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (s *Sunroof) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, s)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type CabinClimate struct {
|
|
CabinTemperature int `json:"cabin_temperature" redis:"cabin_temperature"`
|
|
InternalTemperature int `json:"internal_temperature" redis:"internal_temperature"`
|
|
}
|
|
|
|
func (w *CabinClimate) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *CabinClimate) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type RearDefrost struct {
|
|
On bool `json:"on" redis:"on"`
|
|
}
|
|
|
|
func (w *RearDefrost) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *RearDefrost) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type DriverSeatHeat struct {
|
|
Level int `json:"level" redis:"level"`
|
|
}
|
|
|
|
func (w *DriverSeatHeat) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *DriverSeatHeat) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type PassengerSeatHeat struct {
|
|
Level int `json:"level" redis:"level"`
|
|
}
|
|
|
|
func (w *PassengerSeatHeat) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *PassengerSeatHeat) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type SteeringWheelHeat struct {
|
|
On bool `json:"on" redis:"on"`
|
|
}
|
|
|
|
func (w *SteeringWheelHeat) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *SteeringWheelHeat) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type AmbientTemperature struct {
|
|
Temperature int `json:"temperature" redis:"temperature"`
|
|
}
|
|
|
|
func (w *AmbientTemperature) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *AmbientTemperature) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type VehicleSpeed struct {
|
|
Speed float64 `json:"speed" redis:"speed"`
|
|
}
|
|
|
|
func (w *VehicleSpeed) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *VehicleSpeed) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
type CellTemperature struct {
|
|
AvgBatteryTemp int `json:"avg_battery_temp"`
|
|
}
|
|
|
|
type VCU0x260Descriptor struct {
|
|
ChargeType string `json:"charge_type"`
|
|
}
|
|
|
|
type VCUChargingMetrics struct {
|
|
RemainingChargingTime int `json:"remaining_charging_time"`
|
|
RemainingChargingTimeFull int `json:"remaining_charging_time_full"`
|
|
}
|
|
|
|
type Gear struct {
|
|
InPark bool `json:"in_park"`
|
|
Immobilizer string `json:"immobilizer,omitempty"`
|
|
}
|
|
|
|
type Battery12V struct {
|
|
IBS_BatteryVoltage *float64 `json:"voltage,omitempty"` // 12 Volt battery voltage
|
|
IBS_StateOfCharge *float64 `json:"percent_charge,omitempty"` // Percentages of the voltage out of about 15.5 Volts
|
|
IBS_StateOfHealth *int `json:"health,omitempty"` // estimated health of the 12v battery
|
|
}
|
|
|
|
func (c *CarState) GetBattery12V() *Battery12V {
|
|
if c.Battery12V == nil {
|
|
c.Battery12V = &Battery12V{}
|
|
}
|
|
|
|
return c.Battery12V
|
|
}
|
|
|
|
type ExpandedSignals struct {
|
|
// IBS_SOCUpperTolerance *float64 //unconfirmed
|
|
// IBS_SOCLowerTolerance *float64 //unconfirmed
|
|
IBS_NominalCapacity *int `json:",omitempty"`
|
|
IBS_AvailableCapacity *int `json:",omitempty"`
|
|
BCM_TotMilg_ODO *float64 `json:",omitempty"`
|
|
BMS_SwVersS *int `json:",omitempty"`
|
|
BMS_SwVersM *int `json:",omitempty"`
|
|
BMS_SwVers *int `json:",omitempty"`
|
|
BMS_AccueDchaTotAh *int `json:",omitempty"`
|
|
BMS_AccueChrgTotAh *int `json:",omitempty"`
|
|
}
|
|
|
|
func (c *CarState) GetExpandedSignals() *ExpandedSignals {
|
|
if c.ExpandedSignals == nil {
|
|
c.ExpandedSignals = &ExpandedSignals{}
|
|
}
|
|
|
|
return c.ExpandedSignals
|
|
}
|
|
|
|
// I am quite certain there is no reason to have these custom marshalers, but want to keep with the current form incase of unexpected side effects
|
|
func (w *ExpandedSignals) Marshal() ([]byte, error) {
|
|
data, err := json.Marshal(*w)
|
|
return data, errors.WithStack(err)
|
|
}
|
|
|
|
func (w *ExpandedSignals) Unmarshal(data []byte) error {
|
|
err := json.Unmarshal(data, w)
|
|
return errors.WithStack(err)
|
|
}
|