Skip to content

Commit

Permalink
feat: add gsm & gps signal strength percentages
Browse files Browse the repository at this point in the history
  • Loading branch information
drakhart committed Jun 21, 2022
1 parent 9bfce02 commit a3bd383
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 23 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ A total of 28 entities are included as follows:
- Current course in 8-point wind rose
- Current distance from home* with direction of travel (stationary/towards/away from/arrived)
- Current trip distance
- Current GSM signal strength
- Current GPS accuracy
- Current GSM signal strength*
- Current GPS accuracy*
- Last GPS fix time
- Last warning time* with title and content
- Last trip time*, distance* and average speed* (requires native tracking history to be enabled; updates every 10 minutes at most)
Expand Down
16 changes: 12 additions & 4 deletions custom_components/super_soco_custom/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,17 @@
API_GEO_PRECISION = 4 # 4 decimals = 11.1 meters
CDN_BASE_URL = "https://oimg.supersocoeg.com:8996"
CONFIG_FLOW_VERSION = 1
COURSE_ROUNDING_ZEROES = 2
DISTANCE_ROUNDING_ZEROES = 2
COURSE_ROUNDING_DECIMALS = 2
DISTANCE_ROUNDING_DECIMALS = 2
GPS_MAX_ACCURACY = 15 # It goes from 0 to 15
HOME_ZONE = "zone.home"
KM_IN_A_M = 0.001
LAST_TRIP_CACHE_SECONDS = 600
METERS_IN_EARTH_RADIUS = 6378160
POWER_OFF_DISTANCE_THRESHOLD_METERS = 16
POWER_ON_UPDATE_SECONDS = 5
SECONDS_IN_A_MINUTE = 60
SIGNAL_MAX_STRENGTH = 4 # It goes from 0 to 4

# Directions of travel
DIR_ARRIVED = "arrived"
Expand Down Expand Up @@ -93,6 +95,7 @@
DATA_ELEVATION = "elevation"
DATA_ESTIMATED_RANGE = "endurance"
DATA_GPS_ACCURACY = "gps"
DATA_GPS_ACCURACY_PERCENTAGE = "gps_accuracy_percentage"
DATA_LAST_GPS_TIME = "lastGpsTime"
DATA_LAST_TRIP_BEGIN_LATITUDE = "beginLatitude"
DATA_LAST_TRIP_BEGIN_LONGITUDE = "beginLongitude"
Expand Down Expand Up @@ -130,6 +133,7 @@
DATA_REVERSE_GEOCODING_STATE_DISTRICT = "state_district"
DATA_REVERSE_GEOCODING_VILLAGE = "village"
DATA_SIGNAL_STRENGTH = "gsm"
DATA_SIGNAL_STRENGTH_PERCENTAGE = "signal_strength_percentage"
DATA_SPEED = "sleep" # Intended typo
DATA_TITLE = "title"
DATA_TRIP_DISTANCE = "mileages"
Expand Down Expand Up @@ -293,7 +297,9 @@
None,
"mdi:crosshairs-gps",
None,
None,
{
"percentage": DATA_GPS_ACCURACY_PERCENTAGE,
},
),
(
"image",
Expand Down Expand Up @@ -385,7 +391,9 @@
None,
"mdi:signal",
DEVICE_CLASS_SIGNAL_STRENGTH,
None,
{
"percentage": DATA_SIGNAL_STRENGTH_PERCENTAGE,
},
),
(
"speed",
Expand Down
38 changes: 29 additions & 9 deletions custom_components/super_soco_custom/coordinator.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
DATA_DISTANCE_FROM_HOME,
DATA_ELEVATION,
DATA_ESTIMATED_RANGE,
DATA_GPS_ACCURACY_PERCENTAGE,
DATA_GPS_ACCURACY,
DATA_LAST_GPS_TIME,
DATA_LAST_TRIP_BEGIN_LATITUDE,
Expand Down Expand Up @@ -67,6 +68,7 @@
DATA_REVERSE_GEOCODING_STATE,
DATA_REVERSE_GEOCODING_VILLAGE,
DATA_REVERSE_GEOCODING,
DATA_SIGNAL_STRENGTH_PERCENTAGE,
DATA_SIGNAL_STRENGTH,
DATA_SPEED,
DATA_TITLE,
Expand All @@ -83,8 +85,9 @@
DIR_AWAY_FROM_HOME,
DIR_STATIONARY,
DIR_TOWARDS_HOME,
DISTANCE_ROUNDING_ZEROES,
DISTANCE_ROUNDING_DECIMALS,
DOMAIN,
GPS_MAX_ACCURACY,
HOME_ZONE,
KM_IN_A_M,
LAST_TRIP_CACHE_SECONDS,
Expand All @@ -96,11 +99,13 @@
POWER_OFF_DISTANCE_THRESHOLD_METERS,
POWER_ON_UPDATE_SECONDS,
SECONDS_IN_A_MINUTE,
SIGNAL_MAX_STRENGTH,
SWITCH_API_METHODS,
)
from .helpers import (
calculate_course,
calculate_distance,
calculate_percentage,
calculate_wind_rose_course,
parse_date,
)
Expand Down Expand Up @@ -165,7 +170,7 @@ async def _async_update_data(self):
DATA_ALARM_MODULE_VOLTAGE: device_data[DATA_ALARM_MODULE_VOLTAGE],
DATA_BATTERY_PERCENTAGE: device_data[DATA_BATTERY_PERCENTAGE],
DATA_TRIP_DISTANCE: round(
device_data[DATA_TRIP_DISTANCE], DISTANCE_ROUNDING_ZEROES
device_data[DATA_TRIP_DISTANCE], DISTANCE_ROUNDING_DECIMALS
),
DATA_ESTIMATED_RANGE: device_data[DATA_ESTIMATED_RANGE],
DATA_GPS_ACCURACY: device_data[DATA_GPS_ACCURACY],
Expand All @@ -191,9 +196,13 @@ async def _async_update_data(self):
# Check if device is powered on
self._is_powered_on = data[DATA_POWER_STATUS] == 1

