Alfen Eve API client
====================

API Client for Alfen Eve EV charging units.

Installation
------------

As a CLI tool:

.. code-block:: shell

   $ pip install alfeneve[cli]


As a library:

.. code-block:: shell

   $ pip install alfeneve


Configuration
-------------

The CLI tool uses `omniconf <https://pypi.org/project/omniconf/>`_ . This allows you to provide any CLI
argument using a file or through the environment (or a combination).


Directly as arguments:

.. code-block:: shell

   $ alfen-eve --alfen-endpoint https://192.168.1.23 --alfen-username admin --alfen-password foo


Using a YAML file (make sure to install ``PyYAML``, or use ``omniconf[yaml]``):

.. code-block:: shell

   $ cat settings.yaml
   alfen:
     endpoint: https://192.168.1.23
     username: admin
     password: foo

    $ alfen-eve --yaml-filename settings.yaml

Using environment variables:

.. code-block:: shell

    $ ALFEN_ENDPOINT=https://192.168.1.23 ALFEN_USERNAME=admin ALFEN_PASSWORD=foo alfen-eve

API Credentials
---------------

Alfen ships a tool to allow you to configure your Alfen charging unit called `ACE Service Installer (or just Service Installer) <https://alfen.com/en/downloads>`_.
This tool requires a Service Account that you can `request from Alfen <https://aftersales.alfen.com/servicedesk/customer/user/login?destination=portals>`_.

The API doesn't actually use this account directly though. It seems that the API credentials are hard-coded, and the Service Installer either ships with this
password, or can infer or request this password from Alfen. Regardless, you can use the Service Installer tool to sniff out the credentials.

At this time this process is a bit involved, and requires you to know how to insert yourself as a proxy between the Service Installer and your charging unit
on Windows. The broad steps are as follows (using `mitmproxy <https://mitmproxy.org>`_):

1. Install mitmproxy.
2. Start mitmproxy at least once to generate the certificates: `mitmproxy --listen-port 8090`.
3. Install the mitmproxy certificate as `Trusted Root Certificate <https://docs.microsoft.com/en-us/windows-hardware/drivers/install/installing-test-certificates>`_ (you can find it in the `.mitmproxy` folder in your User Account).
4. Start mitmproxy `mitmproxy --listen-port 8090 --insecure` and set it as the OS Global Proxy using `Internet Options <https://docs.microsoft.com/en-us/troubleshoot/browsers/use-proxy-servers-with-ie#use-the-browser-settings>`_.
5. If all is configured properly, you can now start the Service Installer and login using your Service Account.
6. Connect to your Alfen charger, and look in the mitmproxy window. There should be a request to `/api/login`. You can find the username and password in this request.
7. Configure these credentials as specified above.
8. Make sure to remove mitmproxy as your OS Global Proxy.

Examples
--------

Use as a CLI tool:

.. code-block:: shell

   $ alfen-eve --mode categories
   category
   ----------
   generic
   generic2
   accelero
   temp
   states
   meter1
   meter4
   leds
   ocpp
   display
   comm
   MbusTCP

   $ alfen-eve --mode properties --properties-category meter4
   name                                   value  id       cat
   -----------------------------  -------------  -------  ------
   OD_sensOptionalEnergyMeter4      5            5217_0   meter4
   OD_sensEnergyMeterType4          1            5218_0   meter4
   meter4_voltageL1N              225.1          5221_3   meter4
   meter4_voltageL2N              225.7          5221_4   meter4
   meter4_voltageL3N              228.6          5221_5   meter4
   ...

Use as a library:

.. code-block:: python

   from alfeneve.alfen import Alfen
   from pprint import pprint

   with Alfen("https://192.168.1.23", ("admin", "foo")) as eve:

       cats = eve.categories()
       pprint(cats)
       # ['generic',
       #  'generic2',
       #  'accelero',
       #  'temp',
       #  'states',
       #  'meter1',
       #  'meter4',
       #  'leds',
       #  'ocpp',
       #  'display',
       #  'comm',
       #  'MbusTCP']

       properties = eve.properties(category="generic")
       pprint(list(properties))
       # [<AlfenProperty(name=OD_manufacturerDeviceName, value=NG910, id=1008_0, cat=generic)>,
       #  <AlfenProperty(name=OD_manufacturerHardwareVersion, value=G0, id=1009_0, cat=generic)>,
       #  <AlfenProperty(name=OD_manufacturerSoftwareVersion, value=4.8.0-3168, id=100A_0, cat=generic)>,
       #  ... ]


License
-------
MIT
