<?xml version="1.0" encoding="UTF-8"?>
<!-- generator="FeedCreator 1.8" -->
<?xml-stylesheet href="https://sinelabore.com/lib/exe/css.php?s=feed" type="text/css"?>
<rss version="2.0">
    <channel xmlns:g="http://base.google.com/ns/1.0">
        <title>SinelaboreRT - wike:backends</title>
        <description>Productivity for embedded software development</description>
        <link>https://sinelabore.com/</link>
        <lastBuildDate>Wed, 08 Apr 2026 03:53:45 +0000</lastBuildDate>
        <generator>FeedCreator 1.8</generator>
        <image>
            <url>https://sinelabore.com/lib/exe/fetch.php/favicon.ico</url>
            <title>SinelaboreRT</title>
            <link>https://sinelabore.com/</link>
        </image>
        <item>
            <title>Generating GO code</title>
            <link>https://sinelabore.com/doku.php/wike/backends/go_lang</link>
            <description>


&lt;h1 class=&quot;sectionedit1&quot; id=&quot;generating_go_code&quot;&gt;Generating GO code&lt;/h1&gt;
&lt;div class=&quot;level1&quot;&gt;

&lt;p&gt;
Sinelabore creates compact and clearly readable GO code from &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; state machine diagrams. 
&lt;/p&gt;

&lt;p&gt;
To generate GO code, call the code generator with the command line flag &lt;code&gt;-l go&lt;/code&gt;.
&lt;/p&gt;

