How ElaadNL built a PoC Charge Station running fully on IOTA, and IOTA only


A charge station running on IOTA, for payment of the energy, all communication with the customer via IOTA and storing measurement values (like a smart meter) into the Tangle. It’s awesome, you should read the whole article!

At ElaadNL we are researching and innovating with new technologies. We are currently researching the possibilities of Smart Charging in the power grid. We see that DLTs (Distributed Ledger Technologies) can have real impact on the information flow and security of the grid, because of the possibilities of decentral balancing. Especially in e-mobility we will see these decentralised developments come together before these aspects influence the other parts of the electricity system, providing a perfect test-base for the new functionalities and the technical enablers. We jump in and start building. That’s what we do at ElaadNL: turn theory into practice.

The same happened with the start of the IOTA Charge Station. We see the potential of DLTs, and we thought: “Could we integrate this into a charge station? Can we use this technology to create a better integrated system, as with smart grids, and get as much renewables into the system as possible?”

At both ElaadNL and Enexis we have technical experience on charge stations, smart grids and electronics. And both companies have brought some extra skilled people on board. Enough knowledge to get started. When we started, we did not write any requirements and only had an end goal: “Charging your electric vehicle using IOTA”. This allowed us to change the way we solve things, without being forced to deliver what the requirements say. With weekly meetups, we made sure we were still on the right track and discussed possible solutions. Things we came up with during the developments include:

  • kWh-based charging, thus only paying for the amount of energy you exactly use.
  • IOTA Charging App — since we wanted to communicate with the end user and make the experience more user friendly we developed our own app
  • kWh-measurement storage, storing measurement data of the kWh-meter in the Tangle as a immutable storage of the kWh energy consumption over time (like the Odometer in a car).

What’s inside the Charge Station and how does it work?

The charge station has all the common components of a normal charge station. A kWh-meter, a contactor, EVSE controller and a main controller. Usually the main controller communicates with a back office using the OCPP (Open Charge Point Protocol, this protocol was invented by ElaadNL and is now used all over the world in charge stations).

The project was started from scratch, with no software to control the station and only the bare components. We used an Intel NUC for development purposes since we didn’t want to wait while developing (because of low CPU power) we chose a fast device. Running the charge station on a Raspberry Pi is also possible, since the PoW (Proof of Work) is not done on the machine, but outsourced to the IOTA Node.

“Creating the first ever IOTA-based EV charging station has been tremendous”

Dominik Schiener, co-founder of IOTA, about the charge station: “Electric vehicle charging is one of the many applications where IOTA as the base-protocol for the transactional settlement between machines is the obvious choice. The work done by the team at Enexis in creating the first ever IOTA-based EV charging station has been tremendous, and will pave the way for more adoption of IOTA in the mobility space.”

David Sønstebø, co-founder of IOTA, responds: “As cars are evolving into computers with wheels, and the era of electrical vehicles is ushered in, it is imperative that we have the infrastructure to support this new era of mobility. Enexis’ ElaadNL project paves the way for this by utilizing the IOTA protocol, this is exactly what we have in mind for the new ‘Machine Economy’"

NodeJS, TypeScript, JavaScript, Serial communication and more nerd stuff

We started out only trying to get the station to charge. This was achieved surprisingly quickly. After a week or two, we had a charge station that would simply charge. We did this by constantly checking the balance. If it had increased, we would start the charging process.

The above code roughly shows how this looks. We retrieve the account data via the IOTA JavaScript library. If there is an error, we log it to the console. Otherwise, we check the balance of the data object that is returned. If the balance is larger than the last balance, we calculate the tokens that were paid, set the last balance to the new balance and start the charging with the calculated tokens.

This is some example code showing what one of the early versions of this method looked like. We see the minutes are calculated here, based on the rate. The end of the charging session is then calculated by adding the minutes to the current time. This is done with the library momentjs. Then we write a session:start command to the EVSE. This sets in motion the different serial commands sent to the other devices in the charging station.

To be able to write a command to the EVSE, we needed to establish a serial connection to it. Luckily a handy library called serialport was available which made this quite simple.

Smart EVSE

The Smart EVSE controller connects to the Electric Vehicle. It assures, amongst other things, communication with the electric vehicle via the mode 3 (IEC 62196) protocol. The Intel NUC communicates with the Smart EVSE via serial.

