Skip to content

Commit

Permalink
adding address details (#212)
Browse files Browse the repository at this point in the history
* enhanced address details

- added AddressDetails for all endpoints
- changing string to NullString for carName
- fixing NullString

Co-authored-by: Vincent Barrier <[email protected]>
Co-authored-by: Tobias Lindberg <[email protected]>
  • Loading branch information
vbarrier and tobiasehlert committed Sep 22, 2023
1 parent ca0c58b commit 1fbd277
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 66 deletions.
27 changes: 19 additions & 8 deletions src/NullSupport.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ package main

import (
"database/sql"
"database/sql/driver"
"encoding/json"
"errors"
)

// NullInt64 is an alias for sql.NullInt64 data type
Expand Down Expand Up @@ -47,15 +49,24 @@ func (nf *NullFloat64) MarshalJSON() ([]byte, error) {
return json.Marshal(nf.Float64)
}

// NullString is an alias for sql.NullString data type
type NullString struct {
sql.NullString
type NullString string

func (s *NullString) Scan(value interface{}) error {
if value == nil {
*s = ""
return nil
}
strVal, ok := value.(string)
if !ok {
return errors.New("Column is not a string")
}
*s = NullString(strVal)
return nil
}

// MarshalJSON for NullString
func (ns *NullString) MarshalJSON() ([]byte, error) {
if !ns.Valid {
return []byte("null"), nil
func (s NullString) Value() (driver.Value, error) {
if len(s) == 0 { // if nil or empty string
return nil, nil
}
return json.Marshal(ns.String)
return string(s), nil
}
2 changes: 1 addition & 1 deletion src/v1_TeslaMateAPICars.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TeslaMateAPICarsV1(c *gin.Context) {
// Cars struct - child of Data
type Cars struct {
CarID int `json:"car_id"` // smallint
Name string `json:"name"` // text
Name NullString `json:"name"` // text
CarDetails CarDetails `json:"car_details"` // struct
CarExterior CarExterior `json:"car_exterior"` // struct
CarSettings CarSettings `json:"car_settings"` // struct
Expand Down
9 changes: 5 additions & 4 deletions src/v1_TeslaMateAPICarsCharges.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func TeslaMateAPICarsChargesV1(c *gin.Context) {
// creating structs for /cars/<CarID>/charges
// Car struct - child of Data
type Car struct {
CarID int `json:"car_id"` // smallint
CarName string `json:"car_name"` // text
CarID int `json:"car_id"` // smallint
CarName NullString `json:"car_name"` // text
}
// BatteryDetails struct - child of Charges
type BatteryDetails struct {
Expand Down Expand Up @@ -67,8 +67,9 @@ func TeslaMateAPICarsChargesV1(c *gin.Context) {

// creating required vars
var (
ChargesData []Charges
UnitsLength, UnitsTemperature, CarName string
CarName NullString
ChargesData []Charges
UnitsLength, UnitsTemperature string
)

// calculate offset based on page (page 0 is not possible, since first page is minimum 1)
Expand Down
11 changes: 6 additions & 5 deletions src/v1_TeslaMateAPICarsChargesDetails.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) {
// creating structs for /cars/<CarID>/charges/<ChargeID>
// Car struct - child of Data
type Car struct {
CarID int `json:"car_id"` // smallint
CarName string `json:"car_name"` // text
CarID int `json:"car_id"` // smallint
CarName NullString `json:"car_name"` // text
}
// BatteryDetails struct - child of Charges
type BatteryDetails struct {
Expand Down Expand Up @@ -108,9 +108,10 @@ func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) {

// creating required vars
var (
charge Charge
ChargeDetailsData []ChargeDetails
UnitsLength, UnitsTemperature, CarName string
CarName NullString
charge Charge
ChargeDetailsData []ChargeDetails
UnitsLength, UnitsTemperature string
)

// getting data from database
Expand Down
98 changes: 77 additions & 21 deletions src/v1_TeslaMateAPICarsDrives.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,21 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) {
// creating structs for /cars/<CarID>/drives
// Car struct - child of Data
type Car struct {
CarID int `json:"car_id"` // smallint
CarName string `json:"car_name"` // text
CarID int `json:"car_id"` // smallint
CarName NullString `json:"car_name"` // text
}
// AddressDetails struct - child of Drive
type AddressDetails struct {
AddressID int `json:"address_id"` // integer
HouseNumber NullString `json:"house_number"` // text
Road NullString `json:"road"` // text
Neighbourhood NullString `json:"neighbourhood"` // text
City NullString `json:"city"` // text
County NullString `json:"county"` // text
PostCode NullString `json:"post_code"` // text
State NullString `json:"state"` // text
StateDistrict NullString `json:"state_district"` // text
Country NullString `json:"country"` // text
}
// OdometerDetails struct - child of Drives
type OdometerDetails struct {
Expand All @@ -46,23 +59,25 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) {
}
// Drives struct - child of Data
type Drives struct {
DriveID int `json:"drive_id"` // int
StartDate string `json:"start_date"` // string
EndDate string `json:"end_date"` // string
StartAddress string `json:"start_address"` // string
EndAddress string `json:"end_address"` // string
OdometerDetails OdometerDetails `json:"odometer_details"` // OdometerDetails
DurationMin int `json:"duration_min"` // int
DurationStr string `json:"duration_str"` // string
SpeedMax int `json:"speed_max"` // int
SpeedAvg float64 `json:"speed_avg"` // float64
PowerMax int `json:"power_max"` // int
PowerMin int `json:"power_min"` // int
BatteryDetails BatteryDetails `json:"battery_details"` // BatteryDetails
RangeIdeal PreferredRange `json:"range_ideal"` // PreferredRange
RangeRated PreferredRange `json:"range_rated"` // PreferredRange
OutsideTempAvg float64 `json:"outside_temp_avg"` // float64
InsideTempAvg float64 `json:"inside_temp_avg"` // float64
DriveID int `json:"drive_id"` // int
StartDate string `json:"start_date"` // string
EndDate string `json:"end_date"` // string
StartAddress string `json:"start_address"` // string
EndAddress string `json:"end_address"` // string
StartAddressDetails AddressDetails `json:"start_address_details"` // struct
EndAddressDetails AddressDetails `json:"end_address_details"` // struct
OdometerDetails OdometerDetails `json:"odometer_details"` // OdometerDetails
DurationMin int `json:"duration_min"` // int
DurationStr string `json:"duration_str"` // string
SpeedMax int `json:"speed_max"` // int
SpeedAvg float64 `json:"speed_avg"` // float64
PowerMax int `json:"power_max"` // int
PowerMin int `json:"power_min"` // int
BatteryDetails BatteryDetails `json:"battery_details"` // BatteryDetails
RangeIdeal PreferredRange `json:"range_ideal"` // PreferredRange
RangeRated PreferredRange `json:"range_rated"` // PreferredRange
OutsideTempAvg float64 `json:"outside_temp_avg"` // float64
InsideTempAvg float64 `json:"inside_temp_avg"` // float64
}
// TeslaMateUnits struct - child of Data
type TeslaMateUnits struct {
Expand All @@ -82,8 +97,9 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) {

// creating required vars
var (
DrivesData []Drives
UnitsLength, UnitsTemperature, CarName string
CarName NullString
DrivesData []Drives
UnitsLength, UnitsTemperature string
)

// calculate offset based on page (page 0 is not possible, since first page is minimum 1)
Expand All @@ -102,6 +118,26 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) {
end_date,
COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS start_address,
COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS end_address,
start_address.id,
start_address.house_number,
start_address.road,
start_address.neighbourhood,
start_address.city,
start_address.county,
start_address.postcode,
start_address.state,
start_address.state_district,
start_address.country,
end_address.id,
end_address.house_number,
end_address.road,
end_address.neighbourhood,
end_address.city,
end_address.county,
end_address.postcode,
end_address.state,
end_address.state_district,
end_address.country,
start_km,
end_km,
distance,
Expand Down Expand Up @@ -163,6 +199,26 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) {
&drive.EndDate,
&drive.StartAddress,
&drive.EndAddress,
&drive.StartAddressDetails.AddressID,
&drive.StartAddressDetails.HouseNumber,
&drive.StartAddressDetails.Road,
&drive.StartAddressDetails.Neighbourhood,
&drive.StartAddressDetails.City,
&drive.StartAddressDetails.County,
&drive.StartAddressDetails.PostCode,
&drive.StartAddressDetails.State,
&drive.StartAddressDetails.StateDistrict,
&drive.StartAddressDetails.Country,
&drive.EndAddressDetails.AddressID,
&drive.EndAddressDetails.HouseNumber,
&drive.EndAddressDetails.Road,
&drive.EndAddressDetails.Neighbourhood,
&drive.EndAddressDetails.City,
&drive.EndAddressDetails.County,
&drive.EndAddressDetails.PostCode,
&drive.EndAddressDetails.State,
&drive.EndAddressDetails.StateDistrict,
&drive.EndAddressDetails.Country,
&drive.OdometerDetails.OdometerStart,
&drive.OdometerDetails.OdometerEnd,
&drive.OdometerDetails.OdometerDistance,
Expand Down
106 changes: 81 additions & 25 deletions src/v1_TeslaMateAPICarsDrivesDetails.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) {
// creating structs for /cars/<CarID>/drives/<DriveID>
// Car struct - child of Data
type Car struct {
CarID int `json:"car_id"` // smallint
CarName string `json:"car_name"` // text
CarID int `json:"car_id"` // smallint
CarName NullString `json:"car_name"` // text
}
// OdometerDetails struct - child of Drives
type OdometerDetails struct {
Expand Down Expand Up @@ -82,26 +82,41 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) {
ClimateInfo ClimateInfo `json:"climate_info"` // struct
BatteryInfo BatteryInfo `json:"battery_info"` // struct
}
// AddressDetails struct - child of Drive
type AddressDetails struct {
AddressID int `json:"address_id"` // integer
HouseNumber NullString `json:"house_number"` // text
Road NullString `json:"road"` // text
Neighbourhood NullString `json:"neighbourhood"` // text
City NullString `json:"city"` // text
County NullString `json:"county"` // text
PostCode NullString `json:"post_code"` // text
State NullString `json:"state"` // text
StateDistrict NullString `json:"state_district"` // text
Country NullString `json:"country"` // text
}
// Drive struct - child of Data
type Drive struct {
DriveID int `json:"drive_id"` // int
StartDate string `json:"start_date"` // string
EndDate string `json:"end_date"` // string
StartAddress string `json:"start_address"` // string
EndAddress string `json:"end_address"` // string
OdometerDetails OdometerDetails `json:"odometer_details"` // OdometerDetails
DurationMin int `json:"duration_min"` // int
DurationStr string `json:"duration_str"` // string
SpeedMax int `json:"speed_max"` // int
SpeedAvg float64 `json:"speed_avg"` // float64
PowerMax int `json:"power_max"` // int
PowerMin int `json:"power_min"` // int
BatteryDetails BatteryDetails `json:"battery_details"` // BatteryDetails
RangeIdeal PreferredRange `json:"range_ideal"` // PreferredRange
RangeRated PreferredRange `json:"range_rated"` // PreferredRange
OutsideTempAvg float64 `json:"outside_temp_avg"` // float64
InsideTempAvg float64 `json:"inside_temp_avg"` // float64
DriveDetails []DriveDetails `json:"drive_details"` // struct
DriveID int `json:"drive_id"` // int
StartDate string `json:"start_date"` // string
EndDate string `json:"end_date"` // string
StartAddress string `json:"start_address"` // string
EndAddress string `json:"end_address"` // string
StartAddressDetails AddressDetails `json:"start_address_details"` // struct
EndAddressDetails AddressDetails `json:"end_address_details"` // struct
OdometerDetails OdometerDetails `json:"odometer_details"` // OdometerDetails
DurationMin int `json:"duration_min"` // int
DurationStr string `json:"duration_str"` // string
SpeedMax int `json:"speed_max"` // int
SpeedAvg float64 `json:"speed_avg"` // float64
PowerMax int `json:"power_max"` // int
PowerMin int `json:"power_min"` // int
BatteryDetails BatteryDetails `json:"battery_details"` // BatteryDetails
RangeIdeal PreferredRange `json:"range_ideal"` // PreferredRange
RangeRated PreferredRange `json:"range_rated"` // PreferredRange
OutsideTempAvg float64 `json:"outside_temp_avg"` // float64
InsideTempAvg float64 `json:"inside_temp_avg"` // float64
DriveDetails []DriveDetails `json:"drive_details"` // struct
}
// TeslaMateUnits struct - child of Data
type TeslaMateUnits struct {
Expand All @@ -121,9 +136,10 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) {

// creating required vars
var (
drive Drive
DriveDetailsData []DriveDetails
UnitsLength, UnitsTemperature, CarName string
CarName NullString
drive Drive
DriveDetailsData []DriveDetails
UnitsLength, UnitsTemperature string
)

// getting data from database
Expand All @@ -132,8 +148,28 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) {
drives.id AS drive_id,
start_date,
end_date,
COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS start_address,
COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS end_address,
COALESCE(start_geofence.name, CONCAT_WS(', ', COALESCE(start_address.name, nullif(CONCAT_WS(' ', start_address.road, start_address.house_number), '')), start_address.city)) AS start_address_simple,
COALESCE(end_geofence.name, CONCAT_WS(', ', COALESCE(end_address.name, nullif(CONCAT_WS(' ', end_address.road, end_address.house_number), '')), end_address.city)) AS end_address_simple,
start_address.id,
start_address.house_number,
start_address.road,
start_address.neighbourhood,
start_address.city,
start_address.county,
start_address.postcode,
start_address.state,
start_address.state_district,
start_address.country,
end_address.id,
end_address.house_number,
end_address.road,
end_address.neighbourhood,
end_address.city,
end_address.county,
end_address.postcode,
end_address.state,
end_address.state_district,
end_address.country,
start_km,
end_km,
distance,
Expand Down Expand Up @@ -178,6 +214,26 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) {
&drive.EndDate,
&drive.StartAddress,
&drive.EndAddress,
&drive.StartAddressDetails.AddressID,
&drive.StartAddressDetails.HouseNumber,
&drive.StartAddressDetails.Road,
&drive.StartAddressDetails.Neighbourhood,
&drive.StartAddressDetails.City,
&drive.StartAddressDetails.County,
&drive.StartAddressDetails.PostCode,
&drive.StartAddressDetails.State,
&drive.StartAddressDetails.StateDistrict,
&drive.StartAddressDetails.Country,
&drive.EndAddressDetails.AddressID,
&drive.EndAddressDetails.HouseNumber,
&drive.EndAddressDetails.Road,
&drive.EndAddressDetails.Neighbourhood,
&drive.EndAddressDetails.City,
&drive.EndAddressDetails.County,
&drive.EndAddressDetails.PostCode,
&drive.EndAddressDetails.State,
&drive.EndAddressDetails.StateDistrict,
&drive.EndAddressDetails.Country,
&drive.OdometerDetails.OdometerStart,
&drive.OdometerDetails.OdometerEnd,
&drive.OdometerDetails.OdometerDistance,
Expand Down
4 changes: 2 additions & 2 deletions src/v1_TeslaMateAPICarsUpdates.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ func TeslaMateAPICarsUpdatesV1(c *gin.Context) {
// creating structs for /cars/<CarID>/updates
// Car struct - child of Data
type Car struct {
CarID int `json:"car_id"` // smallint
CarName string `json:"car_name"` // text
CarID int `json:"car_id"` // smallint
CarName NullString `json:"car_name"` // text
}
// Updates struct - child of Data
type Updates struct {
Expand Down

0 comments on commit 1fbd277

Please sign in to comment.