&lt;p&gt;
GO has some very convincing new features compared to C. A highlight are &lt;code&gt;go routines&lt;/code&gt; with the &lt;code&gt;select&lt;/code&gt; and the &lt;code&gt;channel concept&lt;/code&gt;. This allows to write very elegant threading code without the need to use pthreads or other more complex methods. Some other interesting features are the availability of maps and slices, generics, the concept of embedding, tickers and timers to name some others. All of these features were used in the oven state machine example (see code here on &lt;a href=&quot;https://github.com/sinelabore/examples&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/sinelabore/examples&quot; rel=&quot;ugc nofollow&quot;&gt;Github&lt;/a&gt;) to create a simple but still powerful command line simulation.
&lt;/p&gt;

&lt;p&gt;
The example oven state machine is driven by an active object that handles events from multiple sources using the GO select and channel feature. The &lt;code&gt;React()&lt;/code&gt; function below is a &lt;code&gt;go routine&lt;/code&gt; which processes keyboard events (line 6) and timer events (line 10) with a resolution provided by a Ticker. The state machine handler is then called with the respective event defined in the state machine diagram.  
&lt;/p&gt;
&lt;pre class=&quot;code go&quot;&gt;&lt;ol&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;kw4&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;smBase &lt;span class=&quot;sy3&quot;&gt;*&lt;/span&gt;Reactor&lt;span class=&quot;sy1&quot;&gt;)&lt;/span&gt; React&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;c &lt;span class=&quot;kw4&quot;&gt;chan&lt;/span&gt; OvenEvent&lt;span class=&quot;sy1&quot;&gt;,&lt;/span&gt; quit &lt;span class=&quot;kw4&quot;&gt;chan&lt;/span&gt; &lt;span class=&quot;kw4&quot;&gt;bool&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;  smBase&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Ticker &lt;span class=&quot;sy2&quot;&gt;=&lt;/span&gt; time&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;NewTicker&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;time&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Millisecond &lt;span class=&quot;sy3&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;  &lt;span class=&quot;kw1&quot;&gt;var&lt;/span&gt; err error &lt;span class=&quot;sy2&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;nil&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;  &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li2&quot;&gt;&lt;div class=&quot;de2&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1 ln-xtra&quot;&gt;&lt;div class=&quot;de1&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; event &lt;span class=&quot;sy2&quot;&gt;:=&lt;/span&gt; &amp;lt;&lt;span class=&quot;sy3&quot;&gt;-&lt;/span&gt;c&lt;span class=&quot;sy1&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// receive events&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      _&lt;span class=&quot;sy1&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;sy2&quot;&gt;=&lt;/span&gt; smBase&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;ProcessEvent&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;event&lt;span class=&quot;sy1&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; &amp;lt;&lt;span class=&quot;sy3&quot;&gt;-&lt;/span&gt;quit&lt;span class=&quot;sy1&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// receive quit event&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// Quit Co-routine&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li2 ln-xtra&quot;&gt;&lt;div class=&quot;de2&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;case&lt;/span&gt; &amp;lt;&lt;span class=&quot;sy3&quot;&gt;-&lt;/span&gt;smBase&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Ticker&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;C&lt;span class=&quot;sy1&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;co1&quot;&gt;// timer tick to check if there are any timeouts&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      vals &lt;span class=&quot;sy2&quot;&gt;:=&lt;/span&gt; smBase&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Timers&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Tick&lt;span class=&quot;sy1&quot;&gt;()&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      &lt;span class=&quot;kw1&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;nu2&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;sy2&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nu0&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nu2&quot;&gt;i&lt;/span&gt; &amp;lt; &lt;span class=&quot;kw3&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;vals&lt;span class=&quot;sy1&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;nu2&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;sy2&quot;&gt;++&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;        &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; evt&lt;span class=&quot;sy1&quot;&gt;,&lt;/span&gt; ok &lt;span class=&quot;sy2&quot;&gt;:=&lt;/span&gt; vals&lt;span class=&quot;sy1&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nu2&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Event&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;OvenEvent&lt;span class=&quot;sy1&quot;&gt;);&lt;/span&gt; ok &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;          _&lt;span class=&quot;sy1&quot;&gt;,&lt;/span&gt; err &lt;span class=&quot;sy2&quot;&gt;=&lt;/span&gt; smBase&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;ProcessEvent&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;evt&lt;span class=&quot;sy1&quot;&gt;)&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li2&quot;&gt;&lt;div class=&quot;de2&quot;&gt;        &lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      &lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;    &lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;    &lt;span class=&quot;kw1&quot;&gt;if&lt;/span&gt; err &lt;span class=&quot;sy2&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kw2&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      debugPrint&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;fmt&lt;span class=&quot;sy3&quot;&gt;.&lt;/span&gt;Sprintf&lt;span class=&quot;sy1&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;st0&quot;&gt;&amp;quot;internal error in sm %s&lt;span class=&quot;es1&quot;&gt;\n&lt;/span&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;sy1&quot;&gt;,&lt;/span&gt; err&lt;span class=&quot;sy1&quot;&gt;))&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li2&quot;&gt;&lt;div class=&quot;de2&quot;&gt;&amp;nbsp;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;      &lt;span class=&quot;kw1&quot;&gt;return&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;    &lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;  &lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;li class=&quot;li1&quot;&gt;&lt;div class=&quot;de1&quot;&gt;&lt;span class=&quot;sy1&quot;&gt;}&lt;/span&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/pre&gt;