Its features:

  • Fits into a standard DIN rail enclosure.
  • switched 230VAC output, for contactor/relays.
  • selects current capacity of the connected cable automatically (13/20/32/63A)
  • locking solenoid support,locks the charging cable in the socket, automatically unlocks on a power failure.
  • built-in temperature sensor.
  • optionally supports a 8x2 character LCD.
  • setup through serial command line interface, things like MAX/MIN Current can be set.
  • easy to upgrade through serial bootloader.

The checkTime function initiates a new moment object containing the current time. If the current time is larger than the end, then we write a session:stop command to the EVSE. Otherwise, we set a timeout for this function to be called again in a few seconds (given by the TIMER_CHARGE variable).


Because of the freedom to develop towards an end goal which we had already reached from a technical perspective, we added layers and features on top of this, almost in a scrum-like manner.

We started by adding LED support for user feedback. We added the colors yellow, green, light blue, dark blue and red representing idle, connected, offering, charging and error respectively. These colors are already used throughout the world for charging stations. The EVSE gives us some information on the current state, which we can then use to set the LED color. The LED is also controlled via the serialport library using serial commands.

After adding the colors, we started working on one of the cool things we could do using the Tangle. We wanted to secure the data from the kWh meter on the Tangle. This would be the first transaction sent from the station itself!

To be able to access the kWh meter, we needed to use a different library, because there is a slightly different way of accessing it. The kWh meter uses holding registers, which can be read to get to the information. For example, to read out the kWh state of the meter, we would have to read four registers. These registers would hold two bytes each. These bytes would have to be shifted to get the correct number. A small example with two registers can be seen below.

The example shows two registers written out in full (so two pairs of two bytes). In this example the last register comes first, so its value is 32768. Because only the first bit of the first byte is set to one, the rest is all zero. The top register (Register 1) has a value of 65535. This is because this register must be multiplied by the total value of the first. It adds to the number so to speak. So if Register 1 had a one at the second most right bit (instead of where it is now), it would be 2 * 65535 = 131070. Given the value of Register 2 being 32768 and Register 1 being 65535, the total value of the kWh meter at these particular register values would be: 65535 + 32768 = 98303. The last two digits give the two decimals in the kWh meter. So the final actual stance of the kWh meter would be 98303 / 100 = 983.03 kWh.

Now that we knew how to read the registers, we were able to read the current kWh level at any time. So we set up a loop that would make a zero-value-transaction every so often that transaction is sent to a given address and contains the current kWh level.

Here we see the loop. We print some info to the console: that we are sending a kWh report. Then we call the send transaction function with the constant address to send the data to, zero as the value for the amount of tokens to send, the specific tag that identifies this charging station, and finally the message, which is a function call to interweave. Interweave is a simple function that replaces argument positions with the arguments you give in a string.

This would print Hello Harm, how are you? My name is Lucas. After the transaction is sent, a timeout is set after which the function is called again. Sending the transaction is what is the most important though! Let us see how that works. In the code below we see the parameters we mentioned before, the address, the value, the tag and the message. These four were given above. So looking through the function we see we convert the message to trytes, if there is a message. We create the transactions array (array of objects). We only add one transaction here, namely the one given by the parameters. If no tag is provided, we set the standard tag. Then we call the send transfer function, which will start the process of sending a transaction in IOTA. We use the seed of the charge station, the constant depth, set to 9 and the minimum weight magnitude of 14. We pass in the transaction array we created before and finally the function that will log the error if anything went wrong.

Even more improvements

The second set of improvements came after we had sent the first transaction to report the kWh state. Currently the only way to know which address to send the tokens to was to read the log from the charging station. That isn’t really a friendly way to interact, nor would it be possible as the charging station would not get a display. So we decided we should somehow be able to get the address from the charging station via the Tangle. We would do this in a way that we would come to call Broadcasting. It is when you send a 0-value transaction to your own address. Other parties can then scan for this transaction in the tangle by looking at the specific tag that you put on the transaction. This way the user can enter some station ‘code’ and it would scan the Tangle for a transaction with a tag with that code.

Below we see a bit of code of how one might do this. We create a search values object, where the tags we want to look for are given by the base tag plus the code the user entered. We then use the API to find the transaction objects with these search values. We make use of the JavaScript promise structure, to allow the caller to handle whatever we wish to return. If something goes wrong, we reject the promise. If the data is empty, we also reject the promise. Otherwise we start looking at the data. We sort it by its timestamp. Following, the code loops through the data and extracts the message. The message is still in tryte form, meaning it consists of only 9s and the uppercase alphabet. This is a encoded form, that can be encoded and decoded with the toTrytes and fromTrytes function, respectively. So we replace the 9s at the end with empty characters (remove the trailing 9s). Then we turn the message (still in Tryte form) to a ‘normal’ message. We push this message to the messages array, which we resolve at the end of the function.

