14 May, 2024

Let's automate... PVM!

Writing code: is there a remedy to assist with routine tasks?

You might have read the article about flespi team participating in the Gurtam AI hackathon. We had an ambitious goal to teach AI to write code in PVM, our internally developed programming language designed for data parsing. PVM can be used by two groups of people:

  • Our customers who need custom parsing with PVM plugins.
  • Flespi developers who develop new and maintain existing IoT communication protocols.

The requirements of the customers were fulfilled recently as we introduced the PVM Generator. The second group — flespi developers — are good “PVM Generators” by themselves 🙂 because we have been using and developing PVM for years. But sometimes I wish I had a tool like Code Copilot, especially for some routine tasks. As long as the PVM Generator has got a simple REST API call under the hood, I decided to test the hypothesis if it can be used to automate some operations while creating PVM code.

So the goal was to design a workflow where a PVM developer can outline the basic concepts of the protocol implementation code, and the rest of the work is accompanied by AI. To do that, I created a VS Code extension to track the user’s input. When 'AI' is typed, it’s a signal for the extension to get the context of the code (I simply used the previous 50 lines of code) and equip it with the basic prompt:

Act as an AI assistant in writing PVM code. Here’ss a part of the PVM code. You need to write the next line based on the context and the last line comment. Give output only as PVM code, start code from a new line and appropriate amount of tabs, no comments and explanations.

And send it to the flespi PVM Generating API method (the response is inserted instead of the typed 'AI' characters). 

Even though PVM Generator is instructed to write PVM code for plugins, it showed itself fairly confident with regular PVM development tasks. Further, you’ll see live examples of the extension working on different tasks. On the next line of code after 'AI', I have a comment with the expected result so we can check if the PVM Generator solved the problem or not. Note that AI takes only the previous 50 lines of code as context, so the answer does not affect its output.

We regularly face situations when the protocol specification has a description of the parameter (which is not implemented in flespi yet), and we need to add it. So if we might just copy the parameter description as a comment and trigger AI generation. Look how the PVM Generator correctly implemented multiplication by a coefficient:

Sometimes in our code, we use a pretty rare construction of labels (starting from ‘@’ symbol), and using context, PVM Generator can effectively guess what is expected from it. Also, note how it got division by 2 instead of multiplying by 0.5 as was written by a human in the past 🙂

From time to time, it doesn’t generate exact parameter names. But it is forgivable; still, the result is pretty good because I didn’t spend a lot of time on mastering some sophisticated context or different base prompts for various scenarios. Sometimes I even think its output is better than mine: yes, the previous parameter has a ‘trip.’ prefix. Why shouldn’t it be in the next one?

So, the regular workflow with the protocol using PVM Generator as I imagine it now is as follows: we copy the protocol specification to code comments and then just go line by line checking the input generated by AI.

Bonus: I tried to use it in the declarations of logic in the ‘Settings’ code. It is something that PVM Generator doesn’t know about in common, as it was designed to do custom parsing. But through a couple of iterations, it gave me absolutely valid and correct code! I just had to supply it with a bit of helpful information:

We're generating a 'send' section. It holds the bytes to be sent when we trigger the ‘setting.set’ method. At the beginning, PVM Generator input '000000' at the 'HHMMSS' section, and I told it that it must have the current time. It did not understand that the current time is something that can be obtained from the ‘now’ operator and formatted through the ‘timestr[]’ function. And when I pointed it out as a hint, it generated 10 valid lines of code!

In conclusion, it will be pretty fun to read this article in 5 years when we have a simple API method for protocol documentation upload and the full code tested and ready for deployment. ;)