&lt;p&gt;
In the generated code, state hierarchies are mapped to nested switch/case code. Event handling code is mapped to if/else-if/else structures.
There are several configuration/command line options to adjust the generated code:
Configuration file options:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;BaseClassMachine&lt;/code&gt;: GO supports the language concept of embedding of structs to express a more seamless composition of types. With the ‘BaseClassMachine’ parameter the parent structure (embedding) Type can be specified. The nice thing in GO is the possibility to access structure members or functions of the embedding structure in the generated state machine code. This feature is used in the oven example to provide access to a Timer service and to store some data (timer IDs).&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;code go&quot;&gt;&lt;span class=&quot;co1&quot;&gt;// Demonstrates how to embedded the statemachine type into another type&lt;/span&gt;
&lt;span class=&quot;co1&quot;&gt;// and use data/functions from this type e.g. as guards ... in the statemachine.&lt;/span&gt;
&lt;span class=&quot;kw1&quot;&gt;type&lt;/span&gt; Reactor &lt;span class=&quot;kw4&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;sy1&quot;&gt;{&lt;/span&gt;
  id           &lt;span class=&quot;kw4&quot;&gt;uint8&lt;/span&gt;
  idBlink      &lt;span class=&quot;kw4&quot;&gt;uint8&lt;/span&gt;
  Ticker       &lt;span class=&quot;sy3&quot;&gt;*&lt;/span&gt;&lt;a href=&quot;http://golang.org/search?q=time.Ticker&quot;&gt;&lt;span class=&quot;kw5&quot;&gt;time.&lt;span class=&quot;me1&quot;&gt;Ticker&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;
  Timers       &lt;span class=&quot;sy3&quot;&gt;*&lt;/span&gt;CountdownTimers
  Statemachine &lt;span class=&quot;sy3&quot;&gt;*&lt;/span&gt;Oven&lt;/pre&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;Namespace&lt;/code&gt;: The specified value is used as package name of the generated code.&lt;/div&gt;
&lt;/li&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;ValidationCall&lt;/code&gt;: If set to ‘yes’ a function is added to the generated code that allows to check if a state transition is allowed or simply to log state changes. It is expected that the function is implemented on the embedding data type. &lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
Command line options:
&lt;/p&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;-Trace&lt;/code&gt;:  Generates trace the taken transition which includes the triggering event as well as the guard. It is expected that the function is implemented on the embedding data type.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li class=&quot;level1&quot;&gt;&lt;div class=&quot;li&quot;&gt; &lt;code&gt;-l GO&lt;/code&gt;: Instructs the code generator to generate GO code.&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
As in the other backends too, code at the beginning of the generated GO file can be specified with the ‘header’ linked to the class in a &lt;abbr title=&quot;Unified Modeling Language&quot;&gt;UML&lt;/abbr&gt; diagram. Use this to define your imports or other local code. As well as pre- and post-action code of the generated state handler (see section &amp;#039;Introduction&amp;#039; in the manual).
&lt;/p&gt;

&lt;p&gt;
The code generator supports code generation from models with regions. A region is an orthogonal part of a state. Regions allow to express parallelism within a state. A state can have two or more regions. Region contains states and transitions.
&lt;/p&gt;

&lt;p&gt;
The example state diagram of a microwave oven state machine built with regions is shown below. 
Imagine how much time can be saved by generating 100% of the code instead of manually writing it. And even worse how much wasted time it would be to maintain it over time when new states/events are added. The oven uses the generic countdown_counter to schedule timers. This example uses two timers. One cyclic timer is used to flash an LED if the oven is running. The other one is used for the cooking time set by the user (single-shot).
&lt;/p&gt;

&lt;p&gt;
Get an impression about the powerful generation here: &lt;a href=&quot;https://github.com/sinelabore/examples/tree/master/OS_neutral/microwave_go&quot; class=&quot;urlextern&quot; title=&quot;https://github.com/sinelabore/examples/tree/master/OS_neutral/microwave_go&quot; rel=&quot;ugc nofollow&quot;&gt;https://github.com/sinelabore/examples/tree/master/OS_neutral/microwave_go&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
&lt;a href=&quot;https://sinelabore.com/lib/exe/detail.php/wike/backends/oven.png?id=wike%3Abackends%3Ago_lang&quot; class=&quot;media&quot; title=&quot;wike:backends:oven.png&quot;&gt;&lt;img src=&quot;https://sinelabore.com/lib/exe/fetch.php/wike/backends/oven.png&quot; class=&quot;mediacenter&quot; loading=&quot;lazy&quot; title=&quot; State machine diagram of a microwave oven with GO code inside states and transitions.&quot; alt=&quot; State machine diagram of a microwave oven with GO code inside states and transitions.&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
Below the console trace output of the oven simulation program is shown with the following user interaction: First set the cooking time to 2 seconds (pressing &lt;code&gt;++&lt;/code&gt;) which sends 2x &lt;code&gt;EvInc&lt;/code&gt;. Then start cooking by closing the door (press &lt;code&gt;c&lt;/code&gt;) which sends &lt;code&gt;EvDoorClosed&lt;/code&gt;. Then pause the cooking by opening the door (pressing &lt;code&gt;o&lt;/code&gt;) which sends &lt;code&gt;EvDoorOpen&lt;/code&gt; and then close again the door (pressing &lt;code&gt;c&lt;/code&gt;) which sends &lt;code&gt;EvDoorClosed&lt;/code&gt;. In-between you can see the timer events of the blinking LED and finally the cooking timeout event.
&lt;/p&gt;

&lt;p&gt;
Question: what keys do you have to press to cook again? Hint: you have to open the door again before you can set the cooking timer again. Look into the state diagram and all should be clear!
&lt;/p&gt;
&lt;pre class=&quot;code sh&quot;&gt; ===== Microwave oven simulation
 ===== Use the following keys:
 ===== o,O: Open the door
 ===== c,C: Close the door
 ===== + increase cooking time
 ===== - decrese cooking time
 ===== q,Q: quit
 ===== 
 ===== Example sequence: +++++c   o   c +++ c
 ===== 
2023/11/20 21:15:08 Oven off
2023/11/20 21:15:09 Change state from Super to Super
2023/11/20 21:15:09 Oven off
2023/11/20 21:15:09 Trace msg: EvInc
2023/11/20 21:15:10 Change state from Super to Super
2023/11/20 21:15:10 Oven off
2023/11/20 21:15:10 Trace msg: EvInc
2023/11/20 21:15:13 Change state from Idle to Cooking
2023/11/20 21:15:13 Oven on
LED on
2023/11/20 21:15:13 Trace msg: EvDoorClosed[smBase.Timers.GetPresetInSec(smBase.id)&amp;gt;0]
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=2000)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=500)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1900)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=400)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1800)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=300)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1700)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=200)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1600)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=100)
2023/11/20 21:15:13 Change state from LedOn to LedOff
LED off
2023/11/20 21:15:13 Trace msg: EvTimeoutBlink
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1500)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=500)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1400)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=400)
2023/11/20 21:15:13 Timer 1 running but not expired (Cnt=1300)
2023/11/20 21:15:13 Timer 2 running but not expired (Cnt=300)
2023/11/20 21:15:13 Change state from Cooking to CookingPause
LED Off
2023/11/20 21:15:13 Oven off
2023/11/20 21:15:13 Trace msg: EvDoorOpen
2023/11/20 21:15:14 Change state from CookingPause to Cooking
2023/11/20 21:15:14 Oven on
LED on
2023/11/20 21:15:14 Trace msg: EvDoorClosed
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=1200)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=500)
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=1100)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=400)
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=1000)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=300)
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=900)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=200)
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=800)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=100)
2023/11/20 21:15:14 Change state from LedOn to LedOff
LED off
2023/11/20 21:15:14 Trace msg: EvTimeoutBlink
2023/11/20 21:15:14 Timer 1 running but not expired (Cnt=700)
2023/11/20 21:15:14 Timer 2 running but not expired (Cnt=500)
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=600)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=400)
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=500)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=300)
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=400)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=200)
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=300)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=100)
2023/11/20 21:15:15 Change state from LedOff to LedOn
LED on
2023/11/20 21:15:15 Trace msg: EvTimeoutBlink
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=200)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=500)
2023/11/20 21:15:15 Timer 1 running but not expired (Cnt=100)
2023/11/20 21:15:15 Timer 2 running but not expired (Cnt=400)
2023/11/20 21:15:15 Change state from Cooking to Completed
LED Off
2023/11/20 21:15:15 Oven off
2023/11/20 21:15:15 Trace msg: EvTimeout&lt;/pre&gt;

&lt;p&gt;
For further information, please refer to the corresponding manual chapter on GO.
&lt;/p&gt;

&lt;/div&gt;
&lt;!-- EDIT{&amp;quot;target&amp;quot;:&amp;quot;section&amp;quot;,&amp;quot;name&amp;quot;:&amp;quot;Generating GO code&amp;quot;,&amp;quot;hid&amp;quot;:&amp;quot;generating_go_code&amp;quot;,&amp;quot;codeblockOffset&amp;quot;:0,&amp;quot;secid&amp;quot;:1,&amp;quot;range&amp;quot;:&amp;quot;14-&amp;quot;} --&gt;</description>
            <author>anonymous@undisclosed.example.com (Anonymous)</author>
            <pubDate>Fri, 03 May 2024 20:42:59 +0000</pubDate>
        </item>
    </channel>
</rss>
