{
    "version": "https://jsonfeed.org/version/1",
    "title": "Apache StreamPipes blog",
    "home_page_url": "https://streampipes.apache.org/blog/",
    "description": "Release notes, how-tos and news from the Apache StreamPipes project.",
    "items": [
        {
            "id": "https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/",
            "content_html": "<p>If you have used StreamPipes for a while, you will have noticed that the number of things in it grows quickly. One machine easily ends up with an adapter, a persisted dataset, two or three pipelines, a handful of charts and a dashboard. Multiply that by a line, and then by a plant, and the lists in the UI stop being useful. Everything is there, but you have to remember what it is called.</p>\n<p>Assets are our answer to that. They let you describe the plant the way people on the floor think about it, as plants, lines, machines and components, and attach all of those technical resources to the object they belong to. Over the past year most of the UI has been rebuilt around this idea, and in this post I want to explain what that means in practice.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-idea-in-one-sentence\">The idea in one sentence<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#the-idea-in-one-sentence\" class=\"hash-link\" aria-label=\"Direct link to The idea in one sentence\" title=\"Direct link to The idea in one sentence\" translate=\"no\">​</a></h2>\n<p>An asset is a real-world thing: a plant, a line, a machine, a station, a subsystem. Assets can be nested, so a plant contains lines and a line contains machines. Each asset can be linked to the StreamPipes resources that belong to it. Once those links exist, you can start from the machine and find everything around it, instead of starting from a list of adapters and working out which one is which.</p>\n<p>Sites add a second dimension. A site is shared location context, such as a factory, a building or a hall, with an optional area. You define a site once and assign it to as many assets as you like. An asset can also carry an exact position, which is what puts it on the map.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"start-on-the-home-screen\">Start on the home screen<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#start-on-the-home-screen\" class=\"hash-link\" aria-label=\"Direct link to Start on the home screen\" title=\"Direct link to Start on the home screen\" translate=\"no\">​</a></h2>\n<p>The home screen is the first place where this shows. Instead of a list of modules, it opens with your assets. In table mode every row is one asset with its type, location and a row of icons for the linked resources, and each icon takes you straight to that adapter, pipeline, chart or dashboard. Switch to map mode and the same assets appear as markers on a map, which is the view we see most often on large screens in control rooms.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Home screen with assets on a map\" src=\"https://streampipes.apache.org/assets/images/home-map-5360635df00313b665f59597b182d82f.png\" width=\"800\" height=\"444\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"one-page-per-machine\">One page per machine<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#one-page-per-machine\" class=\"hash-link\" aria-label=\"Direct link to One page per machine\" title=\"Direct link to One page per machine\" translate=\"no\">​</a></h2>\n<p>Open an asset and you get a detail page: identifier, type, labels, the site and area it belongs to, a small map if a position is set, and the full list of linked resources. The demo machine below has 29 of them, three adapters, their datasets, the pipelines that persist and process the data, and the charts and dashboards built on top. This is the page we point people to when they ask \"where is the data for this machine\".</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Asset detail view with linked resources\" src=\"https://streampipes.apache.org/assets/images/asset-view-660b2ab47a847600846a602c011370a2.png\" width=\"800\" height=\"444\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"asset-context-everywhere-else\">Asset context everywhere else<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#asset-context-everywhere-else\" class=\"hash-link\" aria-label=\"Direct link to Asset context everywhere else\" title=\"Direct link to Asset context everywhere else\" translate=\"no\">​</a></h2>\n<p>The part that took the longest, and that I think matters most, is that assets are not confined to their own module. Every resource list in StreamPipes, adapters, pipelines, datasets, charts and dashboards, shows the asset context of each row and can be filtered by it. The filter button in the top right lets you narrow a list by asset, by asset type, by site and by label, and the filter is kept while you edit resources.</p>\n<p>So an operator responsible for the Hamburg plant can set the filter and see only the adapters, pipelines and dashboards for that plant. A maintenance team interested in everything tagged <code>critical</code> can do the same with a label.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Asset filter on the adapter list\" src=\"https://streampipes.apache.org/assets/images/asset-filter-b21fc80277b9352c6723239f481c0644.png\" width=\"800\" height=\"444\" class=\"img_ev3q\"></p>\n<p>New resources pick up the context automatically where it makes sense. When a pipeline persists a stream into a dataset, that dataset is assigned to the same asset as the pipeline.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"modelling-your-own-plant\">Modelling your own plant<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#modelling-your-own-plant\" class=\"hash-link\" aria-label=\"Direct link to Modelling your own plant\" title=\"Direct link to Modelling your own plant\" translate=\"no\">​</a></h2>\n<p>The asset editor shows the hierarchy on the left and the details of the selected node on the right. A few things we learned while building and using it:</p>\n<ul>\n<li class=\"\"><strong>Start with the root that people navigate from.</strong> For some teams that is the plant, for others a single line. The root does not have to be the most detailed object, it is the entry point.</li>\n<li class=\"\"><strong>Mirror how people talk about the equipment.</strong> If the packaging line is \"filler, capper, labeler\" in daily conversation, those are the sub-assets. If maintenance thinks in subsystems, model subsystems. The tree can be reordered and nodes can be moved to another parent later, so the first version does not have to be final.</li>\n<li class=\"\"><strong>Use labels for the lightweight stuff and custom fields for the structured stuff.</strong> <code>critical</code> or <code>testbench</code> are labels. Vendor, serial number and commissioning date are custom fields. Custom fields work on sub-assets too, so a machine and its components can carry different sets.</li>\n<li class=\"\"><strong>Assign the site at the root, the exact position only where it is needed.</strong> Not every pump needs a map pin. The ones that do can have one without forcing the same detail on everything else.</li>\n</ul>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Asset editor with hierarchy, basics and labels\" src=\"https://streampipes.apache.org/assets/images/asset-edit-basics-190b09af49a9f66311ff0cdc18249918.webp\" width=\"1440\" height=\"735\" class=\"img_ev3q\"></p>\n<p>Linking resources is the last step, and the one most often forgotten. The editor lets you add links one at a time or open a dialog to attach several at once. Our rule of thumb is to model the hierarchy first, assign the site second and link resources third. The structure should exist before the technical objects are hung onto it.</p>\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Site assignment and asset links in the editor\" src=\"https://streampipes.apache.org/assets/images/asset-edit-links-8c704d216a2f06a24f22ad31be810f2a.webp\" width=\"1440\" height=\"747\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"permissions-follow-the-model\">Permissions follow the model<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#permissions-follow-the-model\" class=\"hash-link\" aria-label=\"Direct link to Permissions follow the model\" title=\"Direct link to Permissions follow the model\" translate=\"no\">​</a></h2>\n<p>Assets have their own permissions, so a shared installation can give one team edit rights on their line and read access on the rest. Combined with the filters, this is how we run installations where several groups share one StreamPipes instance without seeing each other's clutter.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"where-this-is-heading\">Where this is heading<a href=\"https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/#where-this-is-heading\" class=\"hash-link\" aria-label=\"Direct link to Where this is heading\" title=\"Direct link to Where this is heading\" translate=\"no\">​</a></h2>\n<p>Most of what is shown here is in the development version of StreamPipes and will ship with the next release; parts of it are already in 0.98.0. The direction is clear: assets are becoming the way you navigate the platform, and new features are designed with that context in mind from the start. If you run StreamPipes today, it is worth taking an afternoon to model your plant. The benefit grows with every resource you add afterwards.</p>\n<p>The <a class=\"\" href=\"https://streampipes.apache.org/docs/use-assets/\">assets and sites documentation</a> covers the editor step by step. If you have ideas for what asset context should do next, the <a class=\"\" href=\"https://streampipes.apache.org/community/mailing-lists/\">mailing lists</a> and <a href=\"https://github.com/apache/streampipes/discussions\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Discussions</a> are the right places.</p>",
            "url": "https://streampipes.apache.org/blog/2026/10/30/assets-as-the-backbone/",
            "title": "Assets are the backbone of StreamPipes",
            "summary": "Why StreamPipes organises adapters, datasets, pipelines, charts and dashboards around machines, lines and plants, and how to model your own assets.",
            "date_modified": "2026-10-30T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/",
            "content_html": "<p>A question we get a lot: \"We already use Node-RED, why would we need StreamPipes?\" It is a fair question. Both tools have a browser-based editor where you connect boxes into a flow, and if that is all you have seen of either, they look like the same thing. They are not, and this post tries to explain where the difference is, so you can pick the right one for the job, or use both.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-node-red-is-built-for\">What Node-RED is built for<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#what-node-red-is-built-for\" class=\"hash-link\" aria-label=\"Direct link to What Node-RED is built for\" title=\"Direct link to What Node-RED is built for\" translate=\"no\">​</a></h2>\n<p>Node-RED is a general-purpose, flow-based programming tool. A flow runs inside a single Node.js process, and the node library covers almost everything: HTTP, MQTT, serial ports, databases, cloud services, and thousands of community nodes. It is excellent for wiring devices and services together, for prototyping, for small automations at the edge, and for home and lab setups. A single developer can build something useful in an afternoon.</p>\n<p>What Node-RED does not try to be is a data platform. There is no built-in time-series storage, no idea of a dataset with a retention rule, no user and role management beyond basic authentication, and no catalog of typed streams. Dashboards are an add-on. Once you run many flows across several sites, you end up building the operations side yourself.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-apache-streampipes-is-built-for\">What Apache StreamPipes is built for<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#what-apache-streampipes-is-built-for\" class=\"hash-link\" aria-label=\"Direct link to What Apache StreamPipes is built for\" title=\"Direct link to What Apache StreamPipes is built for\" translate=\"no\">​</a></h2>\n<p>StreamPipes is an industrial IoT data platform. Its unit of work is a typed data stream: an adapter connects a source such as OPC UA, Siemens S7, Modbus or MQTT, describes the fields, units and metadata once, and every pipeline, chart and dashboard builds on that description. Pipelines are built from processors and sinks that are validated against the stream schema, run as separate services, and are monitored by the core. Datasets keep history with retention rules and export. Assets and sites give streams their place in the plant. Users, roles, groups, permissions, single sign-on and an audit log are part of the platform.</p>\n<p>That is the setting StreamPipes is made for: several people, several machines, data that has to be kept and governed, and one platform that operators, engineers and developers all use.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"where-the-difference-is-biggest-getting-data-out-of-machines\">Where the difference is biggest: getting data out of machines<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#where-the-difference-is-biggest-getting-data-out-of-machines\" class=\"hash-link\" aria-label=\"Direct link to Where the difference is biggest: getting data out of machines\" title=\"Direct link to Where the difference is biggest: getting data out of machines\" translate=\"no\">​</a></h2>\n<p>This is the point most comparisons gloss over, so it deserves its own section. Both tools can talk to a PLC. The experience of doing so is very different.</p>\n<p>In Node-RED, industrial connectivity comes from community nodes. The OPC UA nodes, for example, expect you to know the node ids you want to read, to type them into a node configuration or inject them from a function node, and to deal with security settings, reconnects and data types in the flow yourself. That works well for a handful of tags on a server you know. It becomes hard to maintain once there is a server with thousands of nodes, several machines from different vendors, certificates to manage, and colleagues who have to understand the flow later.</p>\n<p>StreamPipes treats machine connectivity as a product feature, not as a library. The OPC UA adapter opens the server's node tree in a browser, lets you pick the variables you want, and shows live values before you commit. You choose pull or subscription mode per adapter, pick the security mode and policy, and either upload a client certificate or let StreamPipes generate one. Certificates are managed in one place for all adapters, and X.509 user authentication is supported. Complex types in extension objects are decoded into flat fields. A second adapter subscribes to OPC UA alarms and conditions and turns them into a stream of events. All of that is configured in a wizard, with the schema, units and metadata of each field refined in the next step, and saved as an adapter that colleagues can inspect, copy and restart.</p>\n<p>The same applies beyond OPC UA. StreamPipes ships adapters for Siemens S7, Modbus TCP, RTU and ASCII, Beckhoff TwinCAT ADS, Allen-Bradley and Logix CIP, EtherNet/IP, CANopen and generic CAN, IEC 60870-5-104, Mitsubishi SLMP, Schneider UMAS, KNXnet/IP, OI4 and the Siemens WinCC alarm archive, next to the usual MQTT, Kafka, NATS, HTTP, file and database sources. Every adapter follows the same pattern: a guided configuration, a live preview of the incoming events, a schema step where you fix field names, types and measurement units and can run a short transformation script against a sample, and then monitoring of throughput, errors and logs once it runs. When a machine changes, you edit the adapter and the change is validated against the pipelines that depend on it.</p>\n<p>That is what we mean by professional-grade machine data integration. It is not that Node-RED cannot read a PLC. It is that in StreamPipes the hard parts are done once, in the platform, and every machine after the first one benefits.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"where-each-one-wins\">Where each one wins<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#where-each-one-wins\" class=\"hash-link\" aria-label=\"Direct link to Where each one wins\" title=\"Direct link to Where each one wins\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>Question</th><th>Node-RED</th><th>Apache StreamPipes</th></tr></thead><tbody><tr><td>Wire a device to a service in an afternoon</td><td>Yes, with the broadest node library available</td><td>Yes, for anything with an adapter; the SDK covers the rest</td></tr><tr><td>Connect industrial machines</td><td>Community nodes, node ids and security handled in the flow</td><td>Guided adapters with OPC UA node browser, certificate management, PLC protocols, live preview and schema editor</td></tr><tr><td>Keep and query months of machine history</td><td>Not built in</td><td>Datasets with retention, export and charts</td></tr><tr><td>Typed streams with units and metadata</td><td>Per flow, by convention</td><td>Core concept, shared by all features</td></tr><tr><td>Dashboards for operators</td><td>Via the dashboard add-on</td><td>Built in, with assets and permissions</td></tr><tr><td>Users, roles, SSO, audit log</td><td>Basic</td><td>Built in</td></tr><tr><td>Run processing next to the machines, manage centrally</td><td>Multiple independent instances</td><td>Extension services in OT, one core in IT</td></tr><tr><td>Custom logic</td><td>JavaScript function nodes</td><td>Java or Python Functions, SDK for reusable elements</td></tr><tr><td>Operating model</td><td>One process per instance</td><td>Core, broker and extension services on Docker or Kubernetes</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"using-both\">Using both<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#using-both\" class=\"hash-link\" aria-label=\"Direct link to Using both\" title=\"Direct link to Using both\" translate=\"no\">​</a></h2>\n<p>The two get along fine. Node-RED can act as a bridge for a device StreamPipes has no adapter for, publishing to MQTT, where a StreamPipes adapter picks it up. In the other direction, StreamPipes can publish derived values to a broker that Node-RED flows react to. If you have Node-RED flows that work, keep them.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"summary\">Summary<a href=\"https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/#summary\" class=\"hash-link\" aria-label=\"Direct link to Summary\" title=\"Direct link to Summary\" translate=\"no\">​</a></h2>\n<p>Use Node-RED for integrations and automations where the flow is the whole product and one process is enough. Use StreamPipes when the sources are machines and the data has to become something a team shares: connected through adapters that handle the protocols, certificates and schemas properly, kept with history, shown on dashboards and governed with access control. The <a class=\"\" href=\"https://streampipes.apache.org/integrations/\">integrations catalog</a> lists every adapter, and the <a class=\"\" href=\"https://streampipes.apache.org/docs/quick-start-guide/\">quickstart</a> shows the StreamPipes side in about ten minutes.</p>",
            "url": "https://streampipes.apache.org/blog/2026/07/14/streampipes-vs-node-red/",
            "title": "When to use Apache StreamPipes, and when Node-RED is the better fit",
            "summary": "Node-RED and StreamPipes both have a flow editor, and that is roughly where the similarity ends. Where each one is strong, why StreamPipes is the better fit for professional machine data integration, and when to use which.",
            "date_modified": "2026-07-14T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "comparison"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/",
            "content_html": "<p>When it comes to ease of use, Docker Desktop is the goto on windows platform, however for business use there are licensing involved.</p>\n<p>So why not use Podman Desktop, it’s Docker compatible?\nWell yes, almost, would be the answer.<br>\nFor Podman Desktop to handle Apache StreamPipes we need to do a few tricks.</p>\n<p>This guide walks you through installing and running Apache StreamPipes using Podman inside a WSL environment and will try to explain to you the how’s and why’s.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"prerequisits\">Prerequisits<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#prerequisits\" class=\"hash-link\" aria-label=\"Direct link to Prerequisits\" title=\"Direct link to Prerequisits\" translate=\"no\">​</a></h2>\n<a href=\"https://learn.microsoft.com/en-us/windows/wsl/install\">Enable WSL on your machine.</a>\n<br>\n<a href=\"https://podman-desktop.io/\"> Install Podman Desktop.</a>\n<p>After installing Podman Desktop you need to run the setup to enable Podman core.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/podman-setup.png\" alt=\"Setup Podman\">\n<p>Alter this you can setup a virtual machine in which to host Apache Streampipes on.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/create-podman-machine.png\" alt=\"Setup virtual machine\">\n<p>Now we have to embark on a voyage into the (dark) Linux terminal country, so that we can later enjoy the use of a familiar Windows UI in Podman Desktop.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"connect-to-your-podman-wsl-machine\">Connect to Your Podman WSL Machine<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#connect-to-your-podman-wsl-machine\" class=\"hash-link\" aria-label=\"Direct link to Connect to Your Podman WSL Machine\" title=\"Direct link to Connect to Your Podman WSL Machine\" translate=\"no\">​</a></h2>\n<p>Open PowerShell to get a list of available machines.</p>\n<div class=\"language-powershell codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-powershell codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">wsl -l</span><br></div></code></pre></div></div>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/wsl.png\" alt=\"Available machines\">\n<br>\n<br>\n<p>Or you can see the Podman machine in the tray menu</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/podman-machine.png\" alt=\"Available machines tray\">\n<br>\n<p>In PowerShell connect to the Podman machine.</p>\n<div class=\"language-powershell codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-powershell codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">wsl -d podman-machine-default</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"install-required-tools\">Install Required Tools<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#install-required-tools\" class=\"hash-link\" aria-label=\"Direct link to Install Required Tools\" title=\"Direct link to Install Required Tools\" translate=\"no\">​</a></h2>\n<p>Podman uses Fedora Linux and the dnf package manager. Install the following packages to make your life easier.</p>\n<ul>\n<li class=\"\">podman-compose</li>\n</ul>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">sudo dnf install podman-compose.noarch </span><br></div></code></pre></div></div>\n<ul>\n<li class=\"\">unzip</li>\n</ul>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">sudo dnf install unzip.x86_64 </span><br></div></code></pre></div></div>\n<ul>\n<li class=\"\">nano</li>\n</ul>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">sudo dnf install nano.x86_64 </span><br></div></code></pre></div></div>\n<ul>\n<li class=\"\">mc</li>\n</ul>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">sudo dnf install mc.x86_64 </span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"get-apache-streampipes\">Get Apache StreamPipes<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#get-apache-streampipes\" class=\"hash-link\" aria-label=\"Direct link to Get Apache StreamPipes\" title=\"Direct link to Get Apache StreamPipes\" translate=\"no\">​</a></h2>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<p>For ease save it in a subfolder on your C-drive, e.g. c:\\Download <br>\nLets make a folder in WSL to hold our files, and go into it.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">mkdir StreamPipes</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">cd StreamPipes</span><br></div></code></pre></div></div>\n<p>We can now directly copy the downloaded *.zip file to our WSL, note the version number on the zip file.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">cp /mnt/c/Download/apache-streampipes-0.98.0-source-release.zip /home/user/StreamPipes/</span><br></div></code></pre></div></div>\n<p>If the terminal is still a bit outside you'r comfort zone Midnight Commander can help you.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">mc</span><br></div></code></pre></div></div>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/mc-copy.png\" alt=\"Use Midnight Commander\">\n<p>It is possible to reach your WSL from Windows filemanager, but unzipping files will give issues due to long filenames.\nTherefore the approch of handling the files from WSL is preferable.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/zip-fail.jpg\" alt=\"Fail\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"unpack-and-navigate-to-the-compose-directory\">Unpack and Navigate to the Compose Directory<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#unpack-and-navigate-to-the-compose-directory\" class=\"hash-link\" aria-label=\"Direct link to Unpack and Navigate to the Compose Directory\" title=\"Direct link to Unpack and Navigate to the Compose Directory\" translate=\"no\">​</a></h2>\n<p>Unzip the package by using the unzip command and navigate to the extracted folder and go to 'installer/compose' directory.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">unzip apache-streampipes-0.98.0-source-release.zip</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div></code></pre></div></div>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">cd apache-streampipes-0.98.0/installer/compose</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"update-docker-composeyml\">Update docker-compose.yml<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#update-docker-composeyml\" class=\"hash-link\" aria-label=\"Direct link to Update docker-compose.yml\" title=\"Direct link to Update docker-compose.yml\" translate=\"no\">​</a></h2>\n<p>Modify the docker-compose-yml with nano</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">nano docker-compose.yml</span><br></div></code></pre></div></div>\n<p>And add the following.</p>\n<div class=\"language-config codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-config codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">- ./nginx_config/default.conf:/etc/nginx/conf.d/default.conf:ro</span><br></div></code></pre></div></div>\n<p>Looking like this.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/nano-docker-compose.jpg\" alt=\"Edit compose\">\n<p>Remove this line since it is not relevant for this setup.</p>\n<div class=\"language-yml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yml codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token key atrule\">environment</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> SP_HTTP_SERVER_ADAPTER_ENDPOINT=extensions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">all</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">iiot</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">8090</span><br></div></code></pre></div></div>\n<p>And yes you can copy paste from windows into nano.\nUse CRTL + x to quit, and answer ‘y’ to save the file.\nHere is how the docker-compose.yml should look loke</p>\n<div class=\"language-compose codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-compose codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># Licensed to the Apache Software Foundation (ASF) under one or more</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># contributor license agreements.  See the NOTICE file distributed with</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># this work for additional information regarding copyright ownership.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># The ASF licenses this file to You under the Apache License, Version 2.0</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># (the \"License\"); you may not use this file except in compliance with</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># the License.  You may obtain a copy of the License at</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">#</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">#    http://www.apache.org/licenses/LICENSE-2.0</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">#</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># Unless required by applicable law or agreed to in writing, software</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># distributed under the License is distributed on an \"AS IS\" BASIS,</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># See the License for the specific language governing permissions and</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># limitations under the License.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># global logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">x-logging:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  &amp;default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  options:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    max-size: '12m'</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    max-file: '5'</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  driver: json-file</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">services:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  # StreamPipes services</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  backend:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: \"${SP_DOCKER_REGISTRY}/backend:${SP_VERSION}\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    depends_on:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - couchdb</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    environment:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - SP_PRIORITIZED_PROTOCOL=nats</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    volumes:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - backend:/root/.streampipes</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    logging: *default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  ui:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: \"${SP_DOCKER_REGISTRY}/ui:${SP_VERSION}\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    ports:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - \"80:8088\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    depends_on:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - couchdb</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - backend</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    volumes:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - nginx:/etc/nginx/</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - ./nginx_config/default.conf:/etc/nginx/conf.d/default.conf:ro</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    logging: *default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  couchdb:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: couchdb:3.3.1</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    environment:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - COUCHDB_USER=admin</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - COUCHDB_PASSWORD=admin</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    volumes:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - couchdb:/opt/couchdb/data</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    logging: *default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  influxdb:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: influxdb:2.6</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    environment:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - INFLUXDB_DATA_ENGINE=tsm1</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - INFLUXDB_REPORTING_DISABLED=false</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - INFLUXDB_ADMIN_ENABLED=true</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_USERNAME=admin</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_PASSWORD=sp-admin</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_ADMIN_TOKEN=sp-admin</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_ORG=sp</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_BUCKET=sp</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - DOCKER_INFLUXDB_INIT_MODE=${SP_INFLUX_INIT_MODE}</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    volumes:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - influxdb:/var/lib/influxdb</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      - influxdb2:/var/lib/influxdb2</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    logging: *default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  nats:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: nats</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  # Lite version pipeline elements</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  extensions-all-iiot:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    image: \"${SP_DOCKER_REGISTRY}/extensions-all-iiot:${SP_VERSION}\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    logging: *default-logging</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    restart: unless-stopped</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">volumes:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  backend:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  couchdb:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  influxdb:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  influxdb2:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  nginx:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">networks:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  spnet:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    driver: bridge</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"add-custom-nginx-configuration\">Add Custom Nginx Configuration<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#add-custom-nginx-configuration\" class=\"hash-link\" aria-label=\"Direct link to Add Custom Nginx Configuration\" title=\"Direct link to Add Custom Nginx Configuration\" translate=\"no\">​</a></h2>\n<p>Create a 'nginx_config' directory</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">mkdir nginx_config</span><br></div></code></pre></div></div>\n<p>In that directory you add a 'default.conf' with the help of Nano.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">cd nginx_config</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">nano default.conf</span><br></div></code></pre></div></div>\n<p>The following nginx.conf is almost identical to the default Docker-based setup, with the only change being that the resolve parameter is removed as it doesn't work reliably with Podman's networking.</p>\n<div class=\"language-config codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-config codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">server {</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  listen       8088 default_server;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  root /usr/share/nginx/html;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  # Enable gzip compression</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip on;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_static on;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_proxied  any;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_vary on;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_comp_level 6;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_buffers 16 8k;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  gzip_http_version 1.1;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  # StreamPipes Backend Proxy</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  location /streampipes-backend {</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_set_header X-Real-IP $remote_addr;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_set_header X-NginX-Proxy true;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_pass http://backend:8030;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_ssl_session_reuse off;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_set_header Host $http_host;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    proxy_redirect off;</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  }</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">}</span><br></div></code></pre></div></div>\n<p>Now we are almost there, and you are getting good at this terminal thing, so is there a use for Podman Desktop, you ask yourself?</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"start-up-streampipes-using-podman-compose\">Start Up StreamPipes Using Podman Compose<a href=\"https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/#start-up-streampipes-using-podman-compose\" class=\"hash-link\" aria-label=\"Direct link to Start Up StreamPipes Using Podman Compose\" title=\"Direct link to Start Up StreamPipes Using Podman Compose\" translate=\"no\">​</a></h2>\n<p>Do</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">sudo podman-compose -f docker-compose.yml up -d</span><br></div></code></pre></div></div>\n<p>to import and run all containers.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/podman-compose-done.png\" alt=\"Done\">\n<br>\n<p>Once complete, Apache StreamPipes will be available in Podman Desktop and accessible at <a href=\"http://localhost/\"></a><a href=\"http://localhost/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://localhost:80</a>.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2026-03-21/podman-running.png\" alt=\"Running\">\n<p>Congratulations, now we can start to use the strongpoints of Podman which enable us in a fast and terminal free way to make backups of our projects or scale them further with Kubernetes.</p>\n<p>Happy StreamPiping on Windows with Podman Desktop</p>",
            "url": "https://streampipes.apache.org/blog/2026/03/21/_streampipes-with-windows-and-podman/",
            "title": "StreamPipes on Windows with Podman",
            "summary": "When it comes to ease of use, Docker Desktop is the goto on windows platform, however for business use there are licensing involved.",
            "date_modified": "2026-03-21T00:00:00.000Z",
            "author": {
                "name": "Morten Torp",
                "url": "https://www.linkedin.com/in/morten-torp-7b731526/"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/",
            "content_html": "<p>With the introduction of <strong>StreamPipes Functions</strong>, Apache StreamPipes provides a lightweight way to attach fixed runtime logic to existing streams — without creating a full pipeline element.</p>\n<p>Functions are ideal when:</p>\n<ul>\n<li class=\"\">A full processor would be overkill</li>\n<li class=\"\">You want logic that runs with the extensions service lifecycle</li>\n<li class=\"\">You need direct access to incoming events</li>\n</ul>\n<p>Previously, functions could maintain in-memory state during runtime, but any restart of the extensions service resulted in a complete state reset.</p>\n<p>We now provide a new functionality in <strong>developer preview</strong> that introduces typed state persistence for Functions, allowing state to survive service restarts.</p>\n<p>This allows functions to survive restarts and resume exactly where they stopped.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"why-stateful-functions\">Why Stateful Functions?<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#why-stateful-functions\" class=\"hash-link\" aria-label=\"Direct link to Why Stateful Functions?\" title=\"Direct link to Why Stateful Functions?\" translate=\"no\">​</a></h2>\n<p>Many real-world use cases require minimal but persistent runtime state:</p>\n<ul>\n<li class=\"\">Counting processed events</li>\n<li class=\"\">Tracking the last processed timestamp</li>\n<li class=\"\">Storing threshold configurations</li>\n<li class=\"\">Keeping lightweight usage statistics</li>\n</ul>\n<p>Previously, developers had to implement external persistence manually.<br>\n<!-- -->Now, state management is built directly into the Function lifecycle.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-new-state-store-api\">The New State Store API<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#the-new-state-store-api\" class=\"hash-link\" aria-label=\"Direct link to The New State Store API\" title=\"Direct link to The New State Store API\" translate=\"no\">​</a></h2>\n<p>The <code>FunctionContext</code> now provides access to a typed state store:</p>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">StateStore</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">T</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getStateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Class</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">T</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> stateClass</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>This API allows you to:</p>\n<ul>\n<li class=\"\">Load persisted state during startup</li>\n<li class=\"\">Persist state on shutdown</li>\n</ul>\n<p>State handling is <strong>fully optional and backward compatible</strong>.\nIf you don’t request a state store, your function behaves exactly as before.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"lifecycle-integration\">Lifecycle Integration<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#lifecycle-integration\" class=\"hash-link\" aria-label=\"Direct link to Lifecycle Integration\" title=\"Direct link to Lifecycle Integration\" translate=\"no\">​</a></h2>\n<p>Functions still follow the same lifecycle:</p>\n<ul>\n<li class=\"\"><code>onServiceStarted(FunctionContext context)</code></li>\n<li class=\"\"><code>onEvent(Event event, String streamId)</code></li>\n<li class=\"\"><code>onServiceStopped()</code></li>\n</ul>\n<p>The only difference is that you can now initialize a <code>StateStore</code> during startup.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"example-threshold-monitoring-function\">Example: Threshold Monitoring Function<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#example-threshold-monitoring-function\" class=\"hash-link\" aria-label=\"Direct link to Example: Threshold Monitoring Function\" title=\"Direct link to Example: Threshold Monitoring Function\" translate=\"no\">​</a></h2>\n<p>Let’s implement a simple function that:</p>\n<ul>\n<li class=\"\">Counts processed events</li>\n<li class=\"\">Tracks the last processed timestamp</li>\n<li class=\"\">Logs a message when a threshold is reached</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"1-define-the-state-object\">1. Define the State Object<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#1-define-the-state-object\" class=\"hash-link\" aria-label=\"Direct link to 1. Define the State Object\" title=\"Direct link to 1. Define the State Object\" translate=\"no\">​</a></h3>\n<p>State is defined as a typed POJO.</p>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">int</span><span class=\"token plain\"> schemaVersion </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">long</span><span class=\"token plain\"> processedEventCount </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">long</span><span class=\"token plain\"> lastProcessedEpochMs </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">long</span><span class=\"token plain\"> alertThreshold </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1000</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">   </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">   </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// getters/setters omitted for brevity</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<hr>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"2-implement-the-stateful-function\">2. Implement the Stateful Function<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#2-implement-the-stateful-function\" class=\"hash-link\" aria-label=\"Direct link to 2. Implement the Stateful Function\" title=\"Direct link to 2. Implement the Stateful Function\" translate=\"no\">​</a></h3>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ThresholdMonitoringFunction</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">implements</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">StreamPipesFunction</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">StateStore</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> stateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token plain\"> state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getFunctionId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"threshold-monitoring-function\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">requiredStreamIds</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">of</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"your-stream-resource-id\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStarted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionContext</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Request typed state store</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">this</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">stateStore </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getStateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Load existing state or use default</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">this</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">state </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> stateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">load</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token keyword\" style=\"font-style:italic\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onEvent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Event</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> streamId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">setProcessedEventCount</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getProcessedEventCount</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">setLastProcessedEpochMs</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">System</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">currentTimeMillis</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">if</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getProcessedEventCount</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;=</span><span class=\"token plain\"> state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getAlertThreshold</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Handle alert once when threshold is reached</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStopped</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// Persist state before shutdown</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        stateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">persist</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"state-persistence-lifecycle\">State Persistence Lifecycle<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#state-persistence-lifecycle\" class=\"hash-link\" aria-label=\"Direct link to State Persistence Lifecycle\" title=\"Direct link to State Persistence Lifecycle\" translate=\"no\">​</a></h2>\n<p>The persistence mechanism follows a simple and predictable pattern:</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"startup\">Startup<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#startup\" class=\"hash-link\" aria-label=\"Direct link to Startup\" title=\"Direct link to Startup\" translate=\"no\">​</a></h3>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">state </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> stateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">load</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token keyword\" style=\"font-style:italic\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ProcessingState</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></div></code></pre></div></div>\n<ul>\n<li class=\"\">If persisted state exists → it is restored</li>\n<li class=\"\">If not → the provided default object is used</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"runtime\">Runtime<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#runtime\" class=\"hash-link\" aria-label=\"Direct link to Runtime\" title=\"Direct link to Runtime\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\">State is modified in memory during <code>onEvent</code></li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"shutdown\">Shutdown<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#shutdown\" class=\"hash-link\" aria-label=\"Direct link to Shutdown\" title=\"Direct link to Shutdown\" translate=\"no\">​</a></h3>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">stateStore</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">persist</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">state</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><br></div></code></pre></div></div>\n<ul>\n<li class=\"\">The current state is stored before the service stops</li>\n</ul>\n<p>After a restart, the function continues with the restored values.</p>\n<p>No external database setup.\nNo manual serialization logic.\nNo additional infrastructure required.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"backward-compatibility\">Backward Compatibility<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#backward-compatibility\" class=\"hash-link\" aria-label=\"Direct link to Backward Compatibility\" title=\"Direct link to Backward Compatibility\" translate=\"no\">​</a></h2>\n<p>Stateful behavior is <strong>opt-in</strong>.</p>\n<p>Existing functions:</p>\n<ul>\n<li class=\"\">Continue to work unchanged</li>\n<li class=\"\">Require no migration</li>\n<li class=\"\">Remain fully stateless unless <code>getStateStore(...)</code> is used</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion--feedback\">Conclusion &amp; Feedback<a href=\"https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/#conclusion--feedback\" class=\"hash-link\" aria-label=\"Direct link to Conclusion &amp; Feedback\" title=\"Direct link to Conclusion &amp; Feedback\" translate=\"no\">​</a></h2>\n<p>Functions and state persistence are currently available in <strong>developer preview</strong>, and the API may evolve.</p>\n<p>We are open to feedback from developers, if you try out stateful functions, let us know your thoughts and suggestions.</p>",
            "url": "https://streampipes.apache.org/blog/2026/02/23/_streampipes-functions/",
            "title": "Persistent State for StreamPipes Functions",
            "summary": "With the introduction of StreamPipes Functions, Apache StreamPipes provides a lightweight way to attach fixed runtime logic to existing streams — without creating a full pipeline element.",
            "date_modified": "2026-02-23T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/",
            "content_html": "<p>A lot of teams start with the same three tools: Telegraf collects metrics, InfluxDB stores them, Grafana charts them. We used them ourselves before StreamPipes existed, and they are still a good choice for what they do. This post is about what the stack covers, what you tend to build around it over time, and where StreamPipes fits in, including the setup where StreamPipes writes into the same InfluxDB.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-the-stack-does-well\">What the stack does well<a href=\"https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/#what-the-stack-does-well\" class=\"hash-link\" aria-label=\"Direct link to What the stack does well\" title=\"Direct link to What the stack does well\" translate=\"no\">​</a></h2>\n<p>Telegraf has input plugins for OPC UA, Modbus, MQTT, SNMP and hundreds of other sources, and output plugins for InfluxDB and many other databases. InfluxDB is a time-series database with retention policies and a query language built for time-based analysis. Grafana is the standard for charting time-series data, with alerting and a large ecosystem of data sources and panels. If the task is \"collect these metrics and chart them\", the three tools do it with little effort, and all of them are open source.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-you-build-around-it\">What you build around it<a href=\"https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/#what-you-build-around-it\" class=\"hash-link\" aria-label=\"Direct link to What you build around it\" title=\"Direct link to What you build around it\" translate=\"no\">​</a></h2>\n<p>The stack has no shared model of what a stream is. Field names, units and types are conventions in Telegraf configuration files, repeated per source. There is no event preview while configuring a source, no catalog of streams, and no place where a line or machine is modelled so that its data can be found from the asset. Processing is limited to Telegraf's processor plugins and database-side queries; reacting to a live event, for example detecting a trend and notifying a team, means another component such as Kapacitor, Grafana alert rules or custom code. Users and permissions exist in Grafana, not across the pipeline. Extending the stack means writing Telegraf plugins in Go and deploying new agents.</p>\n<p>None of this is a flaw. The stack is a set of focused tools, and teams with enough engineering time assemble them into a platform. The point is that the assembly is yours to do and to maintain.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-streampipes-adds\">What StreamPipes adds<a href=\"https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/#what-streampipes-adds\" class=\"hash-link\" aria-label=\"Direct link to What StreamPipes adds\" title=\"Direct link to What StreamPipes adds\" translate=\"no\">​</a></h2>\n<p>StreamPipes is that platform, already assembled. Adapters connect sources with a guided setup that shows incoming events and lets you set names, units and metadata once. The resulting typed streams drive pipelines that filter, enrich, detect and route in real time, with processors and sinks installed at runtime and validated against the schema. Datasets keep history with retention and export. Charts and dashboards are built on datasets, and assets and sites make them discoverable per machine. Roles, groups, permissions, single sign-on and an audit log cover the whole platform. Python and Java clients and an SDK extend it.</p>\n<p>The storage underneath is a time-series database, and one of the included sinks writes to InfluxDB. Grafana can keep charting the data it already has, while StreamPipes handles connectivity, processing, context and history.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"side-by-side\">Side by side<a href=\"https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/#side-by-side\" class=\"hash-link\" aria-label=\"Direct link to Side by side\" title=\"Direct link to Side by side\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>Topic</th><th>Telegraf, InfluxDB, Grafana</th><th>Apache StreamPipes</th></tr></thead><tbody><tr><td>Connect a source</td><td>Telegraf input plugin, configured in files</td><td>Adapter with guided setup and event preview</td></tr><tr><td>Schema, units, metadata</td><td>Conventions per configuration</td><td>Typed streams, set once, shared by all features</td></tr><tr><td>Real-time processing</td><td>Processor plugins, external alerting</td><td>Pipelines with processors and sinks, Functions</td></tr><tr><td>History</td><td>InfluxDB retention policies</td><td>Datasets with retention, archival and export</td></tr><tr><td>Visualization</td><td>Grafana</td><td>Built-in charts and dashboards; Grafana via InfluxDB sink</td></tr><tr><td>Asset context</td><td>Not modelled</td><td>Assets and sites</td></tr><tr><td>Access control and audit</td><td>Grafana users and teams</td><td>Platform-wide roles, groups, SSO, audit log</td></tr><tr><td>Extensibility</td><td>Go plugins</td><td>SDK for adapters, processors and sinks; Java and Python Functions</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"choosing\">Choosing<a href=\"https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/#choosing\" class=\"hash-link\" aria-label=\"Direct link to Choosing\" title=\"Direct link to Choosing\" translate=\"no\">​</a></h2>\n<p>Keep the stack if what you need is metrics and charts, your team is happy assembling tools, and Grafana is already the house standard. Use StreamPipes when the sources are industrial, when several people need a shared and governed view of the data, and when real-time processing and history should come out of one platform. The two meet at InfluxDB: StreamPipes can feed it, and Grafana can read it. The <a class=\"\" href=\"https://streampipes.apache.org/docs/quick-start-guide/\">quickstart</a> takes about ten minutes.</p>",
            "url": "https://streampipes.apache.org/blog/2026/01/20/streampipes-vs-telegraf-influxdb-grafana/",
            "title": "Apache StreamPipes compared with Telegraf, InfluxDB and Grafana",
            "summary": "Telegraf, InfluxDB and Grafana are a well-worn path for collecting and charting machine data. Where that path ends, and how StreamPipes relates to it.",
            "date_modified": "2026-01-20T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "comparison"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/12/15/_release-098/",
            "content_html": "<p>Apache StreamPipes 0.98.0 is a major step forward in the evolution of the platform, delivering <strong>powerful dashboard\nenhancements, extended OPC UA capabilities, improved security and authentication</strong>, and a large set of <strong>UX and\narchitectural refinements</strong>.</p>\n<p>This release focuses on consolidating visualization and dashboard functionality, improving operational transparency, and\nmodernizing the underlying architecture. Highlights include <strong>dashboard cloning and kiosk mode</strong>, <strong>new aggregation\nfunctions</strong>, <strong>enhanced OPC UA authentication and certificate handling</strong>, <strong>file logging support</strong>, and a <strong>modernized\nUI</strong>.</p>\n<p>In total, this release closes around 100 issues across enhancements, bug fixes, and maintenance tasks.</p>\n<p>Read on to discover what’s new in StreamPipes 0.98.0!</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"industrial-connectivity--opc-ua\">Industrial Connectivity &amp; OPC-UA<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#industrial-connectivity--opc-ua\" class=\"hash-link\" aria-label=\"Direct link to Industrial Connectivity &amp; OPC-UA\" title=\"Direct link to Industrial Connectivity &amp; OPC-UA\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"redesign-of-the-adapter-creation-page\">Redesign of the adapter creation page<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#redesign-of-the-adapter-creation-page\" class=\"hash-link\" aria-label=\"Direct link to Redesign of the adapter creation page\" title=\"Direct link to Redesign of the adapter creation page\" translate=\"no\">​</a></h3>\n<p>StreamPipes Connect is the central interface to connect a wide variety of industrial protocols with Apache StreamPipes.\nIn this release, a new overview page simplifies selection of appropriate adapters, taking less space and allowing users\nto get a better overview over available connectors.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/adapter-selection.png\" alt=\"Excel export\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"opc-ua-x509-authentication--certificate-management\">OPC UA X.509 Authentication &amp; Certificate Management<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#opc-ua-x509-authentication--certificate-management\" class=\"hash-link\" aria-label=\"Direct link to OPC UA X.509 Authentication &amp; Certificate Management\" title=\"Direct link to OPC UA X.509 Authentication &amp; Certificate Management\" translate=\"no\">​</a></h3>\n<p>Support for OPC-UA security is greatly enhanced in 0.98.0.\nWe added a new authentication option that supports <strong>X.509 user authentication</strong>. Users can now directly upload their\nX.509 certificates which are securely stored within StreamPipes.</p>\n<p>For encrypted communication, we also added enterprise features to handle OPC-UA certificates.\nUntil now, certificates had to be managed through environment variables. In the new release, server certificates can be\n<strong>centrally managed</strong> from the user interface, simplifying secure deployments.\nIn case a non-trusted certificate is provided by the OPC-UA server, the certificate is stored in the StreamPipes core\nfor manual approval. In the settings menu, admins can explicitly trust or reject a given certificate.\nThe UI view also contains extended certificate information, making it easy to get an overview of all OPC-UA certificates\nthat are currently used.</p>\n<p>Version 0.98.0 also supports more OPC-UA data types such as better support of <strong>ExtensionObjects</strong>, allowing more\ncomplex OPC-UA data structures to be processed.</p>\n<p>These improvements strengthen StreamPipes as a secure and enterprise-ready IIoT integration platform.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/opc-ua-x509.png\" alt=\"OPC-UA X.509 User Authentication   \">\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/opc-ua-certificate.png\" alt=\"Certificate approval\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"other-improvements\">Other improvements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#other-improvements\" class=\"hash-link\" aria-label=\"Direct link to Other improvements\" title=\"Direct link to Other improvements\" translate=\"no\">​</a></h3>\n<p>Minor improvements for other adapters include:</p>\n<ul>\n<li class=\"\">Configurable <strong>wait and lease times</strong> for PLC connectors.</li>\n<li class=\"\">Improved adapter state handling and recovery options.</li>\n<li class=\"\">Better schema guessing and duplicate field handling in OPC-UA adapters.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"dashboards--data-explorer\">Dashboards &amp; Data Explorer<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#dashboards--data-explorer\" class=\"hash-link\" aria-label=\"Direct link to Dashboards &amp; Data Explorer\" title=\"Direct link to Dashboards &amp; Data Explorer\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"harmonized-data-explorer--dashboard-experience\">Harmonized Data Explorer &amp; Dashboard Experience<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#harmonized-data-explorer--dashboard-experience\" class=\"hash-link\" aria-label=\"Direct link to Harmonized Data Explorer &amp; Dashboard Experience\" title=\"Direct link to Harmonized Data Explorer &amp; Dashboard Experience\" translate=\"no\">​</a></h3>\n<p>The consolidation of visualization tools is finished in 0.98.0.\nThe <strong>Chart and Dashboard</strong> views have been further harmonized, ensuring consistent configuration and behavior.\nThe deprecated dashboard has been removed and the new dashboard tool is fully in place. Users can now add any chart\ndirectly to the live dashboard.</p>\n<p>This work lays the foundation for faster innovation and a more consistent visualization experience going forward.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"dashboard-cloning--kiosk-mode\">Dashboard Cloning &amp; Kiosk Mode<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#dashboard-cloning--kiosk-mode\" class=\"hash-link\" aria-label=\"Direct link to Dashboard Cloning &amp; Kiosk Mode\" title=\"Direct link to Dashboard Cloning &amp; Kiosk Mode\" translate=\"no\">​</a></h3>\n<p>Dashboards have received further several long-awaited improvements:</p>\n<ul>\n<li class=\"\"><strong>Dashboard cloning</strong> allows users to quickly duplicate existing dashboards and reuse configurations.</li>\n<li class=\"\"><strong>Kiosk mode</strong> enables distraction-free, full-screen dashboards—ideal for shop floor displays and control rooms.</li>\n<li class=\"\">Improved configuration panel now clearly indicate missing or incomplete dashboard and chart configurations.</li>\n</ul>\n<p>These enhancements significantly simplify dashboard reuse and deployment in operational environments.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-visualizations--chart-improvements\">New Visualizations &amp; Chart Improvements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#new-visualizations--chart-improvements\" class=\"hash-link\" aria-label=\"Direct link to New Visualizations &amp; Chart Improvements\" title=\"Direct link to New Visualizations &amp; Chart Improvements\" translate=\"no\">​</a></h3>\n<p>Several new visualization and charting capabilities were added:\nThe <strong>status heatmap visualization</strong> was enhanced with a dedicated color-mapping component, in the <strong>chart appearance\nsettings</strong>, additional chart-specific configurations were added, including improved heatmap configuration with\ncustomizable min/max values.\nTo improve usability, icons and descriptions were added to the chart type dropdown, making chart selection more\nintuitive.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-aggregation-functions\">New Aggregation Functions<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#new-aggregation-functions\" class=\"hash-link\" aria-label=\"Direct link to New Aggregation Functions\" title=\"Direct link to New Aggregation Functions\" translate=\"no\">​</a></h3>\n<p>The chart view now supports additional aggregation functions:</p>\n<ul>\n<li class=\"\"><strong>MEDIAN</strong></li>\n<li class=\"\"><strong>SPREAD</strong></li>\n<li class=\"\"><strong>STDDEV</strong></li>\n</ul>\n<p>These functions enable more advanced statistical analysis directly within pipelines and the Chart view.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"excel-export\">Excel export<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#excel-export\" class=\"hash-link\" aria-label=\"Direct link to Excel export\" title=\"Direct link to Excel export\" translate=\"no\">​</a></h3>\n<p>Besides CSV and JSON, datasets can now be directly exported to a Microsoft Excel format (xlsx). In addition, Excel\ntemplates can be uploaded that can be used to add any company-specific header data to an Excel export.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/excel-export.png\" alt=\"Excel export\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"security--authentication\">Security &amp; Authentication<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#security--authentication\" class=\"hash-link\" aria-label=\"Direct link to Security &amp; Authentication\" title=\"Direct link to Security &amp; Authentication\" translate=\"no\">​</a></h2>\n<p>Since we aim for enterprise-grade security, we added additional advanced configuration options to integrate Apache\nStreamPipes with 3rd-party authentication providers.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"oauth--external-authentication-improvements\">OAuth &amp; External Authentication Improvements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#oauth--external-authentication-improvements\" class=\"hash-link\" aria-label=\"Direct link to OAuth &amp; External Authentication Improvements\" title=\"Direct link to OAuth &amp; External Authentication Improvements\" translate=\"no\">​</a></h3>\n<p>Security and identity management received several upgrades.</p>\n<p><strong>External role assignment</strong> is now supported in the OAuth configurations. Besides default roles, users can now be\nassigned their roles directly from an external authentication service.\nTo further increase flexibility, StreamPipes-internal roles and groups can be assigned an <strong>alternate ID</strong>, which can be\nused to map external role names to StreamPipes roles and groups.</p>\n<p><strong>OAuth and OpenID configurations</strong> are now loaded at startup time, so that invalid settings are detected earlier upon\nstartup.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"user-management-enhancements\">User Management Enhancements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#user-management-enhancements\" class=\"hash-link\" aria-label=\"Direct link to User Management Enhancements\" title=\"Direct link to User Management Enhancements\" translate=\"no\">​</a></h3>\n<p>User transparency was improved with:</p>\n<ul>\n<li class=\"\">Tracking and displaying <strong>user creation date</strong> and <strong>last login date</strong> in the user configuration.</li>\n<li class=\"\">Optional <strong>terms acknowledgment</strong>, allowing organizations to enforce acceptance of usage terms.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ux--ui-improvements\">UX &amp; UI Improvements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#ux--ui-improvements\" class=\"hash-link\" aria-label=\"Direct link to UX &amp; UI Improvements\" title=\"Direct link to UX &amp; UI Improvements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"modernized-ui-with-material-3\">Modernized UI with Material 3<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#modernized-ui-with-material-3\" class=\"hash-link\" aria-label=\"Direct link to Modernized UI with Material 3\" title=\"Direct link to Modernized UI with Material 3\" translate=\"no\">​</a></h3>\n<p>The StreamPipes UI has been upgraded to <strong>Material Design 3</strong>, delivering a cleaner, more modern look and feel.\nAdditional UI improvements include:</p>\n<ul>\n<li class=\"\">Broader use of design tokens so that theming becomes easier for external developers.</li>\n<li class=\"\">Panel resize components for flexible layouts.</li>\n<li class=\"\">Improved breadcrumb navigation in dashboards.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-becomes-multilingual\">StreamPipes becomes multilingual<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#streampipes-becomes-multilingual\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes becomes multilingual\" title=\"Direct link to StreamPipes becomes multilingual\" translate=\"no\">​</a></h3>\n<p>Release 0.98.0 starts to add internationalization features to Apache StreamPipes.\nWhile this will be a greater effort spanning multiple releases, this new release lays the groundwork for a completely\nlocalized Apache StreamPipes experience.</p>\n<p>As a first feature, we've localized most parts of the UI to the german language. More languages will follow in the\nfuture - if you are willing to help us translate StreamPipes to more languages, let us know!</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/i18n.png\" alt=\"Localized StreamPipes version in German\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"actions-menu\">Actions menu<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#actions-menu\" class=\"hash-link\" aria-label=\"Direct link to Actions menu\" title=\"Direct link to Actions menu\" translate=\"no\">​</a></h3>\n<p>To ensure a consistent design and a clean, streamlined look and feel, all data tables across StreamPipes now use a\nunified actions menu. Instead of displaying multiple action buttons inline, available actions are grouped under a\nthree-dot menu. Simply hover over the icon to reveal the actions for a given resource, making tables easier to scan\nwhile keeping all functionality readily accessible.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-12-15/actions-menu.png\" alt=\"New actions menu\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"developer-experience\">Developer experience<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#developer-experience\" class=\"hash-link\" aria-label=\"Direct link to Developer experience\" title=\"Direct link to Developer experience\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"migration-to-the-new-data-processor-api\">Migration to the New Data Processor API<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#migration-to-the-new-data-processor-api\" class=\"hash-link\" aria-label=\"Direct link to Migration to the New Data Processor API\" title=\"Direct link to Migration to the New Data Processor API\" translate=\"no\">​</a></h3>\n<p>The migration to the <strong>new Data Processor API</strong> continues, improving consistency and performance across pipeline\nelements.\nAs part of this effort:</p>\n<ul>\n<li class=\"\">The legacy <code>StreamPipesDataProcessor</code> and <code>StreamPipesDataSink</code> APIs are now <strong>deprecated</strong>.</li>\n<li class=\"\">The Flink-based wrapper has also been deprecated and will be removed in a future release.</li>\n</ul>\n<p>Developers are encouraged to migrate to the new APIs to ensure long-term compatibility.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"custom-theming\">Custom theming<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#custom-theming\" class=\"hash-link\" aria-label=\"Direct link to Custom theming\" title=\"Direct link to Custom theming\" translate=\"no\">​</a></h3>\n<p>With the upgrade of the design system, we changed the way how the StreamPipes UI can be customized with company-specific\ncolor settings.\nSettings that can be used for custom theming have been isolated in two files (<code>_custom-variables.scss</code> and <code>_theme-colors.scss</code>).\nWe encourage developers to investigate the modified prebuild script and the two scss files to generate individual\ntheming files.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"breaking-change\">Breaking Change<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#breaking-change\" class=\"hash-link\" aria-label=\"Direct link to Breaking Change\" title=\"Direct link to Breaking Change\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"default-messaging-system-switched-to-nats-\">Default Messaging System Switched to NATS 💣<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#default-messaging-system-switched-to-nats-\" class=\"hash-link\" aria-label=\"Direct link to Default Messaging System Switched to NATS 💣\" title=\"Direct link to Default Messaging System Switched to NATS 💣\" translate=\"no\">​</a></h3>\n<p>The default <code>docker-compose</code> setup in the <strong>installer directory</strong> now uses <strong>NATS</strong> instead of Apache Kafka for internal\nmessaging.</p>\n<p>⚠️ <strong>Important:</strong><br>\n<!-- -->This change only affects users who are updating from a previous installation.<br>\n<!-- -->If your existing StreamPipes instance uses Kafka, continue using the provided <code>docker-compose.kafka.yml</code> file.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"deprecations-️\">Deprecations ⚠️<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#deprecations-%EF%B8%8F\" class=\"hash-link\" aria-label=\"Direct link to Deprecations ⚠️\" title=\"Direct link to Deprecations ⚠️\" translate=\"no\">​</a></h2>\n<p>The following components and features are deprecated and scheduled for removal in future versions:</p>\n<ul>\n<li class=\"\">Deprecated domain property APIs (use semantic type API)</li>\n<li class=\"\">Nested rule creation functionality</li>\n<li class=\"\">Legacy configurable data format APIs</li>\n<li class=\"\">Flink wrapper</li>\n<li class=\"\">IO-Link IFM adapter</li>\n<li class=\"\">NetIO adapter</li>\n</ul>\n<p>Users are encouraged to migrate early to avoid disruption in upcoming releases.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"other-improvements-1\">Other improvements<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#other-improvements-1\" class=\"hash-link\" aria-label=\"Direct link to Other improvements\" title=\"Direct link to Other improvements\" translate=\"no\">​</a></h2>\n<p>As usual, StreamPipes 0.98.0 includes a variety of minor improvements, bug fixes and dependency updates. Users are\nencouraged to update as soon as possible.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion\">Conclusion<a href=\"https://streampipes.apache.org/blog/2025/12/15/_release-098/#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\" translate=\"no\">​</a></h2>\n<p>Apache StreamPipes 0.98.0 delivers major improvements in <strong>dashboarding, OPC UA integration, security, and user\nexperience</strong>, while continuing the architectural cleanup and modernization started in previous releases.</p>\n<p>We would like to thank all contributors and community members who made this release possible.<br>\n<!-- -->As always, we welcome your feedback—join the discussion on <a href=\"https://github.com/apache/streampipes/discussions\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub</a>\nor the <a href=\"mailto:dev@streampipes.apache.org\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">mailing list</a>, and help shape the future of StreamPipes!</p>",
            "url": "https://streampipes.apache.org/blog/2025/12/15/_release-098/",
            "title": "Apache StreamPipes release 0.98.0",
            "summary": "Apache StreamPipes 0.98.0 is a major step forward in the evolution of the platform, delivering powerful dashboard",
            "date_modified": "2025-12-15T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/",
            "content_html": "<p>ThingsBoard comes up in almost every evaluation we hear about, and it deserves to. It is a mature open-source IoT platform with dashboards, rule processing and a plugin model, which on paper sounds like StreamPipes. The difference is the question each tool starts from. ThingsBoard asks: which devices do I have, and what are they reporting? StreamPipes asks: what data is coming from my machines, and what should happen with it? Most of the differences below follow from that.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"thingsboard-in-short\">ThingsBoard in short<a href=\"https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/#thingsboard-in-short\" class=\"hash-link\" aria-label=\"Direct link to ThingsBoard in short\" title=\"Direct link to ThingsBoard in short\" translate=\"no\">​</a></h2>\n<p>ThingsBoard is a device management and telemetry platform. Devices connect over MQTT, CoAP, HTTP or LwM2M, are provisioned and grouped, and send telemetry and attributes. Rule chains react to incoming data with filters, enrichment and actions. Dashboards are built from widgets bound to device telemetry, and a multi-tenant model with customers and users is part of the core. The community edition is open source; some features such as white-labeling, advanced rule nodes and integrations are reserved for the professional edition.</p>\n<p>It fits well when you own a fleet of devices that speak IP protocols, when provisioning and device state are what you manage, and when you need dashboards separated by tenant for different customers.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-in-short\">StreamPipes in short<a href=\"https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/#streampipes-in-short\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes in short\" title=\"Direct link to StreamPipes in short\" translate=\"no\">​</a></h2>\n<p>StreamPipes is an industrial data platform under the Apache Software Foundation. It connects to industrial systems with adapters for OPC UA, Siemens S7, Modbus, PLC4X-based protocols, MQTT, Kafka and more, including an OPC UA node browser and support for OPC UA alarms and events. Every source becomes a typed data stream. Pipelines process streams in real time with validated processors and sinks. Datasets keep history with retention and export. Charts and dashboards are built on datasets, and assets and sites organize everything by plant, line and machine. Users, roles, groups, permissions, single sign-on and an audit log are included, and everything is Apache licensed with no separate edition.</p>\n<p>It fits well when the sources are machines and controllers rather than devices you provision yourself, and when the goal is a data foundation that operators, engineers and developers share.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"side-by-side\">Side by side<a href=\"https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/#side-by-side\" class=\"hash-link\" aria-label=\"Direct link to Side by side\" title=\"Direct link to Side by side\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>Topic</th><th>ThingsBoard</th><th>Apache StreamPipes</th></tr></thead><tbody><tr><td>Primary object</td><td>Device with telemetry and attributes</td><td>Typed data stream from an adapter</td></tr><tr><td>Industrial protocols</td><td>Gateway with OPC UA, Modbus and others</td><td>Native adapters incl. OPC UA browser, S7, Modbus, PLC4X family</td></tr><tr><td>Processing</td><td>Rule chains</td><td>Pipelines with validated processors and sinks, plus Functions</td></tr><tr><td>History</td><td>Telemetry storage per device</td><td>Datasets with retention, archival and export</td></tr><tr><td>Context model</td><td>Devices, assets, customers, tenants</td><td>Assets and sites linked to streams, datasets, dashboards</td></tr><tr><td>Multi-tenancy</td><td>Yes, core concept</td><td>No; one instance per organization</td></tr><tr><td>Licensing</td><td>Community edition open source, professional edition commercial</td><td>Fully Apache licensed</td></tr><tr><td>Extensibility</td><td>Custom rule nodes, widgets, integrations</td><td>SDK for adapters, processors, sinks; Java and Python Functions; UI modules</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"choosing\">Choosing<a href=\"https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/#choosing\" class=\"hash-link\" aria-label=\"Direct link to Choosing\" title=\"Direct link to Choosing\" translate=\"no\">​</a></h2>\n<p>If you manage many devices and need views separated by customer, ThingsBoard is built for exactly that, and the professional edition adds what larger deployments need. If your data comes from machines and controllers, if you want processing, history and dashboards on typed streams, and if you want all of it under one open-source license with no feature tiers, start with StreamPipes.</p>\n<p>The two can also run side by side: a ThingsBoard gateway can forward telemetry to MQTT, and StreamPipes subscribes to it from there. The <a class=\"\" href=\"https://streampipes.apache.org/docs/quick-start-guide/\">quickstart</a> is the fastest way to see the StreamPipes side.</p>",
            "url": "https://streampipes.apache.org/blog/2025/09/16/streampipes-vs-thingsboard/",
            "title": "Apache StreamPipes and ThingsBoard: device platform or data platform?",
            "summary": "ThingsBoard starts from the device, StreamPipes starts from the data. That difference explains most of what each one does well.",
            "date_modified": "2025-09-16T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "comparison"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/",
            "content_html": "<p>Integrating industrial sensors into IIoT architectures often poses significant challenges—especially for IT teams unfamiliar with traditional operational technologies (OT).\nThe complexity of fieldbus protocols, bespoke integrations, and vendor lock-in can create significant barriers to digital transformation on the shop floor.</p>\n<p>This blog post introduces an easy, scalable approach to bridging this IT/OT divide using <strong>IO-Link</strong>, a standardized protocol for industrial sensors, and <strong>Apache StreamPipes</strong>.\nWe'll walk you through a complete setup—from connecting IO-Link sensors to visualizing actionable insights—with a focus on a <strong>vibration sensor</strong> and an <strong>IO-Link Master</strong>.</p>\n<p>Whether you're building condition monitoring systems, predictive maintenance pipelines, or just starting with industrial data analytics, this guide will show how StreamPipes makes it simple to move from raw sensor data to intelligent decisions.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/01-IO-Link-Sensor.png\" alt=\"Image of IO-Link master and VVB001 sensor\" style=\"width:50%;display:block;margin:0 auto\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"why-choose-io-link-sensors\">Why Choose IO-Link Sensors?<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#why-choose-io-link-sensors\" class=\"hash-link\" aria-label=\"Direct link to Why Choose IO-Link Sensors?\" title=\"Direct link to Why Choose IO-Link Sensors?\" translate=\"no\">​</a></h2>\n<p>IO-Link is an increasingly popular choice in modern industrial environments—and for good reason.\nIt enables seamless sensor integration without the headaches of proprietary protocols or specialized wiring.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"benefits-of-io-link-for-iiot\">Benefits of IO-Link for IIoT<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#benefits-of-io-link-for-iiot\" class=\"hash-link\" aria-label=\"Direct link to Benefits of IO-Link for IIoT\" title=\"Direct link to Benefits of IO-Link for IIoT\" translate=\"no\">​</a></h3>\n<p>IO-Link sensors support a wide range of measurements including vibration, temperature, flow, and pressure.\nThanks to IODD (IO Device Description) files, these sensors are interoperable across manufacturers, making configuration fast and reliable.\nWith simple three-wire cabling and support for up to eight sensors via a single IO-Link master, IO-Link dramatically reduces the complexity of sensor installations.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-is-io-link\">What is IO-Link?<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#what-is-io-link\" class=\"hash-link\" aria-label=\"Direct link to What is IO-Link?\" title=\"Direct link to What is IO-Link?\" translate=\"no\">​</a></h3>\n<p>IO-Link is a globally standardized communication protocol (IEC 61131-9) used to connect industrial sensors and actuators.\nUnlike traditional analog or proprietary fieldbus protocols, IO-Link communicates digitally and supports detailed sensor diagnostics, parameterization, and status monitoring.\nIt also integrates easily into IT environments, helping to close the gap between OT data generation and IT-driven analytics.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"oi4-the-key-to-mqtt-based-io-link-integration\">OI4: The Key to MQTT-Based IO-Link Integration<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#oi4-the-key-to-mqtt-based-io-link-integration\" class=\"hash-link\" aria-label=\"Direct link to OI4: The Key to MQTT-Based IO-Link Integration\" title=\"Direct link to OI4: The Key to MQTT-Based IO-Link Integration\" translate=\"no\">​</a></h3>\n<p>To simplify integration with modern IoT platforms, the <strong>Open Industry 4.0 Alliance (OI4)</strong> provides a standardized interface specification for IO-Link over MQTT.\nThis includes well-defined JSON structures, topic hierarchies, and security mechanisms such as TLS encryption and authentication.\nOI4-compliant devices ensure that sensor data can be consumed and interpreted reliably—no matter the vendor.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"use-case-multi-sensor-condition-monitoring\">Use Case: Multi-Sensor Condition Monitoring<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#use-case-multi-sensor-condition-monitoring\" class=\"hash-link\" aria-label=\"Direct link to Use Case: Multi-Sensor Condition Monitoring\" title=\"Direct link to Use Case: Multi-Sensor Condition Monitoring\" translate=\"no\">​</a></h2>\n<p>Let’s consider a typical industrial use case: monitoring the condition of electric motors using vibration, temperature, and pressure sensors.\nThese sensors are connected to a <strong>Hilscher sensorEDGE FIELD</strong> gateway, which publishes all sensor values over MQTT using the OI4 format.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"real-time-insights-with-streampipes\">Real-Time Insights with StreamPipes<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#real-time-insights-with-streampipes\" class=\"hash-link\" aria-label=\"Direct link to Real-Time Insights with StreamPipes\" title=\"Direct link to Real-Time Insights with StreamPipes\" translate=\"no\">​</a></h3>\n<p>In Apache StreamPipes, this data can be ingested using the OI4 adapter and routed through various processing pipelines.\nFor instance, you can configure alerts for high vibration (e.g., <code>aPeak &gt; 8.0 m/s²</code>) and high temperature (<code>&gt; 80°C</code>) to detect early signs of mechanical stress or overheating.\nAdditionally, a rolling average calculation on pressure data helps identify leaks or irregularities.</p>\n<p>This setup not only enables instant notifications via email but also stores the processed data in a timeseries database for long-term trend analysis—reducing the need for manual inspections and improving asset reliability.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"expanding-beyond-vibration\">Expanding Beyond Vibration<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#expanding-beyond-vibration\" class=\"hash-link\" aria-label=\"Direct link to Expanding Beyond Vibration\" title=\"Direct link to Expanding Beyond Vibration\" translate=\"no\">​</a></h3>\n<p>IO-Link sensors can be used across many other domains in industrial environments. Here are a few examples:</p>\n<table><thead><tr><th>Sensor Type</th><th>Use Case</th><th>StreamPipes Processor(s)</th></tr></thead><tbody><tr><td>Flow</td><td>Detect pipe blockages in real-time</td><td>Threshold Alert, Rate of Change</td></tr><tr><td>Distance</td><td>Monitor silo fill levels</td><td>Moving Average, Anomaly Detection</td></tr><tr><td>Pressure</td><td>Predict pump failure from pressure spikes</td><td>Pattern Matching</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"integration-overview-from-hardware-to-streampipes\">Integration Overview: From Hardware to StreamPipes<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#integration-overview-from-hardware-to-streampipes\" class=\"hash-link\" aria-label=\"Direct link to Integration Overview: From Hardware to StreamPipes\" title=\"Direct link to Integration Overview: From Hardware to StreamPipes\" translate=\"no\">​</a></h2>\n<p>Setting up the hardware and data flow is straightforward—even for teams without OT experience.</p>\n<p>After connecting the <strong>VVB001 vibration sensor</strong> to an IO-Link Master, it is automatically detected and begins sending data.\nThis gateway then publishes sensor readings to a local or remote MQTT broker in a structured JSON format, following the OI4 specification.</p>\n<p>Apache StreamPipes, with its OI4 adapter, subscribes to these MQTT topics, automatically infers the data schema, and prepares the events for downstream processing—completely eliminating the need for manual parsing or custom integration scripts.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/02-Architecture-Overview.png\" alt=\"Architectural overview\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-configuration-guide\">StreamPipes Configuration Guide<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#streampipes-configuration-guide\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes Configuration Guide\" title=\"Direct link to StreamPipes Configuration Guide\" translate=\"no\">​</a></h2>\n<p>Setting up the data stream in StreamPipes is quick and intuitive. Here's how it works:</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adding-the-oi4-adapter\">Adding the OI4 Adapter<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#adding-the-oi4-adapter\" class=\"hash-link\" aria-label=\"Direct link to Adding the OI4 Adapter\" title=\"Direct link to Adding the OI4 Adapter\" translate=\"no\">​</a></h3>\n<p>Start by opening the <strong>Connect</strong> section in the StreamPipes UI. From the list of available adapters, choose the <strong>OI4 MQTT Adapter</strong>.\nThis adapter is purpose-built for consuming OI4-compliant MQTT streams, so it comes with built-in support for schema detection and mapping.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/03-Connect.png\" alt=\"OI4 adapter in connect\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"configuring-the-adapter\">Configuring the Adapter<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#configuring-the-adapter\" class=\"hash-link\" aria-label=\"Direct link to Configuring the Adapter\" title=\"Direct link to Configuring the Adapter\" translate=\"no\">​</a></h3>\n<p>In the configuration screen, specify the connection to your MQTT broker. For this use case, the broker runs at <code>tcp://192.168.188.73:1883</code>, with unauthenticated access. Select the desired sensor type (<code>VVB001</code>) and confirm that all available sensors should be included.</p>\n<p>You’ll also need to enter the App ID that identifies the publishing application—in this case, <code>hilscher.com/.../netfield-app-opc-ua-io-link-adapter-1</code>. Once configured, click <em>Next</em>, and StreamPipes will automatically detect the event schema based on the live payloads from the broker.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/04-Configuration-OI4-adapter.png\" alt=\"Configuration of OI4 adapter\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"deep-dive-vvb001-vibration-sensor-data\">Deep Dive: VVB001 Vibration Sensor Data<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#deep-dive-vvb001-vibration-sensor-data\" class=\"hash-link\" aria-label=\"Direct link to Deep Dive: VVB001 Vibration Sensor Data\" title=\"Direct link to Deep Dive: VVB001 Vibration Sensor Data\" translate=\"no\">​</a></h2>\n<p>The VVB001 sensor is an IO-Link-enabled device capable of measuring several key vibration and temperature metrics.\nThese metrics are essential for detecting imbalances, misalignments, and early-stage mechanical wear in rotating equipment.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"key-metrics-explained\">Key Metrics Explained<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#key-metrics-explained\" class=\"hash-link\" aria-label=\"Direct link to Key Metrics Explained\" title=\"Direct link to Key Metrics Explained\" translate=\"no\">​</a></h3>\n<ul>\n<li class=\"\"><strong><code>vRMS</code> (Velocity RMS)</strong>: Indicates the effective vibration velocity over time. Higher values suggest increasing mechanical stress or imbalance.</li>\n<li class=\"\"><strong><code>aPeak</code> (Acceleration Peak)</strong>: Captures the maximum acceleration value in a sampling window. Sudden spikes may point to impacts or misalignment.</li>\n<li class=\"\"><strong><code>aRMS</code> (Acceleration RMS)</strong>: Reflects consistent vibration intensity. Useful for trend analysis and baseline monitoring.</li>\n<li class=\"\"><strong><code>Crest Factor</code></strong>: Calculated as the ratio between peak and RMS acceleration. A rising Crest Factor often signals early-stage bearing damage.</li>\n<li class=\"\"><strong><code>Temperature</code></strong>: Measures the internal temperature of the sensor or its surroundings—crucial for thermal condition monitoring.</li>\n</ul>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"sample-json-payload\">Sample JSON Payload<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#sample-json-payload\" class=\"hash-link\" aria-label=\"Direct link to Sample JSON Payload\" title=\"Direct link to Sample JSON Payload\" translate=\"no\">​</a></h3>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"Temperature\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">37.9</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"sensorId\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"000008740649\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"Crest\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">4</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"vRms\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"aRms\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"aPeak\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"timestamp\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1600599689805</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"preprocessing-in-streampipes\">Preprocessing in StreamPipes<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#preprocessing-in-streampipes\" class=\"hash-link\" aria-label=\"Direct link to Preprocessing in StreamPipes\" title=\"Direct link to Preprocessing in StreamPipes\" translate=\"no\">​</a></h3>\n<p>Before this data can be used for analytics or alerting, it must be scaled and cleaned. For example:</p>\n<ul>\n<li class=\"\"><code>vRMS</code> values need to be multiplied by <strong>0.0001</strong>.</li>\n<li class=\"\"><code>aPeak</code>, <code>aRMS</code>, <code>Temperature</code>, and <code>Crest</code> values are scaled by <strong>0.1</strong>.</li>\n</ul>\n<p>The StreamPipes connect functionality van handle this effortlessly.\nYou can edit the event schema to apply scaling and remove unused fields.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/05-Event-Schema.png\" alt=\"Configuration of OI4 adapter\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"visual-data-exploration\">Visual Data Exploration<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#visual-data-exploration\" class=\"hash-link\" aria-label=\"Direct link to Visual Data Exploration\" title=\"Direct link to Visual Data Exploration\" translate=\"no\">​</a></h2>\n<p>Once the data is flowing, you can use the <strong>Data Explorer</strong> in StreamPipes to monitor sensor metrics in real-time. Line charts help you visualize trends, spikes, and anomalies in vibration and temperature levels.</p>\n<p>Whether you’re fine-tuning processing logic or monitoring asset health, StreamPipes visualizations make it easy to detect anomalies and trends in real time.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/06-Linechart.png\" alt=\"Configuration of OI4 adapter\" style=\"width:70%;display:block;margin:0 auto\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"alerting-with-pipelines\">Alerting with Pipelines<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#alerting-with-pipelines\" class=\"hash-link\" aria-label=\"Direct link to Alerting with Pipelines\" title=\"Direct link to Alerting with Pipelines\" translate=\"no\">​</a></h2>\n<p>With pipelines, you can define rule-based logic to trigger alerts based on sensor values. For example, if the <strong>Crest Factor</strong> exceeds a defined threshold, you can send an email notification to maintenance staff.</p>\n<p>Pipelines are extensible—you can integrate third party tools, store data in databases, or implement predictive analytics using machine learning models.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-06-11/07-Notification-Pipeline.png\" alt=\"Configuration of OI4 adapter\" style=\"width:50%;display:block;margin:0 auto\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion\">Conclusion<a href=\"https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\" translate=\"no\">​</a></h2>\n<p>Apache StreamPipes and IO-Link together offer a highly accessible yet powerful IIoT solution.\nFrom a simple dashboard setup to complex, multi-sensor condition monitoring pipelines, this integration enables IT teams to drive real-time insights from machine data—without needing a background in industrial automation.</p>",
            "url": "https://streampipes.apache.org/blog/2025/06/11/oi4-adapter/",
            "title": "From Sensor to Insight - Rapid IIoT Integration for IO-Link Devices with Apache StreamPipes",
            "summary": "Integrating industrial sensors into IIoT architectures often poses significant challenges—especially for IT teams unfamiliar with traditional operational technologies (OT).",
            "date_modified": "2025-06-11T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/05/20/opc-ua-certificates/",
            "content_html": "<p>With the release of Apache StreamPipes 0.97.0, the OPC UA adapter now supports encrypted communication using\ncertificates, enhancing security for Industrial IoT applications. This guide walks you through generating certificates,\nconfiguring them in StreamPipes, and setting up your OPC UA server for secure communication.</p>\n<p>While an unencrypted security policy is the way most users try when they start testing StreamPipes for their first time,\nproduction-grade scenarios typically require encrypted communication.</p>\n<p>In case you are already using Apache StreamPipes, you might have noticed that the OPC UA adapter now supports encrypted\nsecurity policies:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-05-20/opc-ua-configuration.png\" alt=\"OPC-UA adapter configuration\">\n<p>In this guide, I'll show how to set up a secure connection between your OPC UA server and Apache StreamPipes. This guide\nis intended to be a step-by-step-guide starting from certificate generation to the configuration of the OPC UA adapter\nin StreamPipes.</p>\n<p>I'll show a working example on a local installation using Eclipse Milo as the OPC UA server. The same steps can be\napplied to production systems by integrating certificates into the volume of the extension service. There are other\nways to configure OPC-UA secure connections, but this guide will focus on a complete approach using self-signed\ncertificates for beginners.</p>\n<h1>Prerequisites</h1>\n<ul>\n<li class=\"\">Apache StreamPipes 0.97.0 or newer</li>\n<li class=\"\">An OPC-UA server supporting security policies <code>Sign</code> and <code>Sign &amp; Encrypt</code></li>\n<li class=\"\">OpenSSL installed on your system</li>\n</ul>\n<h1>Generate client certificates</h1>\n<p>When creating a new OPC-UA adapter in Apache StreamPipes, the extension service where the adapter is running in serves\nas the client.\nFirst, we need to create a client certificate for the client. In this example, we'll create a self-signed certificate.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">[req]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">default_bits       = 2048</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">prompt             = no</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">default_md         = sha256</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">req_extensions     = req_ext</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">x509_extensions    = v3_ca</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">distinguished_name = dn</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">[dn]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">CN = stream-pipes-client</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">[req_ext]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">subjectAltName = @alt_names</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">extendedKeyUsage = serverAuth, clientAuth</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">[v3_ca]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">subjectKeyIdentifier = hash</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">basicConstraints = CA:false</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">subjectAltName = @alt_names</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, keyCertSign</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">extendedKeyUsage = serverAuth, clientAuth</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">[alt_names]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">URI.1 = urn:org:apache:streampipes:opcua:client</span><br></div></code></pre></div></div>\n<p>When using a self-signed certificate, it is requried to to provide the CA<!-- -->:false<!-- --> flag under basicConstraints.\nIn addition, note the subject alternative name that later needs to be matched by the application URI of the OPC-UA\nclient.</p>\n<p>The next step is to generate the certificate and import it into a PKCS12 keystore. The keystore is used to store the key\npair we are generating in the first step.</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">openssl req -x509 -nodes -days 365 \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -newkey rsa:2048 \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -keyout client.key \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -out client.crt \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -config cert.conf \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  &amp;&amp; openssl pkcs12 -export \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -in client.crt \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -inkey client.key \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -out client.p12 \\</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  -name streampipes-client</span><br></div></code></pre></div></div>\n<p>When I was asked for a password, I chose <code>streampipes</code>. You can choose any password you like, but make sure to remember\nit, as\nwe will need it in the next step.</p>\n<p>Check that the keystore lists the correct key by executing:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">keytool -list -v -storetype PKCS12 -keystore client.p12</span><br></div></code></pre></div></div>\n<p>You'll see the key you've just generated.</p>\n<h1>Configure StreamPipes to support encrypted connections</h1>\n<p>To enable the OPC UA adapter to use the generated client certificate, we need to provide a few environment variables to\nStreamPipes.</p>\n<p>Here is a list of all environment variables that are available:</p>\n<ul>\n<li class=\"\">SP_OPCUA_SECURITY_DIR (default: /streampipes-security/opcua): This is the directory where the keystore and\ntrusted/rejected server certificates are stored.</li>\n<li class=\"\">SP_OPCUA_KEYSTORE_FILE (default: keystore.pfx): This is the keystore file that contains the client certificate.</li>\n<li class=\"\">SP_OPCUA_KEYSTORE_PASSWORD (default: password): The password for the keystore file.</li>\n<li class=\"\">SP_OPCUA_KEYSTORE_TYPE (default: PKCS12): The type of the keystore file.</li>\n<li class=\"\">SP_OPCUA_KEYSTORE_ALIAS (default: apache-streampipes): The alias of the client certificate in the keystore.</li>\n<li class=\"\">SP_OPCUA_APPLICATION_URI (default: urn:org:apache:streampipes:opcua<!-- -->:client<!-- -->): The application URI of the client\ncertificate.</li>\n</ul>\n<p>We could have made the previous configuration easier by reusing some of the defaults. For learning purposes, we used\nsome other names for the alias and keystore filename.</p>\n<p>In my setup, I've started a local StreamPipes instance. When using Docker, you can add the environment variables to the\nextensions service (e.g., extensions-all-iiot). In my local instance, I just add the emnvironment variables to my IDE\nsettings.</p>\n<p>I add the following variables:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">SP_OPCUA_SECURITY_DIR=/home/user/streampipes-security/opcua</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">SP_OPCUA_KEYSTORE_FILE=client.p12</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">SP_OPCUA_KEYSTORE_PASSWORD=streampipes</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">SP_OPCUA_KEYSTORE_ALIAS=streampipes-client</span><br></div></code></pre></div></div>\n<h1>Connecting to an OPC-UA server</h1>\n<p>For this demo, I'm using the Eclipse Milo OPC UA server. You can download it from <a href=\"https://github.com/digitalpetri/opc-ua-demo-server\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">here</a>.\nOnce the server is running, you can connect to it using the following URL:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">opc.tcp://localhost:62541/milo</span><br></div></code></pre></div></div>\n<p>Now it's time to switch to StreamPipes!</p>\n<p>Go to <strong>Connect</strong> -&gt; <strong>New adapter</strong> -&gt; <strong>OPC UA</strong> and enter the following configuration:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Pull interval 1000</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Incomplete Events Ignore</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Security Mode Sign &amp; Encrypt</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Security Policy Basic256Sha256</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">URL opc.tcp://localhost:62541/milo</span><br></div></code></pre></div></div>\n<p>Defocus the URL input field and wait for the OPC-UA server to connect. After a few seconds, you should see an error message appearing:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-05-20/opcua-connection-error.png\" alt=\"OPC-UA adapter connection error\">\n<p>This is expected, as we haven't added the client certificate to the trusted certificates of the OPC-UA server yet.\nSo we have to let Milo know that the client certificate can be trusted. In my local setup, I need to move the client certificate from the <code>rejected</code> to the <code>trusted/certs</code> folder as seen below:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-05-20/opcua-server-rejected.png\" alt=\"OPC-UA adapter rejected client certificate\">\n<p>So let's try again by clicking <code>Reload</code> in the <code>Available Nodes</code> section of the adapter configuration page.\nWe'll get another error saying that the server certificate is not trusted.\nThis is again expected, as we haven't added the server certificate to the trusted certificates of the OPC-UA client yet.</p>\n<p>To do that, we can have a look at the folder structure under <code>SP_OPC_UA_SECURITY_DIR</code>:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-05-20/opcua-security-dir.png\" alt=\"OPC-UA security directory\">\n<p>Several new folders have been created by the Apache StreamPipes OPC-UA client.\nThe <code>trusted</code> folder contains the trusted server certificates, while the <code>rejected</code> folder contains the rejected server certificates.\nWe'll move the server certificate from the <code>rejected</code> folder to the <code>trusted/certs</code> folder.</p>\n<p>No we'll try again - and this time, we should see the available nodes in the adapter configuration page:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-05-20/opcua-available-nodes.png\" alt=\"OPC-UA adapter available nodes\">\n<p>You'll see the beautiful tree view where you can navigate through all OPC-UA nodes.</p>\n<p>Now you can select the nodes you want to use in your adapter.</p>\n<p>That's it! You've successfully configured the OPC-UA adapter to use encrypted communication with self-signed certificates.</p>",
            "url": "https://streampipes.apache.org/blog/2025/05/20/opc-ua-certificates/",
            "title": "Secure OPC-UA Integration with Apache StreamPipes: A Comprehensive Guide",
            "summary": "With the release of Apache StreamPipes 0.97.0, the OPC UA adapter now supports encrypted communication using",
            "date_modified": "2025-05-20T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/",
            "content_html": "<p>In many manufacturing settings, maintenance is still scheduled at fixed time intervals — often based on past experience rather than actual machine usage.\nThis approach can lead to unnecessary servicing or, worse, unexpected breakdowns.\nA common limitation is that many machines, especially older ones, offer only minimal sensor data, making advanced maintenance strategies seem out of reach.</p>\n<p>However, with Apache StreamPipes, even limited data — such as a simple boolean signal indicating activity — can be leveraged to implement usage-based maintenance.\nIn this blog post, we demonstrate how this is achieved using a real-world example: a packaging machine that processes goods at high throughput.\nYou'll learn how to count machine operations, store event data, visualize usage over time, and trigger notifications when maintenance is due — all with just a few clicks in StreamPipes.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-scenario-packaging-machine-monitoring\">The Scenario: Packaging Machine Monitoring<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#the-scenario-packaging-machine-monitoring\" class=\"hash-link\" aria-label=\"Direct link to The Scenario: Packaging Machine Monitoring\" title=\"Direct link to The Scenario: Packaging Machine Monitoring\" translate=\"no\">​</a></h2>\n<p>Let’s consider a packaging machine that wraps goods into individual packages.\nThe wear and tear on this machine is directly related to the number of items processed.\nHowever, due to the machine’s age, only minimal data is available.</p>\n<p>Currently:</p>\n<ul>\n<li class=\"\">Maintenance occurs at fixed intervals.</li>\n<li class=\"\">These intervals were determined on the basis of the technicians' experience.</li>\n<li class=\"\">There is suspicion that maintenance is done too frequently, leading to unnecessary costs.</li>\n</ul>\n<p>With Apache StreamPipes, we’ll build a pipeline that:</p>\n<ul>\n<li class=\"\">Counts packaging operations in real time.</li>\n<li class=\"\">Stores data for analysis and visualization.</li>\n<li class=\"\">Sends notifications once a maintenance threshold is reached.</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"the-data-a-simple-boolean-signal\">The Data: A Simple Boolean Signal<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#the-data-a-simple-boolean-signal\" class=\"hash-link\" aria-label=\"Direct link to The Data: A Simple Boolean Signal\" title=\"Direct link to The Data: A Simple Boolean Signal\" translate=\"no\">​</a></h2>\n<p>The machine provides a boolean flag — <code>active</code> — which is <code>true</code> when a packaging operation occurs.\nThis flag is streamed using an Apache StreamPipes S7 adapter. The stream also includes a few additional process parameters:</p>\n<table><thead><tr><th>Timestamp</th><th>active</th><th>...</th></tr></thead><tbody><tr><td>1719897720887</td><td>false</td><td>...</td></tr><tr><td>1719897721952</td><td>true</td><td>...</td></tr><tr><td>1719897722952</td><td>true</td><td>...</td></tr><tr><td>...</td><td>...</td><td>...</td></tr></tbody></table>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"part-1-absolute-counter-with-notification\">Part 1: Absolute Counter with Notification<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#part-1-absolute-counter-with-notification\" class=\"hash-link\" aria-label=\"Direct link to Part 1: Absolute Counter with Notification\" title=\"Direct link to Part 1: Absolute Counter with Notification\" translate=\"no\">​</a></h2>\n<p>We’ll begin by building a pipeline that counts how often the machine packages a product and sends an email alert when a predefined threshold is reached.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pipeline-overview\">Pipeline Overview<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#pipeline-overview\" class=\"hash-link\" aria-label=\"Direct link to Pipeline Overview\" title=\"Direct link to Pipeline Overview\" translate=\"no\">​</a></h3>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-30/maintenance-pipeline-one.png\" alt=\"Counting Operations Pipeline\">\n<p><em>A simple StreamPipes pipeline for monitoring the parts produced at the machine</em></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"step-by-step-guide\">Step-by-Step Guide<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#step-by-step-guide\" class=\"hash-link\" aria-label=\"Direct link to Step-by-Step Guide\" title=\"Direct link to Step-by-Step Guide\" translate=\"no\">​</a></h3>\n<ol>\n<li class=\"\">\n<p><strong>Add the Data Source</strong></p>\n<ul>\n<li class=\"\">Drag the data stream of the packaging machine into the pipeline editor.</li>\n</ul>\n</li>\n<li class=\"\">\n<p><strong>Insert the <code>Boolean Counter</code> Processor</strong></p>\n<ul>\n<li class=\"\">Monitors a boolean field and counts transitions (e.g., <code>false → true</code>).</li>\n<li class=\"\"><strong>Configuration:</strong>\n<ul>\n<li class=\"\"><em>Boolean Field:</em> <code>active</code></li>\n<li class=\"\"><em>Flank Parameter:</em> <code>FALSE → TRUE</code></li>\n</ul>\n</li>\n</ul>\n<blockquote>\n<p>The processor emits a new event each time the machine packages an item, incrementing a <code>counter</code> value.</p>\n</blockquote>\n</li>\n<li class=\"\">\n<p><strong>Persist the Count</strong></p>\n<ul>\n<li class=\"\">Add the <strong>Data Lake</strong> sink to store these events for visualization.</li>\n</ul>\n</li>\n<li class=\"\">\n<p><strong>Add a Threshold Alert</strong></p>\n<ul>\n<li class=\"\">Insert the <code>Numerical Filter</code> processor.<!-- -->\n<ul>\n<li class=\"\"><em>Field:</em> <code>counter</code></li>\n<li class=\"\"><em>Filter Operation:</em> <code>&gt;</code></li>\n<li class=\"\"><em>Threshold:</em> <code>100000</code></li>\n</ul>\n</li>\n<li class=\"\">Connect this to the <strong>Email Notification</strong> sink.<!-- -->\n<ul>\n<li class=\"\">Configure recipient, subject, and set the <strong>Silent Period</strong> to avoid spamming the team.</li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"\">\n<p><strong>Visualize in Dashboard</strong></p>\n<ul>\n<li class=\"\">Start the pipeline.</li>\n<li class=\"\">In the dashboard, add an <strong>Indicator Widget</strong> displaying the <code>counter</code> value.</li>\n</ul>\n</li>\n</ol>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-30/maintenance-dashboard.png\" alt=\"Displaying the counting value\">\n<p><em>The live dashboard with an indicator chart showing the current number of goods produced</em></p>\n<p>This setup gives you a live counter of how many products were packaged and notifies the maintenance team when attention is needed.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"part-2-aggregated-counting-over-time\">Part 2: Aggregated Counting Over Time<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#part-2-aggregated-counting-over-time\" class=\"hash-link\" aria-label=\"Direct link to Part 2: Aggregated Counting Over Time\" title=\"Direct link to Part 2: Aggregated Counting Over Time\" translate=\"no\">​</a></h2>\n<p>While a cumulative counter is useful, often it's more insightful to understand how usage varies over time — for example, how many items are processed each day.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"a-time-aggregated-approach\">A Time-Aggregated Approach<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#a-time-aggregated-approach\" class=\"hash-link\" aria-label=\"Direct link to A Time-Aggregated Approach\" title=\"Direct link to A Time-Aggregated Approach\" translate=\"no\">​</a></h3>\n<p>Instead of a total counter, we’ll now generate a single event for each packaging operation and then use the <strong>Data Explorer</strong> to visualize activity per hour or per day.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"alternative-pipeline-using-signal-edge-filter\">Alternative Pipeline Using Signal Edge Filter<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#alternative-pipeline-using-signal-edge-filter\" class=\"hash-link\" aria-label=\"Direct link to Alternative Pipeline Using Signal Edge Filter\" title=\"Direct link to Alternative Pipeline Using Signal Edge Filter\" translate=\"no\">​</a></h3>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-30/maintenance-pipeline-two.png\" alt=\"Count per Time Pipeline\">\n<p><em>Pipeline to recognize when a part is being processed</em></p>\n<p><strong>Step-by-Step:</strong></p>\n<ol>\n<li class=\"\">\n<p>Replace the <code>Boolean Counter</code> with a <strong>Signal Edge Filter</strong> processor.</p>\n<ul>\n<li class=\"\">Filters events based on signal transitions.</li>\n<li class=\"\"><strong>Configuration:</strong>\n<ul>\n<li class=\"\"><em>Boolean Field:</em> <code>active</code></li>\n<li class=\"\"><em>Signal Edge:</em> <code>FALSE → TRUE</code></li>\n<li class=\"\"><em>Delay:</em> <code>0</code></li>\n<li class=\"\"><em>Output Event Selection:</em> <code>First</code></li>\n</ul>\n</li>\n</ul>\n</li>\n<li class=\"\">\n<p>Store the filtered stream in the <strong>Data Lake</strong> sink.</p>\n</li>\n</ol>\n<p>This gives one clean event per packaging operation — ideal for aggregation.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"visualization-in-the-data-explorer\">Visualization in the Data Explorer<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#visualization-in-the-data-explorer\" class=\"hash-link\" aria-label=\"Direct link to Visualization in the Data Explorer\" title=\"Direct link to Visualization in the Data Explorer\" translate=\"no\">​</a></h2>\n<p>Now that we have one event per packaging action, we can analyze the data over time in the Data Explorer.</p>\n<ol>\n<li class=\"\"><strong>Open the Data Explorer</strong></li>\n<li class=\"\"><strong>Table View Configuration:</strong>\n<ul>\n<li class=\"\"><em>Data Source:</em> Select the stream used in the pipeline.</li>\n<li class=\"\"><em>Aggregation:</em> Group by <code>Hour</code> or <code>Day</code>.</li>\n<li class=\"\"><em>Field Aggregation:</em> Use <code>count</code> on any field to count the number of events.</li>\n</ul>\n</li>\n</ol>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-30/maintenance-count-aggregation-table.png\" alt=\"Count per Time in Data Explorer\">\n<ol start=\"3\">\n<li class=\"\"><strong>Bar Chart Visualization:</strong>\n<ul>\n<li class=\"\">Switch to a <strong>Time-Series Chart</strong>.</li>\n<li class=\"\">Select the counted field.</li>\n<li class=\"\">Choose <code>bar</code> from the chart type dropdown.</li>\n</ul>\n</li>\n</ol>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-30/maintenance-count-aggregation-barchart.png\" alt=\"Count per Time in Data Explorer Bar Chart\">\n<p>You now have a clear, time-based view of machine usage. This helps spot trends, detect unusual downtimes, and better plan maintenance.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion\">Conclusion<a href=\"https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\" translate=\"no\">​</a></h2>\n<p>In this post, we’ve shown how even limited sensor data — like a simple boolean signal — can be used to build powerful maintenance logic using Apache StreamPipes. With just a few clicks, you can:</p>\n<ul>\n<li class=\"\">Count operations and trigger maintenance alerts</li>\n<li class=\"\">Store and visualize historical data</li>\n<li class=\"\">Understand machine usage over time with time-based aggregations</li>\n</ul>\n<p>By replacing static maintenance intervals with actual usage insights, you can reduce unnecessary work and improve efficiency — all without needing to retrofit expensive new sensors.</p>",
            "url": "https://streampipes.apache.org/blog/2025/04/30/usage-based-maintanence/",
            "title": "Usage-Based Maintenance with Apache StreamPipes",
            "summary": "In many manufacturing settings, maintenance is still scheduled at fixed time intervals — often based on past experience rather than actual machine usage.",
            "date_modified": "2025-04-30T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/04/28/prompt-processor/",
            "content_html": "<img src=\"https://streampipes.apache.org/img/blog/2025-04-28/prompt-processor-pipeline.png\" alt=\"Prompt Processor in Pipeline\">\n<p>Need a quick sentiment check, a rolling summary, or a safety rule that’s just a bit too fuzzy for SQL?<br>\n<!-- -->With the <strong>Multi-Model Prompt Processor</strong> you can drop the full might of OpenAI, Anthropic, or your own Llama into any\nApache StreamPipes pipeline—no extra code required.</p>\n<p>Below you’ll find:</p>\n<ul>\n<li class=\"\">A quick tour of the options</li>\n<li class=\"\">Five every day use-cases</li>\n<li class=\"\">A hands-on GIF tutorial</li>\n<li class=\"\">Tips on writing prompts that return <strong>only</strong> what you need</li>\n<li class=\"\">A full list of the models that work out of the box</li>\n</ul>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-does-the-processor-do\">What does the processor do?<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#what-does-the-processor-do\" class=\"hash-link\" aria-label=\"Direct link to What does the processor do?\" title=\"Direct link to What does the processor do?\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>Option</th><th>What it controls</th></tr></thead><tbody><tr><td><strong>Model provider / name</strong></td><td>Choose any OpenAI or Anthropic model, or point to a Llama on Ollama.</td></tr><tr><td><strong>Temperature</strong></td><td>0 = repeatable answers, 1 = creative answers.</td></tr><tr><td><strong>History strategy</strong></td><td><em>Stateless</em>, <em>Windowed (N turns)</em>, or <em>Full</em> history.</td></tr><tr><td><strong>Window size</strong></td><td>How many past turns to keep in <em>Windowed</em> mode.</td></tr><tr><td><strong>Multiple input fields</strong></td><td>Combine several event attributes into one user message.</td></tr></tbody></table>\n<p>The processor sends your prompt + current event data to the model, grabs the reply, and writes it to a new field\n<code>llmResponse</code>; ideal when the answer must flow straight into the next processor.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"five-ways-to-use-it\">Five ways to use it<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#five-ways-to-use-it\" class=\"hash-link\" aria-label=\"Direct link to Five ways to use it\" title=\"Direct link to Five ways to use it\" translate=\"no\">​</a></h2>\n<table><thead><tr><th>#</th><th>Scenario</th><th>Prompt idea (few-shot style)</th><th>History</th></tr></thead><tbody><tr><td>1</td><td><strong>Data-quality gate</strong> – flag numbers &gt; 15</td><td>Return WARNING if value &gt; 15 else OK. Example → 12 → OK, 18 → WARNING.</td><td><strong>Stateless</strong></td></tr><tr><td>2</td><td><strong>Rolling minimum</strong> of a sensor</td><td>Pass previousMin + current. “Return the smallest of the two numbers only.”</td><td><strong>Windowed (1)</strong></td></tr><tr><td>3</td><td><strong>Five-tweet sentiment</strong></td><td>Concatenate last 5 tweets. “Return POSITIVE / NEGATIVE / NEUTRAL only.”</td><td><strong>Windowed (5)</strong></td></tr><tr><td>4</td><td><strong>Chat summariser</strong> for support tickets</td><td>System prompt: “Write one-line summary of the whole conversation.”</td><td><strong>Full</strong></td></tr><tr><td>5</td><td><strong>Dynamic threshold helper</strong></td><td>Feed last 10 load values. “Return max(values)*1.1 rounded 0 decimals.”</td><td><strong>Windowed (10)</strong></td></tr></tbody></table>\n<p><em>(Replace the <code>$placeholders$</code> with the actual stream attributes in the mapping dialog.)</em></p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"tutorial--from-stream-to-json-warning\">Tutorial – from stream to JSON warning<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#tutorial--from-stream-to-json-warning\" class=\"hash-link\" aria-label=\"Direct link to Tutorial – from stream to JSON warning\" title=\"Direct link to Tutorial – from stream to JSON warning\" translate=\"no\">​</a></h2>\n<p>Below is a short clip showing the processor in action in a temperature pipeline.<br>\n<!-- -->The prompt forces the model to output a two-field JSON—perfect for machine parsing.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-28/prompt_processor_demo.gif\" alt=\"Animated demo of the prompt processor\">\n<p><strong>Model:</strong> <code>claude-3-5-sonnet-20241022</code><br>\n<strong>Prompt Used:</strong></p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">You are an assistant that ALWAYS replies with a single JSON object</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">containing two string fields: \"status\" and \"message\".</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Rules</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1. If the temperature is strictly greater than 45 °C:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     • \"status\" must be \"WARNING\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     • \"message\" must explain that the temperature is above the safe limit</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">2. Otherwise:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     • \"status\" must be \"OK\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">     • \"message\" must note that the temperature is within the safe range</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">3. Do not output anything except the JSON object.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">### Examples</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Temperature: 50</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">{</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"status\": \"WARNING\",</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"message\": \"Temperature exceeds the 45 °C threshold\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">}</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Temperature: 30</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">{</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"status\": \"OK\",</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"message\": \"Temperature is within the safe range\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">}</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Temperature: 45</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">{</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"status\": \"OK\",</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"message\": \"Temperature is within the safe range\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">}</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Temperature: 60</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">{</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"status\": \"WARNING\",</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  \"message\": \"Temperature exceeds the 45 °C threshold\"</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">}</span><br></div></code></pre></div></div>\n<p>The model now returns either:</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"status\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"WARNING\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"message\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"Temperature exceeds the 45 °C threshold\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>or</p>\n<div class=\"language-json codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-json codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"status\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"OK\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token property\">\"message\"</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"Temperature is within the safe range\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>Nothing else—exactly what we want for downstream processors.</p>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"prompt-writing-tips-for-event-streams\">Prompt writing tips for event streams<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#prompt-writing-tips-for-event-streams\" class=\"hash-link\" aria-label=\"Direct link to Prompt writing tips for event streams\" title=\"Direct link to Prompt writing tips for event streams\" translate=\"no\">​</a></h2>\n<ol>\n<li class=\"\"><strong>State the output format first</strong>: “Reply with OK or WARNING only.”</li>\n<li class=\"\">Give <strong>one or two concrete examples</strong> – LLMs copy patterns.</li>\n<li class=\"\"><strong>End with a clear cue</strong>: “Answer:” or “Output:”.</li>\n<li class=\"\">Keep <em>temperature ≤ 0.3</em> when strict structure matters.</li>\n<li class=\"\">Short replies reduce context size in <em>Windowed</em> / <em>Full</em> modes.</li>\n</ol>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"supported-models\">Supported models<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#supported-models\" class=\"hash-link\" aria-label=\"Direct link to Supported models\" title=\"Direct link to Supported models\" translate=\"no\">​</a></h2>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary><strong>Anthropic models</strong></summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-7-sonnet-20250219</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-5-sonnet-20241022</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-5-haiku-20241022</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-5-sonnet-20240620</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-opus-20240229</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-sonnet-20240229</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-3-haiku-20240307</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-2.1</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">claude-2.0</span><br></div></code></pre></div></div></div></div></details>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary><strong>OpenAI models</strong></summary><div><div class=\"collapsibleContent_i85q\"><div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-3.5-turbo              gpt-3.5-turbo-1106     gpt-3.5-turbo-0125</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-3.5-turbo-16k          gpt-4                  gpt-4-0613</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-4-turbo-preview        gpt-4-1106-preview     gpt-4-0125-preview</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-4-turbo                gpt-4-turbo-2024-04-09 gpt-4-32k</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-4-32k-0613             gpt-4o                 gpt-4o-2024-05-13</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-4o-2024-08-06          gpt-4o-2024-11-20      gpt-4o-mini</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">gpt-4o-mini-2024-07-18     o1                     o1-mini</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">o1-2024-12-17              o1-mini-2024-09-12     o1-preview</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">o1-preview-2024-09-12      o3-mini-2025-01-31</span><br></div></code></pre></div></div></div></div></details>\n<details class=\"details_lb9f alert alert--info details_b_Ee\" data-collapsed=\"true\"><summary><strong>Llama suggestions (Ollama)</strong></summary><div><div class=\"collapsibleContent_i85q\"><p><code>llama3</code>, <code>llama3:8b</code>, <code>llama2</code>, <code>mistral-7b-instruct</code>, or any custom model you have pulled.</p></div></div></details>\n<hr>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"final-thoughts\">Final thoughts<a href=\"https://streampipes.apache.org/blog/2025/04/28/prompt-processor/#final-thoughts\" class=\"hash-link\" aria-label=\"Direct link to Final thoughts\" title=\"Direct link to Final thoughts\" translate=\"no\">​</a></h2>\n<p>Whether you need a lightweight rule engine, live summaries, or just a smarter filter, the Multi-Model Prompt Processor\ndrops straight into your pipeline and starts working within minutes.</p>\n<p>Give it a try, and let us know what you build!</p>",
            "url": "https://streampipes.apache.org/blog/2025/04/28/prompt-processor/",
            "title": "Bringing LLM Power to Every Pipeline – The Multi-Model Prompt Processor",
            "summary": "Need a quick sentiment check, a rolling summary, or a safety rule that’s just a bit too fuzzy for SQL?",
            "date_modified": "2025-04-28T00:00:00.000Z",
            "author": {
                "name": "Grainier Perera",
                "url": "https://github.com/grainier"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/04/09/javascript-processor/",
            "content_html": "<p><strong>Have a use case where none of the existing processors fit?</strong><br>\n<!-- -->Don’t worry—we’ve got just the thing for you.</p>\n<p>The <strong>JavaScript Evaluator Processor</strong> in Apache StreamPipes allows you to define custom event logic with just a few lines of JavaScript. Whether you want to modify values, filter events, or even add stateful logic, this processor empowers you to do just that—without writing a full processing element in Java.</p>\n<p>Let’s take a closer look at how it works, what the configuration options are, and how you can use it in three different ways.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"what-is-the-javascript-evaluator\">What is the JavaScript Evaluator?<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#what-is-the-javascript-evaluator\" class=\"hash-link\" aria-label=\"Direct link to What is the JavaScript Evaluator?\" title=\"Direct link to What is the JavaScript Evaluator?\" translate=\"no\">​</a></h2>\n<p>Sometimes you need to apply custom logic to your data stream. Maybe it's a quick transformation or a complex filter that isn’t supported out of the box. The JavaScript Evaluator Processor is designed exactly for these cases.</p>\n<p>With a simple JavaScript function, you can:</p>\n<ul>\n<li class=\"\">Modify existing fields</li>\n<li class=\"\">Add new fields</li>\n<li class=\"\">Filter out unwanted events</li>\n<li class=\"\">Maintain state across events</li>\n</ul>\n<p>All you need is a little coding and a bit of creativity.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"configuring-the-javascript-processor\">Configuring the JavaScript Processor<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#configuring-the-javascript-processor\" class=\"hash-link\" aria-label=\"Direct link to Configuring the JavaScript Processor\" title=\"Direct link to Configuring the JavaScript Processor\" translate=\"no\">​</a></h2>\n<p>When adding the JavaScript Evaluator to your pipeline, you’ll notice two key configuration sections:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-09/javascript-processor-pipeline.png\" alt=\"Javascript Processor in Pipeline\">\n<ol>\n<li class=\"\"><strong>The JavaScript Function</strong><br>\n<!-- -->This function is triggered once for <em>each incoming event</em>.</li>\n</ol>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-09/javascript-processor-code.png\" alt=\"Javascript Processor Code Editor\">\n<ol start=\"2\">\n<li class=\"\"><strong>The Output Schema</strong><br>\n<!-- -->This defines the structure of your transformed events. It’s important to ensure that the output schema matches what your function returns—otherwise, downstream processors might not be able to validate the events correctly.</li>\n</ol>\n<img src=\"https://streampipes.apache.org/img/blog/2025-04-09/javascript-processor-event-schema.png\" alt=\"Javascript Processor Event Schema Editor\">\n<p>Let’s explore some examples that show different ways to apply custom logic to your event streams using JavaScript.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"example-1-stateless-event-transformation\">Example 1: Stateless Event Transformation<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#example-1-stateless-event-transformation\" class=\"hash-link\" aria-label=\"Direct link to Example 1: Stateless Event Transformation\" title=\"Direct link to Example 1: Stateless Event Transformation\" translate=\"no\">​</a></h2>\n<p>The simplest use case is when you want to modify values in an event.</p>\n<p><strong>Use case:</strong> You want to halve the <code>temperature</code> value of each incoming event.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">process</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token parameter\">event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">temperature</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">temperature</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">/</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">2</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>That’s it! Each event passes through this function, gets modified, and is sent on its way. No extra setup needed.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"example-2-custom-event-filtering\">Example 2: Custom Event Filtering<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#example-2-custom-event-filtering\" class=\"hash-link\" aria-label=\"Direct link to Example 2: Custom Event Filtering\" title=\"Direct link to Example 2: Custom Event Filtering\" translate=\"no\">​</a></h2>\n<p>You don’t always want to forward every event. The JavaScript Evaluator lets you return <code>null</code> (or just omit <code>return</code>) to drop an event.</p>\n<p><strong>Use case:</strong> Only forward events where the <code>temperature</code> is between 50 and 100.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">process</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token parameter\">event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">if</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">temperature</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">50</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&amp;&amp;</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">temperature</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&lt;</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">100</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>With this setup, only \"valid\" events get through. All others are silently ignored. Perfect for quick, custom filtering logic.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"example-3-stateful-logic\">Example 3: Stateful Logic<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#example-3-stateful-logic\" class=\"hash-link\" aria-label=\"Direct link to Example 3: Stateful Logic\" title=\"Direct link to Example 3: Stateful Logic\" translate=\"no\">​</a></h2>\n<p>Need to track information across multiple events? You can wrap your function in an <strong>Immediately Invoked Function Expression (IIFE)</strong> to create persistent variables.</p>\n<p><strong>Use case:</strong> Count how many events have passed through the processor and append that number to each event.</p>\n<div class=\"language-javascript codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-javascript codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token arrow operator\" style=\"color:rgb(137, 221, 255)\">=&gt;</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">let</span><span class=\"token plain\"> count </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">function</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">process</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token parameter\">event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        count </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">+=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token property-access\">count</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> count</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token keyword control-flow\" style=\"font-style:italic\">return</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>This small trick makes it easy to introduce state without needing any external dependencies or full-blown processor development. You can track counts, store intermediate values, or even implement basic alerting.\nJust make sure that any new properties you add to the event, like <code>count</code> in the example, are also included in the output event schema during processor configuration, otherwise the pipeline may fail validation.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"wrap-up\">Wrap-Up<a href=\"https://streampipes.apache.org/blog/2025/04/09/javascript-processor/#wrap-up\" class=\"hash-link\" aria-label=\"Direct link to Wrap-Up\" title=\"Direct link to Wrap-Up\" translate=\"no\">​</a></h2>\n<p>The JavaScript Evaluator is one of the most flexible processors in StreamPipes. Whether you're a beginner or a power user, it lets you:</p>\n<p>✅ Write custom transformations<br>\n<!-- -->✅ Implement simple filters<br>\n<!-- -->✅ Track state between events<br>\n<!-- -->✅ Prototype complex logic—without deploying a new microservice</p>\n<p>So, next time you think <em>\"I wish there was a processor that could...\"</em>, just try the JavaScript Evaluator. Chances are, it can.</p>\n<p>Got a cool use case using this processor? Let us know or share it with the community—we’d love to see what you’re building with Apache StreamPipes!</p>",
            "url": "https://streampipes.apache.org/blog/2025/04/09/javascript-processor/",
            "title": "How to Use the JavaScript Evaluator Processor",
            "summary": "Have a use case where none of the existing processors fit?",
            "date_modified": "2025-04-09T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/",
            "content_html": "<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"introduction\">Introduction<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\" translate=\"no\">​</a></h3>\n<p>Are you excited to explore Apache StreamPipes but find yourself without any sensors to play with?\nOr maybe you're looking to validate StreamPipes for your use case and kick off a Proof of Concept (PoC) but the hardware is not yet available?\nNo worries—the <strong>File Stream Adapter</strong> is here to save the day!</p>\n<p>With the File Stream Adapter, you can upload a file containing sensor data in various formats (JSON, CSV, XML) and replay this data, giving you a hands-on way to dive into StreamPipes.\nIt's not meant for production use, but it's perfect for experimenting with StreamPipes using your own data.</p>\n<p>This blog post will take you on a exciting journey through configuring the <strong>File Stream Adapter</strong> and using it to simulate sensor data streams.</p>\n<div class=\"theme-admonition theme-admonition-info admonition_xJq3 alert alert--info\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 14 16\"><path fill-rule=\"evenodd\" d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"></path></svg></span>info</div><div class=\"admonitionContent_BuS1\"><p>The adapter supports any type of data as long as it contains a <strong>valid timestamp</strong> in the form of a <strong>Unix timestamp in milliseconds</strong>.</p></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapter-configuration\">Adapter Configuration<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#adapter-configuration\" class=\"hash-link\" aria-label=\"Direct link to Adapter Configuration\" title=\"Direct link to Adapter Configuration\" translate=\"no\">​</a></h3>\n<p>Let's break down the configuration options for the <strong>File Stream Adapter:</strong></p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-03-25/adapter_configuration.png\" alt=\"Adapter Configuration\">\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"configuration-options-explained\">Configuration Options Explained<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#configuration-options-explained\" class=\"hash-link\" aria-label=\"Direct link to Configuration Options Explained\" title=\"Direct link to Configuration Options Explained\" translate=\"no\">​</a></h4>\n<ol>\n<li class=\"\"><strong>File:</strong> Choose an existing file or upload a new one.</li>\n<li class=\"\"><strong>Overwrite file time:</strong> If checked, the current time at which the event is triggered is used for the timestamp of the event, regardless of the timestamp value in the file.</li>\n<li class=\"\"><strong>Replay Once:</strong> Decide if the file should be replayed once or continuously until stopped.<!-- -->\n<ul>\n<li class=\"\">Options: <code>yes</code> (file is replayed once), <code>no</code> (file is replayed continuously)</li>\n</ul>\n</li>\n<li class=\"\"><strong>Replay Speed:</strong> Set the frequency of events.<!-- -->\n<ul>\n<li class=\"\">Options: <code>Keep original time</code>, <code>Fastest (Ignore original time)</code>, <code>Speed Up Factor</code></li>\n</ul>\n</li>\n<li class=\"\"><strong>Format:</strong> Choose the format to parse the events.<!-- -->\n<ul>\n<li class=\"\">Options: <code>JSON</code>, <code>CSV</code>, <code>XML</code>, <code>Image</code> (experimental feature)</li>\n</ul>\n</li>\n</ol>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"use-case-create-a-sensor-simulator\">Use Case: Create a Sensor Simulator<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#use-case-create-a-sensor-simulator\" class=\"hash-link\" aria-label=\"Direct link to Use Case: Create a Sensor Simulator\" title=\"Direct link to Use Case: Create a Sensor Simulator\" translate=\"no\">​</a></h3>\n<p>Let's create a simulation data stream using your own sensor data. First, store the sample CSV data in a local file.</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">timestamp,density,mass_flow,sensorId,sensor_fault_flags,temperature,volume_flow</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897720887,41.82,6.306,flowrate01,false,41.9,3.365</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897721952,45.09,9.659,flowrate01,false,43.2,4.103</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897722958,42.84,9.532,flowrate01,true,42.6,3.110</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897723964,49.58,1.929,flowrate01,true,40.3,3.4684</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897724970,41.83,4.173,flowrate01,false,40.7,0.246</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1719897725975,48.11,10.90,flowrate01,false,46.4,5.275</span><br></div></code></pre></div></div>\n<p>To set up the adapter, follow these steps:</p>\n<ol>\n<li class=\"\">Open StreamPipes Connect.</li>\n<li class=\"\">Click on <code>+ New Adapter</code>.</li>\n<li class=\"\">Select the <code>File Stream Adapter</code>.</li>\n<li class=\"\">Enter the following configuration:<!-- -->\n<ul>\n<li class=\"\"><strong>File:</strong> Upload your sample data file.</li>\n<li class=\"\"><strong>Overwrite file time:</strong> Check this box to use the current timestamp instead of the original time of the event in the file.</li>\n<li class=\"\"><strong>Replay Once:</strong> Choose <code>no</code> to create an ongoing data stream.</li>\n<li class=\"\"><strong>Replay Speed:</strong> Select <code>Keep original time</code> to maintain the original event frequency.</li>\n<li class=\"\"><strong>Format:</strong> Pick <code>CSV</code>, set the delimiter as <code>,</code> and check the <code>Header</code> box.</li>\n</ul>\n</li>\n<li class=\"\">Click <code>Next</code> once you've added the correct configuration.</li>\n<li class=\"\">Configure the event schema by editing the <code>timestamp</code> field and selecting <code>Mark as timestamp</code>. Save your changes.</li>\n<li class=\"\">You can add additional meta information to the event schema, but it's not required for this tutorial. Click <code>Next</code> when done.</li>\n<li class=\"\">Enter an <code>Adapter Name</code>.</li>\n<li class=\"\">Check the <code>Persist events</code> box to store the data in the StreamPipes data store.</li>\n<li class=\"\">Click <code>Start Adapter</code>.</li>\n</ol>\n<p>Once configured, you should see the following preview:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-03-25/adapter_started.png\" alt=\"Adapter Preview\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"use-case-persist-csv-file-to-data-lake\">Use Case: Persist CSV File to Data Lake<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#use-case-persist-csv-file-to-data-lake\" class=\"hash-link\" aria-label=\"Direct link to Use Case: Persist CSV File to Data Lake\" title=\"Direct link to Use Case: Persist CSV File to Data Lake\" translate=\"no\">​</a></h3>\n<p>Now, let's store the entire content of the file in the data lake. Once stored, you can analyze it with the <code>Data Explorer</code>. Here’s how to configure the adapter:</p>\n<ul>\n<li class=\"\"><strong>Overwrite file time:</strong> Leave this unchecked to retain the original timestamps.</li>\n<li class=\"\"><strong>Replay Once:</strong> Choose <code>yes</code> to read the file only once.</li>\n<li class=\"\"><strong>Replay Speed:</strong> Select <code>Fastest (Ignore original time)</code> to write data as fast as possible.</li>\n</ul>\n<div class=\"theme-admonition theme-admonition-info admonition_xJq3 alert alert--info\"><div class=\"admonitionHeading_Gvgb\"><span class=\"admonitionIcon_Rf37\"><svg viewBox=\"0 0 14 16\"><path fill-rule=\"evenodd\" d=\"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z\"></path></svg></span>info</div><div class=\"admonitionContent_BuS1\"><p>Ensure the <code>Persist events</code> checkbox is selected to save the data to the data lake during the <code>Start Adapter</code> configuration.</p></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion\">Conclusion<a href=\"https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\" translate=\"no\">​</a></h3>\n<p>In this tutorial, we've explored how to use the File Stream Adapter in Apache StreamPipes to create a simulation data stream and persist CSV data into a data lake.\nThis adapter lets you experiment with StreamPipes' capabilities and explore its functionality using your own data.\nHappy streaming!</p>",
            "url": "https://streampipes.apache.org/blog/2025/03/25/file-stream-adapter/",
            "title": "Explore StreamPipes with Data Simulators!",
            "summary": "Introduction",
            "date_modified": "2025-03-25T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2025/02/15/release-097/",
            "content_html": "<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"introduction\">Introduction<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#introduction\" class=\"hash-link\" aria-label=\"Direct link to Introduction\" title=\"Direct link to Introduction\" translate=\"no\">​</a></h2>\n<p>Apache StreamPipes 0.97.0 brings exciting new features, enhanced security, and significant UX improvements to streamline your IIoT data processing workflows.\nThis release introduces <strong>Adapters &amp; Pipelines as Code</strong>, enabling users to define and deploy StreamPipes resources programmatically using YAML or JSON.\nSecurity enhancements, such as <strong>OPC UA certificate support</strong> and <strong>Kafka SSL/SASL authentication</strong>, improve connectivity and data integrity.\nAdditionally, we have made various <strong>UX improvements</strong>, including an <strong>enhanced Data Explorer</strong> and <strong>asset-based filtering</strong>.</p>\n<p>In total, the new release closes 159 issues including new features, bug fixes and improvements.</p>\n<p>Read on to discover what’s new in StreamPipes 0.97.0!</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapters--pipeline-elements\">Adapters &amp; Pipeline Elements<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#adapters--pipeline-elements\" class=\"hash-link\" aria-label=\"Direct link to Adapters &amp; Pipeline Elements\" title=\"Direct link to Adapters &amp; Pipeline Elements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapter--pipeline-as-code\">Adapter &amp; Pipeline as Code<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#adapter--pipeline-as-code\" class=\"hash-link\" aria-label=\"Direct link to Adapter &amp; Pipeline as Code\" title=\"Direct link to Adapter &amp; Pipeline as Code\" translate=\"no\">​</a></h3>\n<p>StreamPipes now supports managing adapters and pipelines programmatically using compact Json or YAML definitions.\nThese features are ideal for automating deployments, integrating with CI/CD pipelines, and applying infrastructure-as-code practices.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapters-as-code\">Adapters as Code<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#adapters-as-code\" class=\"hash-link\" aria-label=\"Direct link to Adapters as Code\" title=\"Direct link to Adapters as Code\" translate=\"no\">​</a></h4>\n<p>With Adapters as Code, you can define and deploy adapters via a compact description, streamlining the creation of multiple similar adapters and simplifying automation.\nFor example, here's a sample YAML snippet to define an OPC-UA adapter:</p>\n<div class=\"language-yml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yml codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token key atrule\">name</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> My OPC Adapter</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> testadapter</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">description</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> Test</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">appId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> org.apache.streampipes.connect.iiot.adapters.opcua</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">configuration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">opc_host_or_url</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> OPC_URL</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">opc_server_url</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> opc.tcp</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">//localhost</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">62541/milo</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">adapter_type</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> PULL_MODE</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">pulling_interval</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1000</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">access_mode</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> UNAUTHENTICATED</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">available_nodes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"ns=2;s=Leakage Test Station/temperature\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"ns=2;s=Leakage Test Station/pressure\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">schema</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">temperature</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">propertyScope</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> measurement</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">label</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> Temp</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">description</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> Temperature value</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">semanticType</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> http</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">//schema.org/temperature</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">enrich</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">timestamp</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> timestamp</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">transform</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">rename</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">pressure</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> pressure3</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">createOptions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">persist</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean important\" style=\"color:rgb(255, 88, 116)\">true</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">start</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token boolean important\" style=\"color:rgb(255, 88, 116)\">true</span><br></div></code></pre></div></div>\n<p>This approach considerably simplifies the programmatic creation of adapters <a href=\"https://streampipes.apache.org/docs/use-programmatically-create-adapters/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Learn more about Adapters as Code</a></p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pipelines-as-code\">Pipelines as Code<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#pipelines-as-code\" class=\"hash-link\" aria-label=\"Direct link to Pipelines as Code\" title=\"Direct link to Pipelines as Code\" translate=\"no\">​</a></h4>\n<p>Pipelines as Code lets you define end-to-end data flows—from data sources through processors to sinks.\nThis function is ideal for the standardization and automation of pipeline deployments.\nFor example, here’s a sample YAML snippet for a simple pipeline:</p>\n<div class=\"language-yaml codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-yaml codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token key atrule\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> my</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">pipeline</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">name</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">description</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">pipelineElements</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Define pipeline components here</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">type</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> stream     </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Data source</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">ref</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;reference</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Unique reference ID</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;data</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># ID of the stream</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">type</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> processor  </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Data transformation</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">ref</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;reference</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Unique reference ID</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;processor</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># ID of the processor</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">connectedTo</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">     </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Previous pipeline element reference(s)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> &lt;reference</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">configuration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">   </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Processor-specific configurations</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> &lt;configuration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">option</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> </span><span class=\"token key atrule\">type</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> sink       </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Data sink (output)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">ref</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;reference</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Unique reference ID</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;sink</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># ID of the sink</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">connectedTo</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">     </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Previous pipeline element reference(s)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> &lt;reference</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token key atrule\">configuration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">   </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Sink-specific configurations</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">      </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\"> &lt;configuration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">-</span><span class=\"token plain\">option</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token key atrule\">createOptions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token key atrule\">start</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> &lt;true</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">|</span><span class=\"token plain\">false</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># Whether to start the pipeline immediately</span><br></div></code></pre></div></div>\n<p>The code preview of a pipeline has also been added to the <code>Start Pipeline</code> dialog, which has been further improved to make the execution status of pipelines more clear.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/pipeline_as_code_ui.png\" alt=\"Pipeline as code in the UI\">\n<p>This method provides a programmatic interface to deploy and manage pipelines quickly and easily.\n<a href=\"https://streampipes.apache.org/docs/use-programmatically-create-pipelines/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Learn more about Pipelines as Code</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"opc-ua-certificates\">OPC UA Certificates<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#opc-ua-certificates\" class=\"hash-link\" aria-label=\"Direct link to OPC UA Certificates\" title=\"Direct link to OPC UA Certificates\" translate=\"no\">​</a></h3>\n<p>The OPC UA adapter now supports both signed/encrypted and unencrypted communication.\nCertificate provisioning is handled externally via environment variables, following a dedicated security directory layout. Refer to the <a href=\"https://streampipes.apache.org/docs/pe/org.apache.streampipes.connect.iiot.adapters.opcua/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">OPC UA adapter documentation</a> for further details.</p>\n<p><a href=\"https://github.com/apache/streampipes/pull/3354\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/pull/3354</a></p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/opc_ua_configuration.png\" alt=\"OPC UA adapter configuration\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"kafka-avro--certificates\">Kafka Avro &amp; Certificates<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#kafka-avro--certificates\" class=\"hash-link\" aria-label=\"Direct link to Kafka Avro &amp; Certificates\" title=\"Direct link to Kafka Avro &amp; Certificates\" translate=\"no\">​</a></h3>\n<p>The Kafka adapter and sink now support SSL and SASL for enhanced security.\nAdditionally, users can provide custom producer/consumer configurations.\nA new Avro parser has been added along with an input field for specifying the consumer group in the Kafka adapter.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/kafka_configuration.png\" alt=\"Kafka adapter configuration\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-features--deprecations\">New Features &amp; Deprecations<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#new-features--deprecations\" class=\"hash-link\" aria-label=\"Direct link to New Features &amp; Deprecations\" title=\"Direct link to New Features &amp; Deprecations\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"asset-browser\">Asset Browser<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#asset-browser\" class=\"hash-link\" aria-label=\"Direct link to Asset Browser\" title=\"Direct link to Asset Browser\" translate=\"no\">​</a></h3>\n<p>StreamPipes now allows users to model real-world assets and associate them with StreamPipes resources such as adapters, pipelines, and dashboards.\nThese asset mappings enable intuitive filtering across different modules, making it easier to navigate and manage related resources.</p>\n<p>The screenshot below illustrates an example where a StreamPipes instance is configured with two machines and various stations.\nClicking on a machine or station dynamically filters the associated resources in the list on the right.\nThis asset-based filtering is available across all main modules of StreamPipes.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/asset_filter.png\" alt=\"Asset Filtering in StreamPipes\">\n<p>The asset overview panel has been redesigned to provide a more intuitive and user-friendly experience. It is possible to assign labels, locations, and ISA95 types to assets.\nFor each asset, resources such as pipelines, adapters and dashboards can be assigned. The asset overview contains an intuitive overview of all linked resources.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/asset_view.png\" alt=\"Asset View\">\n<p>To manage locations &amp; sites, we extended the configuration menu with additional options to add a custom map layer provider and to configure the map view.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/asset_site_management.png\" alt=\"Asset View\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ux-improvements\">UX improvements<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#ux-improvements\" class=\"hash-link\" aria-label=\"Direct link to UX improvements\" title=\"Direct link to UX improvements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"file-relocation\">File Relocation<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#file-relocation\" class=\"hash-link\" aria-label=\"Direct link to File Relocation\" title=\"Direct link to File Relocation\" translate=\"no\">​</a></h3>\n<p>The file upload configuration has been moved from the top-level navigation to the settings menu, improving the overall structure and clarity of the main navigation.</p>\n<p>This change does not affect file uploads required by adapters or pipeline elements—these configurations remain unchanged.\nFurther, users can still upload files as before via the files configuration section.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/file_upload.png\" alt=\"File upload configuration\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapter-data-preview\">Adapter Data Preview<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#adapter-data-preview\" class=\"hash-link\" aria-label=\"Direct link to Adapter Data Preview\" title=\"Direct link to Adapter Data Preview\" translate=\"no\">​</a></h3>\n<p>Viewing live data streams in the adapter configuration has been improved. By clicking on \"details\", a full-screen view of the data preview is displayed.\nChanging data values are highlighted, so that it is ease to track changes. The Code panel shows the configuration in JSON or YAML format.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/adapter_preview.png\" alt=\"Adapter preview\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"data-explorer-configuration-improvements\">Data Explorer Configuration Improvements<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#data-explorer-configuration-improvements\" class=\"hash-link\" aria-label=\"Direct link to Data Explorer Configuration Improvements\" title=\"Direct link to Data Explorer Configuration Improvements\" translate=\"no\">​</a></h3>\n<p>Configuring data views in the <strong>Data Explorer</strong> is now more intuitive and user-friendly.\nWe have enhanced validation, making it easier to select data sources and specify queries while reducing potential misconfigurations.</p>\n<p>Key improvements include:</p>\n<ul>\n<li class=\"\"><strong>Default Table Visualization</strong>: New data views now default to a table view, minimizing setup effort.</li>\n<li class=\"\"><strong>Improved Time Range Picker</strong>: More flexibility in selecting time ranges, including support for different time ranges per widget in Data Lake dashboards.</li>\n<li class=\"\"><strong>Auto-Refresh for Dashboards</strong>: Live updates are now possible with the new auto-refresh functionality.</li>\n<li class=\"\"><strong>Better Error Messages</strong>: Enhanced feedback when configurations are incorrect to improve usability.</li>\n<li class=\"\"><strong>Custom color coding for pie chart</strong>: In the pie chart, custom colors can be mapped to specific data values.</li>\n<li class=\"\"><strong>Traffic light visualization</strong>: A new traffic light visualization has been added to the Data Explorer.</li>\n</ul>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/data_explorer_configuration.png\" alt=\"Improve configuration for data explorer views\">\n<p>Here is a screenshot of the new traffic light visualization:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/data_explorer_traffic_light.png\" alt=\"Traffic Light chart in the data explorer\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"pipeline-details\">Pipeline Details<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#pipeline-details\" class=\"hash-link\" aria-label=\"Direct link to Pipeline Details\" title=\"Direct link to Pipeline Details\" translate=\"no\">​</a></h3>\n<p>The pipeline details view has been completely remodeled. It now shows the pipeline in full-screen mode, making it easier to view and edit complex pipelines.\nA sidebar contains further information on the pipeline, such as logs, pipeline elements, and execution status.\nIn addition, execution metrics are now intuitively accessible right in the pipeline details view.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/pipeline_preview.png\" alt=\"Pipeline preview\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"deprecation-notice-dashboard\">Deprecation Notice: Dashboard<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#deprecation-notice-dashboard\" class=\"hash-link\" aria-label=\"Direct link to Deprecation Notice: Dashboard\" title=\"Direct link to Deprecation Notice: Dashboard\" translate=\"no\">​</a></h3>\n<p>The current live dashboard feature in StreamPipes is being deprecated and will be removed in a future release.\nAs a replacement, the Data Explorer dashboards has been enhanced with auto-refresh functionality, ensuring a seamless transition for users who rely on real-time data visualization.</p>\n<p>The harmonization of data explorer and live dashboard functionalities will provide a more consistent user experience and will ease the addition of new charts in future version, since all visualizations now rely on a single visualization library.</p>\n<p>We encourage all users to migrate their existing dashboards to the Data Explorer to continue leveraging powerful visualization and analysis capabilities.</p>\n<p>If you think any feature is missing in the data explorer, please let us know!</p>\n<img src=\"https://streampipes.apache.org/img/blog/2025-02-15/deprecated_dashboards.png\" alt=\"Dashboard Deprecation Notice\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"conclusion\">Conclusion<a href=\"https://streampipes.apache.org/blog/2025/02/15/release-097/#conclusion\" class=\"hash-link\" aria-label=\"Direct link to Conclusion\" title=\"Direct link to Conclusion\" translate=\"no\">​</a></h2>\n<p>We appreciate the ongoing support and contributions from our community in making StreamPipes better with each release.\nVersion 0.97.0 brings improvements in usability, security, and automation, helping users to analyze their IIoT data sources.</p>\n<p>As always, we welcome your feedback and suggestions to continue refining and enhancing StreamPipes.\nFeel free to share your thoughts or get involved through <strong>GitHub</strong> or <strong>mailing list</strong>.</p>",
            "url": "https://streampipes.apache.org/blog/2025/02/15/release-097/",
            "title": "Apache StreamPipes release 0.97.0",
            "summary": "Introduction",
            "date_modified": "2025-02-15T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2024/06/13/release-095/",
            "content_html": "<p>We're excited to share the release of StreamPipes 0.95.0, bringing with it a range of bug fixes and new features.\nIn total, the newest release closes over 200 issues.\nThis release doesn't include many large feature drops, we have worked a lot on making small things smoother and improving StreamPipes under the hood.\nAs we continue to work on the 1.0 release of Apache StreamPipes probably later this year, this release features many improvements to the end-user experience and bug fixes.</p>\n<p>Let's delve into the key updates introduced in this release.</p>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapters--pipeline-elements\">Adapters &amp; Pipeline Elements<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#adapters--pipeline-elements\" class=\"hash-link\" aria-label=\"Direct link to Adapters &amp; Pipeline Elements\" title=\"Direct link to Adapters &amp; Pipeline Elements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"improve-deletion-workflow-of-adapters\">Improve deletion workflow of adapters<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#improve-deletion-workflow-of-adapters\" class=\"hash-link\" aria-label=\"Direct link to Improve deletion workflow of adapters\" title=\"Direct link to Improve deletion workflow of adapters\" translate=\"no\">​</a></h3>\n<p>Within StreamPipes 0.93.0 we introduced the possibility to <a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#editing-existing-adapters\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">edit existing adapters</a>.\nThis release improves adapter management by conveniently allowing to delete existing adapters even if they are used in a pipeline.\nWhen deleting a new adapter, a dialog appears which allows users to delete all pipelines which are using the data stream produced by the adapter.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/1936\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/1936</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"enhance-data-lake-schema-management\">Enhance data lake schema management<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#enhance-data-lake-schema-management\" class=\"hash-link\" aria-label=\"Direct link to Enhance data lake schema management\" title=\"Direct link to Enhance data lake schema management\" translate=\"no\">​</a></h3>\n<p>We've added a new option to the data lake sink which provides users more flexibility when writing data to the internal time-series storage.\nUsers can choose between the <code>Update Schema</code> and <code>Extend existing schema</code> options.\nBy choosing <code>Extend schema</code>, it is possible to also see \"old\" data in the data explorer after the schema has changed.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-06-13/data-lake-sink-configuration.png\" style=\"width:70%;margin-left:auto;margin-right:auto\">\n<p><a href=\"https://github.com/apache/streampipes/issues/2252\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2252</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-adapter-open-industry-40-devices\">New Adapter: Open Industry 4.0 devices<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-adapter-open-industry-40-devices\" class=\"hash-link\" aria-label=\"Direct link to New Adapter: Open Industry 4.0 devices\" title=\"Direct link to New Adapter: Open Industry 4.0 devices\" translate=\"no\">​</a></h3>\n<p>A new adapter in 0.95.0 is support for the <a href=\"https://openindustry4.com/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Open Industry 4.0</a> specification over MQTT.\nThe adapter can be used to connect to a variety of devices which support the data format defined in the <a href=\"https://openindustry4.com/fileadmin/Dateien/Downloads/OEC_Development_Guideline_V1.1.1.pdf\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Development Guidelines for Open Edge Computing</a>.</p>\n<p>For instance, the adapter makes it easy to use IO-Link sensors together with an OI4-compatible IO-Link master.</p>\n<p><a href=\"https://github.com/apache/streampipes/pull/2511\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/pull/2511</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-adapters-all-plc4x-protocols-supported-as-adapters\">New Adapter(s): All PLC4X protocols supported as adapters<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-adapters-all-plc4x-protocols-supported-as-adapters\" class=\"hash-link\" aria-label=\"Direct link to New Adapter(s): All PLC4X protocols supported as adapters\" title=\"Direct link to New Adapter(s): All PLC4X protocols supported as adapters\" translate=\"no\">​</a></h3>\n<p>Since our \"sister project\" <a href=\"https://plc4x.apache.org/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Apache PLC4X</a> has introduced a new metadata API for gathering available drivers, StreamPipes 0.95.0 now supports a much larger collection of PLC connectors.\nThe list of newly supported protocols include:</p>\n<ul>\n<li class=\"\">Allen Bradley ETH</li>\n<li class=\"\">BACnet/IP</li>\n<li class=\"\">Beckhoff TwinCat ADS</li>\n<li class=\"\">EthernetIP</li>\n<li class=\"\">Modbus ASCII/RTU/TCP</li>\n</ul>\n<p>The already existing S7 adapter is now also available with additional configuration options.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-06-13/plc-adapter-overview.png\">\n<p>Configurations on protocol and transport level are dynamically resolved from the PLC4X API. This ensures that users now have much greater flexibility when connecting to industrial protocols.</p>\n<p>The screenshot below shows the advanced options panel for Modbus TCP:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-06-13/modbus-configuration.png\">\n<p>The new adapters should be considered a beta feature and we still recommend to use the existing Modbus and S7 adapters until the new adapters have proven their stability.\nMore information on the usage of these new adapters and supported features can also be found on the PLC4X website.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/2632\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2632</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-processor-static-metadata-enrichment\">New Processor: Static Metadata enrichment<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-processor-static-metadata-enrichment\" class=\"hash-link\" aria-label=\"Direct link to New Processor: Static Metadata enrichment\" title=\"Direct link to New Processor: Static Metadata enrichment\" translate=\"no\">​</a></h3>\n<p>We added a new processor to add static metadata (such as sensor ID or location IDs) to any data stream within a pipeline.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/2350\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2350</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-processor-datetime-from-string\">New Processor: Datetime from String<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-processor-datetime-from-string\" class=\"hash-link\" aria-label=\"Direct link to New Processor: Datetime from String\" title=\"Direct link to New Processor: Datetime from String\" translate=\"no\">​</a></h3>\n<p>The new <code>Datetime from String</code> processor allows to convert a datetime string to a timestamp value and lets users conveniently choose the desired target time zone.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-06-13/datetime-from-string.png\">\n<p><a href=\"https://github.com/apache/streampipes/issues/1865\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/1865</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-sink-ms-teams\">New Sink: MS Teams<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-sink-ms-teams\" class=\"hash-link\" aria-label=\"Direct link to New Sink: MS Teams\" title=\"Direct link to New Sink: MS Teams\" translate=\"no\">​</a></h3>\n<p>StreamPipes 0.95.0 comes with a new data sink for Microsoft Teams, which allows to publish notifications from a pipeline to a teams channel using Webhooks.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-06-13/ms-teams-sink.png\">\n<p><a href=\"https://github.com/apache/streampipes/pull/2248\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/pull/2248</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"remove-deprecated-adapters\">Remove deprecated adapters<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#remove-deprecated-adapters\" class=\"hash-link\" aria-label=\"Direct link to Remove deprecated adapters\" title=\"Direct link to Remove deprecated adapters\" translate=\"no\">​</a></h3>\n<p>We removed several outdated adapters that were deprecated in release 0.93.0:</p>\n<ul>\n<li class=\"\">CoindeskBitcoinAdapter</li>\n<li class=\"\">GdeltAdapter</li>\n<li class=\"\">FlicMQTTAdapter</li>\n<li class=\"\">TISensorTag</li>\n<li class=\"\">IexCloudAdapter</li>\n<li class=\"\">OpenSenseMapAdapter</li>\n<li class=\"\">WikipediaAdapter</li>\n</ul>\n<p><a href=\"https://github.com/apache/streampipes/issues/2128\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2128</a></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ux-improvements\">UX improvements<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#ux-improvements\" class=\"hash-link\" aria-label=\"Direct link to UX improvements\" title=\"Direct link to UX improvements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"display-file-types-in-different-colors\">Display file types in different colors<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#display-file-types-in-different-colors\" class=\"hash-link\" aria-label=\"Direct link to Display file types in different colors\" title=\"Direct link to Display file types in different colors\" translate=\"no\">​</a></h3>\n<p>Different file types in the <code>Files</code> overview are now better highlighted by a dedicated color.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/2107\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2107</a></p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"download-button-for-asset--files\">Download button for asset &amp; files<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#download-button-for-asset--files\" class=\"hash-link\" aria-label=\"Direct link to Download button for asset &amp; files\" title=\"Direct link to Download button for asset &amp; files\" translate=\"no\">​</a></h3>\n<p>In the asset and file overview, resources can be now directly downloaded by using a new download button.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/2192\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2192</a>\n<a href=\"https://github.com/apache/streampipes/issues/2074\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2074</a></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-python\">StreamPipes Python<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#streampipes-python\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes Python\" title=\"Direct link to StreamPipes Python\" translate=\"no\">​</a></h2>\n<p>As already mentioned in our <a class=\"\" href=\"https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/\">blog post</a>, we added an example to use an existing <a href=\"https://onnx.ai/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">ONNX</a> model as part of a StreamPipes function.</p>\n<p><a href=\"https://github.com/apache/streampipes/pull/2687\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/pull/2687</a></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"administration--development\">Administration &amp; Development<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#administration--development\" class=\"hash-link\" aria-label=\"Direct link to Administration &amp; Development\" title=\"Direct link to Administration &amp; Development\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"remove-consul-entirely\">Remove Consul entirely<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#remove-consul-entirely\" class=\"hash-link\" aria-label=\"Direct link to Remove Consul entirely\" title=\"Direct link to Remove Consul entirely\" translate=\"no\">​</a></h3>\n<p>Following the replacement of Consul with an internal service registration and discovery mechanism, StreamPipes 0.95.0 also removes Consul from all installation files.</p>\n<p><a href=\"https://github.com/apache/streampipes/issues/2133\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/issues/2133</a></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-apache-streampipes-go-client\">New Apache StreamPipes Go-Client<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#new-apache-streampipes-go-client\" class=\"hash-link\" aria-label=\"Direct link to New Apache StreamPipes Go-Client\" title=\"Direct link to New Apache StreamPipes Go-Client\" translate=\"no\">​</a></h2>\n<p>Apache StreamPipes now includes a new client library for Golang.\nOur first version of the Go client interacts with the StreamPipes API and provides various ways to gather data from StreamPipes.</p>\n<p>Here is an example on the usage of the Go client:</p>\n<div class=\"language-go codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-go codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">package</span><span class=\"token plain\"> main</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"github.com/apache/streampipes/streampipes-client-go/streampipes\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"github.com/apache/streampipes/streampipes-client-go/streampipes/config\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"log\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">/*</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\tHere are some examples of using go client, including outputting the data returned by streams.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\tOnly supports outputting model data</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">*/</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">func</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">main</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\tclientConfig </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:=</span><span class=\"token plain\"> config</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">StreamPipesClientConfig</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\tUrl</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"http://localhost:8030\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\tCredential</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> config</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">StreamPipesApiKeyCredentials</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\t\tUserName</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"&lt;Your-User-Name&gt;\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\t\tApiKey</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\">   </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"&lt;Your-API-Key&gt;\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\t</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\tstreamPipesClient</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> err </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:=</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">NewStreamPipesClient</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">clientConfig</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token keyword\" style=\"font-style:italic\">if</span><span class=\"token plain\"> err </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">!=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">nil</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\tlog</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">Fatal</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">err</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\tdataSeries</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> err </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">:=</span><span class=\"token plain\"> streamPipesClient</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">DataLakeMeasures</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">GetSingleDataSeries</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"measureName\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token keyword\" style=\"font-style:italic\">if</span><span class=\"token plain\"> err </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">!=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">nil</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t\tlog</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">Fatal</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">err</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\tdataSeries</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">Print</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">\t</span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">/*</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\toutput format:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\tThere are 2 pieces of DataSerie in the Dataseries</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\tThe 1 DataSeries</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\ttime                   msg                   test</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:37:09.052Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:37:26.044Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:37:29.007Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\tThe 2 DataSeries</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t    time                   msg                   test</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:38:06.052Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:38:35.044Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t\t\t2024-02-23T13:38:38.007Z   go-client_test   2f4556</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">\t*/</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p><a href=\"https://github.com/apache/streampipes/pull/2437\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">https://github.com/apache/streampipes/pull/2437</a></p>\n<p>First release, are working on more examples and better docs - stay tuned</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"final-remarks\">Final Remarks<a href=\"https://streampipes.apache.org/blog/2024/06/13/release-095/#final-remarks\" class=\"hash-link\" aria-label=\"Direct link to Final Remarks\" title=\"Direct link to Final Remarks\" translate=\"no\">​</a></h2>\n<p>We highly recommend updating to StreamPipes 0.95.0 to take advantage of these new features, bug fixes, and improvements.\nFor more detailed information, please refer to\nthe <a href=\"https://github.com/apache/incubator-streampipes/blob/release/0.95.0/RELEASE_NOTES.md#0950\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">release notes</a>.</p>\n<p>We appreciate your continued support and valuable feedback.\nStreamPipes is continually evolving, and we are dedicated to providing you with a powerful and reliable platform for\nyour IIoT streaming data needs.</p>",
            "url": "https://streampipes.apache.org/blog/2024/06/13/release-095/",
            "title": "Apache StreamPipes release 0.95.0",
            "summary": "We're excited to share the release of StreamPipes 0.95.0, bringing with it a range of bug fixes and new features.",
            "date_modified": "2024-06-13T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/",
            "content_html": "<p>Apache StreamPipes saves the day when it comes to connecting to data sources in the IIoT world. Want to do more with\nyour IIoT data than just analyze it in a dashboard? If so, this blog post is for you! We'll show you how to extract\nhistorical data from StreamPipes, use it to train a machine learning model, bring the model back to StreamPipes using\nONNX, and apply the model to live data.</p>\n<center><img class=\"blog-image\" style=\"max-width:75%\" src=\"https://streampipes.apache.org/img/blog/2024-03-26/prediction-analysis.png\" alt=\"anomaly-detection\"><br></center>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"motivation\">Motivation<a href=\"https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/#motivation\" class=\"hash-link\" aria-label=\"Direct link to Motivation\" title=\"Direct link to Motivation\" translate=\"no\">​</a></h2>\n<p>With this blogpost we want to illustrate how one can easily extract historical IIoT data collected with StreamPipes,\ntrain a machine learning model on this data and bringing the model back to StreamPipes with the interoperability\nstandard <a href=\"https://onnx.ai/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">ONNX</a> to make inference in live data.</p>\n<p>A very common use case in the area of IIoT is the detection of anomalies, so we want to tackle this challenge in this\narticle as well. We will use data generated by\nthe <a href=\"https://streampipes.apache.org/docs/pe/org.apache.streampipes.connect.iiot.adapters.simulator.machine/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Machine Data Simulator</a>\nadapter. More specifically, we will focus on the <code>flowrate</code> data, which consists of various sensor values coming from a\nwater pipe system. Our goal is to keep an eye on the parameter <code>volume_flow</code>, which represents the current volume flow\nin\ncubic meters/second. For this parameter, we want to detect anomalies that could indicate problems such as leaks,\nblockages, etc.</p>\n<p>To get the concerned data, we simply need to create an instance of the machine data simulator and persist the data in\nthe data lake:</p>\n<p><img decoding=\"async\" loading=\"lazy\" src=\"https://raw.githubusercontent.com/apache/streampipes/dev/streampipes-client-python/docs/img/tutorial-preparation.gif\" alt=\"tutorial-preparation\" class=\"img_ev3q\"></p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"set-up--prepare-python-client\">Set Up &amp; Prepare Python Client<a href=\"https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/#set-up--prepare-python-client\" class=\"hash-link\" aria-label=\"Direct link to Set Up &amp; Prepare Python Client\" title=\"Direct link to Set Up &amp; Prepare Python Client\" translate=\"no\">​</a></h2>\n<p>As a prerequisite, we need to install the StreamPipes Python client and all other dependencies,</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">pip install git+https://github.com/apache/streampipes.git#subdirectory=streampipes-client-python</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">pip install scikit-learn==1.4.0 skl2onnx==1.16.0 onnxruntime==1.17.1</span><br></div></code></pre></div></div>\n<p>The next step is to configure and initialize an instance of the client.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> os</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesClient</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">config </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesClientConfig</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">credential_provider </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesApiKeyCredentials</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">os</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">environ</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"BROKER-HOST\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"localhost\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">os</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">environ</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"KAFKA-PORT\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"9094\"</span><span class=\"token plain\">  </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\"># When using Kafka as message broker</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">config </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> StreamPipesClientConfig</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    credential_provider</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">StreamPipesApiKeyCredentials</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        username</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"admin@streampipes.apache.org\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        api_key</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"TOKEN\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    host_address</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"localhost\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    https_disabled</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">True</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    port</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">80</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">client </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> StreamPipesClient</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">client_config</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">config</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>In case you have never worked with the Python client before and have problems to get started,\nplease have a look at\nour <a href=\"https://streampipes.apache.org/docs/docs/python/latest/tutorials/1-introduction-to-streampipes-python-client/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">tutorial</a>.</p>\n<p>If you already have an ONNX model and are only interested in applying it with StreamPipes on a data stream, you can skip\nthe following section.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"model-training-with-historic-data\">Model Training with Historic Data<a href=\"https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/#model-training-with-historic-data\" class=\"hash-link\" aria-label=\"Direct link to Model Training with Historic Data\" title=\"Direct link to Model Training with Historic Data\" translate=\"no\">​</a></h2>\n<p>As said above, the aim of our model is to detect anomalies of the <code>volume_flow</code> parameter. For this task, we will use\n<a href=\"https://en.wikipedia.org/wiki/Isolation_forest\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Isolation Forests</a>. Please note that the focus of the tutorial is not\non training the model, so please be patient even though the training is very simplified and lacks important preparation\nsteps such as standardization.</p>\n<p>As a first step, lets query the <code>flowrate</code> data from the StreamPipes data lake and extract the values of <code>volume_flow</code>\nas a feature:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">flowrate_df </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">dataLakeMeasureApi</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"flow-rate\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">to_pandas</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">X </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> flowrate_df</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"volume_flow\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">values</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">reshape</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">astype</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"float32\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>As a next step, we can already train our model with the historic data:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> sklearn</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">ensemble </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> IsolationForest</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">model </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> IsolationForest</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">contamination</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0.01</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">fit</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">X</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>The <code>contamination</code> parameter models the proportion of outliers in the data. See\nthe <a href=\"https://scikit-learn.org/stable/modules/generated/sklearn.ensemble.IsolationForest.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">scikit-learn</a>\ndocumentation for more information.</p>\n<p>Here you can see how this simple model performs:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-03-26/prediction-analysis.png\">\n<p></p>\n<p>This doesn't look too bad, right? Let's continue by converting our model to the ONNX representation.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> onnxconverter_common </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> FloatTensorType</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> skl2onnx </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> to_onnx</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">model_onnx </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> to_onnx</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    model</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    initial_types</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'input'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> FloatTensorType</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> X</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">shape</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    target_opset</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'ai.onnx.ml'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">3</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">'ai.onnx'</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">15</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">''</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">15</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">with</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">open</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"isolation_forest.onnx\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"wb\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">as</span><span class=\"token plain\"> f</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    f</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">write</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">model_onnx</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">SerializeToString</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"model-inference-with-live-data\">Model Inference with Live Data<a href=\"https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/#model-inference-with-live-data\" class=\"hash-link\" aria-label=\"Direct link to Model Inference with Live Data\" title=\"Direct link to Model Inference with Live Data\" translate=\"no\">​</a></h2>\n<p>Utilizing a pre-trained model within StreamPipes becomes seamless with the ONNX interoperability standard, enabling\neffortless application of your existing model on live data streams.</p>\n<p>Interacting with live data from StreamPipes is facilitated through StreamPipes functions. Below, we'll create a Python\nStreamPipes function that leverages an ONNX model to generate predictions for each incoming event, making the results\naccessible as a data stream within StreamPipes for subsequent steps.</p>\n<p>So let's create an <code>ONNXFunction</code> that is capable of applying a model in ONNX representation to a StreamPipes data\nstream.\nIf you'd like to read more details about how functions are defined, refer\nto <a href=\"https://streampipes.apache.org/docs/docs/python/latest/tutorials/3-getting-live-data-from-the-streampipes-data-stream/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">our tutorial</a>.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> numpy </span><span class=\"token keyword\" style=\"font-style:italic\">as</span><span class=\"token plain\"> np</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> onnxruntime </span><span class=\"token keyword\" style=\"font-style:italic\">as</span><span class=\"token plain\"> rt</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">broker</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">broker_handler </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> get_broker_description</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">streampipes_function </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesFunction</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">utils</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">data_stream_generator </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> create_data_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> RuntimeType</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">utils</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">function_context </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> FunctionContext</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">model</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">resource </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> FunctionDefinition</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> DataStream</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> typing </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> Dict</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> Any</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> List</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ONNXFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">StreamPipesFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">__init__</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> feature_names</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">list</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">str</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> input_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> DataStream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        output_stream </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> create_data_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            name</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"flowrate-prediction\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            attributes</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"is_anomaly\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> RuntimeType</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">BOOLEAN</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">value</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            broker</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">get_broker_description</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">input_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        function_definition </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> FunctionDefinition</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            consumed_streams</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\">input_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">element_id</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">add_output_data_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">output_stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">feature_names </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> feature_names</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">input_name </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">output_name </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">session </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">super</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">__init__</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">function_definition</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">function_definition</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><br></div></code></pre></div></div>\n<p>First, we need to take care about the data stream that is required to send the predictions from our function to\nStreamPipes. Thus, we create a dedicated output data stream which we need to provide with the attributes our event will\nconsist of (a timestamp attribute is always added automatically). This output data stream needs to be registered at the\nfunction definition which is to be passed to the parent class. Lastly, we need to define some instance variables that\nare mainly required for the ONNX runtime.</p>\n<p>Next, we need to ensure that ONNX runtime session is created on start up. Thus, we need to invoke an InferenceSession\nand retrieving the corresponding configuration parameters:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ONNXFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">StreamPipesFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStarted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> FunctionContext</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">session </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> rt</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">InferenceSession</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            path_or_bytes</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"isolation_forest.onnx\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            providers</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">rt</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get_available_providers</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">input_name </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">session</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get_inputs</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">name</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">output_name </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">session</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get_outputs</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">name</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div></code></pre></div></div>\n<p>Lastly, we need to implement the inference logic that is applied to every event.\nIf you have brought up your own model, you need to adapt line <code>10-13</code>:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv codeBlockLinesWithNumbering_o6Pm\" style=\"counter-reset:line-count 0\"><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">ONNXFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">StreamPipesFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">    </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onEvent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> Dict</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">str</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> Any</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> streamId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">str</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        feature_vector </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">for</span><span class=\"token plain\"> feature </span><span class=\"token keyword\" style=\"font-style:italic\">in</span><span class=\"token plain\"> self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">feature_names</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            feature_vector</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">append</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\">feature</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line theme-code-block-highlighted-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        prediction </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">session</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">run</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line theme-code-block-highlighted-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">output_name</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line theme-code-block-highlighted-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">input_name</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> np</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">expand_dims</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">np</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">array</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">feature_vector</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> axis</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">astype</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"float32\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line theme-code-block-highlighted-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        output </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"is_anomaly\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"> </span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">int</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">prediction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">==</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">add_output</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            stream_id</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">function_definition</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get_output_stream_ids</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">            event</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">output</span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\" style=\"display:inline-block\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">def</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStopped</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">self</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">-</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">None</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">:</span><span class=\"token plain\"></span></span><br></div><div class=\"token-line codeLine_lJS_\" style=\"color:#bfc7d5\"><span class=\"codeLineNumber_Tfdd\"></span><span class=\"codeLineContent_feaV\"><span class=\"token plain\">        </span><span class=\"token keyword\" style=\"font-style:italic\">pass</span></span><br></div></code></pre></div></div>\n<p>Having the function code in place, we can start the function with the following:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">registration </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> Registration</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">functions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">function_handler </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> FunctionHandler</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">stream </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    stream</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">for</span><span class=\"token plain\"> stream</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">in</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">dataStreamApi</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">all</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">if</span><span class=\"token plain\"> stream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">name </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">==</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"flow-rate\"</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">0</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">function </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> ONNXFunction</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    feature_names</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">[</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"volume_flow\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">]</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    input_stream</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">stream</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">registration </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> Registration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">registration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">register</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">function</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">function_handler </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> FunctionHandler</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">registration</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">function_handler</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">initializeFunctions</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>We can now access the live values of the prediction in the StreamPipes UI, e.g., in the pipeline editor.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2024-03-26/tutorial-prediction-data-stream.png\">\n<p></p>\n<p>From here on you can further work with the prediction events in StreamPipes, e.g., by sending notifications\nto <a href=\"https://streampipes.apache.org/docs/next/pe/org.apache.streampipes.sinks.notifications.jvm.msteams/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">MS Teams</a>.</p>",
            "url": "https://streampipes.apache.org/blog/2024/03/27/anomaly-detection-with-python-functions/",
            "title": "Anomaly Detection with StreamPipes Functions in Python and ONNX",
            "summary": "Apache StreamPipes saves the day when it comes to connecting to data sources in the IIoT world. Want to do more with",
            "date_modified": "2024-03-27T00:00:00.000Z",
            "author": {
                "name": "Tim Bossenmaier",
                "url": "https://github.com/bossenti"
            },
            "tags": [
                "tutorial"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2023/11/28/release-093/",
            "content_html": "<p><strong></strong></p><div style=\"float:left;padding-right:40px\"><strong>9 minutes to read</strong></div><p></p>\n<p>We're excited to share the release of StreamPipes 0.93.0, bringing with it a range of bug fixes and new features.\nThis release places a strong emphasis on refining the technical foundations of\nStreamPipes, featuring significant changes that set the stage for our major 1.0 release.\nNevertheless, we haven't overlooked the end-user experience and have implemented several enhancements.\nLet's delve into the key updates introduced in this release.</p>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapters--pipeline-elements\">Adapters &amp; Pipeline Elements<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#adapters--pipeline-elements\" class=\"hash-link\" aria-label=\"Direct link to Adapters &amp; Pipeline Elements\" title=\"Direct link to Adapters &amp; Pipeline Elements\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"editing-existing-adapters\">Editing existing adapters<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#editing-existing-adapters\" class=\"hash-link\" aria-label=\"Direct link to Editing existing adapters\" title=\"Direct link to Editing existing adapters\" translate=\"no\">​</a></h3>\n<p>StreamPipes has streamlined the process of modifying existing adapter instances, eliminating the inconvenience users\npreviously faced. In prior versions, altering an adapter required a cumbersome sequence of stopping, deleting, and then\nrecreating the adapter. However, with the introduction of StreamPipes 0.93.0, this arduous process is now a thing of the\npast.</p>\n<p>Users can now seamlessly edit running adapters, and the changes will be applied automatically, obviating the need for\nthe aforementioned manual steps. To guide you through this newfound capability, refer to the below animation,\nwhich demonstrates how to modify an existing adapter.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/edit-adapter-success.gif\" alt=\"animation of editing a running adapter\">\n<br>\n<br>\n<p>While the automatic migration seamlessly handles the majority of cases, there are instances where it may not be\nfeasible. One such scenario arises when an event property, used by a pipeline element, is removed. In such cases,\nStreamPipes proactively alerts users before initiating the adapter update. Following the alert, the system takes\nprecautionary measures by halting the adapter and marking the associated pipeline for review.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/edit-adapter-fail.gif\" alt=\"animation of editing running adapter where migration cannot be performed\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"opc-ua-allows-detailed--asynchronous-browsing\">OPC-UA allows detailed &amp; asynchronous browsing<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#opc-ua-allows-detailed--asynchronous-browsing\" class=\"hash-link\" aria-label=\"Direct link to OPC-UA allows detailed &amp; asynchronous browsing\" title=\"Direct link to OPC-UA allows detailed &amp; asynchronous browsing\" translate=\"no\">​</a></h3>\n<p>We have fully reworked the browsing interface of our OPC-UA adapter.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/opc-ua-demo.gif\" alt=\"demonstration of the new OPC UA capabilities described below\">\n<br>\n<br>\n<p>Now, all you need to do is specify the URL where the OPC UA server is accessible, eliminating the need to concern\nyourself with namespaces or node ids. Once the URL is provided, the adapter effortlessly presents all top-level nodes\nwithin the user interface. You can then navigate through the node tree interactively by clicking on the desired node.</p>\n<p>For every data node, accessing node information is a breeze – simply click on the eye icon. If you wish to subscribe to\na particular node, a straightforward click on the plus icon is all it takes.</p>\n<p>All the nodes you select become integral to the event structure of this adapter, accessible by clicking on  <code>Next</code>. The\nensuing view not only displays the OPC UA status for each node but also allows for the removal of a node with ease,\nespecially if its status is not <code>Good</code>.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/opc-ua-status.png\" alt=\"Screenshot of the OPC UA event view that shows the status codes\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"adapter-for-s7-plcs-supports-array-based-data\">Adapter for S7 PLCs supports array-based data<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#adapter-for-s7-plcs-supports-array-based-data\" class=\"hash-link\" aria-label=\"Direct link to Adapter for S7 PLCs supports array-based data\" title=\"Direct link to Adapter for S7 PLCs supports array-based data\" translate=\"no\">​</a></h3>\n<p>Until now, our S7 PLC adapter lacked the capability to read values structured in arrays. We're pleased to announce that\nthis limitation has been addressed through the introduction of an <code>Advanced</code> register input mode.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/s7-advanced-mode.png\" alt=\"Screenshot of new advanced register input mode for S7 PLC adapter\">\n<br>\n<br>\n<p>This new mode empowers you to configure the registers to be queried in a manner specific to the requirements of our\nunderlying dependency, <a href=\"https://plc4x.apache.org/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">PLC4X</a>. For detailed insights and guidance on the configuration\nprocess, refer to the <a href=\"https://plc4x.apache.org/users/protocols/s7.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">PLC4X S7 documentation</a>.</p>\n<p>When dealing with array definitions, the configuration would resemble the following:</p>\n<div class=\"language-text codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-text codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"># propertyName=%{Memory-Area}{start-address}:{Data-Type}[{array-size}]</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">temperature=%DB3.DB0.0[BOOL]</span><br></div></code></pre></div></div>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-adapter-ifm-iolink\">New Adapter: ifm IOLink<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#new-adapter-ifm-iolink\" class=\"hash-link\" aria-label=\"Direct link to New Adapter: ifm IOLink\" title=\"Direct link to New Adapter: ifm IOLink\" translate=\"no\">​</a></h3>\n<p>The <a href=\"https://www.ifm.com/de/en/product/AL1350\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">IO-Link Master (AL1350)</a> from ifm comes equipped with an IoT interface\ndesigned for transmitting sensor data via MQTT. With the introduction of this adapter, users gain the capability to\neffortlessly incorporate IO-Link sensor data into StreamPipes. This experimental integration empowers users to\neffortlessly connect to data from the ifm sensor VVB001.</p>\n<p>For more details refer to\nthe <a href=\"https://streampipes.apache.org/docs/next/pe/org.apache.streampipes.connect.iiot.adapters.iolink/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">adapter documentation</a>.</p>\n<p>For the integration of additional sensors we are thinking about supporting <a href=\"https://en.wikipedia.org/wiki/IODD\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">IODD</a>.\nYour feedback on these considerations is invaluable to us. If you find the integration of IODD\nfor supporting more sensors within StreamPipes appealing or have insights to share, we welcome your input. Please let us\nknow your thoughts on this potential feature enhancement.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-processor-numeric-rounding\">New Processor: Numeric Rounding<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#new-processor-numeric-rounding\" class=\"hash-link\" aria-label=\"Direct link to New Processor: Numeric Rounding\" title=\"Direct link to New Processor: Numeric Rounding\" translate=\"no\">​</a></h3>\n<p>Introducing our latest data processor, <em>Numeric Rounding</em> , designed to perform rounding operations on numeric values\nwithin an event stream. This processor enables users to select one or more numeric values from their event data,\nspecifying the desired rounding precision and the rounding mode.</p>\n<p>For more details refer to\nthe <a href=\"https://streampipes.apache.org/docs/next/pe/org.apache.streampipes.processors.transformation.jvm.round/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">processor documentation</a>.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ux-improvements\">UX improvements<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#ux-improvements\" class=\"hash-link\" aria-label=\"Direct link to UX improvements\" title=\"Direct link to UX improvements\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"ordered-measurement-units\">Ordered measurement units<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#ordered-measurement-units\" class=\"hash-link\" aria-label=\"Direct link to Ordered measurement units\" title=\"Direct link to Ordered measurement units\" translate=\"no\">​</a></h4>\n<p>In the adapter configuration step, when setting up a transformation rule for an event value, the available units of\nmeasurement are now conveniently organized in alphabetical order for improved accessibility and ease of selection.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"extended-information-for-existing-adapters\">Extended information for existing adapters<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#extended-information-for-existing-adapters\" class=\"hash-link\" aria-label=\"Direct link to Extended information for existing adapters\" title=\"Direct link to Extended information for existing adapters\" translate=\"no\">​</a></h4>\n<p>When accessing the <em>Connect</em> module, a comprehensive list of all existing adapters is presented. Within this view, each\nadapter now includes details about the timestamp of the last event creation and the total count of elements published\nsince startup. This enhancement provides a quick and efficient means to evaluate the health of each adapter.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/adapter-information.png\" alt=\"Screenshot that shows the extended information for existing adapters\">\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"interactive-tutorial-is-back\">Interactive tutorial is back<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#interactive-tutorial-is-back\" class=\"hash-link\" aria-label=\"Direct link to Interactive tutorial is back\" title=\"Direct link to Interactive tutorial is back\" translate=\"no\">​</a></h4>\n<p>Upon initiating a new StreamPipes instance, a dialog prompts users to embark on an interactive tutorial showcasing the\nplatform's key features. We're pleased to announce that this tutorial is now operational again. Enjoy exploring and\ndiscovering the most important functionalities in StreamPipes. Happy learning!</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-11-28/interactive-tutorial.png\" alt=\"Screenshot of the interactive tutorial\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"deployment\">Deployment<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#deployment\" class=\"hash-link\" aria-label=\"Direct link to Deployment\" title=\"Direct link to Deployment\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"kubernetes-deployment\">Kubernetes Deployment<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#kubernetes-deployment\" class=\"hash-link\" aria-label=\"Direct link to Kubernetes Deployment\" title=\"Direct link to Kubernetes Deployment\" translate=\"no\">​</a></h3>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"add-probes-to-the-helm-chart\">Add probes to the Helm chart<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#add-probes-to-the-helm-chart\" class=\"hash-link\" aria-label=\"Direct link to Add probes to the Helm chart\" title=\"Direct link to Add probes to the Helm chart\" translate=\"no\">​</a></h4>\n<p>Integrating readiness, liveness, and startup probes into StreamPipes' Kubernetes containers enhances the system's health\nmonitoring. These probes automatically detect and handle anomalies, significantly improving application availability and\nstability. The readiness probe ensures preparedness, the liveness probe validates ongoing functionality, and the startup\nprobe assesses initialization status, collectively fortifying StreamPipes against potential disruptions.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"rework-the-values-file\">Rework the values file<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#rework-the-values-file\" class=\"hash-link\" aria-label=\"Direct link to Rework the values file\" title=\"Direct link to Rework the values file\" translate=\"no\">​</a></h4>\n<p>We've refined and simplified the values file for our Helm chart, optimizing its structure. Furthermore, we've invested\nin comprehensive documentation for all available options. Check out\nthe <a href=\"https://github.com/apache/streampipes/blob/dev/installer/k8s/README.md\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">README file</a> of our Helm chart for detailed\ninformation on configuration and deployment.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"add-apache-pulsar-to-helm-file\">Add Apache Pulsar to Helm file<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#add-apache-pulsar-to-helm-file\" class=\"hash-link\" aria-label=\"Direct link to Add Apache Pulsar to Helm file\" title=\"Direct link to Add Apache Pulsar to Helm file\" translate=\"no\">​</a></h4>\n<p>In our last release, we've expanded StreamPipes' capabilities to include Apache Pulsar as a supported messaging layer.\nAlongside this enhancement, our Helm chart has now been updated to seamlessly deploy StreamPipes on Kubernetes with\nPulsar\nas the underlying messaging infrastructure.</p>\n<h4 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"monitoring-integration-grafana--prometheus\">Monitoring Integration (Grafana &amp; Prometheus)<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#monitoring-integration-grafana--prometheus\" class=\"hash-link\" aria-label=\"Direct link to Monitoring Integration (Grafana &amp; Prometheus)\" title=\"Direct link to Monitoring Integration (Grafana &amp; Prometheus)\" translate=\"no\">​</a></h4>\n<p>We've now integrated monitoring support for StreamPipes through Prometheus and Grafana, making it seamlessly available\nin both our Kubernetes and Docker deployments. If you're using Kubernetes, we recommend checking out\nour <a href=\"https://github.com/apache/streampipes/tree/dev/installer/k8s#monitoring-common-parameters\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Helm chart</a> for\nstraightforward setup instructions. For Docker users, stay tuned for an upcoming blog post where we'll provide a\nstep-by-step guide on configuring Prometheus and Grafana to monitor StreamPipes effectively.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-deployment-mode-for-first-time-users\">New Deployment mode for first time users<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#new-deployment-mode-for-first-time-users\" class=\"hash-link\" aria-label=\"Direct link to New Deployment mode for first time users\" title=\"Direct link to New Deployment mode for first time users\" translate=\"no\">​</a></h3>\n<p>To simplify onboarding with Apache StreamPipes and demonstrate its capabilities, we've added a quickstart deployment\noption. This docker-compose variant provides users with a pre-configured StreamPipes instance and rich examples. Explore\nit in our <a class=\"\" href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/%22https://streampipes.apache.org/docs/user-guide-for-quickstart/%22/\">user guide</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-python\">StreamPipes Python<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#streampipes-python\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes Python\" title=\"Direct link to StreamPipes Python\" translate=\"no\">​</a></h2>\n<p>Our official Python support for Apache StreamPipes got some small improvements as well.\nNotable among other improvements are especially the following two:</p>\n<ul>\n<li class=\"\">Support for Python 3.11</li>\n<li class=\"\">StreamPipes Python does now also support other protocols than Apache Kafka to interact with live data</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"administration--development\">Administration &amp; Development<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#administration--development\" class=\"hash-link\" aria-label=\"Direct link to Administration &amp; Development\" title=\"Direct link to Administration &amp; Development\" translate=\"no\">​</a></h2>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"email-templates-are-configurable\">Email Templates are configurable<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#email-templates-are-configurable\" class=\"hash-link\" aria-label=\"Direct link to Email Templates are configurable\" title=\"Direct link to Email Templates are configurable\" translate=\"no\">​</a></h3>\n<p>StreamPipes already supported the sending of notifications, such as those for password recovery and account\nregistration, when properly configured. However, in previous versions, the email content was predefined and couldn't be\nadjusted. In this latest release, administrators now have the flexibility to modify the email templates, offering\ngreater customization options for notifications.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"remove-legacy-resources\">Remove legacy resources<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#remove-legacy-resources\" class=\"hash-link\" aria-label=\"Direct link to Remove legacy resources\" title=\"Direct link to Remove legacy resources\" translate=\"no\">​</a></h2>\n<p>In this release, we've eliminated legacy resources that were initially employed for demonstration purposes. As these\nresources are no longer actively supported, we have decided to completely remove them. The affected components include\nthe vehicle simulator and watertank simulator.\nThis removal has led to the discontinuation of the StreamPipes package <code>streampipes-sources</code>.</p>\n<p>Furthermore, we are pleased to announce the forthcoming removal of Consul as an additional dependency required to run\nStreamPipes in the upcoming release. Within this release, we have already implemented the fundamental steps to eliminate\nthe need for Consul. This marks a significant stride towards making StreamPipes a more lightweight platform. It's\ncrucial to highlight that this modification is purely a technical enhancement and will have no impact on the end user\nexperience.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"enable-migrations-for-pipeline-elements\">Enable migrations for pipeline elements<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#enable-migrations-for-pipeline-elements\" class=\"hash-link\" aria-label=\"Direct link to Enable migrations for pipeline elements\" title=\"Direct link to Enable migrations for pipeline elements\" translate=\"no\">​</a></h2>\n<p>We have established a crucial technical foundation to simplify the update process for upcoming versions of StreamPipes.\nIt is now possible to define migrations for adapters, data processors, and data sinks. For a more in-depth understanding\nof how migrations function and how to define them, please refer to\nour <a href=\"https://streampipes.apache.org/docs/extend-sdk-migration/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">documentation</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-homepage\">New Homepage<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#new-homepage\" class=\"hash-link\" aria-label=\"Direct link to New Homepage\" title=\"Direct link to New Homepage\" translate=\"no\">​</a></h2>\n<p>We've undergone a comprehensive redesign of our website, <a href=\"https://streampipes.apache.org/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">streampipes.apache.org</a>. Take\na moment to explore the new look,\nand we welcome your feedback on your experience. Let us know what you think!</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"security\">Security<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#security\" class=\"hash-link\" aria-label=\"Direct link to Security\" title=\"Direct link to Security\" translate=\"no\">​</a></h2>\n<p>We've addressed a vulnerability in the default password generation for new users during the self-registration process.\nPreviously, a cryptographically weak pseudo-random number generator (PRNG) was utilized, but we've now rectified this by\nimplementing Apache Commons RNG. We extend our sincere thanks to Alessandro Albani from the Digital Security Division\nVar\nGroup for bringing this to our attention.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"final-remarks\">Final Remarks<a href=\"https://streampipes.apache.org/blog/2023/11/28/release-093/#final-remarks\" class=\"hash-link\" aria-label=\"Direct link to Final Remarks\" title=\"Direct link to Final Remarks\" translate=\"no\">​</a></h2>\n<p>We highly recommend updating to StreamPipes 0.93.0 to take advantage of these new features, bug fixes, and improvements.\nFor more detailed information, please refer to\nthe <a href=\"https://github.com/apache/incubator-streampipes/blob/release/0.92.0/RELEASE_NOTES.md#0920\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">release notes</a>.</p>\n<p>We appreciate your continued support and valuable feedback.\nStreamPipes is continually evolving, and we are dedicated to providing you with a powerful and reliable platform for\nyour IIoT streaming data needs.</p>",
            "url": "https://streampipes.apache.org/blog/2023/11/28/release-093/",
            "title": "Apache StreamPipes release 0.93.0",
            "summary": "9 minutes to read",
            "date_modified": "2023-11-28T00:00:00.000Z",
            "author": {
                "name": "Tim Bossenmaier",
                "url": "https://github.com/bossenti"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2023/06/16/release-092/",
            "content_html": "<p><strong></strong></p><div style=\"float:left;padding-right:40px\"><strong>8 minutes to read</strong></div><p></p>\n<p>We are pleased to announce the release of StreamPipes 0.92.0, which includes several bug fixes, performance improvements, and new features.\nThis version focuses on enhancing the technical aspects of StreamPipes.\nLet's explore the key updates in this release:</p>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"improved-python-support\">Improved Python Support:<a href=\"https://streampipes.apache.org/blog/2023/06/16/release-092/#improved-python-support\" class=\"hash-link\" aria-label=\"Direct link to Improved Python Support:\" title=\"Direct link to Improved Python Support:\" translate=\"no\">​</a></h2>\n<p>In response to valuable user feedback, we have improved Python support in StreamPipes.\nUsers can now seamlessly integrate Python-based scripts, libraries, and modules into their functions.\nThis enhancement enables leveraging the power of machine learning and advanced analytics algorithms for IIoT data sources.\nPlease refer to the <a href=\"https://streampipes.apache.org/docs/docs/python/latest/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Python documentation</a> for further details.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-processing-elements-introducing-the-swinging-door-trending-sdt-filter-processor\">New Processing Elements: Introducing the Swinging Door Trending (SDT) Filter Processor:<a href=\"https://streampipes.apache.org/blog/2023/06/16/release-092/#new-processing-elements-introducing-the-swinging-door-trending-sdt-filter-processor\" class=\"hash-link\" aria-label=\"Direct link to New Processing Elements: Introducing the Swinging Door Trending (SDT) Filter Processor:\" title=\"Direct link to New Processing Elements: Introducing the Swinging Door Trending (SDT) Filter Processor:\" translate=\"no\">​</a></h2>\n<p>To expand the functionality of StreamPipes, we have introduced several new processing elements.\nAmong them is the <strong>Swinging Door Trending (SDT) Filter Processor</strong>.\nThis processor provides a linear trend compression algorithm.\nEssentially, it replaces a series of continuous points (timestamp, value) with a straight line determined by the start and end points.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-06-16/swinging_door_trending.gif\" alt=\"demonstration how to use the swinging door trending processor\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"bug-fixes-and-improvements\">Bug Fixes and Improvements:<a href=\"https://streampipes.apache.org/blog/2023/06/16/release-092/#bug-fixes-and-improvements\" class=\"hash-link\" aria-label=\"Direct link to Bug Fixes and Improvements:\" title=\"Direct link to Bug Fixes and Improvements:\" translate=\"no\">​</a></h2>\n<p>We have addressed various bugs and issues reported by our users, resulting in a more stable and reliable StreamPipes experience.\nWe have also made several performance and usability improvements to enhance overall system efficiency.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"deprecation-of-set-adapters\">Deprecation of Set Adapters<a href=\"https://streampipes.apache.org/blog/2023/06/16/release-092/#deprecation-of-set-adapters\" class=\"hash-link\" aria-label=\"Direct link to Deprecation of Set Adapters\" title=\"Direct link to Deprecation of Set Adapters\" translate=\"no\">​</a></h2>\n<p>In order to streamline the StreamPipes ecosystem, we have deprecated the functionality of Set Adapters.\nGoing forward, our focus will solely be on streaming event sources.\nHowever, we understand the importance of working with files of sensor data, especially during development.\nTo accommodate this need, we have extended the <strong>File Stream Adapter</strong>, which now offers the following functionalities:</p>\n<ol>\n<li class=\"\">Create a live simulation of sensor data based on the file.</li>\n<li class=\"\">Replay the data in the file once, for example, to store it in the <strong>Data Lake</strong>.</li>\n</ol>\n<p><strong>IMPORTANT: The set adapters will be removed in the next release.</strong></p>\n<p>From this release onwards, we encourage you to utilize the <strong>File Stream Adapter</strong> instead of the <strong>File Set Adapter</strong>.\nTo simulate a file set using the <strong>File Stream Adapter</strong>, you can configure it with <code>Replay Once: Yes</code> and <code>Replay Speed: Fastest (Ignore original time)</code>.\nSee the example below:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-06-16/file_stream_set.gif\" alt=\"demonstration how to use file sets with the file stream adapter\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"final-remarks\">Final Remarks<a href=\"https://streampipes.apache.org/blog/2023/06/16/release-092/#final-remarks\" class=\"hash-link\" aria-label=\"Direct link to Final Remarks\" title=\"Direct link to Final Remarks\" translate=\"no\">​</a></h2>\n<p>We highly recommend updating to StreamPipes 0.92.0 to take advantage of these new features, bug fixes, and improvements.\nFor more detailed information, please refer to the <a href=\"https://github.com/apache/incubator-streampipes/blob/release/0.92.0/RELEASE_NOTES.md#0920\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">release notes</a>.</p>\n<p>We appreciate your continued support and valuable feedback.\nStreamPipes is continually evolving, and we are dedicated to providing you with a powerful and reliable platform for your IIoT streaming data needs.</p>",
            "url": "https://streampipes.apache.org/blog/2023/06/16/release-092/",
            "title": "Apache StreamPipes release 0.92.0",
            "summary": "8 minutes to read",
            "date_modified": "2023-06-16T00:00:00.000Z",
            "author": {
                "name": "Philipp Zehnder",
                "url": "https://github.com/tenthe"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2023/04/12/release-091/",
            "content_html": "<p><strong></strong></p><div style=\"float:left;padding-right:40px\"><strong>14 minutes to read</strong></div><p></p>\n<br>\n<p>The Apache StreamPipes community is delighted to announce the release of Apache StreamPipes version 0.91.0!\nThe biggest highlight of this release is the birth of our official StreamPipes Python library.\nApart from that, we have made a lot of improvements under the hood, especially in terms of improving the development experience (e.g., by introducing and enforcing code style rules).\nNevertheless, our new version includes more than 90 improvements and bug fixes in total.</p>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"streampipes-python\">StreamPipes Python<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#streampipes-python\" class=\"hash-link\" aria-label=\"Direct link to StreamPipes Python\" title=\"Direct link to StreamPipes Python\" translate=\"no\">​</a></h2>\n<p><a href=\"https://streampipes.apache.org/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">Apache StreamPipes</a> aims to enable non-technical users to connect and analyze IoT data streams.\nTo this end, it provides an easy-to-use and convenient user interface that allows one to connect to an IoT data source and create some visual\ngraphs within a few minutes. <br>\nAlthough this is the main use case of Apache StreamPipes, it can also provide great value for people who are eager to work on data analysis or data science with IoT data, but don't want to get in touch with all the hassle associated with extracting data from devices in a suitable format.\nIn this scenario, StreamPipes helps you connect to your data source and extract the data for you.\nYou then can make the data available outside StreamPipes by writing it into an external source, such as a database, Kafka, etc.\nWhile this requires another component, you can also extract your data directly from StreamPipes programmatically using the StreamPipes API.\nFor convenience, we also provide you with a StreamPipes client both available for Java and Python.\nSpecifically with StreamPipes Python, we want to address the amazing data analytics and data science community in Python and benefit from the great universe of Python libraries out there.</p>\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"getting-started\">Getting started<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#getting-started\" class=\"hash-link\" aria-label=\"Direct link to Getting started\" title=\"Direct link to Getting started\" translate=\"no\">​</a></h3>\n<p>Besides our official version, which you can access <a href=\"https://streampipes.apache.org/download.html\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">here</a>,\nwe provide Apache StreamPipes as a convenient release via PyPI.\nTherefore, you can easily install it via the following command</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">pip install streampipes</span><br></div></code></pre></div></div>\n<p>All documentation related to StreamPipes Python can be found <a href=\"https://streampipes.apache.org/docs/docs/python/latest/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">here</a>.</p>\n<p>But now enough words are written, let's just start with a few examples.\nAs a first step, we want to establish a connection to a running StreamPipes instance.</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesClient</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">config </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesClientConfig</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token keyword\" style=\"font-style:italic\">from</span><span class=\"token plain\"> streampipes</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">credential_provider </span><span class=\"token keyword\" style=\"font-style:italic\">import</span><span class=\"token plain\"> StreamPipesApiKeyCredentials</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">config </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> StreamPipesClientConfig</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    credential_provider </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> StreamPipesApiKeyCredentials</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        username </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"test@streampipes.apache.org\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        api_key </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"DEMO-KEY\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    host_address </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"localhost\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    https_disabled </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token boolean\" style=\"color:rgb(255, 88, 116)\">True</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    port </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">80</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">client </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> StreamPipesClient</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">client_config</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\">config</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p><code>client.describe()</code> gives you an overview about what can be discovered via the Python client:</p>\n<div class=\"language-bash codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-bash codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">Hi there!</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">You are connected to a StreamPipes instance running at http://localhost:80.</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">The following StreamPipes resources are available with this client:</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1x DataLakeMeasures</span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">1x DataStreams</span><br></div></code></pre></div></div>\n<p>The required API key can be retrieved from StreamPipes via the UI:</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-04-12/how-to-get-api-key.gif\" alt=\"demonstration how to get an API key in form of a gif\">\n<h3 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"query-data-from-streampipes-data-lake\">Query Data from StreamPipes data lake<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#query-data-from-streampipes-data-lake\" class=\"hash-link\" aria-label=\"Direct link to Query Data from StreamPipes data lake\" title=\"Direct link to Query Data from StreamPipes data lake\" translate=\"no\">​</a></h3>\n<p>As a first step, we can see which data sets are available in the data lake:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">dataLakeMeasureApi</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token builtin\" style=\"color:rgb(130, 170, 255)\">all</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">to_pandas</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>To query data for a specific data lake measure, the following command takes you there:</p>\n<div class=\"language-python codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-python codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">client</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">dataLakeMeasureApi</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">get</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">identifier</span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"flow-rate\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">to_pandas</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><br></div></code></pre></div></div>\n<p>There are some parameters that allow you to query data more specifically, visit the <a href=\"https://streampipes.apache.org/docs/docs/python/latest/reference/endpoint/api/data_lake_measure/#streampipes.endpoint.api.data_lake_measure.MeasurementGetQueryConfig\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">docs</a> for more detailed information.</p>\n<p>If you are curious which features are available for StreamPipes Python, have a look at our <a href=\"https://streampipes.apache.org/docs/docs/python/latest/tutorials/1-introduction-to-streampipes-python-client/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">tutorial section</a>.</p>\n<p>We plan to further extend the Python library in the next releases - we welcome your ideas on any features you'd like to see!</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"create-adapter-without-starting\">Create Adapter without starting<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#create-adapter-without-starting\" class=\"hash-link\" aria-label=\"Direct link to Create Adapter without starting\" title=\"Direct link to Create Adapter without starting\" translate=\"no\">​</a></h2>\n<p>Until now, when creating an adapter in StreamPipes, the adapter was started immediately after completion.\nFrom now on you can choose via the adapter overview in the last dialog whether the adapter should be started immediately or later (this is then possible in the adapter overview).</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-04-12/adapter-running.gif\" alt=\"demonstration how to disable automatic start of an adapter in form of a gif\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"redirect-after-login\">Redirect after Login<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#redirect-after-login\" class=\"hash-link\" aria-label=\"Direct link to Redirect after Login\" title=\"Direct link to Redirect after Login\" translate=\"no\">​</a></h2>\n<p>This is another small user interface improvement: when a user opens a StreamPipes link even though they are not logged in, e.g.,\n<a href=\"http://streampipes.demo/#/connect\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">http://streampipes.demo/#/connect</a>, StreamPipes displays the login dialog and now redirects the user directly to the target view\n(in this case the connection overview).</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"support-output-streams-for-standalone-functions\">Support Output Streams for Standalone Functions<a href=\"https://streampipes.apache.org/blog/2023/04/12/release-091/#support-output-streams-for-standalone-functions\" class=\"hash-link\" aria-label=\"Direct link to Support Output Streams for Standalone Functions\" title=\"Direct link to Support Output Streams for Standalone Functions\" translate=\"no\">​</a></h2>\n<p>Within the last release, <a class=\"\" href=\"https://streampipes.apache.org/blog/2023/01/17/release-090.html/\">0.90.0</a>, we introduced StreamPipes Functions as a lightweight alternative to processing elements.<br>\n<!-- -->StreamPipes Functions do now support having output streams, which means that they allow not only to consume but to send data to StreamPipes as well.</p>\n<p>Below you can see a simple example function that demonstrates how events can be pushed back to StreamPipes again.</p>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionPublishExample</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">extends</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">StreamPipesFunction</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">static</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">final</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Logger</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">LOG</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">LoggerFactory</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getLogger</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionPublishExample</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">static</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">final</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">FUNCTION_ID</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"org.apache.streampipes.example.function.publish\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">static</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">final</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">STREAM_APP_ID</span><span class=\"token plain\"> </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"example-output-stream-1\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">private</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">SpOutputCollector</span><span class=\"token plain\"> outputCollector</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">requiredStreamIds</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">of</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"urn:streampipes.apache.org:eventstream:EtMUkN\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStarted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionContext</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">LOG</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">info</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"Service started\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">this</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">outputCollector </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getOutputCollectors</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">get</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">STREAM_APP_ID</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onEvent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Event</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> streamId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">LOG</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">info</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"on event\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">var</span><span class=\"token plain\"> ev </span><span class=\"token operator\" style=\"color:rgb(137, 221, 255)\">=</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">new</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    ev</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">addField</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"timestamp\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">System</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">currentTimeMillis</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    ev</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">addField</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"example-property\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"abc\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">this</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token plain\">outputCollector</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">collect</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\">ev</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStopped</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">LOG</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">info</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"service stopped\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionConfig</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getFunctionConfig</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionConfigBuilder</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">create</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">from</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">FUNCTION_ID</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">withOutputStream</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">DataStreamBuilder</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">create</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">STREAM_APP_ID</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"My Function Stream\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">property</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">EpProperties</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">timestampProperty</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"timestamp\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">property</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">EpProperties</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">stringEp</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Labels</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">from</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"my-example-property\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"test\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"test\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"example-property\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">SO</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">TEXT</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">                </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">PropertyScope</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">MEASUREMENT_PROPERTY</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">format</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Formats</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">jsonFormat</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">protocol</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Protocols</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">kafka</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"localhost\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">9094</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token constant\" style=\"color:rgb(130, 170, 255)\">STREAM_APP_ID</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">            </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">build</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">        </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">build</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>This functionality is also already supported in StreamPipes Python! 🚀</p>\n<p>This means that you can write a StreamPipes function in Python that allows you to consume streams of data from StreamPipes,\nperform any data manipulation in Python, and send the data back to StreamPipes, where it can be further processed.</p>\n<br>\n<p>To get a comprehensive overview of all changes released within Apache StreamPipes 0.91.0\nplease visit our <a href=\"https://github.com/apache/incubator-streampipes/blob/release/0.91.0/RELEASE_NOTES.md#0910\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">release notes</a>.</p>",
            "url": "https://streampipes.apache.org/blog/2023/04/12/release-091/",
            "title": "Apache StreamPipes release 0.91.0",
            "summary": "14 minutes to read",
            "date_modified": "2023-04-12T00:00:00.000Z",
            "author": {
                "name": "Tim Bossenmaier",
                "url": "https://github.com/bossenti"
            },
            "tags": [
                "release"
            ]
        },
        {
            "id": "https://streampipes.apache.org/blog/2023/01/17/release-090/",
            "content_html": "<p><strong></strong></p><div style=\"float:left;padding-right:40px\"><strong>5 minutes to read</strong></div><p></p>\n<br>\n<p>The Apache StreamPipes community is pleased to announce the immediate availability of Apache StreamPipes version 0.90.0!\nIn total, this release was focused on stabilization and closes 57 issues with improvements and bug fixes as well as some new features such as adapters and data sinks.</p>\n<p>The current release can be downloaded <a href=\"https://streampipes.apache.org/download.html\">here</a>.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"improvements\">Improvements<a href=\"https://streampipes.apache.org/blog/2023/01/17/release-090/#improvements\" class=\"hash-link\" aria-label=\"Direct link to Improvements\" title=\"Direct link to Improvements\" translate=\"no\">​</a></h2>\n<p>The focus of this release cycle was on general usability improvements and bug fixes. We continued to harmonize the\nStreamPipes web interface, so that all views follow a similar navigation. Many improvements were added to the data explorer:</p>\n<ul>\n<li class=\"\">Incomplete events with missing values are now displayed in the data explorer</li>\n<li class=\"\">Improvements to the time selector and edit mode</li>\n<li class=\"\">More configuration options for data download</li>\n<li class=\"\">Improved overall data explorer performance</li>\n</ul>\n<p>In addition, we improved features to monitor pipelines and extensions services. The pipeline monitoring component has been restructured and now works independent from the underlying message broker.\nIn addition, we extended the SDK so that runtime errors can be forwarded to the StreamPipes UI.\nFurther improvements to the monitoring stack will be added in the next versions.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"new-adapters-and-data-sinks\">New Adapters and Data Sinks<a href=\"https://streampipes.apache.org/blog/2023/01/17/release-090/#new-adapters-and-data-sinks\" class=\"hash-link\" aria-label=\"Direct link to New Adapters and Data Sinks\" title=\"Direct link to New Adapters and Data Sinks\" translate=\"no\">​</a></h2>\n<p>This version improves support for existing message brokers in form of adapters and sinks:</p>\n<ul>\n<li class=\"\">Improvements of the <code>Apache Pulsar</code> (which is also available as a data sink)</li>\n<li class=\"\">A new adapter and data sink for <code>Apache RocketMQ</code></li>\n<li class=\"\">A new adapter for <code>NATS</code> (also available as a data sink)</li>\n</ul>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"github-community-features\">GitHub Community Features<a href=\"https://streampipes.apache.org/blog/2023/01/17/release-090/#github-community-features\" class=\"hash-link\" aria-label=\"Direct link to GitHub Community Features\" title=\"Direct link to GitHub Community Features\" translate=\"no\">​</a></h2>\n<p>Apache StreamPipes is a community effort - everyone is welcome not only to contribute code, but also to provide feedback and other input which helps improving the product.\nTo improve community interaction, we switched our issue management from Jira to GitHub issues - making it much easier to create issues and to discuss future features.\nIn addition, we've enabled Github Discussions - feel free to participate in the existing discussions and ask questions if you have problems!</p>\n<ul>\n<li class=\"\"><a href=\"https://github.com/apache/streampipes/issues\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Issues</a></li>\n<li class=\"\"><a href=\"https://github.com/apache/streampipes/discussions\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">GitHub Discussions</a></li>\n</ul>\n<p>And if you prefer the mailing list, subscribe to <a href=\"mailto:dev-subscribe@streampipes.apache.org\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">dev@streampipes.apache.org</a> or <a href=\"mailto:users-subscribe@streampipes.apache.org\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">users@streampipes.apache.org</a>.\nTech-related and general project discussions as well as release votes will continue to happen on the dev list.</p>\n<img src=\"https://streampipes.apache.org/img/blog/2023-01-17/github-discussions.png\" alt=\"Github Discussions overview\">\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"preview-of-standalone-functions\">Preview of Standalone Functions<a href=\"https://streampipes.apache.org/blog/2023/01/17/release-090/#preview-of-standalone-functions\" class=\"hash-link\" aria-label=\"Direct link to Preview of Standalone Functions\" title=\"Direct link to Preview of Standalone Functions\" translate=\"no\">​</a></h2>\n<p>An exciting new feature is available in preview mode: StreamPipes Functions are a new way to interact with connected data streams in StreamPipes.\nAs an open system, there are already several ways to extend the functionality of StreamPipes: New adapter can be added to connect to non-supported systems.\nIn addition, the SDK supports building custom data processors and sinks, so that StreamPipes can be easily extended at runtime in case new analytics operators are needed.</p>\n<p>But providing extensions in form of pipeline elements are not always the best choice: E.g., in cases where non-generic algorithms should be executed on a specific data stream,\nproviding a reusable component for pipeline development is unsuitable.</p>\n<p>This is where Functions come into play! StreamPipes Functions allow to define standalone components, which consume one or more connected data streams from StreamPipes and can be used to add custom processing logic.\nE.g., it becomes easy to apply an ML model on continuous data without the need to build a specific data processing pipeline.</p>\n<p>Functions can be registered in an extensions service similar to data processors and sinks by extending a single class:</p>\n<div class=\"language-java codeBlockContainer_Ckt0 theme-code-block\" style=\"--prism-color:#bfc7d5;--prism-background-color:#292d3e\"><div class=\"codeBlockContent_QJqH\"><pre tabindex=\"0\" class=\"prism-code language-java codeBlock_bY9V thin-scrollbar\" style=\"color:#bfc7d5;background-color:#292d3e\"><code class=\"codeBlockLines_e6Vv\"><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">class</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">MyFunction</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">extends</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">StreamPipesFunction</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionId</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">getFunctionId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">from</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"my-app-id\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token number\" style=\"color:rgb(247, 140, 108)\">1</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&lt;</span><span class=\"token generics class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token generics punctuation\" style=\"color:rgb(199, 146, 234)\">&gt;</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">requiredStreamIds</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token keyword\" style=\"font-style:italic\">return</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">List</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">.</span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">of</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token string\" style=\"color:rgb(195, 232, 141)\">\"my-stream-id\"</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">;</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStarted</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">FunctionContext</span><span class=\"token plain\"> context</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// called on service startup</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onEvent</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">Event</span><span class=\"token plain\"> event</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">,</span><span class=\"token plain\"> </span><span class=\"token class-name\" style=\"color:rgb(255, 203, 107)\">String</span><span class=\"token plain\"> streamId</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// called for each incoming event</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\" style=\"display:inline-block\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token annotation punctuation\" style=\"color:rgb(199, 146, 234)\">@Override</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token keyword\" style=\"font-style:italic\">public</span><span class=\"token plain\"> </span><span class=\"token keyword\" style=\"font-style:italic\">void</span><span class=\"token plain\"> </span><span class=\"token function\" style=\"color:rgb(130, 170, 255)\">onServiceStopped</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">(</span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">)</span><span class=\"token plain\"> </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">{</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">    </span><span class=\"token comment\" style=\"color:rgb(105, 112, 152);font-style:italic\">// called on service shutdown</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\">  </span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><span class=\"token plain\"></span><br></div><div class=\"token-line\" style=\"color:#bfc7d5\"><span class=\"token plain\"></span><span class=\"token punctuation\" style=\"color:rgb(199, 146, 234)\">}</span><br></div></code></pre></div></div>\n<p>This concept, which will also come for more programming languages besides Java offer new ways for developers to interact with available data in StreamPipes and build custom extensions for IIoT analytics.</p>\n<p>Functions are available in preview mode and their API should therefore be considered unstable.</p>\n<h2 class=\"anchor anchorTargetStickyNavbar_Vzrq\" id=\"future-roadmap\">Future Roadmap<a href=\"https://streampipes.apache.org/blog/2023/01/17/release-090/#future-roadmap\" class=\"hash-link\" aria-label=\"Direct link to Future Roadmap\" title=\"Direct link to Future Roadmap\" translate=\"no\">​</a></h2>\n<p>After this stabilization release, the next version will most probably bring a major new feature - Python support!\nThe community is currently working hard to bring the StreamPipes client and functions to the Python world. Stay tuned!</p>\n<br>\n<p>To get a comprehensive overview of all changes released within Apache StreamPipes 0.90.0\nplease visit our <a href=\"https://github.com/apache/incubator-streampipes/blob/release/0.90.0/RELEASE_NOTES.md#0900\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"\">release notes</a>.</p>",
            "url": "https://streampipes.apache.org/blog/2023/01/17/release-090/",
            "title": "Apache StreamPipes release 0.90.0",
            "summary": "5 minutes to read",
            "date_modified": "2023-01-17T00:00:00.000Z",
            "author": {
                "name": "Dominik Riemer",
                "url": "https://github.com/dominikriemer"
            },
            "tags": [
                "release"
            ]
        }
    ]
}