]> git.giorgioravera.it Git - mercedes_me_api.git/commitdiff
Major improvements
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Sun, 25 Oct 2020 16:47:07 +0000 (17:47 +0100)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Sun, 25 Oct 2020 16:47:07 +0000 (17:47 +0100)
mercedes_me_api.py
query.py
resources.py

index f40e7fff30a73012390c2e1d18dc55339eb9500e..d7019fde81568478a1844d0697d0bb354270f9cd 100644 (file)
@@ -11,17 +11,18 @@ import logging
 import sys
 
 from config import MercedesMeConfig
-from resources import MercedesMeResourcesDB
+from resources import MercedesMeResources
+from const import *
 
 # Logger
-logger = logging.getLogger(__name__)
+_LOGGER = logging.getLogger(__name__)
 
 class MercedesMeData:
     def __init__(self):
         # Configuration Data
-        self.config = MercedesMeConfig()
+        self.mercedesConfig = MercedesMeConfig()
         # Resource Data
-        self.resourcesDB = MercedesMeResourcesDB(self.config)
+        self.mercedesResources = MercedesMeResources(self.mercedesConfig)
 
 ########################
 # Parse Input
@@ -32,7 +33,7 @@ def ParseInput():
     parser.add_argument('-r', '--refresh', action='store_true', help="Procedure to refresh the Access Token")
     parser.add_argument('-s', '--status', action='store_true', help="Retrive the Status of your Vehicle")
     parser.add_argument('-R', '--resources', action='store_true', help="Retrive the list of available resources of your Vehicle")
-    parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + data.config.version)
+    parser.add_argument('-v', '--version', action='version', version='%(prog)s ' + VERSION)
 
     if len(sys.argv)==1:
         parser.print_help(sys.stderr)
@@ -45,33 +46,39 @@ def ParseInput():
 ########################
 if __name__ == "__main__":
 
+    # Reading Arguments
+    args = ParseInput()
+
     # Creating Data Structure
     data = MercedesMeData()
 
-    args = ParseInput()
-
     # Reading Configuration
-    if not data.config.ReadConfig():
-        logger.error ("Error initializing configuration")
-        exit (1)
-
-    if not data.resourcesDB.ReadResources():
-        logger.error ("Error initializing resources")
+    if not data.mercedesConfig.ReadConfig():
+        _LOGGER.error ("Error initializing configuration")
         exit (1)
 
+    # Create Token
     if (args.token == True):
-        if not data.config.CreateToken():
-            logger.error ("Error creating token")
+        if not data.mercedesConfig.CreateToken():
+            _LOGGER.error ("Error creating token")
             exit (1)
 
+    # Refresh Token
     if (args.refresh == True):
-        if not data.config.RefreshToken():
-            logger.error ("Error refreshing token")
+        if not data.mercedesConfig.RefreshToken():
+            _LOGGER.error ("Error refreshing token")
             exit (1)
             
+    # Read Resources
+    if not data.mercedesResources.ReadResources():
+        _LOGGER.error ("Error initializing resources")
+        exit (1)
+
+    # Print Available Resources
     if (args.resources):
-        data.resourcesDB.PrintAvailableResources()
+        data.mercedesResources.PrintAvailableResources()
 
+    # Print Resources State
     if (args.status == True):
-        data.resourcesDB.UpdateResourcesStatus()
-        data.resourcesDB.PrintResourcesStatus()
+        data.mercedesResources.UpdateResourcesState()
+        data.mercedesResources.PrintResourcesState()
index 77275285588b3aa932b9e6ad34d79fa359948627..ea51a461b810fdb7e493b0db78091a566464f373 100644 (file)
--- a/query.py
+++ b/query.py
@@ -1,5 +1,19 @@
+"""
+Mercedes Me APIs
+
+Author: G. Ravera
+
+For more details about this component, please refer to the documentation at
+https://github.com/xraver/mercedes_me_api/
+"""
+import logging
 import requests
 
+from const import *
+
+# Logger
+_LOGGER = logging.getLogger(__name__)
+
 ########################
 # GetResource
 ########################
@@ -58,16 +72,16 @@ def GetToken(config, refresh=True, auth_code=""):
 
     if (not refresh):
         # New Token
-        data = "grant_type=authorization_code&code=" + auth_code + "&redirect_uri=" + config.redirect_uri
+        data = "grant_type=authorization_code&code=" + auth_code + "&redirect_uri=" + REDIRECT_URL
     else:
         # Refresh
         data = "grant_type=refresh_token&refresh_token=" + config.refresh_token
 