We also wanted to inform the user of what was happening. In the current state, all they could see was some LEDs lighting up. But because of the strength of the Tangle we could also just send the user status updates on the state of their charging transaction via the Tangle. After some experimenting, we figured it out and we could send the user some feedback via the Tangle.

What we found out along the way…

Incoming transactions

It became apparent that the current measuring of incoming balance, could be done in a more effective way. So we went from the old way, polling the balance every time and then checking the last transaction for the customer address, to the new way where we just poll for incoming transaction and if they add balance to our address, then we see it as a new value-transaction, and we immediately know the address of the customer, which we save for further messaging. This led to easy communication between the charging station and the user. A small example of how a bundle might look like is shown below. The transaction in blue shows the correct address to remember of the customer.

Messages vs Light Wallet

After learning how to get the user address, we started trying to send the user messages via zero-value transactions. However this is where we found one small downside of the current light wallet. We could not see the messages in the transaction history. So we ended up using tags for this.

More logical payment

As we were working on the new way to scan for incoming transactions, it also occurred to us, that the current way of paying for time does not make much sense. The more logical way is to pay for a certain amount of power. So we changed the time loop for a kWh loop. This loop would gather the current kWh level and compare it to how much the user bought.

User friendliness

As we were developing the charging station itself, we started working on a more user friendly way to interact with the station. First this was just a small website, where one could fill in the code to find the address that the station broadcasted. After making this, the next step was to extend this website into something more extensive. We created a online ‘wallet’, which was made exclusively to work with the charging station. We dubbed it the IOTA Charging App. This app featured the ability to:

  • enter a seed.
  • save that seed locally on your device (it is never sent anywhere).
  • search for a charging station by entering its code.
  • find the station and its current up-to-date position, rate, state (occupied or not) and its deposit address (if you do not want to enter your seed into the app).
  • pay for your kWh at a station by sending a transaction from the app (requires seed).
  • look at your messages sorted by date and time (requires seed).
  • look at your past transactions sorted by date and time (requires seed).

The screenshots below show some of the features of the app.

Entering the seed
Send a transaction after finding the station
Messages sent from the charge station to the customer
Transaction history

Future developments


In the current proof of concept we are not making use of MAM (Masked Authentication Messaging). MAM enables users (or machines) to communicate more securely, or even secretly with the use of signatures and/or symmetric encryption. Implementing MAM into the charge station would make it even more secure. We could use it for communication with the customer, for storing measurement data into the Tangle or even the grid operator supplying the current capacity on the grid to which the charge station behaves.

Flash Channels

Flash Channels are a super easy way to create even more trust between the customer and the charge station. With flash channels both parties (which could just be machines) can set up a channel. Via this channel they can, offline from the Tangle, make payments to each other. This means that small payments (for example for every 100Wh of consumed energy) can be made between the car and the charge station, all offline. Once the charging session has finished the result of that channel can be uploaded to the Tangle, and the payments are taken care of. If one of the parties while being in the channel, refuses to pay for something, all previous payments are still valid. Thus, with micro transactions for small (intermediate) amounts of energy, the charge station can be sure it gets paid and the car can be sure that it gets the energy it pays for.

Setting the current

Because of the ease of messaging via the Tangle, in the future we can also look at sending a message to the station which will set the maximum allowed current (capacity) through the station. The grid operator can then alter the energy flow, to meet capacity challenges.

The car with a wallet

In our proof of concept we still require the user to make the payment. Our next proof of concept we would like to build a solution with a car holding a wallet, setting up a flash channel with the charge station and paying for the energy it receives. It could also broadcast its energy need (state of charge), which can be interesting for parties like a grid operator to forecast the energy needs in particular parts of the grid. We have ideas enough, let’s see what we can get into practise.

Harm van den Brink (LinkedIn) is leading these innovations at ElaadNL and Enexis: “These technologies can radically change the world. At ElaadNL we’re following and actively participating in these promising technologies like IOTA. Building a fully working charge station, based on IOTA shows the real potential and disruptive power of these technologies.”

I want to specially thank Lucas Weideveld for programming the charge station, and Klaas van Zuuren for building the actual charge station with all the components.