# Inject alarm module battery data
# Inject alarm module data
data.update(
self._get_alarm_module_battery_data(data[DATA_ALARM_MODULE_VOLTAGE])
self._get_alarm_module_data(
data[DATA_ALARM_MODULE_VOLTAGE],
data[DATA_GPS_ACCURACY],
data[DATA_SIGNAL_STRENGTH],
)
)

# Inject home and course data only if vehicle is powered on or moving noticeably
Expand Down Expand Up @@ -252,10 +261,21 @@ async def _async_update_data(self):
_LOGGER.exception(exception)
raise UpdateFailed() from exception

def _get_alarm_module_battery_data(self, alarm_module_voltage: int) -> dict:
def _get_alarm_module_data(
self,
voltage: int,
gps_accuracy: int,
signal_strength: int,
) -> dict:
return {
DATA_ALARM_MODULE_BATTERY_PERCENTAGE: round(
100 * (alarm_module_voltage / ALARM_MODULE_MAX_VOLTAGE)
DATA_ALARM_MODULE_BATTERY_PERCENTAGE: calculate_percentage(
voltage, ALARM_MODULE_MAX_VOLTAGE
),
DATA_GPS_ACCURACY_PERCENTAGE: calculate_percentage(
gps_accuracy, GPS_MAX_ACCURACY
),
DATA_SIGNAL_STRENGTH_PERCENTAGE: calculate_percentage(
signal_strength, SIGNAL_MAX_STRENGTH
),
}

Expand Down Expand Up @@ -300,13 +320,13 @@ def _get_home_data(self, latitude: float, longitude: float) -> dict:
home_latitude = home.attributes.get(DATA_LATITUDE)
home_longitude = home.attributes.get(DATA_LONGITUDE)
home_radius = round(
home.attributes.get(DATA_RADIUS) * KM_IN_A_M, DISTANCE_ROUNDING_ZEROES
home.attributes.get(DATA_RADIUS) * KM_IN_A_M, DISTANCE_ROUNDING_DECIMALS
)

data[DATA_DISTANCE_FROM_HOME] = round(
calculate_distance(home_latitude, home_longitude, latitude, longitude)
* KM_IN_A_M,
DISTANCE_ROUNDING_ZEROES,
DISTANCE_ROUNDING_DECIMALS,
)

if data[DATA_DISTANCE_FROM_HOME] <= home_radius:
Expand Down
20 changes: 12 additions & 8 deletions custom_components/super_soco_custom/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,12 @@
from numpy import arctan2, degrees

from .const import (
COURSE_ROUNDING_ZEROES,
COURSE_ROUNDING_DECIMALS,
DEFAULT_FLOAT,
METERS_IN_EARTH_RADIUS,
)


def calculate_wind_rose_course(course: float) -> str:
wind_rose_brackets = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]

return wind_rose_brackets[round(course / 45)]


def calculate_course(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
if lat1 == lat2 and lon1 == lon2:
return DEFAULT_FLOAT
Expand All @@ -35,7 +29,7 @@ def calculate_course(lat1: float, lon1: float, lat2: float, lon2: float) -> floa
if course < 0:
course = 360 + course

return round(course, COURSE_ROUNDING_ZEROES)
return round(course, COURSE_ROUNDING_DECIMALS)


def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> float:
Expand Down Expand Up @@ -64,6 +58,16 @@ def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float) -> fl
return METERS_IN_EARTH_RADIUS * theta


def calculate_percentage(current: float, max: float, decimals: int = 0) -> float:
return min(round(100 * (current / max), decimals), 100)


def calculate_wind_rose_course(course: float) -> str:
wind_rose_brackets = ["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]

return wind_rose_brackets[round(course / 45)]


def parse_date(date_string: str) -> datetime:
clean_string = re.sub("AM|PM", "+01:00", date_string)
return datetime.strptime(clean_string, "%d/%m/%Y %H:%M%z")

0 comments on commit a3bd383

Please sign in to comment.