WASM in the building automation system controller? Part 3

WASM in the building automation system controller? Part 3

Recent articles have explored the potential of WebAssembly in the building automation sector, particularly in hardware and firmware applications. This focus stems from the intricate nature of HVAC sequencing, which often leads to errors in technology procurement. For instance, referencing a previous post akin to Part 1 on an LBNL website, engineers can leverage this resource to draft detailed HVAC operation sequences based on ASHRAE Guideline 36. While this is a valuable tool, it often falls upon mechanical engineers, who may lack expertise in controls, to utilize it in their designs. Subsequently, the responsibility falls on technology contractors to execute these plans. Drawing from my research experience, I've found that involving the manufacturer in a Guideline 36 project is crucial due to its complexity. Without their input, local vendors may interpret the guidelines differently, potentially leading to suboptimal outcomes. Ideally, collaboration with skilled technicians and controls engineers can ensure the success of such projects.

Manufacturers for HVAC controls often provide solutions closely aligned with Guideline 36 (G36) standards but achieving full compliance may require delving into complex control software setups. Local vendors typically rely on these intricate tools to configure their embedded devices, ensuring they adhere to the engineer's specified HVAC sequences. However, in practice, there's often a degree of "close enough" approximation that goes unnoticed, leading to deviations from the intended G36 standards.

Consider this illustration from the LBNL website, showcasing a G36 sequence for a Variable Air Volume (VAV) system. Highlighted in red are the heating and cooling Proportional-Integral-Derivative (PID) calculations within the embedded device. These PIDs dictate the opening of air dampers for cooling or heating coils based on the zone's requirements. The accompanying charts display the airflow settings specified by G36 for technology contractors to adhere to.

Specifically, at the point marked by the red arrow where the heating PID reaches 50%, the engineer intends for the VAV box to open up, increasing airflow and ramping up the heating coil to achieve the maximum discharge air heating setpoint (Max DAT) for the VAV box.

In reality, technology contractors likely approximate this sequence closely. As long as the final zone setpoints are met, there's often no thorough verification to ensure full compliance with G36 standards. Additionally, these G36 sequences are designed for high-performance HVAC systems to save energy and meet setpoints. While deviations from the exact G36 standards may still provide zone comfort and ventilation, they can lead to long-term energy inefficiencies.


G36 snip from LBNL website


For those unfamiliar, a Variable Air Volume (VAV) box, often referred to as a terminal unit in the industry, regulates the temperature of individual zones within a large variable volume HVAC system. You've probably encountered one of these units above the ceiling tiles in your office. They play a crucial role in maintaining comfort by adjusting the airflow and temperature according to the specific needs of each zone.

What is a Variable Air Volume (VAV) System in HVAC? Working, Calculation -

In the HVAC industry, every manufacturer offers a range of hardware solutions. For instance, in Johnson Controls (JCI), their VAV box controller, known as a PCV, is typically represented by the device on the left, while the central plant for Air Handling Unit (AHU) controller, known as a PCA, is usually depicted by the device on the right. Nowadays, these devices are predominantly IP-based, meaning they operate over Internet Protocol, and they communicate using the BACnet protocol to interface with a building automation server. This setup enables efficient monitoring and control of HVAC systems within commercial buildings.

JCI Fx lineup

So where does WebAssembly fit into this?

WebAssembly, as discussed in recent articles, indeed holds immense promise due to its inherent speed, portability, and security features. Its versatility makes it applicable across various domains within the smart building IoT ecosystem. For instance, it can be leveraged in cloud computing microservices, where its efficiency is paramount. Data science applications compiled into WebAssembly binaries benefit from its performance and cross-platform compatibility.

However, what particularly excites me, drawing from my background in controls contracting, is its potential in embedded applications. In the realm of smart buildings, where precise control is crucial for optimizing energy efficiency and ensuring occupant comfort, WebAssembly can revolutionize the way embedded systems operate. Its capability to execute near-native code speed coupled with its security features makes it an ideal candidate for powering the next generation of smart building controls. This shift towards WebAssembly in embedded applications not only enhances performance but also opens doors to seamless integration and future-proofing of IoT solutions in the building automation industry.

Firmware simulation in Python

The integration of heat transfer equations and PID control simulations is a common practice in mechanical engineering coursework. It's not uncommon to find numerous Python projects on platforms like GitHub dedicated to HVAC applications, showcasing the popularity of using Python for simulations within the engineering community.

