Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Event detail endpoint is obsolete #486

Open
fhewitt opened this issue Oct 24, 2024 · 9 comments
Open

Event detail endpoint is obsolete #486

fhewitt opened this issue Oct 24, 2024 · 9 comments
Labels
breaking Breaking Changes deprecation

Comments

@fhewitt
Copy link

fhewitt commented Oct 24, 2024

Hi dear community,

Context

Today, we (the Hilo team) added the deprecation header on the event details endpoints : /GDService/v1/api/locations/{locationId}/events/{eventId}.

This endpoint is not used anymore inside the Hilo application, but we kept it up and functional for Home Assistant.

That being said, it's not tested so much anymore and it will, at some point, be removed or just stop working properly.

New Approach

You should be able to achieve the same result through websocket/signalR :
https://api.hiloenergie.com/ChallengeHub

Request Message: SubscribeToChallenge with a { eventId: long, locationId: long } payload

Which will trigger these 2 events in response

ChallengeDetailsInitialValuesReceived

      {
        "required": [
          "progress",
          "isParticipating",
          "isConfigurable",
          "id",
          "period",
          "phases"
        ],
        "type": "object",
        "properties": {
          "progress": {
            "enum": [
              "none",
              "scheduled",
              "inProgress",
              "completed"
            ],
            "type": "string",
            "default": "none"
          },
          "isParticipating": {
            "type": "boolean"
          },
          "isConfigurable": {
            "type": "boolean"
          },
          "currentPhase": {
            "enum": [
              "none",
              "preheat",
              "reduction",
              "recovery"
            ],
            "type": "string",
            "default": "none",
            "nullable": true
          },
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "period": {
            "enum": [
              "none",
              "am",
              "pm"
            ],
            "type": "string",
            "default": "none"
          },
          "phases": {
            "$ref": "#/components/schemas/eventPhases"
          }
        }
      },

ChallengeConsumptionUpdatedValuesReceived

     {
        "required": [
          "generatedTimeUTC"
        ],
        "type": "object",
        "properties": {
          "currentWh": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "baselineWh": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "estimatedReward": {
            "type": "number",
            "format": "double",
            "nullable": true
          },
          "generatedTimeUTC": {
            "minLength": 1,
            "type": "string",
            "format": "date-time"
          },
          "cumulativeBaselinePoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/cumulativeConsumptionPoints"
            }
          },
          "cumulativeConsumptionPoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/cumulativeConsumptionPoints"
            }
          }
        }
      },

"cumulativeConsumptionPoints": {
        "required": [
          "timeUTC",
          "wh"
        ],
        "type": "object",
        "properties": {
          "timeUTC": {
            "minLength": 1,
            "type": "string",
            "format": "date-time"
          },
          "wh": {
            "type": "number",
            "format": "double"
          }
        }
      },

Obviously, these format could change in the future (probably not for this season).

Sorry that I can't be a lot more helpful, especially in this time of the year.

@fhewitt fhewitt changed the title Event detail endpoint is deprecated Event detail endpoint is obsolete Oct 24, 2024
@ic-dev21
Copy link
Collaborator

@fhewitt un gars s'essaye, y a-t-il un espoir de pull request de ta part?

@fhewitt
Copy link
Author

fhewitt commented Oct 25, 2024

Non, je ne connais pas le projet du tout, ni Python d'ailleurs. Je ne peux pas m'avancer concernant mes collègues, mais là tout de suite, ça ne sera pas priorisé.

Par contre, je m'engage à repasser ici si on s'apprête à l'arracher et que le ticket est toujours ouvert, pour te dire que tu n'a plus le choix. Et ça ne sera certainement pas avant Q1 2025. D'ici là, l'espoir reste permis.

@ic-dev21
Copy link
Collaborator

ic-dev21 commented Oct 26, 2024

@fhewitt je suis pas une brute (c'est pas mon code, je l'apprends sur le tas), je vois que l'on utilise cet endpoint dans cette fonction-là:

events = await self._hilo._api.get_gd_events(self._hilo.devices.location_id)

Qui par la suite appelle celle-ci:

https://github.com/dvd-dev/python-hilo/blob/99c73b76b74b8539672e68bbdd8942f63ba347e7/pyhilo/api.py#L531-L600

Je comprends vite quand on m'explique longtemps.

Est-ce que l'on souhaite obtenir que l'URL passe de:

/GDService/v1/api/locations/{locationId}/events/{eventId}

À

/ChallengeHub/v1/api/locations/{locationId}/events/{eventId}

Ou bien j'ai mal saisi l'information? Si j'ai bien saisi, ça me retourne une erreur 404 ici dans mon test en local.

J'ai pas nécessairement besoin d'aide côté Python en tant que tel, plus ma compréhension de ce qui doit changer.

@valleedelisle
Copy link
Contributor

Ce code ne marchera plus. Il va falloir passer par le websocket et subscribe à ce nouvel url. Je suis aussi un noob avec tout ce qui est async et websocket.