-    res = requests.post(config.oauth_url, data = data, headers = headers)
+    res = requests.post(URL_OAUTH, data = data, headers = headers)
     try:
         token = res.json()
     except ValueError:
-        logger.error ("Error retriving token " + str(res.status_code))
+        _LOGGER.error ("Error retriving token " + str(res.status_code))
         return None
 
     return token
index b3caf0e5077560f3134dcced13a3324ff013f91c..0ed405a38660fad0069968a89ffcfb32ef00bd9f 100644 (file)
@@ -12,39 +12,77 @@ import os
 
 from config import MercedesMeConfig
 from query import GetResource
+from const import *
 
 # Logger
-logger = logging.getLogger(__name__)
+_LOGGER = logging.getLogger(__name__)
 
 class MercedesMeResource:
-    def __init__( self, name, version, href, status=None, timestamp=None, valid=False ):
-        self.name = name 
-        self.version = version
-        self.href = href
-        self.status = status
-        self.timestamp = timestamp
-        self.valid = valid
+    def __init__( self, name, vin, version, href, state=None, timestamp=None, valid=False ):
+        self._name = name
+        self._version = version
+        self._href = href
+        self._vin = vin
+        self._state = state
+        self._timestamp = timestamp
+        self._valid = valid
+
+    def __str__(self):
+        return json.dumps({ 
+            "name" : self._name,
+            "vin" : self._vin,
+            "version" : self._version,
+            "href" : self._href,
+            "state" : self._state,
+            "timestamp" : self._timestamp,
+            "valid" : self._valid,
+            })
 
     def getJson(self):
         return ({ 
-            "name" : self.name,
-            "version" : self.version,
-            "href" : self.href,
-            "status" : self.status,
-            "timestamp" : self.timestamp,
-            "valid" : self.valid,
+            "name" : self._name,
+            "vin" : self._vin,
+            "version" : self._version,
+            "href" : self._href,
+            "state" : self._state,
+            "timestamp" : self._timestamp,
+            "valid" : self._valid,
             })
 
-class MercedesMeResourcesDB:
+    def name(self):
+        """Return the name of the sensor."""
+        return self._vin + "_" + self._name
+
+    def state(self):
+        """Return state for the sensor."""
+        return self._state
+
+    def device_state_attributes(self):
+        """Return attributes for the sensor."""
+        return ({
+                "valid": self._valid,
+                "timestamp": self._timestamp,
+                })
 
-    database = { }
-    config = None
+    def update(self):
+        """Fetch new state data for the sensor."""
+        resName = self._name
+        resURL = URL_RES_PREFIX + self._href
+        result = GetResource(resName, resURL, self._config)
+        if not "reason" in result:
+            self._valid = True
+            self._timestamp = result[resName]["timestamp"]
+            self._state = result[resName]["value"]
+
+class MercedesMeResources:
 
     ########################
     # Init
     ########################
-    def __init__(self, config):
-        self.config = config
+    def __init__(self, mercedesConfig):
+
+        self.database = []
+        self.mercedesConfig = mercedesConfig
 
     ########################
     # Read Resources
@@ -54,12 +92,12 @@ class MercedesMeResourcesDB:
         found = False
         resources = None
 
-        if not os.path.isfile(self.config.resources_file):
+        if not os.path.isfile(self.mercedesConfig.resources_file):
             # Resources File not present - Retriving new one from server
-            logger.error ("Resource File missing - Creating a new one.")
+            _LOGGER.error ("Resource File missing - Creating a new one.")
             found = False
         else:
-            with open(self.config.resources_file, 'r') as file:
+            with open(self.mercedesConfig.resources_file, 'r') as file:
                 try:
                     resources = json.load(file)
                     if (not self.CheckResources(resources)):
@@ -67,7 +105,7 @@ class MercedesMeResourcesDB:
                     else:
                         found = True
                 except ValueError:
-                    logger.error ("Error reading resource file - Creating a new one.")
+                    _LOGGER.error ("Error reading resource file - Creating a new one.")
                     found = False
 
         if ( not found ):
@@ -75,7 +113,7 @@ class MercedesMeResourcesDB:
             resources = self.RetriveResourcesList()
             if( resources == None ):
                 # Not found or wrong
-                logger.error ("Error retriving resource list.")
+                _LOGGER.error ("Error retriving resource list.")
                 return False
             else:
                 # import and write
@@ -92,16 +130,16 @@ class MercedesMeResourcesDB:
     ########################
     def CheckResources(self, resources):
         if "reason" in resources:
-            logger.error ("Error retriving available resources - " + resources["reason"] + " (" + str(resources["code"]) + ")")
+            _LOGGER.error ("Error retriving available resources - " + resources["reason"] + " (" + str(resources["code"]) + ")")
             return False
         if "error" in resources:
             if "error_description" in resources:
-                logger.error ("Error retriving resources: " + resources["error_description"])
+                _LOGGER.error ("Error retriving resources: " + resources["error_description"])
             else:
-                logger.error ("Error retriving resources: " + resources["error"])
+                _LOGGER.error ("Error retriving resources: " + resources["error"])
             return False
         if len(resources) == 0:
-            logger.error ("Empty resources found.")
+            _LOGGER.error ("Empty resources found.")
             return False
         return True
 
@@ -110,10 +148,10 @@ class MercedesMeResourcesDB:
     ########################
     def RetriveResourcesList(self):
         resName = "resources"
-        resURL = self.config.res_url_prefix + "/vehicles/" + self.config.vin + "/" + resName
-        resources = GetResource(resName, resURL, self.config)
+        resURL = URL_RES_PREFIX + "/vehicles/" + self.mercedesConfig.vin + "/" + resName
+        resources = GetResource(resName, resURL, self.mercedesConfig)
         if not self.CheckResources(resources):
-            logger.error ("Error retriving available resources")
+            _LOGGER.error ("Error retriving available resources")
             return None
         else:
             return resources
@@ -123,10 +161,10 @@ class MercedesMeResourcesDB:
     ########################
     def ImportResourcesList(self, resources):
         for res in resources:
-            if("status" in res):
-                self.database[res["name"]] = MercedesMeResource (res["name"], res["version"], res["href"], res["status"], res["timestamp"], res["valid"])
+            if("state" in res):
+                self.database.append( MercedesMeResource (res["name"], self.mercedesConfig.vin, res["version"], res["href"], res["state"], res["timestamp"], res["valid"]) )
             else:
-                self.database[res["name"]] = MercedesMeResource (res["name"], res["version"], res["href"])
+                self.database.append( MercedesMeResource (res["name"], self.mercedesConfig.vin, res["version"], res["href"]) )
 
     ########################
     # Write Resources File
@@ -135,9 +173,9 @@ class MercedesMeResourcesDB:
         output = []
         # Extract List
         for res in self.database:
-            output.append( self.database[res].getJson() )
+            output.append( res.getJson() )
         # Write File
-        with open(self.config.resources_file, 'w') as file:
+        with open(self.mercedesConfig.resources_file, 'w') as file:
             json.dump(output, file)
 
     ########################
@@ -146,30 +184,31 @@ class MercedesMeResourcesDB:
     def PrintAvailableResources(self):
         print ("Found %d resources" % len(self.database) + ":")
         for res in self.database:
-            print (self.database[res].name + ": " + self.config.res_url_prefix + self.database[res].href)
+            print (res._name + ": " + URL_RES_PREFIX + res._href)
 
     ########################
-    # Print Resources Status
+    # Print Resources State
     ########################
-    def PrintResourcesStatus(self, valid = True):
+    def PrintResourcesState(self, valid = True):
         for res in self.database:
-            if((not valid) | self.database[res].valid):
-                print (self.database[res].name + ":")
-                print ("\tvalid: " + str(self.database[res].valid))
-                print ("\tstatus: " + self.database[res].status)
-                print ("\ttimestamp: " + str(self.database[res].timestamp))
+            if((not valid) | res._valid):
+                print (res._name + ":")
+                print ("\tvalid: " + str(res._valid))
+                print ("\tstate: " + res._state)
+                print ("\ttimestamp: " + str(res._timestamp))
 
     ########################
-    # Update Resources Status
+    # Update Resources State
     ########################
-    def UpdateResourcesStatus(self):
+    def UpdateResourcesState(self):
+        _LOGGER.error("Update Resources")
         for res in self.database:
-            resName = self.database[res].name
-            resURL = self.config.res_url_prefix + self.database[res].href
-            result = GetResource(resName, resURL, self.config)
+            resName = res._name
+            resURL = URL_RES_PREFIX + res._href
+            result = GetResource(resName, resURL, self.mercedesConfig)
             if not "reason" in result:
-                self.database[res].valid = True
-                self.database[res].timestamp = result[resName]["timestamp"]
-                self.database[res].status = result[resName]["value"]
+                res._valid = True
+                res._timestamp = result[resName]["timestamp"]
+                res._state = result[resName]["value"]
         # Write Resource File
         self.WriteResourcesFile()