Harnessing the precision and efficiency of WebAssembly, coupled with Python's versatility in simulation modeling, presents an exciting prospect for the engineering community. By adhering to precise guidelines such as G36, developers could create WebAssembly modules tailored for HVAC simulations, enabling highly realistic and life-like representations of VAV box operations and other HVAC systems.

This convergence of WebAssembly and Python could revolutionize the simulation landscape, offering engineers a powerful toolset to accurately model and analyze complex heat transfer dynamics and control strategies. Such simulations not only enhance the educational experience for mechanical engineering students but also provide valuable insights for professionals in the field, ultimately driving innovation and efficiency in HVAC design and operation.

For example, a PID written in Python could look something like this below which is part of the engineer's sequence that a heating and cooling PID need to ramp depending on if a zone is under or above setpoint.

def calc_heating_pid(self, error, dt=1):
    self.integral_heating += error * dt
    derivative = (error - self.prev_error_heating) / dt
    output = (self.Kp_heating * error) + (self.Ki_heating * self.integral_heating)
    output += self.Kd_heating * derivative
    self.prev_error_heating = error
    return output        

I've developed a Python-based simulation of a VAV (Variable Air Volume) box, which served as the natural starting point for this project. Before delving into the intricacies of condensing it into WebAssembly, I opted to establish a foundational model. While this simulation currently remains rudimentary, it doesn't delve deeply into the complexities of heat transfer equations. Instead, it relies on simulated values for zone temperature sensors, meticulously controlled within narrow random ranges. Although the simulation may seem basic, it effectively captures the essence of the concept, laying a sturdy groundwork for future enhancements and optimizations.

My weekend endeavor led me to explore rewriting the simulation in Rust, a straightforward task with the convenience of compiling to WebAssembly using Cargo. However, a significant hurdle emerged when grappling with the necessity of an external tool for generating the WebAssembly file. I believe it's imperative that mechanical engineers accustomed to Python simulations can seamlessly transition to reading the WebAssembly file (typically with a .wasm extension). My primary challenge arose from verifying that the simulation remained functional after this transition, ensuring parity between the WebAssembly version and its Python counterpart in terms of VAV box firmware functionality.

While Python offers a convenient package like wasmtime for interacting with WebAssembly, my journey uncovered a significant challenge. I learned the hard way that when generating a WebAssembly binary using external tools, all memory management concepts specific to the source language are compiled into the resulting file. Consequently, I found myself confronting the intricate task of managing memory within the WebAssembly environment. This complexity became apparent enough to compel me to seek an alternative approach. As someone accustomed to the comforts of a garbage-collected language like Python, where memory management is abstracted away, the transition presented a notable shift in perspective and required careful consideration.

Dinosaur Game

What actually got me inspired to just abandon trying to figure out memory management in C or Rust of a WebAssembly binary was stumbling across a version of the Dinosaur Game written completely in a .wat file which is the text file version of WebAssembly. The Dinosaur Game is a browser game developed by Google and built into the Google Chrome web browser. The player guides a pixelated Tyrannosaurus rex across a side-scrolling landscape, avoiding obstacles to achieve a higher score. The game was created by members of the Chrome UX team in 2014.

Dinosaur Game


This Git repository is truly remarkable, see the link to play the Dyno game if you would like. A former Google employee managed to encapsulate the entire Dyno game within roughly 800 lines of raw .wat format, representing WebAssembly. What's particularly mind-blowing is that .wat isn't even a programming language; it's simply a text version of WebAssembly. Considering the complexity of the game, which admittedly goes over my head, it's astonishing how the developer achieved such a feat. Personally, I find game development to be quite challenging, and this accomplishment makes even a VAV box with a simple PID block seem straightforward in comparison.

Why not create a WebAssembly version of my Python-based VAV box simulation in a .wat format? Surprisingly, this approach has proven to be much simpler than relying on external tools like Rust, C/C++, or GoLang to generate my WebAssembly binary. Utilizing the Py wasmtime package, integrating the generated .wat file back into Python has been seamless and straightforward.

In its raw WebAssembly .wat file format, this is how a PID appears. It's worth noting that, by design, G36 specifies the use of only PI control in the PID, omitting the derivative component. This simplifies the implementation significantly. When I successfully managed to integrate this back into Python and achieve functionality, it was an immense relief. I'm deeply grateful to whoever created the Dyno game in raw .wat format; without it, I might have abandoned this journey altogether.

