diff --git a/README.md b/README.md index 8301c48..ebcc300 100644 --- a/README.md +++ b/README.md @@ -211,7 +211,7 @@ The data that is accessible is data like the cars, charges, drives, current stat Also, apply some authentication on your webserver in front of the container, so your data is not unprotected and too exposed. In the example above, we use the same .htpasswd file as used by TeslaMate. -If you have applied a level of authentication in front of the container `API_TOKEN_DISABLE=true` will allow commands without requiring the header or uri token value. +If you have applied a level of authentication in front of the container `API_TOKEN_DISABLE=true` will allow commands without requiring the header or uri token value. But even then it's always rekommended to use an apikey. ## Credits diff --git a/src/CommandSupport.go b/src/CommandSupport.go index e365378..3707925 100644 --- a/src/CommandSupport.go +++ b/src/CommandSupport.go @@ -142,10 +142,8 @@ func initCommandAllowList() { for key := range CommandList { // checking if env is set from key or if all should be allowed if getEnvAsBool(key, false) || allowAll { - // looping over all values and appending to allowList - for _, values := range CommandList[key] { - allowList = append(allowList, string(values)) - } + // appending to allowList + allowList = append(allowList, strings.Join(CommandList[key], " ")) } } diff --git a/src/v1_TeslaMateAPICarsCharges.go b/src/v1_TeslaMateAPICarsCharges.go index 7750211..247e7e9 100644 --- a/src/v1_TeslaMateAPICarsCharges.go +++ b/src/v1_TeslaMateAPICarsCharges.go @@ -66,8 +66,10 @@ func TeslaMateAPICarsChargesV1(c *gin.Context) { } // creating required vars - var ChargesData []Charges - var UnitsLength, UnitsTemperature, CarName string + var ( + ChargesData []Charges + UnitsLength, UnitsTemperature, CarName string + ) // calculate offset based on page (page 0 is not possible, since first page is minimum 1) if ResultPage > 0 { diff --git a/src/v1_TeslaMateAPICarsChargesDetails.go b/src/v1_TeslaMateAPICarsChargesDetails.go index 7645601..504d5a4 100644 --- a/src/v1_TeslaMateAPICarsChargesDetails.go +++ b/src/v1_TeslaMateAPICarsChargesDetails.go @@ -1,6 +1,8 @@ package main import ( + "database/sql" + "github.com/gin-gonic/gin" _ "github.com/lib/pq" ) @@ -9,8 +11,10 @@ import ( func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) { // define error messages - var CarsChargesDetailsError1 = "Unable to load charge." - var CarsChargesDetailsError2 = "Unable to load charge details." + var ( + CarsChargesDetailsError1 = "Unable to load charge." + CarsChargesDetailsError2 = "Unable to load charge details." + ) // getting CarID and ChargeID param from URL CarID := convertStringToInteger(c.Param("CarID")) @@ -103,9 +107,11 @@ func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) { } // creating required vars - var charge Charge - var ChargeDetailsData []ChargeDetails - var UnitsLength, UnitsTemperature, CarName string + var ( + charge Charge + ChargeDetailsData []ChargeDetails + UnitsLength, UnitsTemperature, CarName string + ) // getting data from database query := ` @@ -137,67 +143,61 @@ func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) { LEFT JOIN charges ON charging_processes.id = charges.id WHERE charging_processes.car_id=$1 AND charging_processes.id=$2 AND charging_processes.end_date IS NOT NULL ORDER BY start_date DESC;` - rows, err := db.Query(query, CarID, ChargeID) + row := db.QueryRow(query, CarID, ChargeID) - // checking for errors in query - if err != nil { + // scanning row and putting values into the charge + err := row.Scan( + &charge.ChargeID, + &charge.StartDate, + &charge.EndDate, + &charge.Address, + &charge.ChargeEnergyAdded, + &charge.ChargeEnergyUsed, + &charge.Cost, + &charge.RangeIdeal.StartRange, + &charge.RangeIdeal.EndRange, + &charge.RangeRated.StartRange, + &charge.RangeRated.EndRange, + &charge.BatteryDetails.StartBatteryLevel, + &charge.BatteryDetails.EndBatteryLevel, + &charge.DurationMin, + &charge.DurationStr, + &charge.OutsideTempAvg, + &UnitsLength, + &UnitsTemperature, + &CarName, + ) + + switch err { + case sql.ErrNoRows: + TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", "No rows were returned!", err.Error()) + return + case nil: + // nothing wrong.. continuing + break + default: TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", CarsChargesDetailsError1, err.Error()) return } - // defer closing rows - defer rows.Close() + // converting values based of settings UnitsLength + if UnitsLength == "mi" { + charge.RangeIdeal.StartRange = kilometersToMiles(charge.RangeIdeal.StartRange) + charge.RangeIdeal.EndRange = kilometersToMiles(charge.RangeIdeal.EndRange) + charge.RangeRated.StartRange = kilometersToMiles(charge.RangeRated.StartRange) + charge.RangeRated.EndRange = kilometersToMiles(charge.RangeRated.EndRange) + } + // converting values based of settings UnitsTemperature + if UnitsTemperature == "F" { + charge.OutsideTempAvg = celsiusToFahrenheit(charge.OutsideTempAvg) + } - // looping through all results - for rows.Next() { + // adjusting to timezone differences from UTC to be userspecific + charge.StartDate = getTimeInTimeZone(charge.StartDate) + charge.EndDate = getTimeInTimeZone(charge.EndDate) - // scanning row and putting values into the charge - err = rows.Scan( - &charge.ChargeID, - &charge.StartDate, - &charge.EndDate, - &charge.Address, - &charge.ChargeEnergyAdded, - &charge.ChargeEnergyUsed, - &charge.Cost, - &charge.RangeIdeal.StartRange, - &charge.RangeIdeal.EndRange, - &charge.RangeRated.StartRange, - &charge.RangeRated.EndRange, - &charge.BatteryDetails.StartBatteryLevel, - &charge.BatteryDetails.EndBatteryLevel, - &charge.DurationMin, - &charge.DurationStr, - &charge.OutsideTempAvg, - &UnitsLength, - &UnitsTemperature, - &CarName, - ) - - // converting values based of settings UnitsLength - if UnitsLength == "mi" { - charge.RangeIdeal.StartRange = kilometersToMiles(charge.RangeIdeal.StartRange) - charge.RangeIdeal.EndRange = kilometersToMiles(charge.RangeIdeal.EndRange) - charge.RangeRated.StartRange = kilometersToMiles(charge.RangeRated.StartRange) - charge.RangeRated.EndRange = kilometersToMiles(charge.RangeRated.EndRange) - } - // converting values based of settings UnitsTemperature - if UnitsTemperature == "F" { - charge.OutsideTempAvg = celsiusToFahrenheit(charge.OutsideTempAvg) - } - - // adjusting to timezone differences from UTC to be userspecific - charge.StartDate = getTimeInTimeZone(charge.StartDate) - charge.EndDate = getTimeInTimeZone(charge.EndDate) - - // checking for errors after scanning - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", CarsChargesDetailsError1, err.Error()) - return - } - - // getting detailed charge data from database - query = ` + // getting detailed charge data from database + query = ` SELECT id AS detail_id, date, @@ -223,71 +223,70 @@ func TeslaMateAPICarsChargesDetailsV1(c *gin.Context) { FROM charges WHERE charging_process_id=$1 ORDER BY id ASC;` - rows, err = db.Query(query, ChargeID) + rows, err := db.Query(query, ChargeID) - // checking for errors in query + // checking for errors in query + if err != nil { + TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", CarsChargesDetailsError2, err.Error()) + return + } + + // defer closing rows + defer rows.Close() + + // looping through all results + for rows.Next() { + + // creating chargedetails object based on struct + chargedetails := ChargeDetails{} + + // scanning row and putting values into the drive + err = rows.Scan( + &chargedetails.DetailID, + &chargedetails.Date, + &chargedetails.BatteryLevel, + &chargedetails.UsableBatteryLevel, + &chargedetails.ChargeEnergyAdded, + &chargedetails.NotEnoughPowerToHeat, + &chargedetails.ChargerDetails.ChargerActualCurrent, + &chargedetails.ChargerDetails.ChargerPhases, + &chargedetails.ChargerDetails.ChargerPilotCurrent, + &chargedetails.ChargerDetails.ChargerPower, + &chargedetails.ChargerDetails.ChargerVoltage, + &chargedetails.BatteryInfo.IdealBatteryRange, + &chargedetails.BatteryInfo.RatedBatteryRange, + &chargedetails.BatteryInfo.BatteryHeater, + &chargedetails.BatteryInfo.BatteryHeaterOn, + &chargedetails.BatteryInfo.BatteryHeaterNoPower, + &chargedetails.ConnChargeCable, + &chargedetails.FastChargerInfo.FastChargerPresent, + &chargedetails.FastChargerInfo.FastChargerBrand, + &chargedetails.FastChargerInfo.FastChargerType, + &chargedetails.OutsideTemp, + ) + + // converting values based of settings UnitsLength + if UnitsLength == "mi" { + chargedetails.BatteryInfo.IdealBatteryRange = kilometersToMiles(chargedetails.BatteryInfo.IdealBatteryRange) + chargedetails.BatteryInfo.RatedBatteryRange = kilometersToMiles(chargedetails.BatteryInfo.RatedBatteryRange) + + } + // converting values based of settings UnitsTemperature + if UnitsTemperature == "F" { + chargedetails.OutsideTemp = celsiusToFahrenheit(chargedetails.OutsideTemp) + } + // adjusting to timezone differences from UTC to be userspecific + chargedetails.Date = getTimeInTimeZone(chargedetails.Date) + + // checking for errors after scanning if err != nil { TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", CarsChargesDetailsError2, err.Error()) return } - // defer closing rows - defer rows.Close() - - // looping through all results - for rows.Next() { - - // creating chargedetails object based on struct - chargedetails := ChargeDetails{} - - // scanning row and putting values into the drive - err = rows.Scan( - &chargedetails.DetailID, - &chargedetails.Date, - &chargedetails.BatteryLevel, - &chargedetails.UsableBatteryLevel, - &chargedetails.ChargeEnergyAdded, - &chargedetails.NotEnoughPowerToHeat, - &chargedetails.ChargerDetails.ChargerActualCurrent, - &chargedetails.ChargerDetails.ChargerPhases, - &chargedetails.ChargerDetails.ChargerPilotCurrent, - &chargedetails.ChargerDetails.ChargerPower, - &chargedetails.ChargerDetails.ChargerVoltage, - &chargedetails.BatteryInfo.IdealBatteryRange, - &chargedetails.BatteryInfo.RatedBatteryRange, - &chargedetails.BatteryInfo.BatteryHeater, - &chargedetails.BatteryInfo.BatteryHeaterOn, - &chargedetails.BatteryInfo.BatteryHeaterNoPower, - &chargedetails.ConnChargeCable, - &chargedetails.FastChargerInfo.FastChargerPresent, - &chargedetails.FastChargerInfo.FastChargerBrand, - &chargedetails.FastChargerInfo.FastChargerType, - &chargedetails.OutsideTemp, - ) - - // converting values based of settings UnitsLength - if UnitsLength == "mi" { - chargedetails.BatteryInfo.IdealBatteryRange = kilometersToMiles(chargedetails.BatteryInfo.IdealBatteryRange) - chargedetails.BatteryInfo.RatedBatteryRange = kilometersToMiles(chargedetails.BatteryInfo.RatedBatteryRange) - - } - // converting values based of settings UnitsTemperature - if UnitsTemperature == "F" { - chargedetails.OutsideTemp = celsiusToFahrenheit(chargedetails.OutsideTemp) - } - // adjusting to timezone differences from UTC to be userspecific - chargedetails.Date = getTimeInTimeZone(chargedetails.Date) - - // checking for errors after scanning - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsChargesDetailsV1", CarsChargesDetailsError2, err.Error()) - return - } - - // appending drive to ChargeData - ChargeDetailsData = append(ChargeDetailsData, chargedetails) - charge.ChargeDetails = ChargeDetailsData - } + // appending drive to ChargeData + ChargeDetailsData = append(ChargeDetailsData, chargedetails) + charge.ChargeDetails = ChargeDetailsData } // checking for errors in the rows result diff --git a/src/v1_TeslaMateAPICarsCommand.go b/src/v1_TeslaMateAPICarsCommand.go index f15cba8..95e8f3f 100644 --- a/src/v1_TeslaMateAPICarsCommand.go +++ b/src/v1_TeslaMateAPICarsCommand.go @@ -15,9 +15,11 @@ import ( func TeslaMateAPICarsCommandV1(c *gin.Context) { // creating required vars - var TeslaAccessToken, TeslaVehicleID string - var jsonData map[string]interface{} - var err error + var ( + TeslaAccessToken, TeslaVehicleID string + jsonData map[string]interface{} + err error + ) // check if commands are enabled.. if not we need to abort if !getEnvAsBool("ENABLE_COMMANDS", false) { diff --git a/src/v1_TeslaMateAPICarsDrives.go b/src/v1_TeslaMateAPICarsDrives.go index 28cc8b6..f1c0099 100644 --- a/src/v1_TeslaMateAPICarsDrives.go +++ b/src/v1_TeslaMateAPICarsDrives.go @@ -81,8 +81,10 @@ func TeslaMateAPICarsDrivesV1(c *gin.Context) { } // creating required vars - var DrivesData []Drives - var UnitsLength, UnitsTemperature, CarName string + var ( + DrivesData []Drives + UnitsLength, UnitsTemperature, CarName string + ) // calculate offset based on page (page 0 is not possible, since first page is minimum 1) if ResultPage > 0 { diff --git a/src/v1_TeslaMateAPICarsDrivesDetails.go b/src/v1_TeslaMateAPICarsDrivesDetails.go index b6b0116..6c39a64 100644 --- a/src/v1_TeslaMateAPICarsDrivesDetails.go +++ b/src/v1_TeslaMateAPICarsDrivesDetails.go @@ -1,6 +1,8 @@ package main import ( + "database/sql" + "github.com/gin-gonic/gin" _ "github.com/lib/pq" ) @@ -9,8 +11,10 @@ import ( func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) { // define error messages - var CarsDrivesDetailsError1 = "Unable to load drive." - var CarsDrivesDetailsError2 = "Unable to load drive details." + var ( + CarsDrivesDetailsError1 = "Unable to load drive." + CarsDrivesDetailsError2 = "Unable to load drive details." + ) // getting CarID and DriveID param from URL CarID := convertStringToInteger(c.Param("CarID")) @@ -116,9 +120,11 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) { } // creating required vars - var drive Drive - var DriveDetailsData []DriveDetails - var UnitsLength, UnitsTemperature, CarName string + var ( + drive Drive + DriveDetailsData []DriveDetails + UnitsLength, UnitsTemperature, CarName string + ) // getting data from database query := ` @@ -163,89 +169,80 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) { LEFT JOIN geofences start_geofence ON start_geofence_id = start_geofence.id LEFT JOIN geofences end_geofence ON end_geofence_id = end_geofence.id WHERE drives.car_id=$1 AND end_date IS NOT NULL AND drives.id = $2;` - rows, err := db.Query(query, CarID, DriveID) + row := db.QueryRow(query, CarID, DriveID) - // checking for errors in query - if err != nil { + // scanning row and putting values into the drive + err := row.Scan( + &drive.DriveID, + &drive.StartDate, + &drive.EndDate, + &drive.StartAddress, + &drive.EndAddress, + &drive.OdometerDetails.OdometerStart, + &drive.OdometerDetails.OdometerEnd, + &drive.OdometerDetails.OdometerDistance, + &drive.DurationMin, + &drive.DurationStr, + &drive.SpeedMax, + &drive.SpeedAvg, + &drive.PowerMax, + &drive.PowerMin, + &drive.BatteryDetails.StartUsableBatteryLevel, + &drive.BatteryDetails.StartBatteryLevel, + &drive.BatteryDetails.EndUsableBatteryLevel, + &drive.BatteryDetails.EndBatteryLevel, + &drive.BatteryDetails.ReducedRange, + &drive.BatteryDetails.IsSufficientlyPrecise, + &drive.RangeIdeal.StartRange, + &drive.RangeIdeal.EndRange, + &drive.RangeIdeal.RangeDiff, + &drive.RangeRated.StartRange, + &drive.RangeRated.EndRange, + &drive.RangeRated.RangeDiff, + &drive.OutsideTempAvg, + &drive.InsideTempAvg, + &UnitsLength, + &UnitsTemperature, + &CarName, + ) + + switch err { + case sql.ErrNoRows: + TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", "No rows were returned!", err.Error()) + return + case nil: + // nothing wrong.. continuing + break + default: TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError1, err.Error()) return } - // defer closing rows - defer rows.Close() + // converting values based of settings UnitsLength + if UnitsLength == "mi" { + drive.OdometerDetails.OdometerStart = kilometersToMiles(drive.OdometerDetails.OdometerStart) + drive.OdometerDetails.OdometerEnd = kilometersToMiles(drive.OdometerDetails.OdometerEnd) + drive.OdometerDetails.OdometerDistance = kilometersToMiles(drive.OdometerDetails.OdometerDistance) + drive.SpeedMax = int(kilometersToMiles(float64(drive.SpeedMax))) + drive.SpeedAvg = kilometersToMiles(drive.SpeedAvg) + drive.RangeIdeal.StartRange = kilometersToMiles(drive.RangeIdeal.StartRange) + drive.RangeIdeal.EndRange = kilometersToMiles(drive.RangeIdeal.EndRange) + drive.RangeIdeal.RangeDiff = kilometersToMiles(drive.RangeIdeal.RangeDiff) + drive.RangeRated.StartRange = kilometersToMiles(drive.RangeRated.StartRange) + drive.RangeRated.EndRange = kilometersToMiles(drive.RangeRated.EndRange) + drive.RangeRated.RangeDiff = kilometersToMiles(drive.RangeRated.RangeDiff) + } + // converting values based of settings UnitsTemperature + if UnitsTemperature == "F" { + drive.OutsideTempAvg = celsiusToFahrenheit(drive.OutsideTempAvg) + drive.InsideTempAvg = celsiusToFahrenheit(drive.InsideTempAvg) + } + // adjusting to timezone differences from UTC to be userspecific + drive.StartDate = getTimeInTimeZone(drive.StartDate) + drive.EndDate = getTimeInTimeZone(drive.EndDate) - // looping through all results - for rows.Next() { - - // creating drive object based on struct - drive := Drive{} - - // scanning row and putting values into the drive - err = rows.Scan( - &drive.DriveID, - &drive.StartDate, - &drive.EndDate, - &drive.StartAddress, - &drive.EndAddress, - &drive.OdometerDetails.OdometerStart, - &drive.OdometerDetails.OdometerEnd, - &drive.OdometerDetails.OdometerDistance, - &drive.DurationMin, - &drive.DurationStr, - &drive.SpeedMax, - &drive.SpeedAvg, - &drive.PowerMax, - &drive.PowerMin, - &drive.BatteryDetails.StartUsableBatteryLevel, - &drive.BatteryDetails.StartBatteryLevel, - &drive.BatteryDetails.EndUsableBatteryLevel, - &drive.BatteryDetails.EndBatteryLevel, - &drive.BatteryDetails.ReducedRange, - &drive.BatteryDetails.IsSufficientlyPrecise, - &drive.RangeIdeal.StartRange, - &drive.RangeIdeal.EndRange, - &drive.RangeIdeal.RangeDiff, - &drive.RangeRated.StartRange, - &drive.RangeRated.EndRange, - &drive.RangeRated.RangeDiff, - &drive.OutsideTempAvg, - &drive.InsideTempAvg, - &UnitsLength, - &UnitsTemperature, - &CarName, - ) - - // converting values based of settings UnitsLength - if UnitsLength == "mi" { - drive.OdometerDetails.OdometerStart = kilometersToMiles(drive.OdometerDetails.OdometerStart) - drive.OdometerDetails.OdometerEnd = kilometersToMiles(drive.OdometerDetails.OdometerEnd) - drive.OdometerDetails.OdometerDistance = kilometersToMiles(drive.OdometerDetails.OdometerDistance) - drive.SpeedMax = int(kilometersToMiles(float64(drive.SpeedMax))) - drive.SpeedAvg = kilometersToMiles(drive.SpeedAvg) - drive.RangeIdeal.StartRange = kilometersToMiles(drive.RangeIdeal.StartRange) - drive.RangeIdeal.EndRange = kilometersToMiles(drive.RangeIdeal.EndRange) - drive.RangeIdeal.RangeDiff = kilometersToMiles(drive.RangeIdeal.RangeDiff) - drive.RangeRated.StartRange = kilometersToMiles(drive.RangeRated.StartRange) - drive.RangeRated.EndRange = kilometersToMiles(drive.RangeRated.EndRange) - drive.RangeRated.RangeDiff = kilometersToMiles(drive.RangeRated.RangeDiff) - } - // converting values based of settings UnitsTemperature - if UnitsTemperature == "F" { - drive.OutsideTempAvg = celsiusToFahrenheit(drive.OutsideTempAvg) - drive.InsideTempAvg = celsiusToFahrenheit(drive.InsideTempAvg) - } - // adjusting to timezone differences from UTC to be userspecific - drive.StartDate = getTimeInTimeZone(drive.StartDate) - drive.EndDate = getTimeInTimeZone(drive.EndDate) - - // checking for errors after scanning - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError1, err.Error()) - return - } - - // getting detailed drive data from database - query = ` + // getting detailed drive data from database + query = ` SELECT id AS detail_id, date, @@ -274,87 +271,78 @@ func TeslaMateAPICarsDrivesDetailsV1(c *gin.Context) { FROM positions WHERE drive_id = $1 ORDER BY id ASC;` - rows, err = db.Query(query, DriveID) + rows, err := db.Query(query, DriveID) - // checking for errors in query - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError2, err.Error()) - return - } - - // defer closing rows - defer rows.Close() - - // looping through all results - for rows.Next() { - - // creating drivedetails object based on struct - drivedetails := DriveDetails{} - - // scanning row and putting values into the drive - err = rows.Scan( - &drivedetails.DetailID, - &drivedetails.Date, - &drivedetails.Latitude, - &drivedetails.Longitude, - &drivedetails.Speed, - &drivedetails.Power, - &drivedetails.Odometer, - &drivedetails.BatteryLevel, - &drivedetails.UsableBatteryLevel, - &drivedetails.Elevation, - &drivedetails.ClimateInfo.InsideTemp, - &drivedetails.ClimateInfo.OutsideTemp, - &drivedetails.ClimateInfo.IsClimateOn, - &drivedetails.ClimateInfo.FanStatus, - &drivedetails.ClimateInfo.DriverTempSetting, - &drivedetails.ClimateInfo.PassengerTempSetting, - &drivedetails.ClimateInfo.IsRearDefrosterOn, - &drivedetails.ClimateInfo.IsFrontDefrosterOn, - &drivedetails.BatteryInfo.EstBatteryRange, - &drivedetails.BatteryInfo.IdealBatteryRange, - &drivedetails.BatteryInfo.RatedBatteryRange, - &drivedetails.BatteryInfo.BatteryHeater, - &drivedetails.BatteryInfo.BatteryHeaterOn, - &drivedetails.BatteryInfo.BatteryHeaterNoPower, - ) - - // converting values based of settings UnitsLength - if UnitsLength == "mi" { - drivedetails.Odometer = kilometersToMiles(drivedetails.Odometer) - drivedetails.Speed = int(kilometersToMiles(float64(drivedetails.Speed))) - drivedetails.BatteryInfo.EstBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.EstBatteryRange) - drivedetails.BatteryInfo.IdealBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.IdealBatteryRange) - drivedetails.BatteryInfo.RatedBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.RatedBatteryRange) - } - // converting values based of settings UnitsTemperature - if UnitsTemperature == "F" { - drivedetails.ClimateInfo.InsideTemp = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.InsideTemp) - drivedetails.ClimateInfo.OutsideTemp = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.OutsideTemp) - drivedetails.ClimateInfo.DriverTempSetting = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.DriverTempSetting) - drivedetails.ClimateInfo.PassengerTempSetting = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.PassengerTempSetting) - } - // adjusting to timezone differences from UTC to be userspecific - drivedetails.Date = getTimeInTimeZone(drivedetails.Date) - - // checking for errors after scanning - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError2, err.Error()) - return - } - - // appending drive to drive - DriveDetailsData = append(DriveDetailsData, drivedetails) - drive.DriveDetails = DriveDetailsData - } - - // checking for errors in the rows result - err = rows.Err() + // checking for errors in query + if err != nil { + TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError2, err.Error()) + return + } + + // defer closing rows + defer rows.Close() + + // looping through all results + for rows.Next() { + + // creating drivedetails object based on struct + drivedetails := DriveDetails{} + + // scanning row and putting values into the drive + err = rows.Scan( + &drivedetails.DetailID, + &drivedetails.Date, + &drivedetails.Latitude, + &drivedetails.Longitude, + &drivedetails.Speed, + &drivedetails.Power, + &drivedetails.Odometer, + &drivedetails.BatteryLevel, + &drivedetails.UsableBatteryLevel, + &drivedetails.Elevation, + &drivedetails.ClimateInfo.InsideTemp, + &drivedetails.ClimateInfo.OutsideTemp, + &drivedetails.ClimateInfo.IsClimateOn, + &drivedetails.ClimateInfo.FanStatus, + &drivedetails.ClimateInfo.DriverTempSetting, + &drivedetails.ClimateInfo.PassengerTempSetting, + &drivedetails.ClimateInfo.IsRearDefrosterOn, + &drivedetails.ClimateInfo.IsFrontDefrosterOn, + &drivedetails.BatteryInfo.EstBatteryRange, + &drivedetails.BatteryInfo.IdealBatteryRange, + &drivedetails.BatteryInfo.RatedBatteryRange, + &drivedetails.BatteryInfo.BatteryHeater, + &drivedetails.BatteryInfo.BatteryHeaterOn, + &drivedetails.BatteryInfo.BatteryHeaterNoPower, + ) + + // converting values based of settings UnitsLength + if UnitsLength == "mi" { + drivedetails.Odometer = kilometersToMiles(drivedetails.Odometer) + drivedetails.Speed = int(kilometersToMiles(float64(drivedetails.Speed))) + drivedetails.BatteryInfo.EstBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.EstBatteryRange) + drivedetails.BatteryInfo.IdealBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.IdealBatteryRange) + drivedetails.BatteryInfo.RatedBatteryRange = kilometersToMilesNilSupport(drivedetails.BatteryInfo.RatedBatteryRange) + } + // converting values based of settings UnitsTemperature + if UnitsTemperature == "F" { + drivedetails.ClimateInfo.InsideTemp = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.InsideTemp) + drivedetails.ClimateInfo.OutsideTemp = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.OutsideTemp) + drivedetails.ClimateInfo.DriverTempSetting = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.DriverTempSetting) + drivedetails.ClimateInfo.PassengerTempSetting = celsiusToFahrenheitNilSupport(drivedetails.ClimateInfo.PassengerTempSetting) + } + // adjusting to timezone differences from UTC to be userspecific + drivedetails.Date = getTimeInTimeZone(drivedetails.Date) + + // checking for errors after scanning if err != nil { TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPICarsDrivesDetailsV1", CarsDrivesDetailsError2, err.Error()) return } + // appending drive to drive + DriveDetailsData = append(DriveDetailsData, drivedetails) + drive.DriveDetails = DriveDetailsData } // checking for errors in the rows result diff --git a/src/v1_TeslaMateAPICarsLogging.go b/src/v1_TeslaMateAPICarsLogging.go index 85bd892..05f95b3 100644 --- a/src/v1_TeslaMateAPICarsLogging.go +++ b/src/v1_TeslaMateAPICarsLogging.go @@ -16,8 +16,10 @@ import ( func TeslaMateAPICarsLoggingV1(c *gin.Context) { // creating required vars - var jsonData map[string]interface{} - var err error + var ( + jsonData map[string]interface{} + err error + ) // check if commands are enabled.. if not we need to abort if !getEnvAsBool("ENABLE_COMMANDS", false) { diff --git a/src/v1_TeslaMateAPICarsStatus.go b/src/v1_TeslaMateAPICarsStatus.go index e7e4bc0..2bc3658 100644 --- a/src/v1_TeslaMateAPICarsStatus.go +++ b/src/v1_TeslaMateAPICarsStatus.go @@ -160,8 +160,10 @@ func startMQTT() (*statusCache, error) { // newMessage - called by mqtt package when new message received func (s *statusCache) newMessage(c mqtt.Client, msg mqtt.Message) { // topic is in the format teslamateMQTT_NAMESPACE/cars/carID/display_name - var carID int - var MqttTopic string + var ( + carID int + MqttTopic string + ) _, err := fmt.Sscanf(msg.Topic(), s.topicScan, &carID, &MqttTopic) if err != nil { log.Printf("[warning] TeslaMateAPICarsStatusV1 unexpected topic format (%s) - ignoring message: %v", msg.Topic(), err) @@ -409,9 +411,11 @@ func (s *statusCache) TeslaMateAPICarsStatusV1(c *gin.Context) { } // creating required vars - var CarData Car - var MQTTInformationData MQTTInformation - var UnitsLength, UnitsTemperature string + var ( + CarData Car + MQTTInformationData MQTTInformation + UnitsLength, UnitsTemperature string + ) // getting data from database (assume that carID is unique!) query := ` diff --git a/src/v1_TeslaMateAPICarsUpdates.go b/src/v1_TeslaMateAPICarsUpdates.go index 28fda32..39b4b1f 100644 --- a/src/v1_TeslaMateAPICarsUpdates.go +++ b/src/v1_TeslaMateAPICarsUpdates.go @@ -41,8 +41,10 @@ func TeslaMateAPICarsUpdatesV1(c *gin.Context) { } // creating required vars - var UpdatesData []Updates - var CarData Car + var ( + UpdatesData []Updates + CarData Car + ) // calculate offset based on page (page 0 is not possible, since first page is minimum 1) if ResultPage > 0 { diff --git a/src/v1_TeslaMateAPIGlobalsettings.go b/src/v1_TeslaMateAPIGlobalsettings.go index 7dc6c2d..60c0e3b 100644 --- a/src/v1_TeslaMateAPIGlobalsettings.go +++ b/src/v1_TeslaMateAPIGlobalsettings.go @@ -1,6 +1,8 @@ package main import ( + "database/sql" + "github.com/gin-gonic/gin" _ "github.com/lib/pq" ) @@ -50,7 +52,7 @@ func TeslaMateAPIGlobalsettingsV1(c *gin.Context) { } // creating required vars - var GlobalSettingData GlobalSettings + var globalSetting GlobalSettings // getting data from database query := ` @@ -66,62 +68,42 @@ func TeslaMateAPIGlobalsettingsV1(c *gin.Context) { grafana_url FROM settings LIMIT 1;` - rows, err := db.Query(query) + row := db.QueryRow(query) - // checking for errors in query - if err != nil { + // scanning row and putting values into the globalSetting + err := row.Scan( + &globalSetting.SettingID, + &globalSetting.AccountInfo.InsertedAt, + &globalSetting.AccountInfo.UpdatedAt, + &globalSetting.TeslaMateUnits.UnitsLength, + &globalSetting.TeslaMateUnits.UnitsTemperature, + &globalSetting.TeslaMateGUI.PreferredRange, + &globalSetting.TeslaMateGUI.Language, + &globalSetting.TeslaMateURLs.BaseURL, + &globalSetting.TeslaMateURLs.GrafanaURL, + ) + + switch err { + case sql.ErrNoRows: + TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPIGlobalsettingsV1", "No rows were returned!", err.Error()) + return + case nil: + // nothing wrong.. continuing + break + default: TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPIGlobalsettingsV1", CarsGlobalsettingsError1, err.Error()) return } - // defer closing rows - defer rows.Close() - - // looping through all results - for rows.Next() { - - // creating GlobalSetting object based on struct - GlobalSetting := GlobalSettings{} - - // scanning row and putting values into the GlobalSetting - err = rows.Scan( - &GlobalSetting.SettingID, - &GlobalSetting.AccountInfo.InsertedAt, - &GlobalSetting.AccountInfo.UpdatedAt, - &GlobalSetting.TeslaMateUnits.UnitsLength, - &GlobalSetting.TeslaMateUnits.UnitsTemperature, - &GlobalSetting.TeslaMateGUI.PreferredRange, - &GlobalSetting.TeslaMateGUI.Language, - &GlobalSetting.TeslaMateURLs.BaseURL, - &GlobalSetting.TeslaMateURLs.GrafanaURL, - ) - - // checking for errors after scanning - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPIGlobalsettingsV1", CarsGlobalsettingsError1, err.Error()) - return - } - - // adjusting to timezone differences from UTC to be userspecific - GlobalSetting.AccountInfo.InsertedAt = getTimeInTimeZone(GlobalSetting.AccountInfo.InsertedAt) - GlobalSetting.AccountInfo.UpdatedAt = getTimeInTimeZone(GlobalSetting.AccountInfo.UpdatedAt) - - // setting response to valid - GlobalSettingData = GlobalSetting - } - - // checking for errors in the rows result - err = rows.Err() - if err != nil { - TeslaMateAPIHandleErrorResponse(c, "TeslaMateAPIGlobalsettingsV1", CarsGlobalsettingsError1, err.Error()) - return - } + // adjusting to timezone differences from UTC to be userspecific + globalSetting.AccountInfo.InsertedAt = getTimeInTimeZone(globalSetting.AccountInfo.InsertedAt) + globalSetting.AccountInfo.UpdatedAt = getTimeInTimeZone(globalSetting.AccountInfo.UpdatedAt) // // build the data-blob jsonData := JSONData{ Data{ - GlobalSettings: GlobalSettingData, + GlobalSettings: globalSetting, }, } diff --git a/src/webserver.go b/src/webserver.go index a096881..6792974 100644 --- a/src/webserver.go +++ b/src/webserver.go @@ -14,17 +14,19 @@ import ( _ "github.com/lib/pq" ) -// setting TeslaMateApi version number -var apiVersion = "unspecified" +var ( + // setting TeslaMateApi version number + apiVersion = "unspecified" -// defining db var -var db *sql.DB + // defining db var + db *sql.DB -// defining envToken that contains API_TOKEN value -var envToken string + // defining envToken that contains API_TOKEN value + envToken string -// list of allowed commands -var allowList []string + // list of allowed commands + allowList []string +) // main function func main() {