Je crois qu'on va avoir besoin de deux instances de WebsocketClient. Faut faire de quoi avec ce hack la qui hardcode le DeviceHub dans la methode de connexion. À moins qu'on puisse subscribe à plusieurs endpoints avec la même instance?

Donc cette instance est créée dans le _post_init, je crois qu'on pourrait en créé une deuxième à cet endroit à moins qu'on puisse utilisé la même pour les deux endpoint, je ne suis pas assez familier avec tout ça.

Ensuite, tout dépendemment si on utilise une ou deux instances de websocket client, on va devoir adapter tout le code ici pour supporter ces deux connexions. Tant qu'à le faire pour deux, on s'arrange pour que ça soit dynamique et pouvoir subscribe à une liste de websocket. Faudrait aussi ajuster le callback pour qui soit dynamique tant qu'à ça.

C'est une pas pire job tout ça, surtout pour des noobs comme nous qui ont codé ça instinctivement en snoopant le traffic de l'app. Q1 2025 arrive très vite. C'est vraiment sympathique d'Hilo d'avoir supporté le REST API pour les events pour nous aussi longtemps mais ça serait aussi bien que Hilo puisse engagé un consultant afin de migrer vers la nouvelle infra. Un professionnel python devrait pouvoir comprendre et coder ça en pas trop long à mon avis.

@ic-dev21 ic-dev21 added breaking Breaking Changes deprecation labels Oct 31, 2024
@Leicas
Copy link

Leicas commented Nov 12, 2024

@fhewitt , en essayant d’implémenter je me frotte à une erreur 401 sur la négociation avec https://api.hiloenergie.com/ChallengeHub, est-ce que le bearer token ne serrait pas un token général ?

En utilisant le token obtenu par Oauth ça veut vraiment pas, alors je me demandais si ce n'était pas un token générique ou à obtenir via une autre méthode.
Merci :)

@ic-dev21
Copy link
Collaborator

Salut gang,

@Leicas @valleedelisle @elafontaine
J'ai eu un peu de temps pour discuter avec @nlz242 car j'avais pas mal de trouble à établir un POST pour obtenir mon URL Websocket de mon côté en dev.

Au final, le token qui doit être utilisé pour la connexion initiale au websocket du ChallengeHub est ici:

https://github.com/dvd-dev/python-hilo/blob/39cc8e28bbf9bbac9636f052f78b1045eda3e7b2/pyhilo/api.py#L130-L135

Pour fins de connexion avec POSTMAN j'ai modifié le code ainsi pour obtenir mon token et confirmer que j'avais la bonne affaire:

    async def async_get_access_token(self) -> str:
        """Return a valid access token."""
        if not self._oauth_session.valid_token:
            await self._oauth_session.async_ensure_token_valid()

        access_token = str(self._oauth_session.token["access_token"])
        LOG.debug(f"ic-dev21 {access_token}")
        return str(self._oauth_session.token["access_token"])

Résultat:
image

Donc il est possible d'obtenir notre WSS URL à partir de là!

Je suis pas allé plus loin encore car je suis pas mal moins à l'aise avec cette portion là du code mais je voulais informer n'importe qui qui veut s'essayer de son côté comment obtenir le bon chemin!

@Leicas
Copy link

Leicas commented Nov 16, 2024

Un peu de progrès, j’ai partagé ça sur dvd-dev/python-hilo#223 pour aider les autres qui travaille dessus, c’est pas très loin encore, mais la partie négo du WS avec les tokens fonctionne chez moi maintenant.

La partie qui voulait vraiment pas et qui m’a tourné le crane c’est https://github.com/dvd-dev/python-hilo/pull/223/files#diff-9ee2958872aa7ec04a975bc72c01bd591c0babd6cdabed3344be35f80fff180dR234 .

@valleedelisle
Copy link
Contributor

Nice job! Merci pour ta contribution. Idéalement, il faudrait que ça soit dynamique au lieu de faire un websocket2. Peut-être un autre classe pour englober le tout? Je manque énormément de temps ces temps-ci, si Hilo pouvait faire des journées de 32h ça m'aiderait. Mais bon, si ça fonctionne comme ça, j'ai pas de problème à merger ce code et j'essaierai d'optimiser éventuellement.

Leicas added a commit to Leicas/hilo that referenced this issue Nov 26, 2024
@ic-dev21
Copy link
Collaborator

ic-dev21 commented Dec 18, 2024

Manager class est faite dans pyhilo, voir dvd-dev/python-hilo#224, c'est pas mergé encore d'un coup que j'me sois planté mais ici en test c'est fonctionnel.

#505 est un bon premier pas, merci beaucoup à @Leicas, je vais continuer à jouer avec pendant le temps des fêtes.

Toute contribution ou essai de contribution sera apprécié

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking Breaking Changes deprecation
Projects
None yet
Development

No branches or pull requests

4 participants