(module
  ;; Import necessary external values
  (import "env" "sensorValue" (global $sensorValue (mut f64)))
  (import "env" "setPoint" (global $setPoint f64))
  (import "env" "Kp" (global $Kp f64))
  (import "env" "Ki" (global $Ki f64))

  ;; Define globals for PI state
  (global $integralError (mut f64) (f64.const 0.0))
  (global $prevError (mut f64) (f64.const 0.0))

  ;; Function to calculate PI
  (func $calculatePID (export "calculateOutput") (result f64)
    (local $error f64)
    (local $output f64)

    ;; Calculate the current error
    (local.set $error
      (f64.sub
        (global.get $setPoint)
        (global.get $sensorValue)
      )
    )

    ;; Calculate integral of error
    (global.set $integralError
      (f64.add
        (global.get $integralError)
        (local.get $error)
      )
    )

    ;; Calculate PI output
    (local.set $output
      (f64.add
        (f64.mul (global.get $Kp) (local.get $error))
        (f64.mul (global.get $Ki) (global.get $integralError))
      )
    )

    ;; Return the output
    (local.get $output)
  )

  ;; Define memory and initial value for integral and previous error (if needed)
  (memory 1)
)        

For me, the longer I stare at something, the more it starts to make sense, allowing me to gradually introduce complexities. Consequently, adding the complete version of the VAV box simulation in finished .wat format wasn't too daunting of a task. This is the finalized version, entirely in .wat format, representing approximately 50% of a full-fledged implementation. I estimate that if one were to expand on this, it would likely amount to around 800 lines, similar in length to the Dyno game.

So now what?

At this stage, I've demonstrated that individuals within the mechanical engineering community, who often favor Python, can seamlessly interact with both .wat and compiled .wasm files. This process is made remarkably simple thanks to projects like wat2wasm. With a mechanical background, one can confidently develop the mechanical simulation and even conduct unit tests to ensure the simulation's behavior is accurate.

In my Python WebAssembly script, defining data types for global variables in WebAssembly is a departure from the norm in Python. However, it's a necessary step when working with the wasmtime package. Specifically, specifying data as 64-bit floating point values and being mutable is essential when reading and writing data to a WebAssembly binary.

import wasmtime
import random
import matplotlib.pyplot as plt

# Initialize the WASM environment
engine = wasmtime.Engine()
store = wasmtime.Store(engine)
module = wasmtime.Module.from_file(engine, "./complete_sim.wat")
linker = wasmtime.Linker(engine)

zone_air_temp = wasmtime.Global(
    store,
    wasmtime.GlobalType(wasmtime.ValType.f64(), mutable=True),
    wasmtime.Val.f64(68.0),
)

set_point = wasmtime.Global(
    store,
    wasmtime.GlobalType(wasmtime.ValType.f64(), mutable=True),
    wasmtime.Val.f64(72.0),
)        

Here's the complete script for using Python to read in a .wat file which will also work with a .wasm, featuring an integrated plotting feature. The plots closely resemble those typically generated by mechanical engineers, albeit with a slight variation.

Python and WebAssembly HVAC sim


What I aimed to achieve in my weekend research hobby was to observe the heating PID ramping up in heating mode, with that additional touch of G36 logic around the 50% heating PID output mark. Similarly, I wanted to witness the cooling PID ramping down in cooling mode and transitioning to satisfied mode when the space setpoint falls within the dead band range. It's fascinating to see how the WebAssembly module replicates what I envision as VAV box control logic tailored to G36 specifications.

Where does embedded applications fit into this?

As I mentioned earlier, every manufacturer offers its own version of a VAV box controller. When a mechanical engineer specifies adherence to G36 standards, the project can become complicated. Unless meticulously commissioned, ensuring compliance can be challenging. This process often involves navigating through proprietary setup tools employed by HVAC controls contractors, which can be daunting due to each vendor's unique toolset. As a result, it's often uncertain whether the system truly adheres to G36 standards. The only recourse is to meticulously scrutinize the data post-implementation, a task that demands considerable time and effort.

Can an embedded software engineer use a WebAssembly module?

In my exploration, I did encounter this, but it took me quite some time to grasp, particularly because I lack a background in embedded software development.

WebAssembly research for the embedded applications

I came across the Wasm3 project, which includes an Arduino library—a fascinating find! For those unfamiliar with Arduino, these are microcontroller development boards popular among hobbyists and widely used in university settings due to their user-friendly nature.

