Added Locks status and tire pressure (psi and kpa)
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 22s
All checks were successful
Golan Testing / testing (1.24.x, ubuntu-latest) (push) Successful in 22s
This commit is contained in:
@ -192,7 +192,7 @@ type VehicleStatus struct {
|
|||||||
WindowFrontRightStatus string `json:"windowFrontRightStatus"` // CLOSE | VENTED | OPEN
|
WindowFrontRightStatus string `json:"windowFrontRightStatus"` // CLOSE | VENTED | OPEN
|
||||||
WindowRearLeftStatus string `json:"windowRearLeftStatus"` // CLOSE | VENTED | OPEN
|
WindowRearLeftStatus string `json:"windowRearLeftStatus"` // CLOSE | VENTED | OPEN
|
||||||
WindowRearRightStatus string `json:"windowRearRightStatus"` // CLOSE | VENTED | OPEN
|
WindowRearRightStatus string `json:"windowRearRightStatus"` // CLOSE | VENTED | OPEN
|
||||||
WindowSunroofStatus string `json:"windowSunroofStatus"` // CLOSE | VENTED | OPEN
|
WindowSunroofStatus string `json:"windowSunroofStatus"` // CLOSE | SLIDE_PARTLY_OPEN | OPEN | TILT
|
||||||
DoorBootPosition string `json:"doorBootPosition"` // CLOSED | OPEN
|
DoorBootPosition string `json:"doorBootPosition"` // CLOSED | OPEN
|
||||||
DoorEngineHoodPosition string `json:"doorEngineHoodPosition"` // CLOSED | OPEN
|
DoorEngineHoodPosition string `json:"doorEngineHoodPosition"` // CLOSED | OPEN
|
||||||
DoorFrontLeftPosition string `json:"doorFrontLeftPosition"` // CLOSED | OPEN
|
DoorFrontLeftPosition string `json:"doorFrontLeftPosition"` // CLOSED | OPEN
|
||||||
|
1
utils.go
1
utils.go
@ -58,6 +58,7 @@ func vinCheck(vin string) (bool, string) {
|
|||||||
return valid, retVin
|
return valid, retVin
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// transcodeDigits .
|
||||||
func transcodeDigits(vin string) int {
|
func transcodeDigits(vin string) int {
|
||||||
var digitSum = 0
|
var digitSum = 0
|
||||||
var code int
|
var code int
|
||||||
|
196
vehicle.go
196
vehicle.go
@ -11,19 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// VEHICLE_STATE_TYPE >> IGNITION_OFF
|
|
||||||
// DISTANCE_TO_EMPTY_FUEL >> 241
|
|
||||||
// AVG_FUEL_CONSUMPTION >> 127
|
|
||||||
// POSITION_SPEED_KMPH >> 0
|
|
||||||
// POSITION_HEADING_DEGREE >> 155
|
|
||||||
// POSITION_TIMESTAMP >> 2022-01-18T20:40:10Z
|
|
||||||
// ODOMETER >> 40223712 (meters)
|
|
||||||
// TYRE_( STATUS | PRESSURE )_( REAR | FRONT )_( LEFT | RIGHT ) >> 2275 | UNKNOWN
|
|
||||||
// SEAT_BELT_STATUS_( ( FRONT | SECOND | THIRD )_( LEFT | MIDDLE | RIGHT ) ) >> NOT_EQUIPPED | UNKNOWN | NOT_BELTED | BELTED
|
|
||||||
// SEAT_OCCUPATION_STATUS_( ( FRONT | SECOND | THIRD )_( LEFT | MIDDLE | RIGHT ) ) >>
|
|
||||||
// DOOR_( ( FRONT | REAR )_( LEFT | RIGHT ) | ENGINE_HOOD | BOOT )_LOCK_STATUS >> UNKNOWN
|
|
||||||
// DOOR_( ( FRONT | REAR )_( LEFT | RIGHT ) | ENGINE_HOOD | BOOT )_POSITION >> CLOSED
|
|
||||||
// WINDOW_( BACK | SUNROOF | ( FRONT | REAR )_( LEFT | RIGHT ) )_STATUS >> UNKNOWN | CLOSE
|
|
||||||
// var parts = map[string]map[string][]string{
|
// var parts = map[string]map[string][]string{
|
||||||
// "door": {
|
// "door": {
|
||||||
// "suffix": {"position", "status"},
|
// "suffix": {"position", "status"},
|
||||||
@ -155,12 +142,12 @@ type Tire struct {
|
|||||||
// Status string
|
// Status string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Warning .
|
// Trouble .
|
||||||
type Trouble struct {
|
type Trouble struct {
|
||||||
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Vehicle) String() string {
|
func (v *Vehicle) String() string {
|
||||||
|
|
||||||
var vString string
|
var vString string
|
||||||
vString += "=== INFORMATION =====================\n"
|
vString += "=== INFORMATION =====================\n"
|
||||||
vString += "Nickname: " + v.CarNickname + "\n"
|
vString += "Nickname: " + v.CarNickname + "\n"
|
||||||
@ -205,7 +192,11 @@ func (v *Vehicle) String() string {
|
|||||||
vString += fmt.Sprintf("%s >> %+v\n", k, v)
|
vString += fmt.Sprintf("%s >> %+v\n", k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
vString += "=== WARNINGS =====================\n"
|
vString += "=== TROUBLES =====================\n"
|
||||||
|
for k, v := range v.Troubles {
|
||||||
|
vString += fmt.Sprintf("%s >> %+v\n", k, v)
|
||||||
|
}
|
||||||
|
|
||||||
vString += "=== FEATURES =====================\n"
|
vString += "=== FEATURES =====================\n"
|
||||||
for i, f := range v.Features {
|
for i, f := range v.Features {
|
||||||
if !strings.HasSuffix(f, "_MIL") {
|
if !strings.HasSuffix(f, "_MIL") {
|
||||||
@ -613,7 +604,7 @@ func (v *Vehicle) GetVehicleStatus() {
|
|||||||
v.DistanceToEmpty.Kilometers = vs.DistanceToEmptyFuelKilometers
|
v.DistanceToEmpty.Kilometers = vs.DistanceToEmptyFuelKilometers
|
||||||
v.DistanceToEmpty.Miles10s = vs.DistanceToEmptyFuelMiles10s
|
v.DistanceToEmpty.Miles10s = vs.DistanceToEmptyFuelMiles10s
|
||||||
v.DistanceToEmpty.Kilometers10s = vs.DistanceToEmptyFuelKilometers10s
|
v.DistanceToEmpty.Kilometers10s = vs.DistanceToEmptyFuelKilometers10s
|
||||||
if vs.RemainingFuelPercent > 0 && vs.RemainingFuelPercent <= 100 {
|
if vs.RemainingFuelPercent > 0 && vs.RemainingFuelPercent <= 101 {
|
||||||
v.DistanceToEmpty.Percentage = vs.RemainingFuelPercent
|
v.DistanceToEmpty.Percentage = vs.RemainingFuelPercent
|
||||||
}
|
}
|
||||||
v.FuelConsumptionAvg.MPG = float64(vs.AvgFuelConsumptionMpg)
|
v.FuelConsumptionAvg.MPG = float64(vs.AvgFuelConsumptionMpg)
|
||||||
@ -626,22 +617,15 @@ func (v *Vehicle) GetVehicleStatus() {
|
|||||||
val := reflect.ValueOf(vs)
|
val := reflect.ValueOf(vs)
|
||||||
typeOfS := val.Type()
|
typeOfS := val.Type()
|
||||||
|
|
||||||
// (?P<type>Door|Window|TirePressure)(?P<pos1>Front|Rear|Boot|EngineHood|Sunroof)(?P<pos2>Left|Right)?(:?Position|Status|LockStatus|Psi)?
|
|
||||||
for i := range val.NumField() {
|
for i := range val.NumField() {
|
||||||
// v.client.logger.Debug("vehicle status >> parsing a car part", "field", typeOfS.Field(i).Name, "value", val.Field(i).Interface(), "type", val.Field(i).Type())
|
// v.client.logger.Debug("vehicle status >> parsing a car part", "field", typeOfS.Field(i).Name, "value", val.Field(i).Interface(), "type", val.Field(i).Type())
|
||||||
if slices.Contains(badValues, val.Field(i).Interface()) {
|
if slices.Contains(badValues, val.Field(i).Interface()) {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "Position") {
|
if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "Position") ||
|
||||||
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "LockStatus") ||
|
||||||
}
|
strings.HasPrefix(typeOfS.Field(i).Name, "Window") && strings.HasSuffix(typeOfS.Field(i).Name, "Status") ||
|
||||||
// if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "LockStatus") {
|
strings.HasPrefix(typeOfS.Field(i).Name, "TirePressure") && strings.HasSuffix(typeOfS.Field(i).Name, "Psi") {
|
||||||
// v.parseLock("Door", "LockStatus", typeOfS.Field(i).Name, val.Field(i).Interface())
|
|
||||||
// }
|
|
||||||
if strings.HasPrefix(typeOfS.Field(i).Name, "Window") && strings.HasSuffix(typeOfS.Field(i).Name, "Status") {
|
|
||||||
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(typeOfS.Field(i).Name, "TirePressure") && strings.HasSuffix(typeOfS.Field(i).Name, "Psi") {
|
|
||||||
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,23 +659,18 @@ func (v *Vehicle) GetVehicleCondition() {
|
|||||||
val := reflect.ValueOf(vc)
|
val := reflect.ValueOf(vc)
|
||||||
typeOfS := val.Type()
|
typeOfS := val.Type()
|
||||||
|
|
||||||
// (?P<type>Door|Window|TirePressure)(?P<pos1>Front|Rear|Boot|EngineHood|Sunroof)(?P<pos2>Left|Right)?(:?Position|Status|LockStatus|Psi)?
|
|
||||||
for i := range val.NumField() {
|
for i := range val.NumField() {
|
||||||
// v.client.logger.Debug("vehicle condition >> parsing a car part", "field", typeOfS.Field(i).Name, "value", val.Field(i).Interface(), "type", val.Field(i).Type())
|
// v.client.logger.Debug("vehicle condition >> parsing a car part", "field", typeOfS.Field(i).Name, "value", val.Field(i).Interface(), "type", val.Field(i).Type())
|
||||||
if slices.Contains(badValues, val.Field(i).Interface()) {
|
if slices.Contains(badValues, val.Field(i).Interface()) {
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "Position") {
|
if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "Position") ||
|
||||||
|
strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "LockStatus") ||
|
||||||
|
strings.HasPrefix(typeOfS.Field(i).Name, "Window") && strings.HasSuffix(typeOfS.Field(i).Name, "Status") {
|
||||||
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(typeOfS.Field(i).Name, "Window") && strings.HasSuffix(typeOfS.Field(i).Name, "Status") {
|
// if strings.HasPrefix(typeOfS.Field(i).Name, "TirePressure") {
|
||||||
v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
// v.parseParts(typeOfS.Field(i).Name, val.Field(i).Interface())
|
||||||
}
|
|
||||||
// if strings.HasPrefix(typeOfS.Field(i).Name, "TirePressure") && !strings.HasSuffix(typeOfS.Field(i).Name, "Unit") {
|
|
||||||
// v.parseTire("TirePressure", "", typeOfS.Field(i).Name, val.Field(i).Interface())
|
|
||||||
// }
|
|
||||||
// if strings.HasPrefix(typeOfS.Field(i).Name, "Door") && strings.HasSuffix(typeOfS.Field(i).Name, "LockStatus") {
|
|
||||||
// v.parseLock("Door", "LockStatus", typeOfS.Field(i).Name, val.Field(i).Interface())
|
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,15 +784,26 @@ func (v *Vehicle) parseParts(name string, value any) {
|
|||||||
switch grps[1] {
|
switch grps[1] {
|
||||||
case "Door", "door":
|
case "Door", "door":
|
||||||
if d, ok := v.Doors[pn]; ok {
|
if d, ok := v.Doors[pn]; ok {
|
||||||
|
if grps[4] == "Position" {
|
||||||
d.Status = value.(string)
|
d.Status = value.(string)
|
||||||
|
}
|
||||||
|
if grps[4] == "LockStatus" {
|
||||||
|
d.Lock = value.(string)
|
||||||
|
}
|
||||||
d.Updated = time.Now()
|
d.Updated = time.Now()
|
||||||
v.Doors[pn] = d
|
v.Doors[pn] = d
|
||||||
} else {
|
} else {
|
||||||
v.Doors[pn] = Door{
|
d = Door{
|
||||||
Position: grps[2],
|
Position: grps[2],
|
||||||
Status: value.(string),
|
|
||||||
Updated: time.Now(),
|
Updated: time.Now(),
|
||||||
}
|
}
|
||||||
|
if grps[4] == "Position" {
|
||||||
|
d.Status = value.(string)
|
||||||
|
}
|
||||||
|
if grps[4] == "LockStatus" {
|
||||||
|
d.Lock = value.(string)
|
||||||
|
}
|
||||||
|
v.Doors[pn] = d
|
||||||
if len(grps) >= 2 {
|
if len(grps) >= 2 {
|
||||||
if d, ok := v.Doors[pn]; ok {
|
if d, ok := v.Doors[pn]; ok {
|
||||||
d.SubPosition = grps[3]
|
d.SubPosition = grps[3]
|
||||||
@ -841,132 +831,28 @@ func (v *Vehicle) parseParts(name string, value any) {
|
|||||||
}
|
}
|
||||||
case "Tire", "tire":
|
case "Tire", "tire":
|
||||||
if t, ok := v.Tires[pn]; ok {
|
if t, ok := v.Tires[pn]; ok {
|
||||||
|
if grps[4] == "Psi" {
|
||||||
t.PressurePsi = value.(int)
|
t.PressurePsi = value.(int)
|
||||||
|
} else {
|
||||||
|
t.Pressure = int(value.(float64))
|
||||||
|
}
|
||||||
t.Updated = time.Now()
|
t.Updated = time.Now()
|
||||||
v.Tires[pn] = t
|
v.Tires[pn] = t
|
||||||
} else {
|
} else {
|
||||||
v.Tires[pn] = Tire{
|
t = Tire{
|
||||||
Position: grps[2],
|
Position: grps[2],
|
||||||
PressurePsi: value.(int),
|
SubPosition: grps[3],
|
||||||
Updated: time.Now(),
|
Updated: time.Now(),
|
||||||
}
|
}
|
||||||
if len(grps) >= 2 {
|
if grps[4] == "Psi" {
|
||||||
if t, ok := v.Tires[pn]; ok {
|
t.PressurePsi = value.(int)
|
||||||
t.SubPosition = grps[3]
|
} else {
|
||||||
|
t.Pressure = int(value.(float64))
|
||||||
|
}
|
||||||
v.Tires[pn] = t
|
v.Tires[pn] = t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// parseLock .
|
|
||||||
// func (v *Vehicle) parseLock(prefix, suffix, name string, value any) {
|
|
||||||
// re := regexp.MustCompile(`[A-Z][^A-Z]*`)
|
|
||||||
// pos := strings.TrimPrefix(name, prefix)
|
|
||||||
// pos = strings.TrimSuffix(pos, suffix)
|
|
||||||
// submatchall := re.FindAllString(pos, -1)
|
|
||||||
// // v.client.logger.Debug("door lock status", "key", name, "value", value, "number", len(submatchall))
|
|
||||||
|
|
||||||
// if d, ok := v.Doors[pos]; ok {
|
|
||||||
// d.Lock = value.(string)
|
|
||||||
// d.Updated = time.Now()
|
|
||||||
// v.Doors[pos] = d
|
|
||||||
// } else {
|
|
||||||
// v.Doors[pos] = Door{
|
|
||||||
// Position: submatchall[0],
|
|
||||||
// Lock: value.(string),
|
|
||||||
// Updated: time.Now(),
|
|
||||||
// }
|
|
||||||
// if len(submatchall) >= 2 {
|
|
||||||
// if d, ok := v.Doors[pos]; ok {
|
|
||||||
// d.SubPosition = submatchall[1]
|
|
||||||
// v.Doors[pos] = d
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// parseWindow .
|
|
||||||
// func (v *Vehicle) parseWindow(prefix, suffix, name string, value any) {
|
|
||||||
// re := regexp.MustCompile(`[A-Z][^A-Z]*`)
|
|
||||||
// pos := strings.TrimPrefix(name, prefix)
|
|
||||||
// pos = strings.TrimSuffix(pos, suffix)
|
|
||||||
// submatchall := re.FindAllString(pos, -1)
|
|
||||||
// // v.client.logger.Debug("VEHICLE COND", "key", name, "data", value, "number", len(submatchall))
|
|
||||||
|
|
||||||
// if w, ok := v.Windows[pos]; ok {
|
|
||||||
// w.Status = value.(string)
|
|
||||||
// w.Updated = time.Now()
|
|
||||||
// v.Windows[pos] = w
|
|
||||||
// } else {
|
|
||||||
// v.Windows[pos] = Window{
|
|
||||||
// Position: submatchall[0],
|
|
||||||
// Status: value.(string),
|
|
||||||
// Updated: time.Now(),
|
|
||||||
// }
|
|
||||||
// if len(submatchall) >= 2 {
|
|
||||||
// if w, ok := v.Windows[pos]; ok {
|
|
||||||
// w.SubPosition = submatchall[1]
|
|
||||||
// v.Windows[pos] = w
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// parseTirePsi .
|
|
||||||
// func (v *Vehicle) parseTirePsi(prefix, suffix, name string, value any) {
|
|
||||||
// re := regexp.MustCompile(`[A-Z][^A-Z]*`)
|
|
||||||
// pos := strings.TrimPrefix(name, prefix)
|
|
||||||
// pos = strings.TrimSuffix(pos, suffix)
|
|
||||||
// submatchall := re.FindAllString(pos, -1)
|
|
||||||
// // v.client.logger.Debug("VEHICLE COND", "key", name, "data", value, "number", len(submatchall))
|
|
||||||
|
|
||||||
// if t, ok := v.Tires[pos]; ok {
|
|
||||||
// t.PressurePsi = value.(int)
|
|
||||||
// t.Updated = time.Now()
|
|
||||||
// v.Tires[pos] = t
|
|
||||||
// } else {
|
|
||||||
// v.Tires[pos] = Tire{
|
|
||||||
// Position: submatchall[0],
|
|
||||||
// PressurePsi: value.(int),
|
|
||||||
// Updated: time.Now(),
|
|
||||||
// }
|
|
||||||
// if len(submatchall) >= 2 {
|
|
||||||
// if t, ok := v.Tires[pos]; ok {
|
|
||||||
// t.SubPosition = submatchall[1]
|
|
||||||
// v.Tires[pos] = t
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// parseTire .
|
|
||||||
// func (v *Vehicle) parseTire(prefix, suffix, name string, value any) {
|
|
||||||
// re := regexp.MustCompile(`[A-Z][^A-Z]*`)
|
|
||||||
// pos := strings.TrimPrefix(name, prefix)
|
|
||||||
// pos = strings.TrimSuffix(pos, suffix)
|
|
||||||
// submatchall := re.FindAllString(pos, -1)
|
|
||||||
// // v.client.logger.Debug("VEHICLE COND", "key", name, "data", value, "number", len(submatchall))
|
|
||||||
|
|
||||||
// if t, ok := v.Tires[pos]; ok {
|
|
||||||
// t.Pressure = int(value.(float64))
|
|
||||||
// t.Updated = time.Now()
|
|
||||||
// v.Tires[pos] = t
|
|
||||||
// } else {
|
|
||||||
// v.Tires[pos] = Tire{
|
|
||||||
// Position: submatchall[0],
|
|
||||||
// Pressure: int(value.(float64)),
|
|
||||||
// Updated: time.Now(),
|
|
||||||
// }
|
|
||||||
// if len(submatchall) >= 2 {
|
|
||||||
// if t, ok := v.Tires[pos]; ok {
|
|
||||||
// t.SubPosition = submatchall[1]
|
|
||||||
// v.Tires[pos] = t
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // getRemoteStartStatus .
|
// // getRemoteStartStatus .
|
||||||
// // Get whether the specified VIN has remote engine start service available.
|
// // Get whether the specified VIN has remote engine start service available.
|
||||||
|
Reference in New Issue
Block a user