What further piqued my curiosity was a podcast called Embedded.fm recommended to me by John Sullivan is amazing. As someone still acclimating to much of the terminology in this field, I found it incredibly insightful. In episode 396, they featured an Arduino simulator creator named Wokwi, which I listened to twice. It was fascinating to learn about how computer hardware can be simulated, especially considering the advanced features such as simulating Assembly processor code and even versions of Linux and gcc running in a browser. This experience ultimately inspired me to delve deeper into exploring the Wasm3 Arduino examples. Without listening to that episode, I might have overlooked the idea of trying a simulation for a microcontroller, but now I find it to be a genuinely enjoyable and fascinating endeavor.

Upon discovering a thermistor coding example for Arduino on Wokwi, I began experimenting with it using an ESP32 development board. The simulation tool allows for the integration of a wide range of sensors and devices. The code snippet below illustrates the setup for a thermistor. For individuals with a background in HVAC controls contracting, this setup may feel familiar, as wiring in numerous temperature sensors is a common practice in this field. Even the math in the C code below for the 10k thermistor is something quite familiar if your HVAC control hardware used thermistors. Fortunately, working with embedded C code isn't too challenging, thanks to the abundance of Arduino learning tutorials available online.

Wokwi Arduino Sim

The challenging aspect lies in integrating the Wasm3 project into the Arduino board, further complicated by the fact that the examples all utilize hexadecimal representations, where WebAssembly is condensed into a compact binary bytecode and hard-coded into an array in C. Python can actually convert a raw .wasm file to hexadecimal pretty easily with no external libraries need.

Getting this up and running was surprisingly straightforward, as depicted below. In the hexadecimal version of my VAV box firmware, the highlighted yellow section indicates the WebAssembly implementation. The debug print lines confirm that the PID is indeed ramping up for heat. Although the values of the simulated temperature sensor may appear unusual, everything seems to be functioning as intended!

Rough concept idea of WebAssembly firmware simulated on Wokwi


For anyone that wants to try this out on Wokwi!

Final Thoughts

This maybe a bit of a stretch but could something like WebAssembly be the glue that can bind the work between the Mechanical Engineer and the Embedded Software Engineer in the HVAC industry?

How remarkable it would be for both Mechanical Engineers and Embedded Engineers to collaborate seamlessly, working with the same files or firmware! Imagine if, akin to Part 1 of this post where the LBNL website offers G36 sequences for download, HVAC engineers could also download firmware in `.wasm` format for use in embedded devices set up by technology contractors. This could potentially alleviate many of the issues stemming from building startups, lack of HVAC commissioning, and misunderstanding of G36 by technology contractor engineers. However, there might be pushback from the technology contractors and/or manufactures themselves, as this approach could be perceived as removing features from the control system. Take, for instance, JCI CCT, a powerful and highly customizable software platform where the problem is it is a powerful and highly customizable software platform. While its robustness and customizability are strengths, they also make it all too easy to inadvertently deviate from G36 standards. Consequently, this may necessitate a Part 4 of this series focusing on the conceptual design of a G36-compliant software setup tool for controls technicians in the field. This was hinted at in Part 1, referencing the outdated tools, particularly in the JCI world, where such functionality was lacking.

Also not to mention this hasn't been the first time for software revolution in this industry and these are exciting times. At least in research there is lots of Grid Interactive Efficient Building (GEB) active projects going on right now and even other mind-boggling stuff where the Ph.D. Mechanical Engineer is teaming up with the Ph.D. Chemical Engineer on producing synthetic materials for thermal storage which can outperform what industry has used for decades in just freezing water in ice storage tanks. Who knows the HVAC of today may look way different than the HVAC of tomorrow! Thanks for reading!


Caleb Eastman

IT/OT Convergence Subject Matter Expert

8mo

It's very rare that I see a LinkedIn post that really moves the entire state of the industry forward and invokes a genuinely good idea that deserves increased research and study. This is one of them. Great work here. There is a concept in Industrial Controls called MTP that defines all the states and connections within a defined piece of equipment called a Process Equipment Assembly or PEA for short. A VAV would be considered a PEA. Now you have inspired me to define a PEA using a WAT file and a YAML file. Thank you!

John Sullivan

The Digital Shepherd - Bringing People and Technology together! HW/SW | AI/ML | IoT / IIOT | Edge | IT/OT | MES

8mo

Amazing article Ben Bartling. Thanks for documenting your trips down those rabbit holes that ended up leading to the same burrow! And thermal storage - more interest in sand is coming, and since all building should have a proper foundation, sticking a 30 foot tank if sand under it is likely not an issue (AND then you also have the time differences from the hot sand to roof temps that could be leveraged.) Thanks for the mention too. Now I need to go listen to that Wokwi episode 😎

To view or add a comment, sign in

Insights from the community

Others also viewed

Explore topics