
<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.atronia.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WikiManagement</id>
	<title>ATRONIA Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.atronia.eu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WikiManagement"/>
	<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/Special:Contributions/WikiManagement"/>
	<updated>2026-07-14T04:14:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.44.0</generator>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS&amp;diff=1945</id>
		<title>SENSBLUE ATLAS</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS&amp;diff=1945"/>
		<updated>2026-07-13T16:51:34Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-atlas/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:SENSBLUE-ATLAS-Gateway.png|center|frameless|360x360px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;border: none; background: transparent; margin: 15px 0; border-collapse: collapse;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Datasheet|Datasheet]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Realease Notes|Realease Notes]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Home Assistant|Home Assistant]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Node-RED|Node-RED]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Fast Deploy|Fast Deploy]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;SENSBLUE ATLAS&#039;&#039;&#039; ==&lt;br /&gt;
Is a universal edge gateway and embedded controller that connects sensors and assets, runs control logic and ships to production without platform changes.&lt;br /&gt;
&lt;br /&gt;
Designed for industrial teams who need one dependable path from experiments to operations.&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS&amp;diff=1944</id>
		<title>SENSBLUE ATLAS</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS&amp;diff=1944"/>
		<updated>2026-07-13T16:50:47Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-atlas/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:SENSBLUE-ATLAS-Gateway.png|center|frameless|360x360px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table style=&amp;quot;border: none; background: transparent; margin: 15px 0; border-collapse: collapse;&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Datasheet|Datasheet]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Realease Notes|Realease Notes]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Home Assistant|Home Assistant]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Node-RED|Node-RED]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td style=&amp;quot;padding: 0 0 0 10px; border: none; background: transparent;&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;span class=&amp;quot;atlas-btn&amp;quot;&amp;gt;[[SENSBLUE ATLAS/Speed Up Your Deployment|Speed Up Your Deployment]]&amp;lt;/span&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;SENSBLUE ATLAS&#039;&#039;&#039; ==&lt;br /&gt;
Is a universal edge gateway and embedded controller that connects sensors and assets, runs control logic and ships to production without platform changes.&lt;br /&gt;
&lt;br /&gt;
Designed for industrial teams who need one dependable path from experiments to operations.&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Salinity_Conductivity_TDS_Probe_AT-SB-PROBE-S-P-C1&amp;diff=1943</id>
		<title>Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Salinity_Conductivity_TDS_Probe_AT-SB-PROBE-S-P-C1&amp;diff=1943"/>
		<updated>2026-07-13T11:56:30Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Salinity Probe.png|center|frameless|412x412px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
&amp;quot;The SENSBLUE RS-485 Salinity Conductivity TDS Probe (AT-SB-PROBE-S-P-C1) introduces a new generation of four-electrode conductivity sensor, adopts international leading four-electrode technology, RS485 digital interface, supports MODBUS protocol, and environmentally friendly design. Compared with the traditional two-electrode conductivity sensor, it has higher accuracy, wider measurement range and excellent stability. The four-electrode conductivity sensor also has a unique advantage in quantity: one is to completely solve the polarization problem in high conductivity test; the other is to solve the problem of inaccurate reading caused by electrode contamination.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Simultaneous output of conductivity, salinity, TDS, and temperature parameters;&lt;br /&gt;
* Corrosion-resistant housing with IP68 waterproof rating for long-term underwater operation;&lt;br /&gt;
* Built-in temperature sensor with automatic temperature compensation;&lt;br /&gt;
* Factory-calibrated with built-in calibration parameters for immediate installation and use&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
|KWS-300A&lt;br /&gt;
|KWS-300B&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Conductivity Range&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0-200mS/cm (0-2mS/cm, 2-20mS/cm,  20-200mS/cm)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Accuracy&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |±1%  or 0.01mS/cm (which is bigger)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Salinity Range&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0 -175 ppt&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Accuracy&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |±1  ppt&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;TDS Range&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0 – 128000 mg/L&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Response Time&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |＜10s&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Ip Grade&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |IP68&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Max. Pressure&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |6  bar&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sheath Material&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Titanium&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Operating Temperature&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0~50℃  (no freezing)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Output&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |RS485, Modbus&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Power  Consumption&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.2W  (Recommended power supply: DC 9–24V, &amp;gt;500mA)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sensor Dimension&#039;&#039;&#039;&lt;br /&gt;
|φ22mm*175.5mm&lt;br /&gt;
|φ22mm*165.8mm&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Assembly&#039;&#039;&#039;&lt;br /&gt;
|NPT3/4  male thread&lt;br /&gt;
|Connect  with multi-parameter host&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Cable  Length&#039;&#039;&#039;&lt;br /&gt;
|10  meters (default), customizable&lt;br /&gt;
|None&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Calibration&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |support  one point or two-points calibration&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Casing  Material&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Titanium  + PEEK&lt;br /&gt;
|}&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
The above technical specifications are based on laboratory standard solution conditions;&lt;br /&gt;
&lt;br /&gt;
Sensor lifespan and calibration/maintenance frequency depend on actual site conditions.&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Salinity KWS-300A.svg|center|frameless|555x555px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Salinity KWS-300B.svg|center|frameless|555x555px]]&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|765x765px]]&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation ===&lt;br /&gt;
(1)&#039;&#039;&#039;Wiring and Power Tips&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
a.) Do not use the sensor cable to suspend the sensor. It is recommended to install a cable protection sleeve to ensure reliable power supply and waterproofing.&lt;br /&gt;
&lt;br /&gt;
b.) Ensure that the connector between the sensor and the cable (or main unit) is properly aligned and securely tightened. Take care not to damage the sealing ring to maintain good waterproof performance.&lt;br /&gt;
&lt;br /&gt;
c.) Before powering on, make sure the wiring sequence and supply voltage are correct.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;(2) Sensor Installation&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
a.) It is recommended to install the sensor vertically with the electrodes facing downward. Avoid locations with excessive air bubbles.&lt;br /&gt;
&lt;br /&gt;
b.) The sensor must be securely fixed to prevent impact or movement caused by water flow or other external forces.&lt;br /&gt;
&lt;br /&gt;
c.) The sensor should be installed with sufficient clearance: the distance from the bottom should be ≥40 mm, and the distance from the side wall should be ≥20 mm (see reference diagram below). For pressurized pipeline installations, ensure the electrodes are used within their pressure tolerance range.&lt;br /&gt;
[[File:Salinity Instalation.svg|center|frameless|595x595px]]&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance Schedule and Method ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Maintenance Schedule ====&lt;br /&gt;
Unlike traditional two-electrode conductivity sensors, the four-electrode probe offers strong antipolarisation capability and requires minimal maintenance. However, the electrodes must be kept clean. If solid buildup occurs on the optical window, soak the sensor in a suitable detergent, solvent, or diluted acid solution to dissolve and remove the deposits. You may also use a soft cotton swab to gently remove debris from the titanium electrodes, but do not scrub the electrode surface forcefully. Do not touch the surface of graphite or platinum-coated electrodes and always rinse the sensor thoroughly with deionized water after cleaning.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Maintenance  Task&#039;&#039;&#039;&lt;br /&gt;
|Recommended Maintenance Frequency&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Clean the sensor&#039;&#039;&#039;&lt;br /&gt;
|Recommended every 3 - 4 weeks. (shorter  if the water body is dirty);&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Calibrate the sensor&#039;&#039;&#039;&lt;br /&gt;
|Recommended  every 3 - 4 weeks. (depending on the working conditions)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Maintenance Methods ====&lt;br /&gt;
a.) Sensor Surface Cleaning: The sensor is made of chemically resistant materials and can be cleaned using most diluted cleaning agents, acidic substances, or other suitable solvents for removing scaling or coating. Warning: If hazardous cleaning materials are used, appropriate safety precautions must be taken. For coatings between the metal electrodes, a cotton swab can be used to gently wipe the surface. However, do not use brushes and do not touch the electrodes directly, as this may smooth the intentionally roughened surface and result in inaccurate low conductivity readings.&lt;br /&gt;
&lt;br /&gt;
b.) Sensor Storage: After cleaning, the conductivity sensor can be placed in a flow cell and kept moist for several days. However, if the equipment will be out of service for an extended period, it is recommended to remove the sensor and let it dry to prevent microbial growth.&lt;br /&gt;
&lt;br /&gt;
c.) Cable Inspection: During normal operation, the cable should not be under tension. Excessive strain may cause internal wire breakage, resulting in sensor malfunction.&lt;br /&gt;
&lt;br /&gt;
d.) Casing Inspection: Check whether the sensor housing has been damaged due to corrosion or other causes.&lt;br /&gt;
&lt;br /&gt;
=== 7. Calibration ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Standard solution configuration ====&lt;br /&gt;
1. Conductivity standard solution configuration:&lt;br /&gt;
&lt;br /&gt;
Potassium Chloride: Analytical reagent grade; dry at 220–240 °C for 2 hours, then cool to room temperature in a desiccator.&lt;br /&gt;
&lt;br /&gt;
Water: Use laboratory-grade Type I water, or distilled/deionized water with a conductivity not exceeding 0.2 × 10⁻⁶ S/cm at 25 °C.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Solution code&#039;&#039;&#039;&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Approximate&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;concentration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mol/L&#039;&#039;&#039;&lt;br /&gt;
| colspan=&amp;quot;5&amp;quot; |&#039;&#039;&#039;Conductivity values S/cm&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;15℃&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;18℃&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;20℃&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;25℃&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;35℃&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|1&lt;br /&gt;
|0.09212&lt;br /&gt;
|0.09780&lt;br /&gt;
|0.10170&lt;br /&gt;
|0.11131&lt;br /&gt;
|0.13110&lt;br /&gt;
|-&lt;br /&gt;
|B&lt;br /&gt;
|0,1&lt;br /&gt;
|0.010455&lt;br /&gt;
|0.011163&lt;br /&gt;
|0.011644&lt;br /&gt;
|0.012852&lt;br /&gt;
|0.015353&lt;br /&gt;
|-&lt;br /&gt;
|C&lt;br /&gt;
|0,01&lt;br /&gt;
|0.0011414&lt;br /&gt;
|0.0012200&lt;br /&gt;
|0.0012737&lt;br /&gt;
|0.0014083&lt;br /&gt;
|0.0016876&lt;br /&gt;
|-&lt;br /&gt;
|D&lt;br /&gt;
|0,001&lt;br /&gt;
|0.0001185&lt;br /&gt;
|0.0001267&lt;br /&gt;
|0.0001322&lt;br /&gt;
|0.0001465&lt;br /&gt;
|0.0001765&lt;br /&gt;
|}&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Solution number&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Approximate molar&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;concentration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mol/L&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Potassium  chloride required to prepare 1 L of solution&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;g&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|A&lt;br /&gt;
|1&lt;br /&gt;
|74.2457&lt;br /&gt;
|-&lt;br /&gt;
|B&lt;br /&gt;
|0,1&lt;br /&gt;
|7.4365&lt;br /&gt;
|-&lt;br /&gt;
|C&lt;br /&gt;
|0,01&lt;br /&gt;
|0.7440&lt;br /&gt;
|-&lt;br /&gt;
|D&lt;br /&gt;
|0,001&lt;br /&gt;
|Dilute  100 mL of Solution C to a final volume of 1,000 mL&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 8. Modbus Protocol ===&lt;br /&gt;
The RS485 communication protocol uses MODBUS communication protocol, and the sensors are used as slaves.&lt;br /&gt;
&lt;br /&gt;
Data byte format:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Baud  rate&#039;&#039;&#039;&lt;br /&gt;
|9600&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Starting position&#039;&#039;&#039;&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Data bits&#039;&#039;&#039;&lt;br /&gt;
|8&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Stop bit&#039;&#039;&#039;&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Check  digit&#039;&#039;&#039;&lt;br /&gt;
|N&lt;br /&gt;
|}&lt;br /&gt;
Read and write data (standard MODBUS protocol).&lt;br /&gt;
&lt;br /&gt;
The default address is 0x01, the address can be modified by register&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reading data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Host call (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
01 03 00 00 00 01 84 0A&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Remarks&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|03&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|00 00&lt;br /&gt;
|Start Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Number of registers&lt;br /&gt;
|Length of registers (2 bytes for 1  register)&lt;br /&gt;
|-&lt;br /&gt;
|84 0A&lt;br /&gt;
|CRC checksum, front low and back high&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Slave answer (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
01 03 02 00 xx xx xx xx&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Remarks&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|03&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|02&lt;br /&gt;
|Number of bytes read&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|XX XX&lt;br /&gt;
|Data (front low and back high DCBA)&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|XX XX&lt;br /&gt;
|CRC checksum, front low and back high&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Writing data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Host call (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
01 10 1B 00 00 01 02 01 00 0C C1&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Remarks&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|1B 00&lt;br /&gt;
|Register Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Number of registers&lt;br /&gt;
|Number of read registers&lt;br /&gt;
|-&lt;br /&gt;
|02&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|Number of read registersx2&lt;br /&gt;
|-&lt;br /&gt;
|01 00&lt;br /&gt;
|Data (front low and back high DCBA)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|0C C1&lt;br /&gt;
|CRC checksum, front low and back high&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Slave answer (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
01 10 1B 00 00 01 07 2D&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Remarks&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|1B 00&lt;br /&gt;
|Register Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Returns the number of registers written&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|7D 2D&lt;br /&gt;
|CRC checksum (front low and back high)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 9. Calculating CRC Checksum ===&lt;br /&gt;
a.) Preset a 16-bit register as hexadecimal FFFF (i.e., all 1s), and call this register the CRC register;&lt;br /&gt;
&lt;br /&gt;
b.) XOR the first 8-bit binary data (the first byte of the communication information frame) with the lower 8 bits of the 16-bit CRC register, and placing the result in the CRC register, leaving the upper eight bits unchanged;&lt;br /&gt;
&lt;br /&gt;
c.) Shift the contents of the CRC register one bit to the right (toward the low bit) to fill the highest bit with a 0, and check the shifted-out bit after the right shift;&lt;br /&gt;
&lt;br /&gt;
d.) If the shifted-out bit is 0: repeat step 3 (shift one bit to the right again); if the shifted-out bit is 1, XOR the CRC register with the polynomial A001 (1010 0000 0000 0001);&lt;br /&gt;
&lt;br /&gt;
e.) Repeat steps 3 and 4 until the right shift is made 8 times, so that the entire 8-bit data is processed;&lt;br /&gt;
&lt;br /&gt;
f.) Repeat steps 2 through 5 for the next byte of the communication information frame;&lt;br /&gt;
&lt;br /&gt;
g.) Exchange the high and low bytes of the 16-bit CRC register obtained after all bytes of this&lt;br /&gt;
&lt;br /&gt;
communication information frame have been calculated according to the above steps.&lt;br /&gt;
&lt;br /&gt;
h.) The final content of the CRC register is CRC code.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Register Table&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%; border-collapse: collapse;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%; padding: 10px;&amp;quot; | Register Starting Address&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | Function Definition&lt;br /&gt;
! style=&amp;quot;width: 10%;&amp;quot; | Number of registers&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | Data format (hexadecimal)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x3000H&lt;br /&gt;
| Device Address (Read / Write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 1&lt;br /&gt;
| 2 bytes in total&amp;lt;br/&amp;gt;00~01: Device address&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;The settable range is 1~247. For example, the data obtained is 02 00 (low first, which means the address is 2). Taking address 15 as an example, write 0F 00 (low first) to the corresponding address. When the current device address is unknown, FF can be used as the general device address to query the current device address.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x2600H&lt;br /&gt;
| Temperature, Conductivity and Salinity Value Acquisition&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 8&lt;br /&gt;
| 16 bytes in total&amp;lt;br/&amp;gt;00~03: Temperature value&amp;lt;br/&amp;gt;04~07: Conductivity value&amp;lt;br/&amp;gt;08~11: TDS&amp;lt;br/&amp;gt;12~15: Salinity value&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Continuously read temperature / conductivity / TDS / salinity value, each is 4 bytes of data. (The low first, DCBA format, this data needs to be converted to floating point number)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x2000&lt;br /&gt;
| Temperature Calibration TK/TB (Read/Write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 4&lt;br /&gt;
| 8 bytes in total&amp;lt;br/&amp;gt;00~03: TK&amp;lt;br/&amp;gt;04~07: TB&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;To read TK for example, readout is 4 bytes of data (the low first, DCBA format, this data needs to be converted to floating point number). To write TK for example, TK needs to be converted to 32-bit floating point first and written in according to (DCBA format).&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: TK and TB need to be read and written together.&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1100H&lt;br /&gt;
| User Calibration K/B (Read / Write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 12&lt;br /&gt;
| 24 bytes in total&amp;lt;br/&amp;gt;00~03：K1&amp;lt;br/&amp;gt;04~07：B1&amp;lt;br/&amp;gt;08~11：K2&amp;lt;br/&amp;gt;12~15：B2&amp;lt;br/&amp;gt;16~19：K3&amp;lt;br/&amp;gt;20~24：B3&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;User calibration is divided into three sections:&amp;lt;br/&amp;gt;0~2mS/cm corresponds to K1 and B1, default K1=1 B1=0&amp;lt;br/&amp;gt;2~20mS/cm corresponds to K2 and B2, default K2=1 B2=0&amp;lt;br/&amp;gt;20~200mS/cm corresponds to K3 and B3, default K3=1 B3=0&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Taking reading K1 as an example, the data read out is 4 bytes (lower bit first, DCBA format, this data needs to be converted into floating point number). Taking writing K1 as an example, k1 needs to be converted into a 32-bit floating point number first, and written in (DCBA format).&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: The writing process requires 24 bytes to be written at the same time&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1200H&lt;br /&gt;
| User calibration K1/B1 (read and write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 4&lt;br /&gt;
| 8 bytes in total&amp;lt;br/&amp;gt;00~03: K1&amp;lt;br/&amp;gt;04~07: B1&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;User calibration corresponds to 0~2mS/cm. Take reading K1 as an example, the readout is 4 bytes of data (low bit first, DCBA format, this data needs to be converted to floating point). Take writing K1 as an example, K1 needs to be converted to 32-bit floating point first, and written in (DCBA format).&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: K1 and B1 need to be read and written together&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1300H&lt;br /&gt;
| User calibration K2/B2 (read and write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 4&lt;br /&gt;
| 8 bytes in total&amp;lt;br/&amp;gt;00~03: K2&amp;lt;br/&amp;gt;04~07: B2&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;User calibration corresponds to 2~20mS/cm. Take reading K2 as an example, the readout is 4 bytes of data (low bit first, DCBA format, this data needs to be converted to floating point). Take writing K2 as an example, K2 needs to be converted to 32-bit floating point first, and written in (DCBA format).&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: K2 and B2 need to be read and written together&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1400H&lt;br /&gt;
| User calibration K3/B3 (read and write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 4&lt;br /&gt;
| 8 bytes in total&amp;lt;br/&amp;gt;00~03: K3&amp;lt;br/&amp;gt;04~07: B3&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;User calibration corresponds to 20~200mS/cm. Take reading K3 as an example, the readout is 4 bytes of data (low bit first, DCBA format, this data needs to be converted to floating point). Take writing K3 as an example, K3 needs to be converted to 32-bit floating point first, and written in (DCBA format).&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: K3 and B3 need to be read and written together&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 11. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 12. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_Turbidity_Probe_AT-SB-PROBE-T-P&amp;diff=1942</id>
		<title>RS-485 Turbidity Probe AT-SB-PROBE-T-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_Turbidity_Probe_AT-SB-PROBE-T-P&amp;diff=1942"/>
		<updated>2026-07-13T11:56:07Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/rs-485-turbidity-probe-at-sb-probe-t-p/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Turbidity Datasheet.png|center|frameless|321x321px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE RS-485 Turbidity Probe AT-SB-PROBE-T-P is used in environmental water quality monitoring, acid/alkali/salt solutions, chemical reaction processes, and industrial production processes. It can meet the requirements of online pH measurement for most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* 90° angle scattered light principle, built-in temperature sensor&lt;br /&gt;
* Support RS-485, Modbus/RTU protocol&lt;br /&gt;
* Optical fiber structure, strong resistance to external light interference&lt;br /&gt;
* Infrared LED light source with high stability&lt;br /&gt;
* IP68 protection, water depth within 20 meters&lt;br /&gt;
* Convenient, fast, stable and easy to maintain&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;KWS-960&#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Turbidity  PPR AT-SB-PROBE-T-P&lt;br /&gt;
|-&lt;br /&gt;
|Principle&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Light  scattering method&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; |Range/Resolution&lt;br /&gt;
|0～20.00NTU&lt;br /&gt;
|0.01NTU/0.1℃&lt;br /&gt;
|-&lt;br /&gt;
|0～200.0NTU&lt;br /&gt;
|0.01NTU/0.1℃&lt;br /&gt;
|-&lt;br /&gt;
|0～1000.0NTU&lt;br /&gt;
|0.1NTU/0.1℃&lt;br /&gt;
|-&lt;br /&gt;
|Precision&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |±3%  or ±1.5NTU(0～20.00NTU)&amp;lt;br&amp;gt;±3%  or ±2NTU(0～200.0NTU)&amp;lt;br&amp;gt;±5%  or ±3NTU(0～1000.0NTU)&lt;br /&gt;
|-&lt;br /&gt;
|Response Time (T90)&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |＜60s&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Lowest  Detection Limit&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.01 (0-20NTU)&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.3NTU&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Mode&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Two-point  calibration&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Compensation&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Automatic  temperature compensation (Pt1000)&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |RS-485  (Modbus/RTU)&lt;br /&gt;
|-&lt;br /&gt;
|Working Conditions&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0～50℃，&amp;lt;0.2MPa&lt;br /&gt;
|-&lt;br /&gt;
|Storage Temperature&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |-  5 ～ 65 ℃&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Immersion  mount with 3/4NPT pipe thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |5  meters, other lengths can be customized&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.2W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |12～24VDC&lt;br /&gt;
|-&lt;br /&gt;
|Protection Grade&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions ===&lt;br /&gt;
[[File:Turbidity Dimensions.svg|center|frameless|540x540px]]&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: The sensor joint is M16-5 core waterproof joint male head&#039;&#039;&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Pinouts ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Installation ====&lt;br /&gt;
Installation distance requirements: keep above 5cm with side wall and above 10cm with bottom.&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|812x812px]]&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1  - Pin 12-24V DC&lt;br /&gt;
|4  - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2  - GND&lt;br /&gt;
|5  – NA&lt;br /&gt;
|-&lt;br /&gt;
|3  - RS485 A+&lt;br /&gt;
|6  - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
&#039;&#039;&#039;a) Maintenance schedule&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The cleanliness of the measuring window is very important for maintaining accurate readings.&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance task&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Recommended maintenance frequency&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Calibrate  sensors&lt;br /&gt;
&lt;br /&gt;
(if  required, by the competent authority)&lt;br /&gt;
|According to the maintenance schedule  required by the competent department&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;b) Maintenance method&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Sensor outer surface: Clean the outer surface of the sensor with tap water. If debris remains, wipe it with a soft, wet cloth. For stubborn dirt, you can add some household detergent to the tap water, but rinse thoroughly with clean water afterwards.&lt;br /&gt;
* Check the cable of the sensor: The cable should not be tightened while the sensor is operating, as this may cause the internal wires to break and prevent the sensor from functioning properly.&lt;br /&gt;
* Check the sensor’s measurement window to see if there is any dirt. Use a normal cleaning brush if there is some.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Matters that require attention&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* The probe contains sensitive optical and electronic components. Make sure the probe is not subjected to severe mechanical impact. There are no components inside the probe that need to be maintained by the user; open it only when specifically instructed by ATRONIA, as opening it may damage the internal components.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;d) Sensor’s Calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Zero calibration: Take an appropriate amount of zero‑turbidity solution in a large beaker. Place the sensor vertically in the solution, ensuring that the front end of the sensor is at least 10 cm from the bottom of the beaker. Perform the zero calibration after the reading has stabilized for 3 minutes. For instructions, refer to the appendix.&lt;br /&gt;
* Slope calibration: Place the sensor probe in the standard solution, ensuring that the front end of the sensor is at least 10 cm from the bottom of the beaker. Perform the slope calibration after the reading has stabilized for 3 to 5 minutes. For instructions, refer to the appendix.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Frequently Asked Questions ====&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Problem&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Probable cause&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Solution&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |The  operating interface cannot connect or does not display the measurement  results&lt;br /&gt;
|The measured value is too&lt;br /&gt;
&lt;br /&gt;
high, too low, or the numerical value  remains unstable.&lt;br /&gt;
|Reconnect the controller and cable&lt;br /&gt;
|-&lt;br /&gt;
|Cable  failure&lt;br /&gt;
|Please contact us.&lt;br /&gt;
|-&lt;br /&gt;
|The  measured value is too&lt;br /&gt;
&lt;br /&gt;
high,  too low, or the numerical value remains unstable.&lt;br /&gt;
|The sensor window is attached to the  external object&lt;br /&gt;
|Clean the window surface of the sensor&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Information Frame  Format ====&lt;br /&gt;
(xx for one byte).&lt;br /&gt;
&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
&lt;br /&gt;
07                         03                       xx  xx                         xx   xx                    xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address   Function code   Register start address   Number of registers   CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
&lt;br /&gt;
07                         03                       xx  xx                         xx   xx                   xx  xx&lt;br /&gt;
&lt;br /&gt;
Address    Function code             Bytes                   Response data     CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
c) Wriite data instruction frame&lt;br /&gt;
&lt;br /&gt;
07                         06                       xx  xx                         xx   xx                    xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address   Function code   Register address          Read-in data       CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
d) Write data response frame (same data command frame)&lt;br /&gt;
&lt;br /&gt;
07                         06                       xx  xx                          xx   xx                   xx  xx&lt;br /&gt;
&lt;br /&gt;
Address    Function code    Register ddress            Read-in data     CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Designation&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Explain&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number of registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Access mode&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001  (0x0000)&lt;br /&gt;
|Measured value + temperature&lt;br /&gt;
|4 double-byte integers, namely, the  measured value, the number of decimal places of the measured value, the  temperature value, and the number of decimal places of the temperature value.&lt;br /&gt;
|4 (8 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097&lt;br /&gt;
&lt;br /&gt;
(0x1000))&lt;br /&gt;
|Zero calibration&lt;br /&gt;
|The 0-20NTU range is calibrated in  0-10NTU turbidity solution, and the written data is the actual value of the  standard solution × 100; the 0-100NTU range is calibrated in 0-20NTU  turbidity solution, and the written data is the actual value of the standard  solution × 10; the 0-1000NTU range is calibrated in 0-200NTU turbidity  solution, and the written data is the actual value of the standard solution ×  10; the read data is the zero-point offset.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|44101&lt;br /&gt;
&lt;br /&gt;
(0x1004)&lt;br /&gt;
|Slope calibration&lt;br /&gt;
|The 0-20NTU range is calibrated in  10-20NTU turbidity solution, and the written data is the actual value of the  standard solution × 100; the 0-100NTU range is calibrated in 20-100NTU  turbidity solution, and the written data is the actual value of the standard  solution × 10; the 0-1000NTU range is calibrated in 200-1000NTU turbidity  solution, and the written data is the actual value of the standard solution ×  10; the read data is the slope value × 1000.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|44113&lt;br /&gt;
&lt;br /&gt;
(0x1010)&lt;br /&gt;
|temperature correction&lt;br /&gt;
|When calibrated in solution, the  written data is the actual temperature value × 10; the read data is the  temperature calibration offset × 10.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48195&lt;br /&gt;
&lt;br /&gt;
(0x2002)&lt;br /&gt;
|Sensor&lt;br /&gt;
&lt;br /&gt;
address&lt;br /&gt;
|The default is 7, and the write data  range is 1-255.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48196&lt;br /&gt;
&lt;br /&gt;
(0x2003)&lt;br /&gt;
|Baud rate&lt;br /&gt;
|Default is 9600. 0-9600, 1-19200.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write/  Read&lt;br /&gt;
|-&lt;br /&gt;
|48225&lt;br /&gt;
&lt;br /&gt;
(0x2020)&lt;br /&gt;
|Reset sensor&lt;br /&gt;
|The calibration value is restored to  the default value, and the written data is 0. Note that the sensor needs to  be calibrated again after being reset before it can be used.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a) Start measurement instructions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Function: Obtain the turbidity value and temperature of the measuring probe; the unit of temperature is Celsius, and the unit of turbidity is NTU.&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;07 03 00 00 00 04 44 6F&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;07 03 08 01 02 00 01 00 B0 00 01 94 B4&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of reading:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Turbidity value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Temperature scale&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;01  02 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;00  B0 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example: turbidity value 01 02 means hexadecimal reading turbidity value, 00 01 means turbidity&lt;br /&gt;
&lt;br /&gt;
value with 1 decimal point, converted to decimal value 25.8.&lt;br /&gt;
&lt;br /&gt;
The temperature value 00 B0 represents the hexadecimal reading temperature value, and 00 01&lt;br /&gt;
&lt;br /&gt;
represents the temperature value with a decimal point converted to a decimal value of 17.6.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Calibration instructions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zero calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Set the zero-calibration value of the turbidity of the sensor; here the zero calibration is&lt;br /&gt;
&lt;br /&gt;
performed in zero turbidity water;&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;07 06 10 00 00 00 8C 6E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;07 06 10 00 00 00 8C 6E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Slope calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Set the slope calibration value of the sensor turbidity.&lt;br /&gt;
&lt;br /&gt;
For sensor with a range of 0 to 1000 NTU and 0 to 100 NTU, the slope calibration example is as&lt;br /&gt;
&lt;br /&gt;
follows (calibrated in 1000 NTU standard solution, the written value is 1000x10, i.e. 0x2710):&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;07 06 10 04 27 10 D6 91&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;07 06 10 04 27 10 D6 91&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For sensor with a range of 0 to 20 NTU, the slope calibration example is as follows (calibrated in&lt;br /&gt;
&lt;br /&gt;
20 NTU standard solution, the written value is 20x100, i.e. 0x07D0):&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;07 06 10 04 07 D0 CF 01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;07 06 10 04 07 D0 CF 01&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Role: set the MODBUS device address of the electrode;&lt;br /&gt;
&lt;br /&gt;
Change the device address 06 to 01. The example is as follows&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;07 06 20 02 00 01 E2 6C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;07 06 20 02 00 01 E3 6C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;If the sensor does not execute the upper computer command correctly, the following format information is returned:&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Function Code&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;CODE&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;CRC check&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|Number of  bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE: 01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
                  03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM：Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_pH_Probe_AT-SB-PROBE-pH-P&amp;diff=1941</id>
		<title>RS-485 pH Probe AT-SB-PROBE-pH-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_pH_Probe_AT-SB-PROBE-pH-P&amp;diff=1941"/>
		<updated>2026-07-13T11:55:08Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/rs-485-ph-probe-at-sb-probe-ph-p/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:PH Probe.png|center|frameless|311x311px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE pH POM AT-SB-PROBE-pH-P sensor is used in environmental water quality monitoring, acid/alkali/salt solutions, chemical reaction processes, and industrial production processes. It can meet the requirements of online pH measurement for most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol).&lt;br /&gt;
* Convenient connection to third-party equipment such as PLCs, DCS, industrial control computers, general controllers, paperless recorders, or touch screens.&lt;br /&gt;
* Double high-impedance differential amplifier with strong anti-interference capability and fast response.&lt;br /&gt;
* The pH probe’s internal reference solution oozes very slowly from the microporous salt bridge under a pressure of at least 100 kPa (1 bar), and its forward bleed continues for more than 20 months. Such a reference system is very stable, and the electrode life is extended by a factor of two compared to conventional industrial electrodes.&lt;br /&gt;
* Easy to install: 3/4 NPT pipe thread for easy submersible installation or installation in pipes and tanks.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
! &#039;&#039;&#039;pH POM AT-SB-PROBE-pH-P&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
|0～14pH&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±0.1pH&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|0.01pH&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
|0 ~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Work Pressure&lt;br /&gt;
|＜0.2MPa&lt;br /&gt;
|-&lt;br /&gt;
|Temperature  Compensation&lt;br /&gt;
|automatic temperature  compensation&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
|12～24VDC ±10%&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
|POM&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
|Immersion mounting, 3/4 NPT thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
|5 m, customizable&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
|Two-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
|＜0.3W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Ip Grade&lt;br /&gt;
|IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions ===&lt;br /&gt;
[[File:NO3-(4.Dimensions).svg|center|frameless|600x600px]]&lt;br /&gt;
The sensor connector is M16-5 core waterproof male connector.&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Install ====&lt;br /&gt;
Note: The sensor must not be installed horizontally or upside down. It should be mounted at an inclination of at least 15° to ensure correct operation.&lt;br /&gt;
[[File:Instalation.svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|812x812px]]&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1  - Pin 12-24V DC&lt;br /&gt;
|4  - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2  - GND&lt;br /&gt;
|5  – NA&lt;br /&gt;
|-&lt;br /&gt;
|3  - RS485 A+&lt;br /&gt;
|6  - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
When measuring with the pH sensor, it should be cleaned in distilled water (or deionized water), and filter paper should be used to absorb the moisture to prevent impurities from being introduced into the solution to be tested. One-third of the sensor should be inserted into the solution being measured. When not in use, the sensor should be washed and placed in a protective sleeve containing a 3.5 mol/L potassium chloride solution or inserted into a container with the same 3.5 mol/L potassium chloride solution.   Check whether the terminal is dry. If it is stained, wipe it with absolute alcohol and allow it to dry. Avoid long-term immersion in distilled water or protein solutions and prevent contact with silicone grease. Over time, the sensor’s glass membrane may become translucent or accumulate deposits, it can be cleaned with dilute hydrochloric acid and then rinsed with water. If the sensor is used for a long period and measurement errors occur, it must be calibrated using the meter. If calibration and measurement cannot be performed even after maintaining the sensor as described above, the sensor has failed. Please replace the sensor.&lt;br /&gt;
&lt;br /&gt;
==== Standard Buffer Ph Reference Table ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Temp(°C  )&lt;br /&gt;
|4.00&lt;br /&gt;
|4.01&lt;br /&gt;
|6.86&lt;br /&gt;
|7.00&lt;br /&gt;
|9.18&lt;br /&gt;
|10.01&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|4.00&lt;br /&gt;
|4.00&lt;br /&gt;
|6.98&lt;br /&gt;
|7.12&lt;br /&gt;
|9.46&lt;br /&gt;
|10.32&lt;br /&gt;
|-&lt;br /&gt;
|5&lt;br /&gt;
|4.00&lt;br /&gt;
|4.00&lt;br /&gt;
|6.95&lt;br /&gt;
|7.09&lt;br /&gt;
|9.39&lt;br /&gt;
|10.25&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|4.00&lt;br /&gt;
|4.00&lt;br /&gt;
|6.92&lt;br /&gt;
|7.06&lt;br /&gt;
|9.33&lt;br /&gt;
|10.18&lt;br /&gt;
|-&lt;br /&gt;
|15&lt;br /&gt;
|4.00&lt;br /&gt;
|4.00&lt;br /&gt;
|6.90&lt;br /&gt;
|7.04&lt;br /&gt;
|9.28&lt;br /&gt;
|10.12&lt;br /&gt;
|-&lt;br /&gt;
|20&lt;br /&gt;
|4.00&lt;br /&gt;
|4.00&lt;br /&gt;
|6.88&lt;br /&gt;
|7.02&lt;br /&gt;
|9.23&lt;br /&gt;
|10.06&lt;br /&gt;
|-&lt;br /&gt;
|25&lt;br /&gt;
|4.00&lt;br /&gt;
|4.01&lt;br /&gt;
|6.86&lt;br /&gt;
|7.00&lt;br /&gt;
|9.18&lt;br /&gt;
|10.01&lt;br /&gt;
|-&lt;br /&gt;
|30&lt;br /&gt;
|4.01&lt;br /&gt;
|4.02&lt;br /&gt;
|6.85&lt;br /&gt;
|6.99&lt;br /&gt;
|9.14&lt;br /&gt;
|9.97&lt;br /&gt;
|-&lt;br /&gt;
|35&lt;br /&gt;
|4.02&lt;br /&gt;
|4.02&lt;br /&gt;
|6.84&lt;br /&gt;
|6.98&lt;br /&gt;
|9.17&lt;br /&gt;
|9.93&lt;br /&gt;
|-&lt;br /&gt;
|40&lt;br /&gt;
|4.03&lt;br /&gt;
|4.04&lt;br /&gt;
|6.84&lt;br /&gt;
|6.97&lt;br /&gt;
|9.07&lt;br /&gt;
|9.89&lt;br /&gt;
|-&lt;br /&gt;
|45&lt;br /&gt;
|4.04&lt;br /&gt;
|4.05&lt;br /&gt;
|6.83&lt;br /&gt;
|6.97&lt;br /&gt;
|9.04&lt;br /&gt;
|9.86&lt;br /&gt;
|-&lt;br /&gt;
|50&lt;br /&gt;
|4.06&lt;br /&gt;
|4.06&lt;br /&gt;
|6.83&lt;br /&gt;
|6.97&lt;br /&gt;
|9.02&lt;br /&gt;
|9.83&lt;br /&gt;
|}&lt;br /&gt;
The actual reading and standard of the instrument sometimes have an error of ±1 digit.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Calibration ====&lt;br /&gt;
Note: the sensor has been calibrated at the factory, if not exceeding the measurement error, the calibration should not be random.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;a.) Zero calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use 250 mL of distilled water in a measuring cylinder, pour it into a beaker, add a packet of calibration powder with pH = 6.86, and stir evenly with a glass rod until the powder is completely dissolved. Prepare the solution with a pH of 6.86, place the sensor into the solution, and wait for 3–5 minutes. After the value stabilizes, check whether the displayed value is 6.86. If not, zero calibration is required. Refer to the appendix for calibration instructions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b)  Slope calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
“For acidic solution: Take 250 mL of distilled water in a measuring cylinder, pour it into a beaker, add a packet of calibration powder with pH = 4.00, and stir evenly with a glass rod until the powder is completely dissolved. Prepare the solution to pH = 4.00. Place the sensor into the solution and wait for 3 to 5 minutes. After the value stabilizes, check whether the value is 4.00. If not, slope calibration is required. Refer to the appendix for the calibration instructions.&lt;br /&gt;
&lt;br /&gt;
For alkaline solution: Take 250 mL of distilled water in a measuring cylinder, pour it into a beaker, add a packet of calibration powder with pH = 9.18, and stir evenly with a glass rod until the powder is completely dissolved. Prepare the solution to pH = 9.18. Place the sensor into the solution and wait for 3 to 5 minutes. After the value stabilizes, check whether the display shows 9.18. If not, slope calibration is required. Refer to the appendix for the calibration instructions.&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600 bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
Parameters such as the baud rate can be customized.&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Information Frame Format ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
&lt;br /&gt;
06                             03                           xx  xx                             xx   xx                            xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address        Function code       Register address      Number of registers       CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
&lt;br /&gt;
06                             03                          xx  xx                             xx   xx                             xx  xx&lt;br /&gt;
&lt;br /&gt;
Address        Function code               Bytes                       Answer data             RC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
c) Wriite data instruction frame&lt;br /&gt;
&lt;br /&gt;
06                             06                           xx  xx                           xx   xx                             xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address         Function code       Register address            Wriite data            CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
d) Write data response frame (same data command frame)&lt;br /&gt;
&lt;br /&gt;
06                             06                       xx  xx                             xx   xx                                xx  xx&lt;br /&gt;
&lt;br /&gt;
Address        Function code      Register ddress                Write data             CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number Of Registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Interview Method&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001(0x0000)&lt;br /&gt;
|Measured  pH + temperature&lt;br /&gt;
|4  double-byte integers, which are the measured pH, the measured pH number of decimal places, the temperature value, and  the decimal value of the temperature  value.&lt;br /&gt;
|4 ( 8 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097(0x1000)&lt;br /&gt;
|Zero  calibration&lt;br /&gt;
|Calibrated  in a standard solution with a pH of 6.86, writing data to 0&lt;br /&gt;
|1  ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44099(0x1002)&lt;br /&gt;
|Slope  calibration (4pH)&lt;br /&gt;
|Calibrated  in a standard solution with  a pH of 4.00, writing data to 0&lt;br /&gt;
|1  ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44101(0x1004)&lt;br /&gt;
|Slope  calibration (9.18pH)&lt;br /&gt;
|Calibrated in a standard solution with  a pH of 9.18, writing data to&lt;br /&gt;
|1  ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103(0x1006)&lt;br /&gt;
|Zero calibration value&lt;br /&gt;
|The  data is read out as a zero offset.&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44105(0x1008)&lt;br /&gt;
|Slope  calibration value&lt;br /&gt;
|The  read data is the slope value x1000&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44113(0x1010)&lt;br /&gt;
|Temperature  calibration&lt;br /&gt;
|Calibrated  in solution, the data written is the actual temperature value x10 ; the read  data is the temperature   calibration  offset x10 .&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48195(0x2002)&lt;br /&gt;
|Sensor  address&lt;br /&gt;
|The  default is 6 and the data range  is 1-127&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225(0x2020)&lt;br /&gt;
|Reset  sensor&lt;br /&gt;
|The  calibration value is restored to the default value and the write data is 0. Note: the sensor needs to be calibrated again after resetting.&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
Note: Modbus register address according to the protocol defined with the register type register start address (16 hex represents the actual starting address register in parentheses).&lt;br /&gt;
&lt;br /&gt;
a) When changing the sensor address, the sensor address in the return command is the changed   new address.&lt;br /&gt;
&lt;br /&gt;
b) The data definition that returns the measured value when reading data:&lt;br /&gt;
&lt;br /&gt;
xx xx                                                                       xx  xx                                                                   xx  xx                                     xx  xx&lt;br /&gt;
&lt;br /&gt;
2- byte measurement        2-byte measurement / Scale value scale number         2-byte temperature value          2-byte temperature&lt;br /&gt;
&lt;br /&gt;
The data type defaults to: double-byte integer, high byte first; others are optional as floating-point types.&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a.) Read data instruction&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Obtain the pH and temperature of the measuring probe; the unit of pH is pH; the unit of temperature is °C.&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 03 00 00 00 04 45 BE&amp;lt;/code&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 03 08 00 62 00 02 01 01 00 01 24 59&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of reading:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;pH value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Temperature value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;00  62 00 02&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;01  01 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
pH: 00 62 indicates the hexadecimal reading pH value, 00 02 indicates that the pH value has 2 decimal places and is converted to a decimal value of 0.98.&lt;br /&gt;
&lt;br /&gt;
Temperature value: 01 01 indicates the hexadecimal reading temperature value, 00 01 indicates that the temperature value has 1 decimal place and is converted to a decimal value of 25.7.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b.) Calibration instructions:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Zero calibration&lt;br /&gt;
&lt;br /&gt;
Function: Set the pH zero calibration value of the electrode. The zero value is based on the 6.86 pH standard. The examples are as follows;&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 10 00 00 00 8C BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 10 00 00 00 8C BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Slope calibration&lt;br /&gt;
&lt;br /&gt;
Function: Set the pH slope calibration value of the electrode. The slope calibration is divided into high‑point and low‑point calibration. The alkaline solution is measured at the high point, and the acidic solution is measured at the low point. The standard solutions used are 9.18 pH for the high point and 4.00 pH for the low point. Examples are as follows:&lt;br /&gt;
&lt;br /&gt;
High point standard solution 9.18 pH calibration:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 10 04 00 00 CD 7C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 10 04 00 00 CD 7C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Low standard solution 4.00 pH calibration:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 10 02 00 00 2D 7D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 10 02 00 00 2D 7D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Role: set the MODBUS device address of the electrode;&lt;br /&gt;
&lt;br /&gt;
Change the device address 06 to 01.&lt;br /&gt;
&lt;br /&gt;
The example is as follows&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 20 02 00 01 E3 BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 20 02 00 01 E3 BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
If the sensor does not execute the host command correctly, it will return the following format information:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Address&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CODE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CRC check&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|Xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|Number&lt;br /&gt;
&lt;br /&gt;
of  bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
d) CODE : 01 – function code error&lt;br /&gt;
&lt;br /&gt;
03 – data is wrong&lt;br /&gt;
&lt;br /&gt;
e) COM : Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_Nitrates_(NO3)_Probe_AT-SB-PROBE-NO3-P&amp;diff=1940</id>
		<title>RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_Nitrates_(NO3)_Probe_AT-SB-PROBE-NO3-P&amp;diff=1940"/>
		<updated>2026-07-13T11:53:40Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/rs-485-nitrates-no3-probe-at-sb-probe-no3-p/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Nitrates (NO3-).png|center|frameless|310x310px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE RS-485 Nitrates (NO3) Probe AT-SB-PROBENO3-P can be used for environmental water quality monitoring, acid/alkali/salt solutions, chemical reaction processes, and industrial production processes, and meets the requirements for online ORP measurement in most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol).&lt;br /&gt;
* Conveniently connects to third‑party equipment such as PLCs, DCS systems, industrial control computers, general controllers, paperless recorders, or touch screens.&lt;br /&gt;
* Double high‑impedance differential amplifier with strong anti‑interference capability and fast response speed.&lt;br /&gt;
* Durable ORP electrode: the internal reference fluid seeps out of the microporous salt bridge very slowly under a pressure of at least 100 kPa (1 bar), maintaining positive seepage for more than 20 months. This reference system is highly stable, and the electrode lifespan is doubled compared to ordinary industrial electrodes.&lt;br /&gt;
* Easy to install: the 3/4 NPT pipe thread allows convenient immersion installation or mounting in pipelines and tanks.&lt;br /&gt;
* IP68 protection level.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;AT-SB-PROBE-ORP-P&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-1500～+1500mV&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±6mV&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|1mV&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
|0 ~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Work Pressure&lt;br /&gt;
|＜0.1MPa&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
|12～24VDC ±10%&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
|POM&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
|Immersion mounting, 3/4 NPT thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
|15m&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
|One-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
|＜0.3W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Ip  Grade&lt;br /&gt;
|IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions ===&lt;br /&gt;
[[File:NO3-(4.Dimensions).svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Install ====&lt;br /&gt;
Note: The sensor should not be installed upside down or horizontally when installed, at least at an angle of 15 degrees or more.&lt;br /&gt;
[[File:Instalation.svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|812x812px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1  - Pin 12-24V DC&lt;br /&gt;
|4  - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2  - GND&lt;br /&gt;
|5  – NA&lt;br /&gt;
|-&lt;br /&gt;
|3  - RS485 A+&lt;br /&gt;
|6  - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
When measuring with the ORP electrode, rinse it with distilled or deionized water and gently dry it with filter paper to avoid introducing impurities into the test solution. Immerse one‑third of the electrode in the solution during measurement. When not in use, clean the electrode and store it in a protective cap or container filled with 3.5 mol/L potassium chloride solution.Ensure the terminal is dry; if dirty, clean it with absolute alcohol and let it dry. Avoid long‑term immersion in distilled water or protein solutions, and prevent contact with silicone grease.Over time, the glass membrane may become translucent or accumulate sediment; if so, clean it with diluted hydrochloric acid and rinse with water. If measurement errors persist even after calibration and proper maintenance, the electrode has likely failed and should be replaced.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 ORP standard solution preparation method ====&lt;br /&gt;
a) Preparation method of ORP standard solution (256 mV):Weigh 2.1 g of quinhydrone and add it to 200 mL of a standard pH buffer solution with pH 4.00, then mix well.&lt;br /&gt;
&lt;br /&gt;
b) Preparation method of ORP standard solution (86 mV):Weigh 2.1 g of quinhydrone and add it to 200 mL of a standard pH buffer solution with pH 6.86, then mix well.&lt;br /&gt;
&lt;br /&gt;
c) Preparation method of ORP standard solution (–40 mV):Weigh 2.1 g of quinhydrone and add it to 200 mL of a standard pH buffer solution with pH 9.18, then mix well.&lt;br /&gt;
&lt;br /&gt;
Please note that when preparing the pH buffer, a total of 250 mL is prepared, and 200 mL is used.&lt;br /&gt;
&lt;br /&gt;
Method for preparing the corresponding pH standard solution:&lt;br /&gt;
&lt;br /&gt;
          Measure 250 mL of distilled water with a graduated cylinder, pour it into a beaker, add one packet of calibration powder (pH 6.86 / 4.00 / 9.18), and stir with a glass rod until the powder is completely dissolved.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Calibration ====&lt;br /&gt;
Place the sensor in the prepared 86 mV (or 256 mV or –40 mV) solution and wait for 3 to 5 minutes. After the value stabilizes, check whether the displayed value matches 86 mV (or 256 mV or –40 mV). If not, calibration is required. See the appendix for calibration instructions.&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* Avoid exposing the inner surface of the fluorescent film head to sunlight&lt;br /&gt;
* Please do not touch the fluorescent film with your hands&lt;br /&gt;
* Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&lt;br /&gt;
* Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start&lt;br /&gt;
&lt;br /&gt;
address&lt;br /&gt;
|Number of  Registers&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
b)  Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of  Bytes&lt;br /&gt;
|Response  data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
c)  Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
d)  Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Instruction&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number  of Registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Access&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Method&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001 (0x0000)&lt;br /&gt;
|Measured value&lt;br /&gt;
|Two double-byte integers are the  measured value and the number of decimal places of the measure value.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097 (0x1000)&lt;br /&gt;
|Zero calibration&lt;br /&gt;
|Calibrate in the standard  solution, the written data is the actual value of the standard solution.&lt;br /&gt;
|1(2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103 (0x1006)&lt;br /&gt;
|Zero  calibration value&lt;br /&gt;
|Ther read data is the zero offset&lt;br /&gt;
|1(2 bytes）&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|48195 (0x2002)&lt;br /&gt;
|Sensor address&lt;br /&gt;
|The default is 6, and the write  data range is 1-127&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225 (0x2020)&lt;br /&gt;
|Reset Sensor&lt;br /&gt;
|The calibration value is restored  to the default value, and the write data is 0. Note that the sensor needs to  be calibrated again after reset before it can be used.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
a) The register address is the starting address of the register with register type defined   according to the Modbus protocol (the actual starting address of the register represented   by the hexadecimal system in parentheses).&lt;br /&gt;
&lt;br /&gt;
b) When changing the sensor address, the sensor address in the return instruction is the new   address after the change.&lt;br /&gt;
&lt;br /&gt;
c) The data definition of the measured value returned when reading the data:&lt;br /&gt;
&lt;br /&gt;
          xx               xx                                                                      xx                xx&lt;br /&gt;
&lt;br /&gt;
2-byte measurement value                                 2-byte measurement value decimal places&lt;br /&gt;
&lt;br /&gt;
The default data type is double-byte integer, high byte first; other types such as floating-point numbers are optional.&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a) Start measurement command&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Obtain the ORP measured by the sensor, the unit of ORP is mV. Request frame: &amp;lt;code&amp;gt;06 03 00 00 00 02 C5 BC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 03 04 00 78 00 00 0C EA&amp;lt;/code&amp;gt; Examples of readings:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|ORP  value&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;00 78 00 00&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example, the ORP value “00 78” represents the hexadecimal reading of the ORP value, and “00 00” indicates that the ORP value has no decimal places and no temperature value. When converted, the hexadecimal value 00 78 corresponds to a decimal value of 120.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Calibration instruction:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  The ORP sensor only requires one‑point calibration. Before calibrating with another standard solution, the electrode must be cleaned with that solution; otherwise, it may cause significant measurement errors.Place the sensor in the prepared 86 mV or 256 mV standard solution and enter the corresponding calibration command.&lt;br /&gt;
&lt;br /&gt;
The standard solution is 86mV:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 10 00 00 56 0C 83&amp;lt;/code&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 10 00 00 56 0C 83&amp;lt;/code&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
The standard solution is 256mV:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;06 06 10 00 01 00 8D 2D&amp;lt;/code&amp;gt;;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;06 06 10 00 01 00 8D 2D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: The ORP value has a negative value, such as-40mV, its calculation method is:-{FFFF-FFD7 software test value)}=-28; decimal is-40mV.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the MODBUS device address of the electrode. Change the device address 06 to 01, with the following example:&lt;br /&gt;
&lt;br /&gt;
Request frame：&amp;lt;code&amp;gt;06 06 20 02 00 01 E3 BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame：&amp;lt;code&amp;gt;06 06 20 02 00 01 E3 BD&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;7.5 Error response&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If the sensor does not execute the upper computer command correctly, the following format information is returned:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Definition&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|CODE&lt;br /&gt;
|CRC  check&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|Number of  bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE： 01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
                 03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM：Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Multiparameter_Probe_AT-SB-PROBE-MP-P-C1&amp;diff=1939</id>
		<title>Multiparameter Probe AT-SB-PROBE-MP-P-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Multiparameter_Probe_AT-SB-PROBE-MP-P-C1&amp;diff=1939"/>
		<updated>2026-07-13T11:53:13Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-rs-485-multiparameter-probe-at-sb-probe-mp-p-c1/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:MP.svg|center|frameless|288x288px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
The SENSBLUE RS‑485 Multiparameter Probe AT‑SB‑PROBE‑MP‑P is an online multiparameter self‑cleaning digital sensor introduced by the company. It adopts an integrated design, and the product is reliable and easy to use. Up to 8 parameters can be measured at the same time, with optional sensor types such as dissolved oxygen, COD, pH, ORP, conductivity/salinity, ammonia nitrogen, turbidity, etc. Using the RS‑485 bus and Modbus/RTU communication protocol, data can be directly transmitted to the acquisition platform.&lt;br /&gt;
&lt;br /&gt;
  The online multiparameter water quality sensor is equipped with an automatic cleaning device that allows setting the automatic cleaning interval and the number of cleaning cycles to match different water quality conditions. The automatic cleaning device can effectively clean the sensor surface, prevent microorganism adhesion, and greatly reduce maintenance costs. Each sensor is equipped with a quick‑plug waterproof connector, making assembly and disassembly easy. The front sensor protection cover prevents damage to the internal sensor. Slots around the protection cover effectively block large suspended particles and organisms from damaging the probe while maintaining measurement accuracy.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Digital sensor with RS‑485 bus and Modbus/RTU communication protocol.&lt;br /&gt;
* Equipped with an automatic cleaning device that effectively cleans the sensor surface, prevents microorganism attachment, ensures more accurate measurements, and reduces maintenance costs.&lt;br /&gt;
* Optional digital sensors such as dissolved oxygen, COD, conductivity/salinity, turbidity, ammonia nitrogen, pH, ORP, etc., suitable for long‑term online monitoring.&lt;br /&gt;
* Integrated design capable of measuring 8 parameters (including temperature) simultaneously.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; | &#039;&#039;&#039;Dissolved Oxygen Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Measuring Range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0～20mg/L&lt;br /&gt;
|-&lt;br /&gt;
| Accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±0.4mg/L&lt;br /&gt;
|-&lt;br /&gt;
| Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.01mg/L&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;Turbidity Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Measuring range and Accuracy&lt;br /&gt;
| 0～100NTU&lt;br /&gt;
| ±3% or ±2NTU&lt;br /&gt;
|-&lt;br /&gt;
| 0～1000NTU&lt;br /&gt;
| ±5% or ±3NTU&lt;br /&gt;
|-&lt;br /&gt;
| Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.1NTU&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;Conductivity / Salinity Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Measuring range&lt;br /&gt;
| 0～5000uS/cm&lt;br /&gt;
| 1uS/cm&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Resolution&lt;br /&gt;
| 0～200mS/cm&lt;br /&gt;
| 0.1mS/cm&lt;br /&gt;
|-&lt;br /&gt;
| 0～70PSU&lt;br /&gt;
| 0.1PSU&lt;br /&gt;
|-&lt;br /&gt;
| Accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±1.5% F.S.&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;COD Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | Measuring range&lt;br /&gt;
| COD&lt;br /&gt;
| Turbidity&lt;br /&gt;
|-&lt;br /&gt;
| 0～200mg/L equiv. KHP&lt;br /&gt;
| 0～100NTU&lt;br /&gt;
|-&lt;br /&gt;
| 0～500mg/L equiv. KHP&lt;br /&gt;
| 0～200NTU&lt;br /&gt;
|-&lt;br /&gt;
| COD accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±5% F.S.&lt;br /&gt;
|-&lt;br /&gt;
| COD resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.1mg/L&lt;br /&gt;
|-&lt;br /&gt;
| Turbidity accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±5% F.S.&lt;br /&gt;
|-&lt;br /&gt;
| Turbidity resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.1NTU&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;pH Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Measuring range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0～14pH&lt;br /&gt;
|-&lt;br /&gt;
| Accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±0.1pH&lt;br /&gt;
|-&lt;br /&gt;
| Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.01pH&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;ORP Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Measuring range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | -1500mV～+1500mV&lt;br /&gt;
|-&lt;br /&gt;
| Accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±10% or ±2mg/L&lt;br /&gt;
|-&lt;br /&gt;
| Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.1mg/L&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;Temperature&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Measuring range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0～50℃&lt;br /&gt;
|-&lt;br /&gt;
| Accuracy&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | ±0.5℃&lt;br /&gt;
|-&lt;br /&gt;
| Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 0.1℃&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;Other Information of Multi-parameter Probe&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| Output&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | RS-485 (Modbus/RTU)&lt;br /&gt;
|-&lt;br /&gt;
| Cleaning method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | Automatic cleaning&lt;br /&gt;
|-&lt;br /&gt;
| Power consumption&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 5W @ 12V&lt;br /&gt;
|-&lt;br /&gt;
| Power supply&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 12VDC ±5%&lt;br /&gt;
|-&lt;br /&gt;
| Cable length&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; | 5 meters, other lengths can be customized&lt;br /&gt;
|-&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; style=&amp;quot;background:#1B2826 !important; color:#fff !important;&amp;quot; | &#039;&#039;&#039;Chlorophyll&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
[[File:MultiparameterTD.svg|center|frameless|684x684px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: When the sensor is installed for measurement, use lifting rings or pipe thread installation to avoid direct force on the cable. The sensor connector is M16-5 core waterproof male connector.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|749x749px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Maintenance Schedule ===&lt;br /&gt;
SENSBLUE RS-485 Multiparameter Probe AT-SB-PROBEMP-P is equipped with a cleaning brush, which can extend the maintenance cycle. However, due to the diversity of the environment, it is recommended to inspect, clean and calibrate the sensors regularly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance Task&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Recommended Maintenance Frequency&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Clean  the sensor&lt;br /&gt;
|According to the use environment&lt;br /&gt;
|-&lt;br /&gt;
|Calibrate the sensor (if required by the competent  authority)&lt;br /&gt;
|Periodic one- or two-point calibration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Maintenance Methods ====&lt;br /&gt;
&#039;&#039;&#039;1.Inspection:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Check whether the sensor´s head is dirty and microorganisms are attached, whether the housing and sensor surface are damaged, whether the cable is normal, whether the test data is normal, and whether the consumables are damaged.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2. Cleaning:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Clean the outer surface of the sensor with tap water. If debris remains, wipe it with a moist soft cloth. For stubborn dirt, you may add some household detergent to the tap water.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;3.Calibration:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039; &#039;&#039;&#039; Perform single‑point or two‑point calibration of the sensor. Select the appropriate standard solution according to the corresponding sensor.&lt;br /&gt;
&lt;br /&gt;
==== 5.2 Matters Needing Attention ====&lt;br /&gt;
The probe contains sensitive optical and electronic components. Make sure the probe is not subjected to severe mechanical shock. There are no parts inside the probe that require user maintenance.&lt;br /&gt;
&lt;br /&gt;
=== 6. Modbus Protocol ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600 bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
  Parameters such as baud rate can be customized.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Information Frame  Format ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
&lt;br /&gt;
06                         03                       xx  xx                         xx   xx                    xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address   Function code   Register start address   Number of registers   CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
&lt;br /&gt;
06                         03                       xx  xx                         xx   xx                   xx  xx&lt;br /&gt;
&lt;br /&gt;
Address    Function code             Bytes                   Answer data     CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
c) Write data instruction frame&lt;br /&gt;
&lt;br /&gt;
06                         06                       xx  xx                         xx   xx                    xx  xx            &lt;br /&gt;
&lt;br /&gt;
Address   Function code   Register address          Write data       CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
d) Write data response frame (same data command frame)&lt;br /&gt;
&lt;br /&gt;
06                         06                       xx  xx                          xx   xx                   xx  xx&lt;br /&gt;
&lt;br /&gt;
Address    Function code    Register ddress            Write data     CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Register Address&lt;br /&gt;
! Name&lt;br /&gt;
! Instruction&lt;br /&gt;
! Number of Registers&lt;br /&gt;
! Access Method&lt;br /&gt;
|-&lt;br /&gt;
|0x0006&lt;br /&gt;
|Conductivity / Salinity value&lt;br /&gt;
|2 double-byte integers: conductivity/salinity value and number of decimal places.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x0008&lt;br /&gt;
|pH value&lt;br /&gt;
|2 double-byte integers: pH value and number of decimal places.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x000A&lt;br /&gt;
|ORP value&lt;br /&gt;
|2 double-byte integers: ORP value and number of decimal places.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x000C&lt;br /&gt;
|DO value&lt;br /&gt;
|2 double-byte integers: DO value and number of decimal places.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x0010&lt;br /&gt;
|Turbidity value&lt;br /&gt;
|2 double-byte integers: turbidity value and number of decimal places.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x0020&lt;br /&gt;
|Chlorophyll&lt;br /&gt;
|2×16-bit integers: chlorophyll value and decimal digits.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1000&lt;br /&gt;
|Temperature calibration&lt;br /&gt;
|Write: actual temperature ×10. Read: temperature calibration offset ×10.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1002&lt;br /&gt;
|COD zero calibration&lt;br /&gt;
|Calibration in deionized water. Write value 0 during calibration; read value is the original COD zero-point signal. For 0–200 mg/L range use 0–20 mg/L standard solution; for 0–500 mg/L range use 0–50 mg/L standard solution. Write value = standard solution ×10.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1003&lt;br /&gt;
|COD slope calibration&lt;br /&gt;
|Calibration in COD standard solutions. Write value = standard solution ×10. Read value = original slope signal.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1004&lt;br /&gt;
|COD built-in zero turbidity calibration&lt;br /&gt;
|Calibration in deionized water. Write 0; read value = zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1005&lt;br /&gt;
|COD built-in turbidity slope calibration&lt;br /&gt;
|Calibration using 20–200 NTU turbidity standard solution. Write = turbidity ×10; read = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1007&lt;br /&gt;
|Slope calibration of conductivity / salinity&lt;br /&gt;
|Calibration in standard solution. Write value = actual solution value (or ×10 depending on range). Read value = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1008&lt;br /&gt;
|Zero calibration of pH&lt;br /&gt;
|Calibration in pH 6.86 standard solution. Write 0; read value = zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1009&lt;br /&gt;
|Slope calibration of pH&lt;br /&gt;
|Calibration in pH 4.00 or pH 9.18 solution. Write 0 (pH4) or 1 (pH9). Read value = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x100A&lt;br /&gt;
|Zero calibration of ORP&lt;br /&gt;
|Calibration in ORP standard solution. Write = actual value; read = zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x100B&lt;br /&gt;
|Slope calibration of ORP&lt;br /&gt;
|Calibration in ORP standard solution. Write = standard value; read = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x100C&lt;br /&gt;
|Zero calibration of DO&lt;br /&gt;
|Calibration in oxygen-free water. Write 0; read value = zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x100E&lt;br /&gt;
|Zero calibration of NH&lt;br /&gt;
|Calibration using 1 ppm or 10 ppm solution. Write value = concentration ×10. Read value = mV ×100 corresponding to zero calibration.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x100F&lt;br /&gt;
|Slope calibration of NH+&lt;br /&gt;
|Calibration using 10 ppm or 100 ppm solution. Write value = concentration ×10. Read value = mV ×100 corresponding to slope calibration.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1010&lt;br /&gt;
|Zero calibration of turbidity&lt;br /&gt;
|Calibration in DI water or 0–20 NTU solution. Write value = turbidity ×10. Read value = zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1011&lt;br /&gt;
|Slope calibration of turbidity&lt;br /&gt;
|Calibration in turbidity standard solution. Write = turbidity ×10; read = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1020&lt;br /&gt;
|Chlorophyll zero calibration&lt;br /&gt;
|Calibration in DI water. Write 0; read value = offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1021&lt;br /&gt;
|Chlorophyll slope calibration&lt;br /&gt;
|Calibration using 200–400 µg/L standard solution. Write = value ×10; read = slope ×1000.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1300&lt;br /&gt;
|Automatic cleaning interval&lt;br /&gt;
|Default 30 minutes. Range: 6–6000 minutes.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x1301&lt;br /&gt;
|Automatic cleaning lap setting&lt;br /&gt;
|Default 3 laps. Range: 0–10 laps.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x2000&lt;br /&gt;
|Temperature sub-sensor address&lt;br /&gt;
|Default value 4. Can be set to 1, 4, 8, 32, 64, 65, etc.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x2002&lt;br /&gt;
|Sensor address&lt;br /&gt;
|Default address 6. Range: 1–127.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06) / Read (0x03)&lt;br /&gt;
|-&lt;br /&gt;
|0x2020&lt;br /&gt;
|Reset&lt;br /&gt;
|Write 0 to restore factory settings for cleaning interval, cleaning cycles, and related parameters.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write (0x06)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 7. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 8. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Low_Conductivity_Probe_AT-SB-PROBE-LC-P-C1&amp;diff=1938</id>
		<title>Low Conductivity Probe AT-SB-PROBE-LC-P-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Low_Conductivity_Probe_AT-SB-PROBE-LC-P-C1&amp;diff=1938"/>
		<updated>2026-07-13T11:52:45Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-rs-485-low-conductivity-probe-at-sb-probe-lc-p-c1/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CD.svg|center|frameless|389x389px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE RS‑485 Conductivity Probe AT‑SB‑PROBE‑C‑P features a wide measurement range with automatic range switching, integrating a built‑in temperature sensor that enables continuous real‑time temperature compensation.&lt;br /&gt;
&lt;br /&gt;
Excellent resistance to pollution even in harsh environments. Long term online monitoring will show no polarization. RS‑485 output can be networked without a controller.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Drinking water / surface water / industrial water treatment;&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol);&lt;br /&gt;
* Convenient connection to third‑party equipment such as PLCs, DCS, industrial control computers, general controllers, paperless recorders, or touch screens;&lt;br /&gt;
* Immersion installation with 3/4 NPT pipe thread, suitable for immersion or installation in pipelines and tanks;&lt;br /&gt;
* IP68 protection.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Product&#039;&#039;&#039;&lt;br /&gt;
! colspan=&amp;quot;3&amp;quot; |&#039;&#039;&#039;Conductivity Sensor&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Model&lt;br /&gt;
|LC&lt;br /&gt;
|MC&lt;br /&gt;
|HC&lt;br /&gt;
|-&lt;br /&gt;
|Measuring Range&lt;br /&gt;
|0  – 20 μS/cm&lt;br /&gt;
|0  – 200 μS/cm&lt;br /&gt;
|0  – 5000 μS/cm&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |1.5% F.S.&lt;br /&gt;
|-&lt;br /&gt;
|Response time&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |&amp;lt;10 sec&lt;br /&gt;
|-&lt;br /&gt;
|Ip Grade&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |IP68&lt;br /&gt;
|-&lt;br /&gt;
|Maximum Operating Pressure&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |6 bar&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |0~50℃&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |12～24VDC±10%&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Compensation&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |Automatic&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |ABS / SUS316L / PVC&lt;br /&gt;
|-&lt;br /&gt;
|Sensor size&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |Φ 30*185 mm&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |Standard 5m, other length customizable&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
| colspan=&amp;quot;3&amp;quot; |Two-point calibration&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
&#039;&#039;&#039;KWS-350 (Range: 0~20.00μS/cm)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:LC.svg|center|frameless|525x525px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KWS-350 (Range: 0~200.0μS/cm)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:MC.svg|center|frameless|534x534px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;KWS-350 (Range: 0~5000μS/cm)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:HC.svg|center|frameless|525x525px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|766x766px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&#039;&#039;&#039;Installation&#039;&#039;&#039;&lt;br /&gt;
[[File:Instalation.svg|center|frameless|817x817px]]&lt;br /&gt;
The sensor needs to be installed below the liquid level. The installation and use should avoid any collisions or scraping against the surface of the fluorescent film head. The fluorescent film head should also be kept from contacting the bottom sediment. Remove the rubber cover when in use.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 User and maintenance ====&lt;br /&gt;
Conventional electrodes need to be cleaned and calibrated periodically, and the maintenance interval is determined by the customer according to their operating conditions. The standard cleaning method is to use a soft brush to remove any attachments (being careful not to scratch the electrode surface), then rinse with distilled water, and perform the calibration procedure.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Calibration ====&lt;br /&gt;
a) Zero calibration: Rinse the sensor with distilled water and blot the liquid with filter paper. Connect the sensor to the power, place it upright in the air, and let it stand for about 3 minutes. After the value becomes stable, perform the zero‑point calibration. Refer to the appendix for details on the calibration instructions.&lt;br /&gt;
&lt;br /&gt;
b) Slope calibration: Place the electrode vertically in the standard solution (20% full scale), ensure that the electrode is at least 2 cm away from the bottom and side walls of the container, and perform the slope calibration. Refer to the appendix for details of the calibration instructions.&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is 9600, n, 8, 1 (baud rate 9600 bps, 1 start bit, 8 data bits, no parity, 1 stop bit). Parameters such as the baud rate can be customized.&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Information Frame Format ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
&lt;br /&gt;
06  03                           xx xx                            xx  xx                         xx  xx&lt;br /&gt;
&lt;br /&gt;
Address Function code Register address Number of registers. CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
&lt;br /&gt;
06  03                           xx                            xx......xx                         xx xx&lt;br /&gt;
&lt;br /&gt;
Address Function code  Bytes  Answer data. CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
c) Write data instruction frame&lt;br /&gt;
&lt;br /&gt;
06                                 06                              xx xx                                xx xx                       xx xx&lt;br /&gt;
&lt;br /&gt;
Address Function code. Register address. Write data. CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
d) Write data response frame (same data command frame)&lt;br /&gt;
&lt;br /&gt;
06                             xx xx                            xx xx                         xx xx&lt;br /&gt;
&lt;br /&gt;
Address Function code. Register address. Write data. CRC check code (low byte first)&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Register address&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Explain&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Number  of registers&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Access  Mode&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001 (0x0000)&lt;br /&gt;
|Measured Value + Temperature&lt;br /&gt;
|Four double‑byte integers are  measured: the value, its decimal places, the temperature value, and the  temperature decimal places.&lt;br /&gt;
|4（8byte)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097 (0x1000)&lt;br /&gt;
|Zero Calibration&lt;br /&gt;
|Calibrate in the air, write data  as 0&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44101 (0x1004)&lt;br /&gt;
|Slope Calibration&lt;br /&gt;
|Calibrate in a known standard  solution (20%–full scale). The written data is the actual value of the  standard solution.&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103&lt;br /&gt;
&lt;br /&gt;
(0x1006)&lt;br /&gt;
|Zero-point calibration value&lt;br /&gt;
|The read value represents the  zero offset.&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44105&lt;br /&gt;
&lt;br /&gt;
(0x1008)&lt;br /&gt;
|Slope&lt;br /&gt;
&lt;br /&gt;
calibration&lt;br /&gt;
&lt;br /&gt;
Value&lt;br /&gt;
|The  read  data  is  the slope  value×1000.&lt;br /&gt;
|1（2byte）&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44113&lt;br /&gt;
&lt;br /&gt;
(0x1010)&lt;br /&gt;
|temperature&lt;br /&gt;
&lt;br /&gt;
Correction&lt;br /&gt;
|In  solution, the value written is the actual temperature ×10. The read value is  the temperature calibration offset ×10.&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Write / read&lt;br /&gt;
|-&lt;br /&gt;
|48195&lt;br /&gt;
&lt;br /&gt;
(0x2002)&lt;br /&gt;
|Sensor&lt;br /&gt;
&lt;br /&gt;
Address&lt;br /&gt;
|The default is 6, and the write data&lt;br /&gt;
&lt;br /&gt;
range is 1 ≤  127.&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Write / read&lt;br /&gt;
|-&lt;br /&gt;
|48225&lt;br /&gt;
&lt;br /&gt;
(0x2020)&lt;br /&gt;
|Reset sensor&lt;br /&gt;
|Restores  calibration values to default. Write value 0. After reset, the sensor must be  recalibrated.&lt;br /&gt;
|1（2byte)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: Register address is the register start address with register type defined according to Modbus protocol (the actual register start address represented by hexadecimal in parentheses). When you change the sensor address, the sensor address in the return instruction is the changed new address. The data definition that returns the measured value when reading the data:&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;xx  xx  xx  xx  xx xx  xx  xx&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;2 bytes measured value Number of decimal places of 2 bytes measured  2 bytes temperature value  2-byte temperature decimal places. The data type defaults to a double-byte integer, with high bytes in front of it; others, such as floating- point types, are optional.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command Example ====&lt;br /&gt;
&#039;&#039;&#039;a) Start measurement command&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Get the conductivity and temperature measured by the sensor; the unit of temperature is degrees Celsius, and the unit of conductivity is US/cm;&lt;br /&gt;
&lt;br /&gt;
Request frame：&amp;lt;code&amp;gt;01 03 00 00 00 04 44 09&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame：&amp;lt;code&amp;gt;01 03 0C 01 02 00 01 00 B0 00 01 00A5 00 01 35 73&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example of reading:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Temperature  scale&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Conductivity value&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;TDS value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;00  B0 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;01 02 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;00 A5 00 00&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example:&lt;br /&gt;
&lt;br /&gt;
* Conductivity value 01 02 represents the hexadecimal reading of the conductivity value, and 00 00 indicates that the conductivity value has no decimal point (the number of decimal places depends on the range), resulting in a decimal value of 258. &lt;br /&gt;
* Temperature value 00 B0 represents the hexadecimal reading of the temperature value, and 00 01 indicates that the temperature value has 1 decimal place, resulting in a decimal value of 17.6.&lt;br /&gt;
* TDSvalue00A5indicates the TDS value in hexadecimal reading, 00 00 indicates the temperature value without decimal point, and the decimal value is 165.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Calibration instruction&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Zero-point calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Set the zero-point calibration value of the conductivity of the sensor here the zero-point calibration is carried out in the air:&lt;br /&gt;
&lt;br /&gt;
Request frame：&amp;lt;code&amp;gt;01 06 10 00 00 00 8D 0A&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame ：&amp;lt;code&amp;gt;01 06 10 00 00 00 8D 0A&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Slope calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Set the conductivity slope calibration value of the sensor; here the slope value is based on the actual standard solution value, taking 5000uS/cm as an example for reference calibration:&lt;br /&gt;
&lt;br /&gt;
Request frame： &amp;lt;code&amp;gt;01 06 10 04 01 F4 CC DC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame：&amp;lt;code&amp;gt;01 06 10 04 01 F4 CC DC&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device address&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the Modbus device address of the electrode; Change the device address 06 to 01, with the following:&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;01 06 20 02 00 06A3 C8&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;01 06 20 02 00 06A3 C8&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error Response ====&lt;br /&gt;
If the sensor does not execute the host command correctly, it will return the following format information:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Address&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function  code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CODE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CRC  Check&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Data&#039;&#039;&#039;&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Number of bytes&#039;&#039;&#039;&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE: &lt;br /&gt;
&lt;br /&gt;
01 – function code error&lt;br /&gt;
&lt;br /&gt;
03 – data error&lt;br /&gt;
&lt;br /&gt;
b) COM: Received function&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-T-C1&amp;diff=1937</id>
		<title>Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-T-C1&amp;diff=1937"/>
		<updated>2026-07-13T11:52:14Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-rs-485-dissolved-oxygen-probe-at-sb-probe-do-t-c1/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Dissolved-Oxygen-T.png|center|frameless|425x425px]]&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
 &amp;quot;The SENSBLUE RS-485 Dissolved Oxygen Probe (AT-SB-PROBE-DO-T-C1) is designed for the aquaculture industry. It offers stable online monitoring, providing excellent performance compared with traditional sensors. As a fluorescence-based dissolved oxygen sensor, it requires no membrane or electrolyte and features strong anti-interference capabilities. It does not require frequent calibration, has no oxygen consumption, and no flow rate limitations. Additionally, it includes automatic temperature and gas pressure compensation, a fast reaction speed, and a long service life. This makes it an economical and convenient choice for the real-time dynamic monitoring of oxygen levels in aquaculture.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Digital sensor, RS485 output, support MODBUS&lt;br /&gt;
* No electrolyte required, strong anti-interference, no need for frequent calibration; no oxygen consumption, no flow rate limit;&lt;br /&gt;
* Built-in temperature sensor, automatic temperature compensation;&lt;br /&gt;
* Tailor-made for the breeding market, with cost-effective performance&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Measurement  principle&#039;&#039;&#039;&lt;br /&gt;
|Fluorescence method&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Range&#039;&#039;&#039;&lt;br /&gt;
|0-20mg/L or 0-200% saturation&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Accuracy&#039;&#039;&#039;&lt;br /&gt;
|±3%&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Casing material&#039;&#039;&#039;&lt;br /&gt;
|316L(KWS-630) Titanium  alloy(KWS-630T)&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Max  water depth&#039;&#039;&#039;&lt;br /&gt;
|30m&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Response time&#039;&#039;&#039;&lt;br /&gt;
|60s&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Temperature  range&#039;&#039;&#039;&lt;br /&gt;
|0-50℃&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sensor interface&#039;&#039;&#039;&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Power consumption&#039;&#039;&#039;&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-0.1W  (recommended power supply: DC9-24V, current&amp;gt;50mA)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Assembly&#039;&#039;&#039;&lt;br /&gt;
|M22*1.5  (optional accessories can be converted to&lt;br /&gt;
&lt;br /&gt;
NPT3/4  thread), immersion installationa&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Sensor dimensions&#039;&#039;&#039;&lt;br /&gt;
|Φ22mm*152.7mm&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Probe  cable length&#039;&#039;&#039;&lt;br /&gt;
|10 meters (default), customizable&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Calibration&#039;&#039;&#039;&lt;br /&gt;
|One  or two-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Fluorescent cap life&#039;&#039;&#039;&lt;br /&gt;
|Guaranteed to use for one year (under  normal use)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
[[File:Dissolved T TD.svg|center|frameless|700x700px]]&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Pinouts ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Installation ====&lt;br /&gt;
(1) Removing the protective cover Prior to installation, please remove the rubber protective cap from the front of the dissolved oxygen sensor and keep it in a safe place.&lt;br /&gt;
&lt;br /&gt;
(2) Wiring and power supply:&lt;br /&gt;
&lt;br /&gt;
  1. The sensor&#039;s watertight connector, and the cable (or female connector) must be tightly screwed together to prevent water ingress.&lt;br /&gt;
&lt;br /&gt;
  2. Do not use the sensor cable to suspend the sensor. It is recommended to install a cable protective sleeve to ensure the connection remains powered and watertight.&lt;br /&gt;
&lt;br /&gt;
  3. Before switching on the power, ensure that the supply voltage and wiring sequence are correct.&lt;br /&gt;
&lt;br /&gt;
(3) Sensor installation&lt;br /&gt;
&lt;br /&gt;
  1. The unit features an M22*1.5 rear thread (optional accessories are available to convert this to an NPT 3/4&amp;quot; thread) for fixed or shell-clamp installation. (Note: It is recommended to install the sensor with the electrode facing downwards).&lt;br /&gt;
&lt;br /&gt;
  2. To account for fluctuating water levels, it is recommended to install the sensor at least 30cm below the lowest water line to avoid prolonged exposure to air during measurement.&lt;br /&gt;
&lt;br /&gt;
  3. The sensor must be securely fixed to prevent probe damage caused by water flow or other external factors.&lt;br /&gt;
&lt;br /&gt;
==== 5.2 Pinouts ====&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|765x765px]]&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 6. Calibration ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Calibration method ====&lt;br /&gt;
The dissolved oxygen sensor supports single-point (typically the 100% saturation point) or two-point calibration. The calibration parameter uses a percentage scale (expressed as a decimal, e.g. 0.96 for 96%). Single-point calibration primarily adjusts the K-value (slope), whereas two-point calibration adjusts both the K and B values (slope and offset).&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Standard solution preparation ====&lt;br /&gt;
1.) Zero-point standard solution To prepare the zero-point standard solution, pour 200ml of distilled water into a beaker. Gradually add anhydrous sodium sulfite while stirring until the solution is saturated (i.e., when it can no longer dissolve and solid crystals begin to appear). The resulting mixture is your zero-point standard solution.&lt;br /&gt;
&lt;br /&gt;
2.) 100% oxygen environment Pour 200ml of pure or distilled water into a beaker. Use a small aerator to oxygenate the water thoroughly for 10–15 minutes (larger volumes of water will require more time).Note: If on-site conditions are restricted, the sensor can be cleaned and a saturation-point calibration can be performed in open air, though accuracy may be slightly reduced.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Manual calibration calculation of K and B example (taking 2-point calibration as an example) ====&lt;br /&gt;
First, restore the user calibration data to the default settings: K=1, B=0 (refer to the Modbus documentation for details). Clean the sensor and place it in a 100% oxygen environment (air). Read the dissolved oxygen value and wait for the data to stabilize. The value should be close to 1 (i.e. 100% saturation), for example, 0.96; record this value as Y. Wash the sensor again and place it in the zero-point standard solution, ensuring the front end of the sensor is completely immersed. Read the dissolved oxygen value and wait for the data to stabilize at a value close to 0, for example, 0.015; record this as X. Calculate the new K and B values using the following formulas:&lt;br /&gt;
&lt;br /&gt;
K = 1 - 0 / Y – X              B = - K x X&lt;br /&gt;
&lt;br /&gt;
Finally, write the calculated &#039;&#039;&#039;K&#039;&#039;&#039; and &#039;&#039;&#039;B&#039;&#039;&#039; values into the sensor registers (see the Modbus documentation for further details).&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Required equipment and materials ====&lt;br /&gt;
Anhydrous sodium sulfite powder; Deionized water or distilled water (such as Watsons distilled water); Beaker, gloves, stirring rod, small aerator.&lt;br /&gt;
&lt;br /&gt;
=== 7. Maintenance schedule and methods ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Maintenance cycle ====&lt;br /&gt;
Different from the electrochemical principle of dissolved oxygen probes, fluorescence dissolved oxygen probes do not consume oxygen, have no filling fluid, etc., and do not require frequent maintenance. Normal cleaning and user calibration are sufficient.&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance tasks&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance cycle (cleaning,  calibration)&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Cleaning  the sensor&lt;br /&gt;
|Recommended every 2~3 weeks (extended  for automatic cleaning brushes. Shortened for those without cleaning brushes  and large biomass)&lt;br /&gt;
|-&lt;br /&gt;
|Inspecting the sensor and fluorescent  cap for damage&lt;br /&gt;
|Check every 30 days&lt;br /&gt;
|-&lt;br /&gt;
|Replacing the fluorescent cap&lt;br /&gt;
|Replace once a year&lt;br /&gt;
|-&lt;br /&gt;
|Calibrating the sensor&lt;br /&gt;
|Recommended every 30 days for frequent  use; before each use for occasional use; or adjust according to actual  working conditions on site.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;Note: The maintenance frequency in the above table is only a suggestion. Please ask maintenance&#039;&#039; &#039;&#039;personnel to maintain the sensor according to the actual use of the sensor; however, it is recommended to replace the fluorescent cap once a year.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Maintenance methods ====&lt;br /&gt;
&#039;&#039;&#039;(1) Sensor maintenance&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  a.) Cleaning the outer surface of the sensor: Use tap water to clean the outer surface of the sensor. If there are still debris left, wipe it with a damp soft cloth. For some stubborn dirt, you can add some household detergent to the tap water to clean it;&lt;br /&gt;
&lt;br /&gt;
  b.) Cleaning the outer surface of the fluorescent cap: Remove the protective cover at the front of the sensor (if any), rinse the dirt on the sensor light window with clean water, and finally put the protective cover on; if you need to wipe it, please wipe it gently with a soft cloth and do not scratch it hard, otherwise, it will scratch or break the fluorescent film layer, and the sensor will not work properly.&lt;br /&gt;
&lt;br /&gt;
  c.) Cleaning the inner surface of the fluorescent cap: If water vapor or dust invades the inside of the fluorescent cap, the cleaning steps are as follows:&lt;br /&gt;
&lt;br /&gt;
* Remove the fluorescent cap and rinse the inner surface of the fluorescent cap with tap water;&lt;br /&gt;
* For dirt containing fat and oil, use warm water with household detergent to clean it;&lt;br /&gt;
* Rinse the inner surface of the fluorescent cap with deionized water;&lt;br /&gt;
&lt;br /&gt;
Gently wipe all surfaces with a clean lint-free cloth and place it in a dry place to allow the water to evaporate completely.&lt;br /&gt;
&lt;br /&gt;
  d.) Check the sensor body and cable: The cable should not be tight during normal operation, otherwise there is a risk of cable breakage, resulting in communication abnormalities; check whether the sensor housing is damaged due to corrosion or other reasons.&lt;br /&gt;
&lt;br /&gt;
  e.) Daily storage of the fluorescent cap: When not in use, place it in a protective cover with a moist sponge and check and rehydrate it regularly to keep the fluorescent film moist for a long time. If the head of the sensor fluorescent cap is dry for a long time, the measurement results will drift. It needs to be soaked in water for 48 hours before continuing to work.&lt;br /&gt;
&lt;br /&gt;
 &#039;&#039;&#039;(2) Precautions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Avoid the inner surface of the fluorescent cap from being exposed to sunlight. Please do not scratch the fluorescent film with your hands. Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use.&lt;br /&gt;
&lt;br /&gt;
=== 8. FAQ ===&lt;br /&gt;
The following table lists possible problems with dissolved oxygen sensors and their solutions. If your problem is not listed or the solution does not solve your problem, please contact us.&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Fault phenomenon&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Possible causes&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Solution&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |The  probe cannot communicate or does not display the measurement result&lt;br /&gt;
|Error in connection between controller&lt;br /&gt;
&lt;br /&gt;
and cable&lt;br /&gt;
|Reconnect the controller&lt;br /&gt;
&lt;br /&gt;
and cable&lt;br /&gt;
|-&lt;br /&gt;
|Cable failure&lt;br /&gt;
|Contact us&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;4&amp;quot; |The measurement value is too high, too  low or the value is continuously Unstable&lt;br /&gt;
|Foreign objects attached to the outer surface of the fluorescent cap&lt;br /&gt;
|Clean the outer surface of the fluorescent cap&lt;br /&gt;
|-&lt;br /&gt;
|The fluorescent cap is damaged&lt;br /&gt;
|Replace the fluorescent cap&lt;br /&gt;
|-&lt;br /&gt;
|The fluorescent cap has exceeded its service life&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; |Contact us&lt;br /&gt;
|-&lt;br /&gt;
|Internal hardware failure of the probe&lt;br /&gt;
|-&lt;br /&gt;
|The temperature measurement value  exceeds the measurable range or the reading is garbled&lt;br /&gt;
|Temperature sensor or probe failure&lt;br /&gt;
|Contact us&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 9. Modbus Protocol ===&lt;br /&gt;
The RS485 communication protocol uses MODBUS communication protocol, and the sensors are used as slaves.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
| style=&amp;quot;width: 50%;&amp;quot; | Baud rate&lt;br /&gt;
| style=&amp;quot;width: 50%;&amp;quot; | 9600&lt;br /&gt;
|-&lt;br /&gt;
| Starting position || 1&lt;br /&gt;
|-&lt;br /&gt;
| Data bits || 8&lt;br /&gt;
|-&lt;br /&gt;
| Stop bit || 1&lt;br /&gt;
|-&lt;br /&gt;
| Check digit || N&lt;br /&gt;
|}&lt;br /&gt;
Read and write data (standard MODBUS protocol).&lt;br /&gt;
&lt;br /&gt;
The default address is 0x01, the address can be modified by register&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reading data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Host call (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;01 03 00 00 00 01 84 0A&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Function Definition&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Remarks&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|03&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|00 00&lt;br /&gt;
|Start Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Number of registers&lt;br /&gt;
|Length of registers (2 bytes for 1  register)&lt;br /&gt;
|-&lt;br /&gt;
|84 0A&lt;br /&gt;
|CRC checksum, front low and back high&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Slave answer (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;01 03 02 00 xx xx xx xx&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%; text-align: center;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 20%;&amp;quot; | Code&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Function Definition&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Remarks&lt;br /&gt;
|-&lt;br /&gt;
| 01 || Device Address ||&lt;br /&gt;
|-&lt;br /&gt;
| 03 || Function Code ||&lt;br /&gt;
|-&lt;br /&gt;
| 02 || Number of bytes read ||&lt;br /&gt;
|-&lt;br /&gt;
| XX XX || Data (front low and back high DCBA) || See register table for details&lt;br /&gt;
|-&lt;br /&gt;
| XX XX || CRC checksum, front low and back high ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Writing data&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Host call (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;01 10 1B 00 00 01 02 01 00 0C C1&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%; text-align: center;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 20%;&amp;quot; | Code&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Function Definition&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Remarks&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|1B 00&lt;br /&gt;
|Register Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Number of registers&lt;br /&gt;
|Number of read registers&lt;br /&gt;
|-&lt;br /&gt;
|02&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|Number of read registers x2&lt;br /&gt;
|-&lt;br /&gt;
|01 00&lt;br /&gt;
|Data (front low and back high DCBA)&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|0C C1&lt;br /&gt;
|CRC checksum, front low and back high&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
Slave answer (hexadecimal)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;01 10 1B 00 00 01 07 2D&amp;lt;/code&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%; text-align: center;&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 20%;&amp;quot; | Code&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Function Definition&lt;br /&gt;
! style=&amp;quot;width: 40%;&amp;quot; | Remarks&lt;br /&gt;
|-&lt;br /&gt;
|01&lt;br /&gt;
|Device Address&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|10&lt;br /&gt;
|Function Code&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|1B 00&lt;br /&gt;
|Register Address&lt;br /&gt;
|See register table for details&lt;br /&gt;
|-&lt;br /&gt;
|00 01&lt;br /&gt;
|Returns the number of registers written&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|7D 2D&lt;br /&gt;
|CRC checksum (front low and back high)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Register Table&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot; style=&amp;quot;width: 100%; border-collapse: collapse;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! style=&amp;quot;width: 15%;&amp;quot; | Start address&lt;br /&gt;
! style=&amp;quot;width: 25%;&amp;quot; | Command Description&lt;br /&gt;
! style=&amp;quot;width: 10%;&amp;quot; | Number of registers&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | Data format (hexadecimal)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1100H&lt;br /&gt;
| User calibration K/B (read/write)&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Note: K and B need to be read and written at the same time, and separate reading and writing are not supported.&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 4&lt;br /&gt;
| 8 bytes in total 00~03: K 04~07: B&amp;lt;br/&amp;gt;To read K for example, read out as 4 bytes of data (low bit in front, DCBA format, need to convert this data to floating point) To write k, for example, we need to convert k to 32-bit floating point and write it in (DCBA format)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x2700H&lt;br /&gt;
| Fluorescent cap parameters settings&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 16&lt;br /&gt;
| 32 bytes in total&amp;lt;br /&amp;gt;00~03: L0&amp;lt;br /&amp;gt;04~07: L1&amp;lt;br /&amp;gt;08~11: L2&amp;lt;br /&amp;gt;12~15: L3&amp;lt;br /&amp;gt;16~19: TanZero&amp;lt;br /&amp;gt;20~23: T0&amp;lt;br /&amp;gt;24~27: T1&amp;lt;br /&amp;gt;28~31: T2&amp;lt;br /&amp;gt;DCBA format, this data needs to be converted to floating point numbers&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x2600H&lt;br /&gt;
| Dissolved oxygen value acquisition&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 6&lt;br /&gt;
| 12 bytes in total&amp;lt;br /&amp;gt;00~03: Temperature values&amp;lt;br /&amp;gt;04~07: Dissolved oxygen percentage&amp;lt;br /&amp;gt;08~011: Dissolved oxygen mg/L&amp;lt;br /&amp;gt;Reads the temperature value / dissolved oxygen value as 4 bytes of data each (low bit first, DCBA format, this data needs to be converted to floating point number)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x3000H&lt;br /&gt;
| Device address (read / write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 2&lt;br /&gt;
| 00~01: Device address Settable in the range 1 to 254 e.g. get data as 02 00 (low bit first means address is 2) To write to address 15, for example, write 0F 00 (lower bit first) to the corresponding address When the current device address is unknown, FF can be used as a generic device address to interrogate the current device address&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x1500H&lt;br /&gt;
| Setting salinity values (read / write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 2&lt;br /&gt;
| 4 bytes in total 00~03: Salinity value Default is 0, unit ppt, DCBA format, this data needs to be converted to floating point number)&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 0x2400H&lt;br /&gt;
| Set air pressure value (read / write)&lt;br /&gt;
| style=&amp;quot;text-align: center;&amp;quot; | 2&lt;br /&gt;
| 4 bytes in total 00~03: Air pressure value The default standard atmospheric pressure is 101.325, unit kpa, DCBA format, this data needs to be converted into a floating-point number&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 11. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 12. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1936</id>
		<title>Template:Other Probes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1936"/>
		<updated>2026-07-13T11:50:30Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Firmware  v.&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000065&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000085&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000091&lt;br /&gt;
|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000086&lt;br /&gt;
|[[Low Conductivity Probe AT-SB-PROBE-LC-P-C1|SENSBLUE RS-485 Low Conductivity Probe AT-SB-PROBE-LC-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000087&lt;br /&gt;
|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000068&lt;br /&gt;
|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000089&lt;br /&gt;
|[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|SENSBLUE RS-485 Salinity/Conductivity/TDS Probe AT-SB-PROBE-S-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000067&lt;br /&gt;
|[[RS-485 pH Probe AT-SB-PROBE-pH-P|SENSBLUE RS-485 pH Probe AT-SB-PROBE-pH-P, w/ 15m cable w/conector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000088&lt;br /&gt;
|[[RS-485 ORP Probe POM AT-SB-PROBE-ORP-P|SENSBLUE RS-485 ORP Probe POM AT-SB-PROBE-ORP-P, w/ 15m cable w/conector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000069&lt;br /&gt;
|[[RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P|SENSBLUE RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000090&lt;br /&gt;
|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000066&lt;br /&gt;
|[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|SENSBLUE RS-485 Turbidity Probe AT-SB-PROBE-T-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000073&lt;br /&gt;
|[[Multiparameter Probe AT-SB-PROBE-MP-P-C1|SENSBLUE RS-485 Multiparameter Probe AT-SB-PROBE-MP-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.71&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1935</id>
		<title>RS-485 ORP Probe POM AT-SB-PROBE-ORP-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1935"/>
		<updated>2026-07-13T11:48:54Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:ORP-100-PH-10-ORP-10-PH-100.png|center|frameless|345x345px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE Monarch ORP Probe POM AT-SB-PROBE-ORP-P can be used for environmental water quality monitoring, acid/alkali/salt solution, chemical reaction process, industrial production process, and can meet the requirements of online ORP measurement for most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol).&lt;br /&gt;
* Conveniently connect to third-party equipment such as PLC, DCS, industrial control computer, general controller, paperless recording instrument or touch screen.&lt;br /&gt;
* Double high impedance differential amplifier, strong anti-interference and fast response speed.&lt;br /&gt;
* Durable ORP electrode, the internal reference fluid seeps out from the microporous salt bridge very slowly under a pressure of at least 100KPa (1Bar), and its positive seepage lasts for more than 20 months. Such a reference system is very stable, and the electrode life is doubled compared to ordinary industrial electrodes.&lt;br /&gt;
* Easy to install: 3/4NPT pipe thread is convenient for sinking installation or installation in pipelines and tanks.&lt;br /&gt;
* IP68protection level.&lt;br /&gt;
* R-485 interface, Modbus/RTU protocol.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;AT-SB-PROBE-ORP-P&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
| -1500～+1500mV&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±6mV&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|1mV&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
|0 ~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Work Pressure&lt;br /&gt;
|＜0.1MPa&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
|12～24VDC ±10%&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
|POM&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
|Immersion mounting, 3/4 NPT thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
|15m&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
|One-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
|＜0.3W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Ip Grade&lt;br /&gt;
|IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimension ===&lt;br /&gt;
[[File:ORP Probe dimensions.svg|center|frameless|540x540px]]&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Install ====&lt;br /&gt;
Note: The sensor should not be installed upside down or horizontally when installed, at least at an angle of 15 degrees or more.&lt;br /&gt;
[[File:Instalation.svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
==== 5.2 Electrical connection ====&lt;br /&gt;
&lt;br /&gt;
* Red wire-power cord（12～24 V）&lt;br /&gt;
* Black wire-ground wire（GND）&lt;br /&gt;
* Blue Line-485 A&lt;br /&gt;
* White Line-485 B&lt;br /&gt;
&lt;br /&gt;
Check the wiring sequence carefully before powering on to avoid unnecessary losses caused by wiring errors.&lt;br /&gt;
&lt;br /&gt;
==== 5.3 Wiring instructions ====&lt;br /&gt;
Considering that the cables have been immersed in water (including seawater) or exposed to air for a long time, all wiring positions are required to be waterproof, and the cables should have certain corrosion resistance.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
When measuring the ORP electrode, it should be cleaned in distilled water (or deionized water) first, and the water should be absorbed with filter paper to prevent impurities from being brought into the test solution. 1/3 of the electrode should be inserted into the test solution. The electrode should be cleaned when not in use and inserted into a protective cover with 3.5mol/L potassium chloride solution or inserted into a container with 3.5mol/L potassium chloride solution. Check whether the terminal is dry, if it is stained, wipe it with absolute alcohol and blow it dry before use. Avoid long-term immersion in distilled water or protein solution and prevent contact with silicone grease. For electrodes that have been used for a long time, its glass membrane may become translucent or attached with sediment. In this case, it can be washed with diluted hydrochloric acid and rinsed with water. The electrode has been used for a long time, and when there is a measurement error, it must be calibrated and corrected with the meter. When the electrode is still unable to be calibrated and measured when the electrode is maintained and maintained by the above method, it means that the electrode has failed. Please replace the electrode.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 ORP standard solution preparation method ====&lt;br /&gt;
a) Preparation method of ORP standard solution 256mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 4.00 and mix well.&lt;br /&gt;
&lt;br /&gt;
b) Preparation method of ORP standard solution 86mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 6.86 and mix well.&lt;br /&gt;
&lt;br /&gt;
c) Preparation method of ORP standard solution-40mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 9.18 and mix well.&lt;br /&gt;
&lt;br /&gt;
Please note that when preparing the pH, a total of 250 mL is prepared, and 200 mL is measured for use.&lt;br /&gt;
&lt;br /&gt;
Method of preparing corresponding standard solution for pH:&lt;br /&gt;
&lt;br /&gt;
Measure 250mL of distilled water with a graduated cylinder, pour it into a beaker, add a package of calibration powder with pH=6.86/4.00/9.18, stir with a glass rod until the powder is completely dissolved, and prepare a solution with pH=6.86/4.00/9.18.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Calibration ====&lt;br /&gt;
Put the sensor into the prepared 86mV (or 256mV or-40mV) solution and wait for 3 to 5 minutes. After the value is stable, check whether the displayed value is 86mV (or 256mV or-40mV). If not, you need to calibrate it. See the appendix for calibration instructions.&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* Avoid exposing the inner surface of the fluorescent film head to sunlight&lt;br /&gt;
* Please do not touch the fluorescent film with your hands&lt;br /&gt;
* Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&lt;br /&gt;
* Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start address&lt;br /&gt;
|Number of registers&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|Response data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
c) Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
d) Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Instruction&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number of Registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Access Method&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001 (0x0000)&lt;br /&gt;
|Measured value&lt;br /&gt;
|Two double-byte integers are the measured value and the number of decimal places of the measured value.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097 (0x1000)&lt;br /&gt;
|Zero calibration&lt;br /&gt;
|Calibrate in the standard solution, the written data is the actual value of the standard solution.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103 (0x1006)&lt;br /&gt;
|Zero calibration value&lt;br /&gt;
|The read data is the zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|48195 (0x2002)&lt;br /&gt;
|Sensor address&lt;br /&gt;
|The default is 6, and the write data range is 1-127.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225 (0x2020)&lt;br /&gt;
|Reset sensor&lt;br /&gt;
|The calibration value is restored to the default value, and the write data is 0. Note that the sensor needs to be calibrated again after reset before it can be used.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44105(0x1008)&lt;br /&gt;
|Slope  calibration value&lt;br /&gt;
|The  read data is the slope value x1000&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44113(0x1010)&lt;br /&gt;
|Temperature  calibration&lt;br /&gt;
|Calibrated  in solution, the data written is the actual temperature value x10 ; the read  data is the temperature   calibration  offset x10 .&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48195(0x2002)&lt;br /&gt;
|Sensor  address&lt;br /&gt;
|The  default is 6 and the data range  is 1-127&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225(0x2020)&lt;br /&gt;
|Reset  sensor&lt;br /&gt;
|The  calibration value is restored to the default value and the write data is 0. Note: the sensor needs to be calibrated again after resetting.&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
a) The register address is the starting address of the register with register type defined according to the Modbus protocol (the actual starting address of the register represented by the hexadecimal system in parentheses).&lt;br /&gt;
&lt;br /&gt;
b) When changing the sensor address, the sensor address in the return instruction is the new address after the change.&lt;br /&gt;
&lt;br /&gt;
c)The data definition of the measured value returned when reading the data:&lt;br /&gt;
&lt;br /&gt;
xx       xx                                                            xx       xx&lt;br /&gt;
&lt;br /&gt;
2-byte measurement value               2-byte measurement value decimal places&lt;br /&gt;
&lt;br /&gt;
The default data type is: double-byte integer, high byte first; other types such as floating-point numbers are optional&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a) Start measurement command&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Obtain the ORP measured by the sensor, the unit of ORP is mV.&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 03 00 00 00 02 C5 BC&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 03 04 00 78 00 00 0C EA&lt;br /&gt;
&lt;br /&gt;
Examples of readings:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;ORP value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;00 78 00 00&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example, ORP value: 00 78 represents the hexadecimal reading ORP value, 00 00 represents the ORP value without a decimal point and no temperature value, converted to a decimal value of 120.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Calibration instruction:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ORP sensor only needs one point calibration. Before calibrating with another calibration solution, the electrode must be cleaned with the latter calibration solution, otherwise it will cause a larger test error.&lt;br /&gt;
&lt;br /&gt;
In the prepared 86mV or 256mV standard solution, enter the corresponding calibration instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The standard solution is 86mV:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 06 10 00 00 56 0C 83;&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 06 10 00 00 56 0C 83;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The standard solution is 256mV:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 06 10 00 01 00 8D 2D;&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 06 10 00 01 00 8D 2D&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The ORP value has a negative value, such as-40mV, its calculation method is:-{FFFF-FFD7 software test value)}=-28; decimal is-40mV.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the MODBUS device address of the electrode.&lt;br /&gt;
&lt;br /&gt;
Change the device address 06 to 01, with the following example:&lt;br /&gt;
&lt;br /&gt;
Request frame：06 06 20 02 00 01 E3 BD&lt;br /&gt;
&lt;br /&gt;
Response frame：06 06 20 02 00 01 E3 BD&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
If the sensor does not execute the upper computer command correctly, the following format information is returned:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Definition&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|CODE&lt;br /&gt;
|CRC check&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC 16&lt;br /&gt;
|-&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE： 01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM: Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1934</id>
		<title>Template:Other Probes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1934"/>
		<updated>2026-07-13T11:46:15Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Firmware  v.&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000065&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000085&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000091&lt;br /&gt;
|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000086&lt;br /&gt;
|[[Low Conductivity Probe AT-SB-PROBE-LC-P-C1|SENSBLUE RS-485 Low Conductivity Probe AT-SB-PROBE-LC-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000087&lt;br /&gt;
|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000068&lt;br /&gt;
|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000089&lt;br /&gt;
|[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|SENSBLUE RS-485 Salinity/Conductivity/TDS Probe AT-SB-PROBE-S-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000067&lt;br /&gt;
|[[RS-485 pH Probe AT-SB-PROBE-pH-P|SENSBLUE RS-485 pH Probe AT-SB-PROBE-pH-P, w/ 15m cable w/conector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|[[RS-485 ORP Probe POM AT-SB-PROBE-ORP-P|SENSBLUE RS-485 ORP Probe POM AT-SB-PROBE-ORP-P, w/ 15m cable w/conector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000088&lt;br /&gt;
|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000069&lt;br /&gt;
|[[RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P|SENSBLUE RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000090&lt;br /&gt;
|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000066&lt;br /&gt;
|[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|SENSBLUE RS-485 Turbidity Probe AT-SB-PROBE-T-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000073&lt;br /&gt;
|[[Multiparameter Probe AT-SB-PROBE-MP-P-C1|SENSBLUE RS-485 Multiparameter Probe AT-SB-PROBE-MP-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.71&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1933</id>
		<title>Template:Other Probes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1933"/>
		<updated>2026-07-13T11:44:04Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Firmware  v.&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000065&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000085&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000091&lt;br /&gt;
|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000086&lt;br /&gt;
|[[Low Conductivity Probe AT-SB-PROBE-LC-P-C1|SENSBLUE RS-485 Low Conductivity Probe AT-SB-PROBE-LC-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000087&lt;br /&gt;
|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000068&lt;br /&gt;
|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000089&lt;br /&gt;
|[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|SENSBLUE RS-485 Salinity/Conductivity/TDS Probe AT-SB-PROBE-S-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000067&lt;br /&gt;
|[[RS-485 pH Probe AT-SB-PROBE-pH-P|SENSBLUE RS-485 pH Probe AT-SB-PROBE-pH-P, w/ 15m cable w/conector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000067&lt;br /&gt;
|[[RS-485 ORP Probe POM AT-SB-PROBE-ORP-P|SENSBLUE RS-485 ORP Probe POM AT-SB-PROBE-ORP-P, w/ 15m cable w/conector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000088&lt;br /&gt;
|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000069&lt;br /&gt;
|[[RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P|SENSBLUE RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000090&lt;br /&gt;
|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000066&lt;br /&gt;
|[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|SENSBLUE RS-485 Turbidity Probe AT-SB-PROBE-T-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000073&lt;br /&gt;
|[[Multiparameter Probe AT-SB-PROBE-MP-P-C1|SENSBLUE RS-485 Multiparameter Probe AT-SB-PROBE-MP-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.71&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-P-C1&amp;diff=1932</id>
		<title>Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-P-C1&amp;diff=1932"/>
		<updated>2026-07-13T11:39:45Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-rs-485-dissolved-oxygen-probe-at-sb-probedo-p/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:DO.svg|center|frameless|363x363px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBEDO-P-C1 is an integrated online fluorescence dissolved oxygen sensor designed based on the quenching principle of excited fluorescence by specific substances in physics. When the excitation light shines on the fluorescent substance on the surface of the fluorescent membrane head, the substance becomes excited and emits fluorescence. The extinguishing time of this fluorescence is affected by the concentration of oxygen molecules on the surface of the fluorescent membrane head. The oxygen concentration can be calculated by detecting the phase difference between the fluorescence and the excitation light and comparing it with the internal calibration curve. The final value is then output after temperature and salinity compensation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DO1.svg|center|frameless|852x852px]]&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* No electrolyte is required and it will not be polarized.&lt;br /&gt;
* No oxygen consumption; not affected by flow rate.&lt;br /&gt;
* Built‑in temperature sensor, automatic temperature compensation.&lt;br /&gt;
* Built‑in salinity compensation, flexible parameter settings.&lt;br /&gt;
* Free from interference by chemicals such as sulfides.&lt;br /&gt;
* Small drift, rapid reaction, for more accurate measurement.&lt;br /&gt;
* Long service cycle, lower cost of use.&lt;br /&gt;
* Simple replacement of fluorescent cap.RS‑485 interface, Modbus/RTU protocol.&lt;br /&gt;
* Low power consumption and anti‑interference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Pro&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Ultra&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Case material&lt;br /&gt;
|POM, ABS/PC alloy, 316L stainless steel&lt;br /&gt;
|316L Titanium Alloy&lt;br /&gt;
|-&lt;br /&gt;
|Measurement principle&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Fluorescence method&lt;br /&gt;
|-&lt;br /&gt;
|Range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0～20.00 mg/L (0～200% saturation, 25℃)&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.01mg/L, 0.1℃&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±2%, ±0.3℃&lt;br /&gt;
|±3%&lt;br /&gt;
|-&lt;br /&gt;
|Response time (T90)&lt;br /&gt;
|＜30s&lt;br /&gt;
|＜60s&lt;br /&gt;
|-&lt;br /&gt;
|Minimum detection limit&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.08mg/L&lt;br /&gt;
|-&lt;br /&gt;
|Calibration method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Two-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Temperature compensation&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Automatic temperature compensation (Pt1000)&lt;br /&gt;
|-&lt;br /&gt;
|Output method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |RS-485 (Modbus RTU)&lt;br /&gt;
|-&lt;br /&gt;
|Storage temperature&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |-5~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Working conditions&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0～50℃, ≤0.2MPa&lt;br /&gt;
|-&lt;br /&gt;
|Installation method&lt;br /&gt;
|Submersible installation, 3/4 NPT&lt;br /&gt;
|Max Depth 30m&lt;br /&gt;
|-&lt;br /&gt;
|Power consumption&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |10.1W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Power supply&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |12~24V DC&lt;br /&gt;
|-&lt;br /&gt;
|Protection level&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |IP68&lt;br /&gt;
|-&lt;br /&gt;
|Life of fluorescent membrane head&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |1 year (under normal use)&lt;br /&gt;
|-&lt;br /&gt;
|Cable length&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |10 meters, other lengths can be customized&lt;br /&gt;
|-&lt;br /&gt;
|Max water depth&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |30m&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DissolvedTD.svg|center|frameless|710x710px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|935x935px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation ===&lt;br /&gt;
&#039;&#039;&#039;Install&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The sensor needs to be installed below the liquid level. The installation and use should avoid any collisions or scraping against the surface of the fluorescent film head. The fluorescent film head should also be kept from contacting the bottom sediment. Remove the rubber cover when in use.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
&#039;&#039;&#039;a) Maintenance schedule&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Different from dissolved‑oxygen probe technology based on the electrochemical principle, the fluorescence dissolved‑oxygen probe does not consume oxygen and does not need to be cleaned frequently (except when used in viscous liquids).&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance Task&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Recommended Maintenance Frequency&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Cleaning  sensor&lt;br /&gt;
|Wash every 30 days&lt;br /&gt;
|-&lt;br /&gt;
|Check for damage to sensors and caps&lt;br /&gt;
|Check every 30 days&lt;br /&gt;
|-&lt;br /&gt;
|Replace the fluorescent cap&lt;br /&gt;
|Replace it once a year&lt;br /&gt;
|-&lt;br /&gt;
|Calibrate (if required by the competent  authority)&lt;br /&gt;
|According to the maintenance schedule  required by the competent department&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: The maintenance frequency in the above table is only recommended, and the maintenance personnel shall clean the sensor according to the actual use of the sensor, however, the replacement frequency of the fluorescent cap is recommended once a year.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Maintenance method ====&lt;br /&gt;
&#039;&#039;&#039;a)&#039;&#039;&#039; &#039;&#039;&#039;Sensor outer surface:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Clean the outer surface of the sensor with tap water, if there is still debris residue, wipe with wet soft cloth, for stubborn dirt, you can add household washing liquid to clean.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Surface of fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If there is dirt on the surface of the fluorescent film head, please rinse it with clean water or wipe it gently with a soft cloth. Pay attention to the cleaning intensity to avoid causing scratches in the measuring area and affecting measurement accuracy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Inside the fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  It is generally unnecessary to clean. If water vapor or dust enters the fluorescent film head, the cleaning steps are as follows:&lt;br /&gt;
&lt;br /&gt;
•Screw down the fluorescent film head;&lt;br /&gt;
&lt;br /&gt;
•Rinse the inner surface of the fluorescent film head and the optical window of the sensor.&lt;br /&gt;
&lt;br /&gt;
•For oily dirt, you can use household cleaning solution;&lt;br /&gt;
&lt;br /&gt;
•Gently dry the water with a clean cloth and let dry;&lt;br /&gt;
&lt;br /&gt;
Reinstall the fluorescent film head.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;d) Check the cables of the sensor:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  There should be no damage to the skin and root of the cables;&lt;br /&gt;
&lt;br /&gt;
Terminals should not be submerged in water; When the sensor is normally installed, the cable should not be tensioned, otherwise the internal wire of the cable will easily break, and the sensor cannot work normally.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;e) Check whether the casing of the sensor is damaged by corrosion or other causes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;f)&#039;&#039;&#039; &#039;&#039;&#039;Daily storage of fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  When not in use, a rubber protective cover with a wet sponge should be placed over the fluorescent film head to keep the surface of the measuring area wet. If the surface of the measuring area of the fluorescent film head becomes chronically dry, measurement errors or data instability may occur, and it needs to be soaked in water for 48 hours before use.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Wrong&#039;&#039;&#039;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Probable Cause&#039;&#039;&#039;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Solution&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | The operating interface cannot connect or does not display the measurement results&lt;br /&gt;
| Error connecting controller to cable&lt;br /&gt;
| Reconnect the controller and cable&lt;br /&gt;
|-&lt;br /&gt;
| Cable failure&lt;br /&gt;
| Please contact us.&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap is not tightened or damaged&lt;br /&gt;
| Refit and tighten the fluorescent cap or replace the fluorescent cap.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | The measured value is too high, too low, or the numerical value remains unstable.&lt;br /&gt;
| The outer surface of the fluorescent cap is attached to the outer object&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Clean the outer surface of the fluorescent film head and agitate the film head during measurement.&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap was damaged&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap has exceeded its service life&lt;br /&gt;
| Replace the fluorescent cap&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Temperature measurements change slowly.&lt;br /&gt;
| The temperature measuring area (stainless steel housing) is attached to the exterior&lt;br /&gt;
| Gently brush the attachment with a soft brush&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Calibration of sensors ====&lt;br /&gt;
&#039;&#039;&#039;a)&#039;&#039;&#039; &#039;&#039;&#039;Zero Calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Weigh 5 g of sodium sulphite using a balance, add 95 mL of water into a 250‑mL measuring cylinder, pour the water into a beaker, add the previously weighed sodium sulphite, and stir with a glass rod until fully dissolved to obtain a 5% sodium sulphite solution. Place the sensor in the solution and perform the zero‑point calibration after the reading has stabilized for three minutes. Refer to the Appendix for instructions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Slope Calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  The sensor probe is placed in air‑saturated water, and the slope is calibrated after 3 minutes of numerical stability. The instructions refer to the appendix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preparation of Air Saturated Water:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Add 2/3 volume of fresh distilled water to the constant‑temperature water bath to allow the porous plastic sheet to float on the water surface (see figure below). At the same time, use the bubbler (air pump) to aerate the water continuously for more than 1 hour. Then stop aeration and obtain air‑saturated water after approximately 20 minutes. Place the sensor into the water and calibrate the slope once the reading has stabilized.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Maintenance.svg|center|frameless|915x915px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: As an alternative, slope calibration can also be performed in water‑saturated air. Pour pure water into the calibration cup, keeping the liquid level column height slightly below 1 mm. After the sensor’s fluorescent membrane head is dipped in water, shake it lightly (to ensure that the surface of the fluorescent membrane is moist and there are no water droplets), and place the sensor vertically on the calibration cup column (as shown in the figure below, ensuring that the water surface does not touch the fluorescent membrane). Wait for 3 minutes for the value to stabilize before calibrating the slope.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 6.5 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Avoid exposing the inner surface of the fluorescent film head to sunlight&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Please do not touch the fluorescent film with your hands&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|03&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start&lt;br /&gt;
&lt;br /&gt;
address&lt;br /&gt;
|Number of  Registers&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
b)  Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|03&lt;br /&gt;
|xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of  Bytes&lt;br /&gt;
|Response  data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
c)  Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
d)  Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! Register Address&lt;br /&gt;
! Name&lt;br /&gt;
! Instruction&lt;br /&gt;
! Number of Registers&lt;br /&gt;
! Access Method&lt;br /&gt;
|-&lt;br /&gt;
| 40001 (0x0000)&lt;br /&gt;
| Measured value + temperature&lt;br /&gt;
| Four double-byte integers: measured value, measured decimal places, temperature value, and temperature decimal places.&lt;br /&gt;
| 4 (8 bytes)&lt;br /&gt;
| Read&lt;br /&gt;
|-&lt;br /&gt;
| 40005 (0x0004)&lt;br /&gt;
| Dissolved oxygen saturation (0–200%)&lt;br /&gt;
| Two double-byte integers: saturation value and decimal places.&lt;br /&gt;
| 2 (4 bytes)&lt;br /&gt;
| Read&lt;br /&gt;
|-&lt;br /&gt;
| 44097 (0x1000)&lt;br /&gt;
| Zero calibration&lt;br /&gt;
| Calibrated in anoxic water. Write value 0; read returns zero offset.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44101 (0x1004)&lt;br /&gt;
| Slope calibration&lt;br /&gt;
| Calibrate in air-saturated water. Write value 0; read returns slope value × 1000.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44113 (0x1010)&lt;br /&gt;
| Temperature correction&lt;br /&gt;
| In solution, write the actual temperature value ×10. Read returns the temperature calibration offset ×10.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44129 (0x1020)&lt;br /&gt;
| Salinity compensation&lt;br /&gt;
| Read/write value is salinity (PSU) ×10 used for compensation. Default = 0 (no compensation). Range: 0–500 (0–50.0 PSU).&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48195 (0x2002)&lt;br /&gt;
| Sensor address&lt;br /&gt;
| Default value is 5. Range: 1–255.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48196 (0x2003)&lt;br /&gt;
| Baud rate&lt;br /&gt;
| Default: 9600.  0 → 9600  1 → 19200&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48225 (0x2020)&lt;br /&gt;
| Reset sensor&lt;br /&gt;
| Restores calibration values to default. Write value 0. Sensor must be recalibrated after reset.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a)  Measurement command:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Function: Get the dissolved oxygen value and temperature measured by the sensor; the unit of dissolved oxygen is mg/L, and the unit of temperature is ℃.&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;05 03 00 00 00 04 45 8D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 03 08 01 02 00 02 00 B0 00 01 DB 0C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reading example:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;DO value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;temperature  scale&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;01 02 00 02&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;00 B0 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example, the DO value 01 02 indicates the hexadecimal DO reading, and 0002 indicates the dissolved oxygen value with 2 decimal places, which is converted to a decimal value of 2.58. The temperature value 00B0 represents the hexadecimal temperature reading, and 0001 indicates the temperature value with 1 decimal place, converted to a decimal value of 17.6.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b.) Calibration instruction&#039;&#039;&#039;：&lt;br /&gt;
&lt;br /&gt;
Zero calibration&lt;br /&gt;
&lt;br /&gt;
Function: set the calibration value of dissolved oxygen zero point of electrode； Request frame：05 06 10 00 00 00 8C 8E&lt;br /&gt;
&lt;br /&gt;
Acknowledgement frame ：&amp;lt;code&amp;gt;05 06 10 00 00 00 8C 8E&amp;lt;/code&amp;gt; Slope calibration&lt;br /&gt;
&lt;br /&gt;
Function: set the slope calibration value of dissolved oxygen for the electrode; here the slope value is calibrated in air saturated water。&lt;br /&gt;
&lt;br /&gt;
Request frame：&amp;lt;code&amp;gt;05 06 10 04 00 00 CD 4F&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 10 04 00 00 CD 4F&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address：&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the MODBUS device address of the electrode;&lt;br /&gt;
&lt;br /&gt;
Change the device address 05 to 01, with the following example Request frame&lt;br /&gt;
&lt;br /&gt;
：&amp;lt;code&amp;gt;05 06 20 02 00 01 E3 8E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 20 02 00 01 E3 8E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;d) Salinity compensation command:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Set the salinity compensation of the sensor;&lt;br /&gt;
&lt;br /&gt;
Measure the water body with a salinity of 35.0 PSU and add salinity compensation. &lt;br /&gt;
&lt;br /&gt;
The example is as follows:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;05 06 10 20 01 5E 0D 2C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 10 20 01 5E 0D 2C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
If the sensor does not execute the upper‑computer command correctly, the following format of information is returned:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Definition&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|CODE&lt;br /&gt;
|CRC  check&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|Number of  bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE： &lt;br /&gt;
&lt;br /&gt;
01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM：Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Gateways &amp;amp; Accessories ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable Gateways &amp;amp; Accessories}}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
&lt;br /&gt;
{{Applicable certifications and standards}}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Applicable_certifications_and_standards&amp;diff=1931</id>
		<title>Template:Applicable certifications and standards</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Applicable_certifications_and_standards&amp;diff=1931"/>
		<updated>2026-07-13T11:39:18Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: Created page with &amp;quot;EMC Directive 2014/30/EU.  * &amp;#039;&amp;#039;&amp;#039;EN IEC 61326-1: 2021&amp;#039;&amp;#039;&amp;#039; * &amp;#039;&amp;#039;&amp;#039;EN 55011: 2016+A2: 2021&amp;#039;&amp;#039;&amp;#039; * &amp;#039;&amp;#039;&amp;#039;EN IEC 61000-3-2: 2019+A1: 2021&amp;#039;&amp;#039;&amp;#039; * &amp;#039;&amp;#039;&amp;#039;EN 61000-3-3: 2013+A2: 2021&amp;#039;&amp;#039;&amp;#039;&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;EMC Directive 2014/30/EU.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61326-1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 55011: 2016+A2: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61000-3-2: 2019+A1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 61000-3-3: 2013+A2: 2021&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-P-C1&amp;diff=1930</id>
		<title>Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Dissolved_Oxygen_Probe_AT-SB-PROBE-DO-P-C1&amp;diff=1930"/>
		<updated>2026-07-13T11:37:16Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-rs-485-dissolved-oxygen-probe-at-sb-probedo-p/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:DO.svg|center|frameless|363x363px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBEDO-P-C1 is an integrated online fluorescence dissolved oxygen sensor designed based on the quenching principle of excited fluorescence by specific substances in physics. When the excitation light shines on the fluorescent substance on the surface of the fluorescent membrane head, the substance becomes excited and emits fluorescence. The extinguishing time of this fluorescence is affected by the concentration of oxygen molecules on the surface of the fluorescent membrane head. The oxygen concentration can be calculated by detecting the phase difference between the fluorescence and the excitation light and comparing it with the internal calibration curve. The final value is then output after temperature and salinity compensation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DO1.svg|center|frameless|852x852px]]&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* No electrolyte is required and it will not be polarized.&lt;br /&gt;
* No oxygen consumption; not affected by flow rate.&lt;br /&gt;
* Built‑in temperature sensor, automatic temperature compensation.&lt;br /&gt;
* Built‑in salinity compensation, flexible parameter settings.&lt;br /&gt;
* Free from interference by chemicals such as sulfides.&lt;br /&gt;
* Small drift, rapid reaction, for more accurate measurement.&lt;br /&gt;
* Long service cycle, lower cost of use.&lt;br /&gt;
* Simple replacement of fluorescent cap.RS‑485 interface, Modbus/RTU protocol.&lt;br /&gt;
* Low power consumption and anti‑interference&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Pro&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Ultra&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Case material&lt;br /&gt;
|POM, ABS/PC alloy, 316L stainless steel&lt;br /&gt;
|316L Titanium Alloy&lt;br /&gt;
|-&lt;br /&gt;
|Measurement principle&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Fluorescence method&lt;br /&gt;
|-&lt;br /&gt;
|Range&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0～20.00 mg/L (0～200% saturation, 25℃)&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.01mg/L, 0.1℃&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±2%, ±0.3℃&lt;br /&gt;
|±3%&lt;br /&gt;
|-&lt;br /&gt;
|Response time (T90)&lt;br /&gt;
|＜30s&lt;br /&gt;
|＜60s&lt;br /&gt;
|-&lt;br /&gt;
|Minimum detection limit&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0.08mg/L&lt;br /&gt;
|-&lt;br /&gt;
|Calibration method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Two-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Temperature compensation&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |Automatic temperature compensation (Pt1000)&lt;br /&gt;
|-&lt;br /&gt;
|Output method&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |RS-485 (Modbus RTU)&lt;br /&gt;
|-&lt;br /&gt;
|Storage temperature&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |-5~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Working conditions&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |0～50℃, ≤0.2MPa&lt;br /&gt;
|-&lt;br /&gt;
|Installation method&lt;br /&gt;
|Submersible installation, 3/4 NPT&lt;br /&gt;
|Max Depth 30m&lt;br /&gt;
|-&lt;br /&gt;
|Power consumption&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |10.1W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Power supply&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |12~24V DC&lt;br /&gt;
|-&lt;br /&gt;
|Protection level&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |IP68&lt;br /&gt;
|-&lt;br /&gt;
|Life of fluorescent membrane head&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |1 year (under normal use)&lt;br /&gt;
|-&lt;br /&gt;
|Cable length&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |10 meters, other lengths can be customized&lt;br /&gt;
|-&lt;br /&gt;
|Max water depth&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |30m&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimensions and Wiring ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:DissolvedTD.svg|center|frameless|710x710px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:ProbesWiring.svg|center|frameless|935x935px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
! colspan=&amp;quot;2&amp;quot; |&#039;&#039;&#039;Pinouts&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 - Pin 12-24V DC&lt;br /&gt;
|4 - RS485 B-&lt;br /&gt;
|-&lt;br /&gt;
|2 - GND&lt;br /&gt;
|5 – NA&lt;br /&gt;
|-&lt;br /&gt;
|3 - RS485 A+&lt;br /&gt;
|6 - NA&lt;br /&gt;
|-&lt;br /&gt;
| colspan=&amp;quot;2&amp;quot; |7 - NA&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation ===&lt;br /&gt;
&#039;&#039;&#039;Install&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The sensor needs to be installed below the liquid level. The installation and use should avoid any collisions or scraping against the surface of the fluorescent film head. The fluorescent film head should also be kept from contacting the bottom sediment. Remove the rubber cover when in use.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
&#039;&#039;&#039;a) Maintenance schedule&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Different from dissolved‑oxygen probe technology based on the electrochemical principle, the fluorescence dissolved‑oxygen probe does not consume oxygen and does not need to be cleaned frequently (except when used in viscous liquids).&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Maintenance Task&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Recommended Maintenance Frequency&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Cleaning  sensor&lt;br /&gt;
|Wash every 30 days&lt;br /&gt;
|-&lt;br /&gt;
|Check for damage to sensors and caps&lt;br /&gt;
|Check every 30 days&lt;br /&gt;
|-&lt;br /&gt;
|Replace the fluorescent cap&lt;br /&gt;
|Replace it once a year&lt;br /&gt;
|-&lt;br /&gt;
|Calibrate (if required by the competent  authority)&lt;br /&gt;
|According to the maintenance schedule  required by the competent department&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: The maintenance frequency in the above table is only recommended, and the maintenance personnel shall clean the sensor according to the actual use of the sensor, however, the replacement frequency of the fluorescent cap is recommended once a year.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 6.2 Maintenance method ====&lt;br /&gt;
&#039;&#039;&#039;a)&#039;&#039;&#039; &#039;&#039;&#039;Sensor outer surface:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Clean the outer surface of the sensor with tap water, if there is still debris residue, wipe with wet soft cloth, for stubborn dirt, you can add household washing liquid to clean.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Surface of fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If there is dirt on the surface of the fluorescent film head, please rinse it with clean water or wipe it gently with a soft cloth. Pay attention to the cleaning intensity to avoid causing scratches in the measuring area and affecting measurement accuracy.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Inside the fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  It is generally unnecessary to clean. If water vapor or dust enters the fluorescent film head, the cleaning steps are as follows:&lt;br /&gt;
&lt;br /&gt;
•Screw down the fluorescent film head;&lt;br /&gt;
&lt;br /&gt;
•Rinse the inner surface of the fluorescent film head and the optical window of the sensor.&lt;br /&gt;
&lt;br /&gt;
•For oily dirt, you can use household cleaning solution;&lt;br /&gt;
&lt;br /&gt;
•Gently dry the water with a clean cloth and let dry;&lt;br /&gt;
&lt;br /&gt;
Reinstall the fluorescent film head.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;d) Check the cables of the sensor:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  There should be no damage to the skin and root of the cables;&lt;br /&gt;
&lt;br /&gt;
Terminals should not be submerged in water; When the sensor is normally installed, the cable should not be tensioned, otherwise the internal wire of the cable will easily break, and the sensor cannot work normally.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;e) Check whether the casing of the sensor is damaged by corrosion or other causes.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;f)&#039;&#039;&#039; &#039;&#039;&#039;Daily storage of fluorescent film head:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  When not in use, a rubber protective cover with a wet sponge should be placed over the fluorescent film head to keep the surface of the measuring area wet. If the surface of the measuring area of the fluorescent film head becomes chronically dry, measurement errors or data instability may occur, and it needs to be soaked in water for 48 hours before use.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
==== 6.3 Frequently asked questions ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Wrong&#039;&#039;&#039;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Probable Cause&#039;&#039;&#039;&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; | &#039;&#039;&#039;Solution&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;3&amp;quot; | The operating interface cannot connect or does not display the measurement results&lt;br /&gt;
| Error connecting controller to cable&lt;br /&gt;
| Reconnect the controller and cable&lt;br /&gt;
|-&lt;br /&gt;
| Cable failure&lt;br /&gt;
| Please contact us.&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap is not tightened or damaged&lt;br /&gt;
| Refit and tighten the fluorescent cap or replace the fluorescent cap.&lt;br /&gt;
|-&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | The measured value is too high, too low, or the numerical value remains unstable.&lt;br /&gt;
| The outer surface of the fluorescent cap is attached to the outer object&lt;br /&gt;
| rowspan=&amp;quot;2&amp;quot; | Clean the outer surface of the fluorescent film head and agitate the film head during measurement.&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap was damaged&lt;br /&gt;
|-&lt;br /&gt;
| The fluorescent cap has exceeded its service life&lt;br /&gt;
| Replace the fluorescent cap&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| Temperature measurements change slowly.&lt;br /&gt;
| The temperature measuring area (stainless steel housing) is attached to the exterior&lt;br /&gt;
| Gently brush the attachment with a soft brush&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Calibration of sensors ====&lt;br /&gt;
&#039;&#039;&#039;a)&#039;&#039;&#039; &#039;&#039;&#039;Zero Calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Weigh 5 g of sodium sulphite using a balance, add 95 mL of water into a 250‑mL measuring cylinder, pour the water into a beaker, add the previously weighed sodium sulphite, and stir with a glass rod until fully dissolved to obtain a 5% sodium sulphite solution. Place the sensor in the solution and perform the zero‑point calibration after the reading has stabilized for three minutes. Refer to the Appendix for instructions.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Slope Calibration&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  The sensor probe is placed in air‑saturated water, and the slope is calibrated after 3 minutes of numerical stability. The instructions refer to the appendix.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Preparation of Air Saturated Water:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Add 2/3 volume of fresh distilled water to the constant‑temperature water bath to allow the porous plastic sheet to float on the water surface (see figure below). At the same time, use the bubbler (air pump) to aerate the water continuously for more than 1 hour. Then stop aeration and obtain air‑saturated water after approximately 20 minutes. Place the sensor into the water and calibrate the slope once the reading has stabilized.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Maintenance.svg|center|frameless|915x915px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&#039;&#039;Note: As an alternative, slope calibration can also be performed in water‑saturated air. Pour pure water into the calibration cup, keeping the liquid level column height slightly below 1 mm. After the sensor’s fluorescent membrane head is dipped in water, shake it lightly (to ensure that the surface of the fluorescent membrane is moist and there are no water droplets), and place the sensor vertically on the calibration cup column (as shown in the figure below, ensuring that the water surface does not touch the fluorescent membrane). Wait for 3 minutes for the value to stabilize before calibrating the slope.&#039;&#039;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 6.5 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Avoid exposing the inner surface of the fluorescent film head to sunlight&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Please do not touch the fluorescent film with your hands&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|03&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start&lt;br /&gt;
&lt;br /&gt;
address&lt;br /&gt;
|Number of  Registers&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
b)  Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|03&lt;br /&gt;
|xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of  Bytes&lt;br /&gt;
|Response  data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
c)  Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
d)  Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|05&lt;br /&gt;
|06&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|xx  xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register  address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC  check code  (low bytes in  front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! Register Address&lt;br /&gt;
! Name&lt;br /&gt;
! Instruction&lt;br /&gt;
! Number of Registers&lt;br /&gt;
! Access Method&lt;br /&gt;
|-&lt;br /&gt;
| 40001 (0x0000)&lt;br /&gt;
| Measured value + temperature&lt;br /&gt;
| Four double-byte integers: measured value, measured decimal places, temperature value, and temperature decimal places.&lt;br /&gt;
| 4 (8 bytes)&lt;br /&gt;
| Read&lt;br /&gt;
|-&lt;br /&gt;
| 40005 (0x0004)&lt;br /&gt;
| Dissolved oxygen saturation (0–200%)&lt;br /&gt;
| Two double-byte integers: saturation value and decimal places.&lt;br /&gt;
| 2 (4 bytes)&lt;br /&gt;
| Read&lt;br /&gt;
|-&lt;br /&gt;
| 44097 (0x1000)&lt;br /&gt;
| Zero calibration&lt;br /&gt;
| Calibrated in anoxic water. Write value 0; read returns zero offset.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44101 (0x1004)&lt;br /&gt;
| Slope calibration&lt;br /&gt;
| Calibrate in air-saturated water. Write value 0; read returns slope value × 1000.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44113 (0x1010)&lt;br /&gt;
| Temperature correction&lt;br /&gt;
| In solution, write the actual temperature value ×10. Read returns the temperature calibration offset ×10.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 44129 (0x1020)&lt;br /&gt;
| Salinity compensation&lt;br /&gt;
| Read/write value is salinity (PSU) ×10 used for compensation. Default = 0 (no compensation). Range: 0–500 (0–50.0 PSU).&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48195 (0x2002)&lt;br /&gt;
| Sensor address&lt;br /&gt;
| Default value is 5. Range: 1–255.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48196 (0x2003)&lt;br /&gt;
| Baud rate&lt;br /&gt;
| Default: 9600.  0 → 9600  1 → 19200&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write / Read&lt;br /&gt;
|-&lt;br /&gt;
| 48225 (0x2020)&lt;br /&gt;
| Reset sensor&lt;br /&gt;
| Restores calibration values to default. Write value 0. Sensor must be recalibrated after reset.&lt;br /&gt;
| 1 (2 bytes)&lt;br /&gt;
| Write&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a)  Measurement command:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
  Function: Get the dissolved oxygen value and temperature measured by the sensor; the unit of dissolved oxygen is mg/L, and the unit of temperature is ℃.&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;05 03 00 00 00 04 45 8D&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 03 08 01 02 00 02 00 B0 00 01 DB 0C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reading example:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;DO value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;temperature  scale&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;01 02 00 02&amp;lt;/code&amp;gt;&lt;br /&gt;
|&amp;lt;code&amp;gt;00 B0 00 01&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example, the DO value 01 02 indicates the hexadecimal DO reading, and 0002 indicates the dissolved oxygen value with 2 decimal places, which is converted to a decimal value of 2.58. The temperature value 00B0 represents the hexadecimal temperature reading, and 0001 indicates the temperature value with 1 decimal place, converted to a decimal value of 17.6.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b.) Calibration instruction&#039;&#039;&#039;：&lt;br /&gt;
&lt;br /&gt;
Zero calibration&lt;br /&gt;
&lt;br /&gt;
Function: set the calibration value of dissolved oxygen zero point of electrode； Request frame：05 06 10 00 00 00 8C 8E&lt;br /&gt;
&lt;br /&gt;
Acknowledgement frame ：&amp;lt;code&amp;gt;05 06 10 00 00 00 8C 8E&amp;lt;/code&amp;gt; Slope calibration&lt;br /&gt;
&lt;br /&gt;
Function: set the slope calibration value of dissolved oxygen for the electrode; here the slope value is calibrated in air saturated water。&lt;br /&gt;
&lt;br /&gt;
Request frame：&amp;lt;code&amp;gt;05 06 10 04 00 00 CD 4F&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 10 04 00 00 CD 4F&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address：&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the MODBUS device address of the electrode;&lt;br /&gt;
&lt;br /&gt;
Change the device address 05 to 01, with the following example Request frame&lt;br /&gt;
&lt;br /&gt;
：&amp;lt;code&amp;gt;05 06 20 02 00 01 E3 8E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 20 02 00 01 E3 8E&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;d) Salinity compensation command:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Set the salinity compensation of the sensor;&lt;br /&gt;
&lt;br /&gt;
Measure the water body with a salinity of 35.0 PSU and add salinity compensation. &lt;br /&gt;
&lt;br /&gt;
The example is as follows:&lt;br /&gt;
&lt;br /&gt;
Request frame: &amp;lt;code&amp;gt;05 06 10 20 01 5E 0D 2C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Response frame: &amp;lt;code&amp;gt;05 06 10 20 01 5E 0D 2C&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
If the sensor does not execute the upper‑computer command correctly, the following format of information is returned:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Definition&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|CODE&lt;br /&gt;
|CRC  check&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC  16&lt;br /&gt;
|-&lt;br /&gt;
|Number of  bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE： &lt;br /&gt;
&lt;br /&gt;
01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM：Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Accessories ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000076&lt;br /&gt;
|SENSBLUE MONARCH Solar Panel 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000079&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000080&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000074&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000081&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000082&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000083&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000084&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000020&lt;br /&gt;
|SENSBLUE  MONARCH RS485 Probe Splitter Box (1 input -&amp;gt; 2 outputs)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 9. Other Probes ===&lt;br /&gt;
&lt;br /&gt;
{{Other Probes}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
EMC Directive 2014/30/EU.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61326-1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 55011: 2016+A2: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61000-3-2: 2019+A1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 61000-3-3: 2013+A2: 2021&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:SimilarProductsTable&amp;diff=1929</id>
		<title>Template:SimilarProductsTable</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:SimilarProductsTable&amp;diff=1929"/>
		<updated>2026-07-13T11:36:34Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: WikiManagement moved page Template:SimilarProductsTable to Template:Other Probes: Misspelled title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;#REDIRECT [[Template:Other Probes]]&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1928</id>
		<title>Template:Other Probes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Other_Probes&amp;diff=1928"/>
		<updated>2026-07-13T11:36:34Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: WikiManagement moved page Template:SimilarProductsTable to Template:Other Probes: Misspelled title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Firmware  v.&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000065&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000085&lt;br /&gt;
|[[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|SENSBLUE RS-485 Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000091&lt;br /&gt;
|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1|SENSBLUE RS-485 Dissolved CO2 Sensor Probe AT-SB-PROBE-CO2-P-5000-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000086&lt;br /&gt;
|[[Low Conductivity Probe AT-SB-PROBE-LC-P-C1|SENSBLUE RS-485 Low Conductivity Probe AT-SB-PROBE-LC-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000087&lt;br /&gt;
|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1|SENSBLUE RS-485 Medium Conductivity Probe AT-SB-PROBE-MC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000068&lt;br /&gt;
|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1|SENSBLUE RS-485 High Conductivity Probe AT-SB-PROBE-HC-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000089&lt;br /&gt;
|[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|SENSBLUE RS-485 Salinity/Conductivity/TDS Probe AT-SB-PROBE-S-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000067&lt;br /&gt;
|[[RS-485 pH Probe AT-SB-PROBE-pH-P|SENSBLUE RS-485 pH Probe AT-SB-PROBE-pH-P, w/ 15m cable w/conector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000088&lt;br /&gt;
|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1|SENSBLUE RS-485 ORP Probe AT-SB-PROBE-ORP-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000069&lt;br /&gt;
|[[RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P|SENSBLUE RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000090&lt;br /&gt;
|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1|SENSBLUE RS-485 Ammonia Nitrogen (NH4-N) Sensor Probe AT-SB-PROBE-NH4-P-C1, w/ 15m cable w/connector&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000066&lt;br /&gt;
|[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|SENSBLUE RS-485 Turbidity Probe AT-SB-PROBE-T-P, w/ 15m cable w/connector]]&lt;br /&gt;
|10.70&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000073&lt;br /&gt;
|[[Multiparameter Probe AT-SB-PROBE-MP-P-C1|SENSBLUE RS-485 Multiparameter Probe AT-SB-PROBE-MP-P-C1, w/ 15m cable w/connector]]&lt;br /&gt;
|10.71&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Template:Applicable_Gateways_%26_Accessories&amp;diff=1927</id>
		<title>Template:Applicable Gateways &amp; Accessories</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Template:Applicable_Gateways_%26_Accessories&amp;diff=1927"/>
		<updated>2026-07-13T11:35:33Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: Created page with &amp;quot;{| class=&amp;quot;wikitable&amp;quot; | |&amp;#039;&amp;#039;&amp;#039;Name&amp;#039;&amp;#039;&amp;#039; |&amp;#039;&amp;#039;&amp;#039;Requirements&amp;#039;&amp;#039;&amp;#039; |- |PA000000076 |SENSBLUE MONARCH Solar Panel 1 Probe | |- |PA000000079 |SENSBLUE  MONARCH Solar Panel 2 Probes | |- |PA000000080 |SENSBLUE  MONARCH Solar Panel 1 Probe External Antenna | |- |PA000000074 |SENSBLUE  MONARCH Solar Panel 2 Probes External Antenna | |- |PA000000081 |SENSBLUE  MONARCH Opaque Case 1 Probe | |- |PA000000082 |SENSBLUE  MONARCH Opaque Case 2 Probes | |- |PA000000083 |SENSBLUE  MONARCH Opaque...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000076&lt;br /&gt;
|SENSBLUE MONARCH Solar Panel 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000079&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000080&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000074&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000081&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000082&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000083&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000084&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000020&lt;br /&gt;
|SENSBLUE  MONARCH RS485 Probe Splitter Box (1 input -&amp;gt; 2 outputs)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1926</id>
		<title>RS-485 ORP Probe POM AT-SB-PROBE-ORP-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1926"/>
		<updated>2026-07-13T11:29:23Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:ORP-100-PH-10-ORP-10-PH-100.png|center|frameless|345x345px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE Monarch ORP Probe POM AT-SB-PROBE-ORP-P can be used for environmental water quality monitoring, acid/alkali/salt solution, chemical reaction process, industrial production process, and can meet the requirements of online ORP measurement for most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol).&lt;br /&gt;
* Conveniently connect to third-party equipment such as PLC, DCS, industrial control computer, general controller, paperless recording instrument or touch screen.&lt;br /&gt;
* Double high impedance differential amplifier, strong anti-interference and fast response speed.&lt;br /&gt;
* Durable ORP electrode, the internal reference fluid seeps out from the microporous salt bridge very slowly under a pressure of at least 100KPa (1Bar), and its positive seepage lasts for more than 20 months. Such a reference system is very stable, and the electrode life is doubled compared to ordinary industrial electrodes.&lt;br /&gt;
* Easy to install: 3/4NPT pipe thread is convenient for sinking installation or installation in pipelines and tanks.&lt;br /&gt;
* IP68protection level.&lt;br /&gt;
* R-485 interface, Modbus/RTU protocol.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;AT-SB-PROBE-ORP-P&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
| -1500～+1500mV&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±6mV&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|1mV&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
|0 ~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Work Pressure&lt;br /&gt;
|＜0.1MPa&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
|12～24VDC ±10%&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
|POM&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
|Immersion mounting, 3/4 NPT thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
|15m&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
|One-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
|＜0.3W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Ip Grade&lt;br /&gt;
|IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimension ===&lt;br /&gt;
[[File:ORP Probe dimensions.svg|center|frameless|540x540px]]&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Install ====&lt;br /&gt;
Note: The sensor should not be installed upside down or horizontally when installed, at least at an angle of 15 degrees or more.&lt;br /&gt;
[[File:Instalation.svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
==== 5.2 Electrical connection ====&lt;br /&gt;
&lt;br /&gt;
* Red wire-power cord（12～24 V）&lt;br /&gt;
* Black wire-ground wire（GND）&lt;br /&gt;
* Blue Line-485 A&lt;br /&gt;
* White Line-485 B&lt;br /&gt;
&lt;br /&gt;
Check the wiring sequence carefully before powering on to avoid unnecessary losses caused by wiring errors.&lt;br /&gt;
&lt;br /&gt;
==== 5.3 Wiring instructions ====&lt;br /&gt;
Considering that the cables have been immersed in water (including seawater) or exposed to air for a long time, all wiring positions are required to be waterproof, and the cables should have certain corrosion resistance.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
When measuring the ORP electrode, it should be cleaned in distilled water (or deionized water) first, and the water should be absorbed with filter paper to prevent impurities from being brought into the test solution. 1/3 of the electrode should be inserted into the test solution. The electrode should be cleaned when not in use and inserted into a protective cover with 3.5mol/L potassium chloride solution or inserted into a container with 3.5mol/L potassium chloride solution. Check whether the terminal is dry, if it is stained, wipe it with absolute alcohol and blow it dry before use. Avoid long-term immersion in distilled water or protein solution and prevent contact with silicone grease. For electrodes that have been used for a long time, its glass membrane may become translucent or attached with sediment. In this case, it can be washed with diluted hydrochloric acid and rinsed with water. The electrode has been used for a long time, and when there is a measurement error, it must be calibrated and corrected with the meter. When the electrode is still unable to be calibrated and measured when the electrode is maintained and maintained by the above method, it means that the electrode has failed. Please replace the electrode.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 ORP standard solution preparation method ====&lt;br /&gt;
a) Preparation method of ORP standard solution 256mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 4.00 and mix well.&lt;br /&gt;
&lt;br /&gt;
b) Preparation method of ORP standard solution 86mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 6.86 and mix well.&lt;br /&gt;
&lt;br /&gt;
c) Preparation method of ORP standard solution-40mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 9.18 and mix well.&lt;br /&gt;
&lt;br /&gt;
Please note that when preparing the pH, a total of 250 mL is prepared, and 200 mL is measured for use.&lt;br /&gt;
&lt;br /&gt;
Method of preparing corresponding standard solution for pH:&lt;br /&gt;
&lt;br /&gt;
Measure 250mL of distilled water with a graduated cylinder, pour it into a beaker, add a package of calibration powder with pH=6.86/4.00/9.18, stir with a glass rod until the powder is completely dissolved, and prepare a solution with pH=6.86/4.00/9.18.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Calibration ====&lt;br /&gt;
Put the sensor into the prepared 86mV (or 256mV or-40mV) solution and wait for 3 to 5 minutes. After the value is stable, check whether the displayed value is 86mV (or 256mV or-40mV). If not, you need to calibrate it. See the appendix for calibration instructions.&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* Avoid exposing the inner surface of the fluorescent film head to sunlight&lt;br /&gt;
* Please do not touch the fluorescent film with your hands&lt;br /&gt;
* Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&lt;br /&gt;
* Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start address&lt;br /&gt;
|Number of registers&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|Response data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
c) Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
d) Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Instruction&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number of Registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Access Method&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001 (0x0000)&lt;br /&gt;
|Measured value&lt;br /&gt;
|Two double-byte integers are the measured value and the number of decimal places of the measured value.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097 (0x1000)&lt;br /&gt;
|Zero calibration&lt;br /&gt;
|Calibrate in the standard solution, the written data is the actual value of the standard solution.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103 (0x1006)&lt;br /&gt;
|Zero calibration value&lt;br /&gt;
|The read data is the zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|48195 (0x2002)&lt;br /&gt;
|Sensor address&lt;br /&gt;
|The default is 6, and the write data range is 1-127.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225 (0x2020)&lt;br /&gt;
|Reset sensor&lt;br /&gt;
|The calibration value is restored to the default value, and the write data is 0. Note that the sensor needs to be calibrated again after reset before it can be used.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44105(0x1008)&lt;br /&gt;
|Slope  calibration value&lt;br /&gt;
|The  read data is the slope value x1000&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44113(0x1010)&lt;br /&gt;
|Temperature  calibration&lt;br /&gt;
|Calibrated  in solution, the data written is the actual temperature value x10 ; the read  data is the temperature   calibration  offset x10 .&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48195(0x2002)&lt;br /&gt;
|Sensor  address&lt;br /&gt;
|The  default is 6 and the data range  is 1-127&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225(0x2020)&lt;br /&gt;
|Reset  sensor&lt;br /&gt;
|The  calibration value is restored to the default value and the write data is 0. Note: the sensor needs to be calibrated again after resetting.&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
a) The register address is the starting address of the register with register type defined according to the Modbus protocol (the actual starting address of the register represented by the hexadecimal system in parentheses).&lt;br /&gt;
&lt;br /&gt;
b) When changing the sensor address, the sensor address in the return instruction is the new address after the change.&lt;br /&gt;
&lt;br /&gt;
c)The data definition of the measured value returned when reading the data:&lt;br /&gt;
&lt;br /&gt;
xx       xx                                                            xx       xx&lt;br /&gt;
&lt;br /&gt;
2-byte measurement value               2-byte measurement value decimal places&lt;br /&gt;
&lt;br /&gt;
The default data type is: double-byte integer, high byte first; other types such as floating-point numbers are optional&lt;br /&gt;
&lt;br /&gt;
==== 7.4 Command example ====&lt;br /&gt;
&#039;&#039;&#039;a) Start measurement command&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: Obtain the ORP measured by the sensor, the unit of ORP is mV.&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 03 00 00 00 02 C5 BC&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 03 04 00 78 00 00 0C EA&lt;br /&gt;
&lt;br /&gt;
Examples of readings:&lt;br /&gt;
{| class=&amp;quot;wikitable mix-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;ORP value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;00 78 00 00&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
For example, ORP value: 00 78 represents the hexadecimal reading ORP value, 00 00 represents the ORP value without a decimal point and no temperature value, converted to a decimal value of 120.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;b) Calibration instruction:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The ORP sensor only needs one point calibration. Before calibrating with another calibration solution, the electrode must be cleaned with the latter calibration solution, otherwise it will cause a larger test error.&lt;br /&gt;
&lt;br /&gt;
In the prepared 86mV or 256mV standard solution, enter the corresponding calibration instructions.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The standard solution is 86mV:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 06 10 00 00 56 0C 83;&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 06 10 00 00 56 0C 83;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The standard solution is 256mV:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Request frame: 06 06 10 00 01 00 8D 2D;&lt;br /&gt;
&lt;br /&gt;
Response frame: 06 06 10 00 01 00 8D 2D&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; The ORP value has a negative value, such as-40mV, its calculation method is:-{FFFF-FFD7 software test value)}=-28; decimal is-40mV.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;c) Set the device ID address:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Function: set the MODBUS device address of the electrode.&lt;br /&gt;
&lt;br /&gt;
Change the device address 06 to 01, with the following example:&lt;br /&gt;
&lt;br /&gt;
Request frame：06 06 20 02 00 01 E3 BD&lt;br /&gt;
&lt;br /&gt;
Response frame：06 06 20 02 00 01 E3 BD&lt;br /&gt;
&lt;br /&gt;
==== 7.5 Error response ====&lt;br /&gt;
If the sensor does not execute the upper computer command correctly, the following format information is returned:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|Definition&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|CODE&lt;br /&gt;
|CRC check&lt;br /&gt;
|-&lt;br /&gt;
|data&lt;br /&gt;
|ADDR&lt;br /&gt;
|COM+80H&lt;br /&gt;
|xx&lt;br /&gt;
|CRC 16&lt;br /&gt;
|-&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|1&lt;br /&gt;
|2&lt;br /&gt;
|}&lt;br /&gt;
a) CODE： 01 – Functional code error&lt;br /&gt;
&lt;br /&gt;
03 – Data error&lt;br /&gt;
&lt;br /&gt;
b) COM: Received function code&lt;br /&gt;
&lt;br /&gt;
=== 8. Applicable Accessories ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000076&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000079&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000080&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000074&lt;br /&gt;
|SENSBLUE  MONARCH Solar Panel 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000081&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000082&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000083&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 1 Probe External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000084&lt;br /&gt;
|SENSBLUE  MONARCH Opaque Case 2 Probes External Antenna&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|PA000000020&lt;br /&gt;
|SENSBLUE  MONARCH RS485 Probe Splitter Box (1 input -&amp;gt; 2 outputs)&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 9. Similar Products ===&lt;br /&gt;
{{SimilarProductsTable}}&lt;br /&gt;
&lt;br /&gt;
=== 10. Applicable certifications and standards ===&lt;br /&gt;
EMC Directive 2014/30/EU.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61326-1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 55011: 2016+A2: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN IEC 61000-3-2: 2019+A1: 2021&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;EN 61000-3-3: 2013+A2: 2021&#039;&#039;&#039;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1925</id>
		<title>RS-485 ORP Probe POM AT-SB-PROBE-ORP-P</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=RS-485_ORP_Probe_POM_AT-SB-PROBE-ORP-P&amp;diff=1925"/>
		<updated>2026-07-13T11:23:04Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: Created page with &amp;quot;345x345px  == Datasheet ==  === 1. Introduction === SENSBLUE Monarch ORP Probe POM AT-SB-PROBE-ORP-P can be used for environmental water quality monitoring, acid/alkali/salt solution, chemical reaction process, industrial production process, and can meet the requirements of online ORP measurement for most industrial applications.  === 2. Features ===  * Signal output: RS-485 (Modbus/RTU protocol). * Conveniently c...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:ORP-100-PH-10-ORP-10-PH-100.png|center|frameless|345x345px]]&lt;br /&gt;
&lt;br /&gt;
== Datasheet ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Introduction ===&lt;br /&gt;
SENSBLUE Monarch ORP Probe POM AT-SB-PROBE-ORP-P can be used for environmental water quality monitoring, acid/alkali/salt solution, chemical reaction process, industrial production process, and can meet the requirements of online ORP measurement for most industrial applications.&lt;br /&gt;
&lt;br /&gt;
=== 2. Features ===&lt;br /&gt;
&lt;br /&gt;
* Signal output: RS-485 (Modbus/RTU protocol).&lt;br /&gt;
* Conveniently connect to third-party equipment such as PLC, DCS, industrial control computer, general controller, paperless recording instrument or touch screen.&lt;br /&gt;
* Double high impedance differential amplifier, strong anti-interference and fast response speed.&lt;br /&gt;
* Durable ORP electrode, the internal reference fluid seeps out from the microporous salt bridge very slowly under a pressure of at least 100KPa (1Bar), and its positive seepage lasts for more than 20 months. Such a reference system is very stable, and the electrode life is doubled compared to ordinary industrial electrodes.&lt;br /&gt;
* Easy to install: 3/4NPT pipe thread is convenient for sinking installation or installation in pipelines and tanks.&lt;br /&gt;
* IP68protection level.&lt;br /&gt;
* R-485 interface, Modbus/RTU protocol.&lt;br /&gt;
&lt;br /&gt;
=== 3. Technical Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Model&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;AT-SB-PROBE-ORP-P&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Measuring  Range&lt;br /&gt;
| -1500～+1500mV&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|±6mV&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|1mV&lt;br /&gt;
|-&lt;br /&gt;
|Temperature Range&lt;br /&gt;
|0 ~65℃&lt;br /&gt;
|-&lt;br /&gt;
|Work Pressure&lt;br /&gt;
|＜0.1MPa&lt;br /&gt;
|-&lt;br /&gt;
|Output&lt;br /&gt;
|RS-485, MODBUS protocol&lt;br /&gt;
|-&lt;br /&gt;
|Power Supply&lt;br /&gt;
|12～24VDC ±10%&lt;br /&gt;
|-&lt;br /&gt;
|Wetted Part Material&lt;br /&gt;
|POM&lt;br /&gt;
|-&lt;br /&gt;
|Installation&lt;br /&gt;
|Immersion mounting, 3/4 NPT thread&lt;br /&gt;
|-&lt;br /&gt;
|Cable Length&lt;br /&gt;
|15m&lt;br /&gt;
|-&lt;br /&gt;
|Calibration Method&lt;br /&gt;
|One-point calibration&lt;br /&gt;
|-&lt;br /&gt;
|Power Consumption&lt;br /&gt;
|＜0.3W@12V&lt;br /&gt;
|-&lt;br /&gt;
|Ip Grade&lt;br /&gt;
|IP68&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Dimension ===&lt;br /&gt;
[[File:ORP Probe dimensions.svg|center|frameless|540x540px]]&lt;br /&gt;
&lt;br /&gt;
=== 5. Installation and Electrical Connection ===&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Install ====&lt;br /&gt;
Note: The sensor should not be installed upside down or horizontally when installed, at least at an angle of 15 degrees or more.&lt;br /&gt;
[[File:Instalation.svg|center|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
==== 5.2 Electrical connection ====&lt;br /&gt;
&lt;br /&gt;
* Red wire-power cord（12～24 V）&lt;br /&gt;
* Black wire-ground wire（GND）&lt;br /&gt;
* Blue Line-485 A&lt;br /&gt;
* White Line-485 B&lt;br /&gt;
&lt;br /&gt;
Check the wiring sequence carefully before powering on to avoid unnecessary losses caused by wiring errors.&lt;br /&gt;
&lt;br /&gt;
==== 5.3 Wiring instructions ====&lt;br /&gt;
Considering that the cables have been immersed in water (including seawater) or exposed to air for a long time, all wiring positions are required to be waterproof, and the cables should have certain corrosion resistance.&lt;br /&gt;
&lt;br /&gt;
=== 6. Maintenance ===&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Use and maintenance ====&lt;br /&gt;
When measuring the ORP electrode, it should be cleaned in distilled water (or deionized water) first, and the water should be absorbed with filter paper to prevent impurities from being brought into the test solution. 1/3 of the electrode should be inserted into the test solution. The electrode should be cleaned when not in use and inserted into a protective cover with 3.5mol/L potassium chloride solution or inserted into a container with 3.5mol/L potassium chloride solution. Check whether the terminal is dry, if it is stained, wipe it with absolute alcohol and blow it dry before use. Avoid long-term immersion in distilled water or protein solution and prevent contact with silicone grease. For electrodes that have been used for a long time, its glass membrane may become translucent or attached with sediment. In this case, it can be washed with diluted hydrochloric acid and rinsed with water. The electrode has been used for a long time, and when there is a measurement error, it must be calibrated and corrected with the meter. When the electrode is still unable to be calibrated and measured when the electrode is maintained and maintained by the above method, it means that the electrode has failed. Please replace the electrode.&lt;br /&gt;
&lt;br /&gt;
==== 6.2 ORP standard solution preparation method ====&lt;br /&gt;
a) Preparation method of ORP standard solution 256mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 4.00 and mix well.&lt;br /&gt;
&lt;br /&gt;
b) Preparation method of ORP standard solution 86mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 6.86 and mix well.&lt;br /&gt;
&lt;br /&gt;
c) Preparation method of ORP standard solution-40mV Weigh 2.1 g of quinhydroquinone and add it to 200 mL of a standard pH buffer solution with a pH of 9.18 and mix well.&lt;br /&gt;
&lt;br /&gt;
Please note that when preparing the pH, a total of 250 mL is prepared, and 200 mL is measured for use.&lt;br /&gt;
&lt;br /&gt;
Method of preparing corresponding standard solution for pH:&lt;br /&gt;
&lt;br /&gt;
Measure 250mL of distilled water with a graduated cylinder, pour it into a beaker, add a package of calibration powder with pH=6.86/4.00/9.18, stir with a glass rod until the powder is completely dissolved, and prepare a solution with pH=6.86/4.00/9.18.&lt;br /&gt;
&lt;br /&gt;
==== 6.3 Calibration ====&lt;br /&gt;
Put the sensor into the prepared 86mV (or 256mV or-40mV) solution and wait for 3 to 5 minutes. After the value is stable, check whether the displayed value is 86mV (or 256mV or-40mV). If not, you need to calibrate it. See the appendix for calibration instructions.&lt;br /&gt;
&lt;br /&gt;
==== 6.4 Precautions ====&lt;br /&gt;
&lt;br /&gt;
* Avoid exposing the inner surface of the fluorescent film head to sunlight&lt;br /&gt;
* Please do not touch the fluorescent film with your hands&lt;br /&gt;
* Avoid bubbles adhering to the surface of the fluorescent film during measurement and calibration&lt;br /&gt;
* Avoid applying any mechanical stress (pressure, scratches, etc.) directly to the fluorescent film during use&lt;br /&gt;
&lt;br /&gt;
=== 7. Appendix data communication ===&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Data Format ====&lt;br /&gt;
The default data format for Modbus communication is: 9600, n, 8, 1 (baud rate 9600bps, 1 start bit, 8 data bits, no parity, 1 stop bit).&lt;br /&gt;
&lt;br /&gt;
==== 7.2 Modbus Frame Format (xx represents a byte) ====&lt;br /&gt;
a) Read data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register start address&lt;br /&gt;
|Number of registers&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
b) Read data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|03&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Number of bytes&lt;br /&gt;
|Response data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
c) Write data instruction frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
d) Data response frame&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|06&lt;br /&gt;
|06&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|xx      xx&lt;br /&gt;
|-&lt;br /&gt;
|Address&lt;br /&gt;
|FC&lt;br /&gt;
|Register address&lt;br /&gt;
|Read-in data&lt;br /&gt;
|CRC check code (low bytes in front)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.3 Register Address ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Register Address&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Instruction&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Number of Registers&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Access Method&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|40001 (0x0000)&lt;br /&gt;
|Measured value&lt;br /&gt;
|Two double-byte integers are the measured value and the number of decimal places of the measured value.&lt;br /&gt;
|2 (4 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44097 (0x1000)&lt;br /&gt;
|Zero calibration&lt;br /&gt;
|Calibrate in the standard solution, the written data is the actual value of the standard solution.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44103 (0x1006)&lt;br /&gt;
|Zero calibration value&lt;br /&gt;
|The read data is the zero offset.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|48195 (0x2002)&lt;br /&gt;
|Sensor address&lt;br /&gt;
|The default is 6, and the write data range is 1-127.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225 (0x2020)&lt;br /&gt;
|Reset sensor&lt;br /&gt;
|The calibration value is restored to the default value, and the write data is 0. Note that the sensor needs to be calibrated again after reset before it can be used.&lt;br /&gt;
|1 (2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|-&lt;br /&gt;
|44105(0x1008)&lt;br /&gt;
|Slope  calibration value&lt;br /&gt;
|The  read data is the slope value x1000&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Read&lt;br /&gt;
|-&lt;br /&gt;
|44113(0x1010)&lt;br /&gt;
|Temperature  calibration&lt;br /&gt;
|Calibrated  in solution, the data written is the actual temperature value x10 ; the read  data is the temperature   calibration  offset x10 .&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48195(0x2002)&lt;br /&gt;
|Sensor  address&lt;br /&gt;
|The  default is 6 and the data range  is 1-127&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write/Read&lt;br /&gt;
|-&lt;br /&gt;
|48225(0x2020)&lt;br /&gt;
|Reset  sensor&lt;br /&gt;
|The  calibration value is restored to the default value and the write data is 0. Note: the sensor needs to be calibrated again after resetting.&lt;br /&gt;
|1 ( 2 bytes)&lt;br /&gt;
|Write&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=File:ORP_Probe_dimensions.svg&amp;diff=1924</id>
		<title>File:ORP Probe dimensions.svg</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=File:ORP_Probe_dimensions.svg&amp;diff=1924"/>
		<updated>2026-07-13T11:07:54Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ORP Probe dimensions&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=File:Orp_Probe_Dimensions.png&amp;diff=1923</id>
		<title>File:Orp Probe Dimensions.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=File:Orp_Probe_Dimensions.png&amp;diff=1923"/>
		<updated>2026-07-13T11:03:55Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Orp Probe Dimensions&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=File:ORP-100-PH-10-ORP-10-PH-100.png&amp;diff=1922</id>
		<title>File:ORP-100-PH-10-ORP-10-PH-100.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=File:ORP-100-PH-10-ORP-10-PH-100.png&amp;diff=1922"/>
		<updated>2026-07-13T10:57:03Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;ORP&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1921</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1921"/>
		<updated>2026-07-13T10:52:43Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: /* Probes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Wiki Main Page Banner.svg|center|frameless|1153x1153px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welcome to the ATRONIA´s Wiki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is where tech makes sense.&lt;br /&gt;
&lt;br /&gt;
Here you will find our product´s datasheets, manuals, integration architectures, firmware releases, and engineering insights that will help you better understand what we do.&lt;br /&gt;
&lt;br /&gt;
We document with purpose. We design with clarity.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gateways &amp;amp; Single Board Computers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch|SENSBLUE MONARCH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateway&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:ATLAS.svg|frameless|106x106px|class=product-image|link=SENSBLUE ATLAS]]&lt;br /&gt;
&#039;&#039;&#039;[[SENSBLUE ATLAS]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;SBC&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- == Solutions ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Probes ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
    [[File:Dissolved Oxygen.svg|center|frameless|106x106px|class=product-image|link=Dissolved Oxygen]]&lt;br /&gt;
        &#039;&#039;&#039;[[Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-customtoggle-1 variations-toggle&amp;quot; style=&amp;quot;cursor: pointer; display: inline-block;height:2rem;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; flex-direction: row; justify-content: center;&amp;quot; class=&amp;quot;product-subtitle&amp;quot;&amp;gt;&lt;br /&gt;
  All Models &lt;br /&gt;
             &amp;lt;span class=&amp;quot;material-symbols-rounded arrow-icon&amp;quot;&amp;gt;&lt;br /&gt;
                   keyboard_arrow_down&lt;br /&gt;
             &amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-1&amp;quot; style=&amp;quot;line-height: 1.8 rem; font-size: 0.85em; &amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;variations-list&amp;quot; style=&amp;quot;overflow: visible !important;&amp;quot;&amp;gt;&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|DO Probe]]&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|DO Titanium]]&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Conductivity.svg|center|frameless|106x106px|class=product-image|link=Low Conductivity Probe AT-SB-PROBE-LC-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Conductivity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px|class=product-image|link=Multiparameter Probe AT-SB-PROBE-MP-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:NO3-.svg|center|frameless|106x106px|class=product-image|link=RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Nitrates (NO3) Probe AT-SB-PROBENO3-P|Nitrates(NO3-)]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:PH.svg|center|frameless|106x106px|class=product-image|link=RS-485 pH Probe AT-SB-PROBE-pH-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 pH Probe AT-SB-PROBE-pH-P|pH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:PH.svg|center|frameless|106x106px|class=product-image|link=RS-485 ORP Probe POM AT-SB-PROBE-ORP-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 ORP Probe POM AT-SB-PROBE-ORP-P|ORP]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Turbidity.svg|center|frameless|106x106px|class=product-image|link=RS-485 Turbidity Probe AT-SB-PROBE-T-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|Turbidity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Salinity.svg|center|frameless|106x106px|class=product-image|link=Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|Salinity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessories ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Straight N-Type Outdoor Antenna.svg|frameless|106x106px|class=product-image|link=Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;[[Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Accessories&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Realease_Notes&amp;diff=1920</id>
		<title>SENSBLUE ATLAS/Realease Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Realease_Notes&amp;diff=1920"/>
		<updated>2026-07-08T10:12:48Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Realease Notes}}&lt;br /&gt;
&lt;br /&gt;
== 1.0.0 ==&lt;br /&gt;
Date: 03-03-2026&lt;br /&gt;
&lt;br /&gt;
First release&lt;br /&gt;
&lt;br /&gt;
== 1.1.0 ==&lt;br /&gt;
Date: 18-06-2026&lt;br /&gt;
&lt;br /&gt;
=== Features: ===&lt;br /&gt;
&lt;br /&gt;
* Implemented Buzzer actor;&lt;br /&gt;
* Implemented INA actor;&lt;br /&gt;
* Implemented Atecc actor;&lt;br /&gt;
* Added GET_SIM_INFO command to modem actor;&lt;br /&gt;
* Added lsusb output command on SystemHealth actor;&lt;br /&gt;
* Added get hardware info on SystemHealth actor;&lt;br /&gt;
* SystemHealth reports the ram and disk usage, free space and total.&lt;br /&gt;
&lt;br /&gt;
=== Improvements: ===&lt;br /&gt;
&lt;br /&gt;
* ADCs now recover after GPIO mechanical error;&lt;br /&gt;
* Version TFT without bootflags;&lt;br /&gt;
* canopen topics changed to be canopenRM8007 on CAN Actor;&lt;br /&gt;
* SystemHealth actor now handles only the peripherals version;&lt;br /&gt;
* TFT System screen now shows the ram and disk usage, free space and total.&lt;br /&gt;
&lt;br /&gt;
=== Bug fixing: ===&lt;br /&gt;
&lt;br /&gt;
* TFT start index wrong;&lt;br /&gt;
* Set apn auto mode on modem actor;&lt;br /&gt;
* remove all retained messages on modem actor.&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Realease_Notes&amp;diff=1919</id>
		<title>SENSBLUE ATLAS/Realease Notes</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Realease_Notes&amp;diff=1919"/>
		<updated>2026-07-02T10:03:29Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Realease Notes}}&lt;br /&gt;
&lt;br /&gt;
== 1.0.0 ==&lt;br /&gt;
Date: 03-03-2026&lt;br /&gt;
&lt;br /&gt;
First release&lt;br /&gt;
&lt;br /&gt;
== 1.1.0 ==&lt;br /&gt;
Date: 18-06-2026&lt;br /&gt;
&lt;br /&gt;
=== Features: ===&lt;br /&gt;
&lt;br /&gt;
* Implemented Buzzer actor;&lt;br /&gt;
* Implemented INA actor;&lt;br /&gt;
* Implemented Atecc actor;&lt;br /&gt;
* Added GET_SIM_INFO command to modem actor;&lt;br /&gt;
* Added lsusb output command on SystemHealth actor;&lt;br /&gt;
* Added get hardware info on SystemHealth actor;&lt;br /&gt;
* SystemHealth reports the ram and disk usage, free space and total;&lt;br /&gt;
* SystemManager Production actor auto provisions the hostname and Wi-Fi Access Point after EEPROMcommissioning, with device serial number.&lt;br /&gt;
&lt;br /&gt;
=== Improvements: ===&lt;br /&gt;
&lt;br /&gt;
* ADCs now recover after GPIO mechanical error;&lt;br /&gt;
* Version TFT without bootflags;&lt;br /&gt;
* canopen topics changed to be canopenRM8007 on CAN Actor;&lt;br /&gt;
* SystemHealth actor now handles only the peripherals version;&lt;br /&gt;
* TFT System screen now shows the ram and disk usage, free space and total.&lt;br /&gt;
&lt;br /&gt;
=== Bug fixing: ===&lt;br /&gt;
&lt;br /&gt;
* TFT start index wrong;&lt;br /&gt;
* Set apn auto mode on modem actor;&lt;br /&gt;
* remove all retained messages on modem actor.&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Datasheet&amp;diff=1918</id>
		<title>SENSBLUE ATLAS/Datasheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Datasheet&amp;diff=1918"/>
		<updated>2026-06-30T13:15:14Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: /* Datasheet */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Datasheet}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-atlas/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:SENSBLUE-ATLAS-Gateway.png|center|frameless|360x360px]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Datasheet&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Table of SENSBLUE ATLAS Reference ID Model Number ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Reference Number&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Version&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;RAM&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Modem&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000102&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 2GB M2.0 M1 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|2GB&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|PA000000103&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 2GB M2.0 M0 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|2GB&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|PA000000104&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 4GB M2.0 M1 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|4GB&lt;br /&gt;
|No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2. General Description ===&lt;br /&gt;
SENSBLUE ATLAS is a single board computer that connects sensors and assets, runs control logic and ships to production without platform changes.&lt;br /&gt;
&lt;br /&gt;
Designed for industrial teams who need one dependable path from experiments to operations.&lt;br /&gt;
&lt;br /&gt;
==== 2.1 Key Features ====&lt;br /&gt;
&#039;&#039;&#039;Processor:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi CM4 (quad-core Cortex-A72)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;I/O:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 12 DIO (8 Digital Outputs and 4 Digital Input)&lt;br /&gt;
* 6 AIO (4 Analog Inputs and 2 Analog Outputs)&lt;br /&gt;
* 2 relays&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Industrial Bus:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* RS-485&lt;br /&gt;
* CAN&lt;br /&gt;
* 2× Ethernet port (Independently managed)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Communication:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Integrated LTE&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
* BLE&lt;br /&gt;
* USB&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Interface &amp;amp; Services:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 1.47″ IPS TFT display + joystick for local setup and feedback.&lt;br /&gt;
* Includes 1 GB of data (up to 500 MB LTE + 500 MB DB storage) via sensblue.cloud — no external SIM required.&lt;br /&gt;
* EU-hosted servers, TLS, weekly backups, VPN on request.&lt;br /&gt;
* Other versions under request.&lt;br /&gt;
&lt;br /&gt;
=== 3. Hardware Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Platform&lt;br /&gt;
|Raspberry  Pi Compute Module 4 (CM4)&lt;br /&gt;
|-&lt;br /&gt;
|Processor&lt;br /&gt;
|Broadcom  BCM2711 Quad-core Cortex-A72 (ARM v8)&lt;br /&gt;
|-&lt;br /&gt;
|CPU Frequency&lt;br /&gt;
|1.5  GHz&lt;br /&gt;
|-&lt;br /&gt;
|RAM&lt;br /&gt;
|2GB, 4GB  LPDDR4&lt;br /&gt;
|-&lt;br /&gt;
|Storage&lt;br /&gt;
|32  GB eMMC&lt;br /&gt;
|-&lt;br /&gt;
|Selected Variant&lt;br /&gt;
|CM4102032-4  GB RAM/ 32 GB eMMC / Wi-Fi / BLE&lt;br /&gt;
|-&lt;br /&gt;
|PCle&lt;br /&gt;
|1  x PCle Gen 2.0 (1 lane)&lt;br /&gt;
|-&lt;br /&gt;
|HDMI&lt;br /&gt;
|1  interfaces&lt;br /&gt;
|-&lt;br /&gt;
|USB&lt;br /&gt;
|2  x USB 2.0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Power ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Input  voltage&lt;br /&gt;
|12-24  VDC ± 5%&lt;br /&gt;
|-&lt;br /&gt;
|Reverse polarity protection&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Overcurrent protection&lt;br /&gt;
|Resettable  PTC fuse&lt;br /&gt;
|-&lt;br /&gt;
|Surge protection&lt;br /&gt;
|TVS  clamp for transient events&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|No  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Typical consumption&lt;br /&gt;
|&amp;lt;  15 W&lt;br /&gt;
|-&lt;br /&gt;
|Maximum consumption&lt;br /&gt;
|25  W (all peripherals active)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Digital Inputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|Input voltage&lt;br /&gt;
|0-24  VDC&lt;br /&gt;
|-&lt;br /&gt;
|Logic LOW&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Logic HIGH&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Input type&lt;br /&gt;
|Sourcing  (PNP)&lt;br /&gt;
|-&lt;br /&gt;
|Input current&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage&lt;br /&gt;
|Functional  isolation between channels on the field side +- 60V&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-11&lt;br /&gt;
|Maximum  working isolation voltage 400V RMS&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-11&lt;br /&gt;
|Maximum  surge  isolation voltage 1 kV RMS&lt;br /&gt;
|-&lt;br /&gt;
|Special feature&lt;br /&gt;
|Can  be used as fast inputs until 100Hz&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Wiring ====&lt;br /&gt;
[[File:DIG IN.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 6. Digital Outputs (Relay) ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|Mechanical  relay&lt;br /&gt;
|-&lt;br /&gt;
|Switching capacity&lt;br /&gt;
|2  A@ 30 VDC&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|1000  VAC galvanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Lifetime (nominal load)&lt;br /&gt;
|≥  100,000 cycles&lt;br /&gt;
|-&lt;br /&gt;
|Lifetime (no load)&lt;br /&gt;
|≥  100,000,000  cycles&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Wiring ====&lt;br /&gt;
[[File:RELAY.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 7. Digital Outputs (Transistor/ SSR) ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|8&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|PNP  (sourcing) SSR&lt;br /&gt;
|-&lt;br /&gt;
|Maximum current&lt;br /&gt;
|300  mA per channel&lt;br /&gt;
|-&lt;br /&gt;
|Maximum voltage&lt;br /&gt;
|24  VDC&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-17&lt;br /&gt;
|Maximum  transient isolation voltage 1 kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Wiring ====&lt;br /&gt;
[[File:DIG OUT.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 8. Analog Inputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|Mode &lt;br /&gt;
|Voltage or current configurable  per channel&lt;br /&gt;
|-&lt;br /&gt;
|Voltage  range&lt;br /&gt;
|0-10 V&lt;br /&gt;
|-&lt;br /&gt;
|Current  range&lt;br /&gt;
|0/4-20 mA&lt;br /&gt;
|-&lt;br /&gt;
|ADC  resolution&lt;br /&gt;
|16 bits&lt;br /&gt;
|-&lt;br /&gt;
|ADC  Sample Rate&lt;br /&gt;
|32 samples/sec&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|≤  ±1.0% FSR&lt;br /&gt;
|-&lt;br /&gt;
|Input  impedance (voltage)&lt;br /&gt;
|&amp;gt; 100 k&#039;&#039;&#039;Ω&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Input  impedance (current)&lt;br /&gt;
|100  &#039;&#039;&#039;Ω&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|TVS  + analog filtering&lt;br /&gt;
|-&lt;br /&gt;
|Sampling  rate&lt;br /&gt;
|≥  10 Hz per channel&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation  Voltage&lt;br /&gt;
|Maximum  transient isolation voltage 1 kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 8.1 Wiring ====&lt;br /&gt;
[[File:ANL IN.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 9. Analog Outputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Output  type&lt;br /&gt;
|Current&lt;br /&gt;
|-&lt;br /&gt;
|Range&lt;br /&gt;
|0-20 mA&lt;br /&gt;
|-&lt;br /&gt;
|Optional  range&lt;br /&gt;
|4-20 mA (software configurable)&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|≤ ±1.0%  FSR&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional Safety Gavanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation  Voltage&lt;br /&gt;
|Maximum transient isolation voltage 1  kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 9.1 Wiring ====&lt;br /&gt;
[[File:ANL OUT.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 10. Communication Interfaces ===&lt;br /&gt;
&lt;br /&gt;
==== 10.1 Ethernet ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | &#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | &#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|2 x RJ45&lt;br /&gt;
|-&lt;br /&gt;
|Port  1&lt;br /&gt;
|10/100 Mbps&lt;br /&gt;
|-&lt;br /&gt;
|Port  2&lt;br /&gt;
|0/100/1000 Mbps (native CM4)&lt;br /&gt;
|-&lt;br /&gt;
|Indicators&lt;br /&gt;
|Link + Activity LEDs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 10.2 RS-485 ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Mode&lt;br /&gt;
|Half-duplex&lt;br /&gt;
|-&lt;br /&gt;
|Control&lt;br /&gt;
|TX_EN line&lt;br /&gt;
|-&lt;br /&gt;
|Protocol&lt;br /&gt;
|Transparent/ any&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|None&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 10.2.1 Wiring =====&lt;br /&gt;
[[File:RS485.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
==== 10.3 USB ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|USB-A&lt;br /&gt;
|-&lt;br /&gt;
|Standard&lt;br /&gt;
|USB 2.0 Host&lt;br /&gt;
|-&lt;br /&gt;
|Maximum  current&lt;br /&gt;
|400 mA per port&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|Overcurrent protection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 10.4 HDMI ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Connector&lt;br /&gt;
|HDMI full-size &lt;br /&gt;
|-&lt;br /&gt;
|Maximum  resolution&lt;br /&gt;
|Depends on CM4 and OS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 11. RF Communications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Technology&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Wi-Fi&lt;br /&gt;
|Integrated in CM4&lt;br /&gt;
|-&lt;br /&gt;
|BLE&lt;br /&gt;
|Integrated in CM4&lt;br /&gt;
|-&lt;br /&gt;
|LTE&lt;br /&gt;
|M.2 NGFF modem SIM7600G&lt;br /&gt;
|-&lt;br /&gt;
|SIM&lt;br /&gt;
|External access&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 11.1  Antenna Connectors ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Connector&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Usage&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|RP-SMA&lt;br /&gt;
|Wi-Fi / BLE&lt;br /&gt;
|-&lt;br /&gt;
|SMA&lt;br /&gt;
|LTE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 12. Local Peripherals ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Peripheral&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Description&#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Temperature  sensor&lt;br /&gt;
|Internal board temperature monitoring&lt;br /&gt;
|-&lt;br /&gt;
|Non-volatile  memory&lt;br /&gt;
|Persistent storage&lt;br /&gt;
|-&lt;br /&gt;
|Security  IC&lt;br /&gt;
|Microchip ATECC608A&lt;br /&gt;
|-&lt;br /&gt;
|RTC&lt;br /&gt;
|Real Time Clock with battery  backup&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 13. HDMI ===&lt;br /&gt;
&lt;br /&gt;
==== 13. 1 Display ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|IPS TFT LCD&lt;br /&gt;
|-&lt;br /&gt;
|Interface&lt;br /&gt;
|SPI&lt;br /&gt;
|-&lt;br /&gt;
|Size&lt;br /&gt;
|1.47&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|≥ 172 X 320&lt;br /&gt;
|-&lt;br /&gt;
|Backlight&lt;br /&gt;
|LED&lt;br /&gt;
|-&lt;br /&gt;
|Mounting&lt;br /&gt;
|Front mounted with transparent  window&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 13. 2 Joystick ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Positions&lt;br /&gt;
|5 (Up/ Down/ Left/ Right/ Enter)&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|Mechanical tactile switch&lt;br /&gt;
|-&lt;br /&gt;
|Interface&lt;br /&gt;
|GPIO Expander&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 14. Mechanical ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Mounting&lt;br /&gt;
|DIN rail (EN 60715)&lt;br /&gt;
|-&lt;br /&gt;
|Enclosure&lt;br /&gt;
|MAT0091092 (same as iSense / iCee)&lt;br /&gt;
|-&lt;br /&gt;
|Protection  rating&lt;br /&gt;
|IP20&lt;br /&gt;
|-&lt;br /&gt;
|Mounting  method&lt;br /&gt;
|DIN rail snap-fit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 15. Environmental ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Operating  temperature&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-10 °C to +60 °C&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Storage  temperature&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-20 °C to +80 °C&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Humidity&lt;br /&gt;
|5-95% non-condensing&lt;br /&gt;
|-&lt;br /&gt;
|Vibration&lt;br /&gt;
|IEC 60068-2-6&lt;br /&gt;
|-&lt;br /&gt;
|Shock&lt;br /&gt;
|IEC 60068-2-27&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 16. Certifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Certification&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Standard  &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|CE&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|EMC&lt;br /&gt;
|2014/30/EU&lt;br /&gt;
|-&lt;br /&gt;
|Radio&lt;br /&gt;
|2014/53/EU (RED)&lt;br /&gt;
|-&lt;br /&gt;
|Ro  HS&lt;br /&gt;
|2011/65/EU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 17. Connectivity ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification  &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Connector  type&lt;br /&gt;
|Pluggable System Terminal Block&lt;br /&gt;
|-&lt;br /&gt;
|Pitch&lt;br /&gt;
|3.5 mm&lt;br /&gt;
|-&lt;br /&gt;
|Layout&lt;br /&gt;
|Dual-row&lt;br /&gt;
|-&lt;br /&gt;
|Identification&lt;br /&gt;
|Side panel silk screen&lt;br /&gt;
|-&lt;br /&gt;
|Fixation&lt;br /&gt;
|Mechanical locking or spring  clamp&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|Mechanical reverse insertion  protection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 18. Expansion ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Feature&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Description &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Piggyback  area&lt;br /&gt;
|Reserved PCB area&lt;br /&gt;
|-&lt;br /&gt;
|Compatibility&lt;br /&gt;
|Fully compatible with existing FW&lt;br /&gt;
|-&lt;br /&gt;
|Power  rails available&lt;br /&gt;
|Vin, 5 V, 3.3 V&lt;br /&gt;
|-&lt;br /&gt;
|Interfaces  available&lt;br /&gt;
|12C, SPI, UART, GPIO&lt;br /&gt;
|-&lt;br /&gt;
|External  1/0 lines&lt;br /&gt;
|32 lines routed to external  connectors&lt;br /&gt;
|-&lt;br /&gt;
|Storage  expansion&lt;br /&gt;
|M.2 NVMe SSD connector&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 19. External Interfaces ===&lt;br /&gt;
&lt;br /&gt;
==== Front View ====&lt;br /&gt;
[[File:Atlas FrontView.png|center|frameless|670x670px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Bottom View ====&lt;br /&gt;
[[File:Atlas bottomview.png|center|frameless|590x590px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 20. Pinouts ===&lt;br /&gt;
&lt;br /&gt;
==== Top View ====&lt;br /&gt;
[[File:Atlas topview.png|center|frameless|688x688px]]&lt;br /&gt;
&lt;br /&gt;
=== 21. System Type ===&lt;br /&gt;
&#039;&#039;&#039;Raspian&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Debian GNU/Linux 13 (trixie) Version 13.2 Linux atlas 6.12.47 +rpt-rpi-v8 #1 SMP PREEMPT&lt;br /&gt;
&lt;br /&gt;
Debian 1 :6.12.47-1 +rpt1 (2025-09-16) aarch64 GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
=== 22. Network Information ===&lt;br /&gt;
There is three ways to connect to the device. IP and state of the connection be checked on the LCD Network Interface.&lt;br /&gt;
&lt;br /&gt;
==== 22.1 Eth1 (ethO) ====&lt;br /&gt;
Client dynamic IP obtained by DHCP server.&lt;br /&gt;
&lt;br /&gt;
==== 22.2 Eth2 (eth1) ====&lt;br /&gt;
Static IP: &#039;&#039;&#039;93.48.86.253&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 22.3 Access Point (wlanO) ====&lt;br /&gt;
IP: &#039;&#039;&#039;192.168.30.1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 23. Software Information ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Node-Red&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Grafana&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;lnfluxDB&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Version&lt;br /&gt;
|4.1.4&lt;br /&gt;
|12.3.1&lt;br /&gt;
|2.8.0&lt;br /&gt;
|-&lt;br /&gt;
|Port&lt;br /&gt;
|1880&lt;br /&gt;
|3000&lt;br /&gt;
|8086&lt;br /&gt;
|-&lt;br /&gt;
|State&lt;br /&gt;
|Clean&lt;br /&gt;
|Clean&lt;br /&gt;
|Clean&lt;br /&gt;
|-&lt;br /&gt;
|Authentication&lt;br /&gt;
|None&lt;br /&gt;
|User/Pass  (admin/admin)&lt;br /&gt;
|Not  defined, configured on first time interface login.&lt;br /&gt;
|-&lt;br /&gt;
|GUI on&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:1880&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:3000&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:8086&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 24. MQTT Broker ===&lt;br /&gt;
port: 1883&lt;br /&gt;
&lt;br /&gt;
address: AP-&amp;gt; 192.168.30.1&lt;br /&gt;
&lt;br /&gt;
Eth1: &#039;&#039;&#039;93.48.86.253&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
user: &amp;lt; not needed&amp;gt;&lt;br /&gt;
&lt;br /&gt;
login &amp;lt;not needed&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.1 Relay Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.1.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set/reset digital output pin/pins state ======&lt;br /&gt;
Both relays &#039;&#039;&#039;default&#039;&#039;&#039; state is &#039;&#039;&#039;open&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/config/in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/config/out&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Get all relays state ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/runtime/out &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Set all relays state ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.2 RTC Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.2.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set timer/alarm interruption ======&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; Timer, alarm or none.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alarmSet:&#039;&#039;&#039; Date and time for alarm interruption (No effect if mode is timer or none). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;timerSetSeconds:&#039;&#039;&#039; Period in seconds for timer interruption (No effect if mode is alarm or none).&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;CLOCK_SET_MODE&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Req-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;CLOCK_SET_MODE&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Toggle RTC sync logic (described below) ======&lt;br /&gt;
&#039;&#039;&#039;tcState:&#039;&#039;&#039; State of the synchronization logic of the RTC, this value is &#039;&#039;&#039;non-persistent&#039;&#039;&#039; so every-time a reboot happens the value return to default (by default the value is &#039;&#039;&#039;ON&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;TOGGLE&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Req-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;rtcState&amp;quot;: &amp;quot;OFF&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read clock configs ======&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; Timer, alarm or none.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alarmSet:&#039;&#039;&#039; Date and time for alarm interruption (No effect if mode is timer or none).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;timerSetSeconds:&#039;&#039;&#039; Period in seconds for timer interruption (No effect if mode is alarm or none).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;rtcState:&#039;&#039;&#039; Current state of the synchronization logic of the RTC.&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;CLOCK_CONFIGS&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;,&lt;br /&gt;
        &amp;quot;rtcState&amp;quot;: &amp;quot;ON&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== d) Read clock ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/runtime/in &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;timestamp&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.2.2 Synchronization loop flowchart (every 30 seconds) =====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTC Actor - Overview&#039;&#039;&#039;&lt;br /&gt;
[[File:RTCActor Overview.svg|center|frameless|903x903px]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.3 Core System Health Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.3.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker.&lt;br /&gt;
&lt;br /&gt;
This interface allows any external App to &#039;&#039;&#039;receive system-level metrics&#039;&#039;&#039; such as CPU load, RAM usage, disk usage, temperature, core frequency, system throttle status and uptime.&lt;br /&gt;
&lt;br /&gt;
No credentials are required to subscribe to this topic.&lt;br /&gt;
&lt;br /&gt;
The System Health Actor &#039;&#039;&#039;does not receive commands&#039;&#039;&#039;. It is fully autonomous and publishes its metrics every &#039;&#039;&#039;1 second&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===== 24.3.2 Runtime Data =====&lt;br /&gt;
&#039;&#039;&#039;Topic: systemHealth/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Publish rate: &#039;&#039;&#039;1 Hz&#039;&#039;&#039; (one message per second, clock-jump safe)&lt;br /&gt;
&lt;br /&gt;
====== a) Metrics Provided ======&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Key&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Unit&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|cpu_percent&lt;br /&gt;
|Current  CPU load&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|cpu_tempC&lt;br /&gt;
|CPU  temperature read from Linux thermal zones&lt;br /&gt;
|ºC&lt;br /&gt;
|-&lt;br /&gt;
|cpu0_freq&lt;br /&gt;
|CPU Core O current  frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpul_freq&lt;br /&gt;
|CPU  Core 1 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu2_freq&lt;br /&gt;
|CPU Core 2 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu3_freq&lt;br /&gt;
|CPU  Core 3 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu0_throttle&lt;br /&gt;
|System  throttle status register&lt;br /&gt;
|Hex&lt;br /&gt;
|-&lt;br /&gt;
|ram_percent&lt;br /&gt;
|RAM  usage&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|disk_percent&lt;br /&gt;
|Disk  usage for filesystem root /&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|uptime_sec&lt;br /&gt;
|Time  since last reboot&lt;br /&gt;
|seconds&lt;br /&gt;
|}&lt;br /&gt;
Example Payload (systemHealth/runtime/out) &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;cpu_percent&amp;quot;: 7.1,&lt;br /&gt;
      &amp;quot;cpu_tempC&amp;quot;: 47.3,&lt;br /&gt;
      &amp;quot;cpu0_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu1_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu2_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu3_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu0_throttle&amp;quot;: &amp;quot;0x0&amp;quot;,&lt;br /&gt;
      &amp;quot;ram_percent&amp;quot;: 32.9,&lt;br /&gt;
      &amp;quot;disk_percent&amp;quot;: 41.2,&lt;br /&gt;
      &amp;quot;uptime_sec&amp;quot;: 5321&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.3.3 Peripherals health =====&lt;br /&gt;
  In order get the peripherals health we had to implement a SystemHealth actor in each bus manager (busi2c­O, busi2c-1, etc. ... ).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Peripherals health.svg|center|frameless|792x792px]]&lt;br /&gt;
&lt;br /&gt;
====== a) Example ======&lt;br /&gt;
&#039;&#039;&#039;For busi2c-0:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply topic: &#039;&#039;&#039;systemHealth/busi2c-0/runtime/out&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Payload:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health-busi2c-0&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;ADC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;ERROR&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;IRQ Retrying&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378753006,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760548,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253313&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760475,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253314&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760528,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253313&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760549,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253312&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DAC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running....&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752576,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 240755,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 240755,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;RTC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752094,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;samples&amp;quot;: 248710,&lt;br /&gt;
          &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
          &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;TEMP&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752579,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;samples&amp;quot;: 240754,&lt;br /&gt;
          &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
          &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;For busi2c-1:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply topic: &#039;&#039;&#039;systemHealth/busi2c-1/runtime/out&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Payload:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health-busi2c-1&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;JOYSTICK&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running....&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770382405050,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 410154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;read_raw&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;buttons&amp;quot;: {&lt;br /&gt;
            &amp;quot;JDOWN&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JRIGHT&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JUP&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JLEFT&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JCENTER&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;RELAYS&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Relay Output MQTT connected&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770298859099,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;set&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;set_many&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;raw_read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;outputs&amp;quot;: {&lt;br /&gt;
          &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
            &amp;quot;writes&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;last_state&amp;quot;: &amp;quot;unknown&amp;quot;&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
            &amp;quot;writes&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;last_state&amp;quot;: &amp;quot;unknown&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770382404832,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 181758,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;read_raw&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;inputs&amp;quot;: {&lt;br /&gt;
            &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.3.4 Commands =====&lt;br /&gt;
&lt;br /&gt;
====== a) List usb devices ======&lt;br /&gt;
The list_usb_devices action returns a parsed list of USB devices detected on the system using the lsusb command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;Dev&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;LIST_USB_DEVICES&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/usb/devices/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;list_usb_devices&amp;quot;,&lt;br /&gt;
  &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
     &amp;quot;usb_devices&amp;quot;: {&lt;br /&gt;
       &amp;quot;success&amp;quot;: true,&lt;br /&gt;
       &amp;quot;command&amp;quot;: &amp;quot;lsusb&amp;quot;,&lt;br /&gt;
       &amp;quot;returncode&amp;quot;: 0,&lt;br /&gt;
       &amp;quot;devices&amp;quot;: [ &lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;1d6b&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;0002&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Linux Foundation 2.0 root hub&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;002&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;0424&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;9514&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;003&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;0424&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;ec00&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;004&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;1e0e&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;9001&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Qualcomm / Option SimTech, Incorporated&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         }&lt;br /&gt;
       ],&lt;br /&gt;
       &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;JSON Path&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Example&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string /number&lt;br /&gt;
|&amp;quot;get-hw-info-001&amp;quot;&lt;br /&gt;
|Request identifier echoed back in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;system-health&amp;quot;&lt;br /&gt;
|Actor/device that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Container for the action response.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;list_usb_devices&amp;quot;&lt;br /&gt;
|Action executed by the actor.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main result object for the action.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the USB device scan result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the lsusb&lt;br /&gt;
commandexecuted successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.command&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;lsusb&amp;quot;&lt;br /&gt;
|Command used to collect USB information.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.returncode&lt;br /&gt;
|number /null&lt;br /&gt;
|0&lt;br /&gt;
|Process return code. 0 means success. null&lt;br /&gt;
means the command was not executed ortimed out.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices&lt;br /&gt;
|array&lt;br /&gt;
|[...]&lt;br /&gt;
|List of USB devices detected by lsusb.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].bus&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;001&amp;quot;&lt;br /&gt;
|USB bus number where the device wasdetected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].device&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;004&amp;quot;&lt;br /&gt;
|USB device number assigned on that bus.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].vendor_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;1e0e&amp;quot;&lt;br /&gt;
|USB vendor ID in hexadecimal format.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].product_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;9001&amp;quot;&lt;br /&gt;
|USB product ID in hexadecimal format.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].description&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;Qualcomm / Option SimTech,Incorporated&amp;quot;&lt;br /&gt;
|Human-readable device description returnedby lsusb.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].parsed&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the lsusb line was parsed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].raw&lt;br /&gt;
|string&lt;br /&gt;
|Optional&lt;br /&gt;
|Present only when a device line could not beparsed.&lt;br /&gt;
Contains the original raw lsusb line.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.stderr&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot; &amp;quot;&lt;br /&gt;
|Error output from the command. Empty stringmeans no error.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== b) List connectivity specs ======&lt;br /&gt;
The list_connectivity_specs action allows the &#039;&#039;&#039;SystemHealth&#039;&#039;&#039; Actor to return connectivity information for the device, including the status of:&lt;br /&gt;
&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
* LTE modem&lt;br /&gt;
* eth0&lt;br /&gt;
* eth1&lt;br /&gt;
* Tunnel interfaces, for possible commissioning use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;quot;connectivity-001&amp;quot;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;list_connectivity_specs&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/connectivity/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;list_connectivity_specs&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;connectivity&amp;quot;: {&lt;br /&gt;
        &amp;quot;sources&amp;quot;: {&lt;br /&gt;
          &amp;quot;sysfs&amp;quot;: &amp;quot;/sys/class/net&amp;quot;,&lt;br /&gt;
          &amp;quot;ip_link&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;ip -j -d link show&amp;quot;,&lt;br /&gt;
            &amp;quot;error&amp;quot;: null&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device status&amp;quot;,&lt;br /&gt;
            &amp;quot;error&amp;quot;: null&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;interfaces&amp;quot;: {&lt;br /&gt;
          &amp;quot;wifi&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;interfaces&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;interface&amp;quot;: &amp;quot;wlan0&amp;quot;,&lt;br /&gt;
                &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                &amp;quot;status&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
                &amp;quot;carrier&amp;quot;: false,&lt;br /&gt;
                &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
                &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
                &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:40&amp;quot;,&lt;br /&gt;
                &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
                &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
                &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
                  &amp;quot;device&amp;quot;: &amp;quot;wlan0&amp;quot;,&lt;br /&gt;
                  &amp;quot;type&amp;quot;: &amp;quot;wifi&amp;quot;,&lt;br /&gt;
                  &amp;quot;state&amp;quot;: &amp;quot;disconnected&amp;quot;,&lt;br /&gt;
                  &amp;quot;connection&amp;quot;: null&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;wifi&amp;quot;: {&lt;br /&gt;
                  &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                  &amp;quot;command&amp;quot;: &amp;quot;iw dev wlan0 link&amp;quot;,&lt;br /&gt;
                  &amp;quot;connected&amp;quot;: false&lt;br /&gt;
                }&lt;br /&gt;
              }&lt;br /&gt;
            ]&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;lte_modem&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;tool_available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;mmcli -L&amp;quot;,&lt;br /&gt;
            &amp;quot;modems&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;id&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
                &amp;quot;success&amp;quot;: true,&lt;br /&gt;
                &amp;quot;command&amp;quot;: &amp;quot;mmcli -m 0 --output-json&amp;quot;,&lt;br /&gt;
                &amp;quot;manufacturer&amp;quot;: &amp;quot;QUALCOMM INCORPORATED&amp;quot;,&lt;br /&gt;
                &amp;quot;model&amp;quot;: &amp;quot;SIMCOM_SIM7600G-H&amp;quot;,&lt;br /&gt;
                &amp;quot;revision&amp;quot;: &amp;quot;LE20B04SIM7600G22&amp;quot;,&lt;br /&gt;
                &amp;quot;hardware_revision&amp;quot;: &amp;quot;10000&amp;quot;,&lt;br /&gt;
                &amp;quot;device&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
                &amp;quot;drivers&amp;quot;: [&lt;br /&gt;
                  &amp;quot;qmi_wwan&amp;quot;,&lt;br /&gt;
                  &amp;quot;option&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;plugin&amp;quot;: &amp;quot;simtech&amp;quot;,&lt;br /&gt;
                &amp;quot;primary_port&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
                &amp;quot;ports&amp;quot;: [&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;qmi&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;ignored&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB1&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;gps&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB2&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;at&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB3&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;at&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB4&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;audio&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;wwan0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;net&amp;quot;&lt;br /&gt;
                  }&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;state&amp;quot;: &amp;quot;failed&amp;quot;,&lt;br /&gt;
                &amp;quot;power_state&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
                &amp;quot;access_technologies&amp;quot;: [],&lt;br /&gt;
                &amp;quot;signal_quality&amp;quot;: {&lt;br /&gt;
                  &amp;quot;recent&amp;quot;: &amp;quot;yes&amp;quot;,&lt;br /&gt;
                  &amp;quot;value&amp;quot;: &amp;quot;0&amp;quot;&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;current_capabilities&amp;quot;: [&lt;br /&gt;
                  &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;supported_capabilities&amp;quot;: [&lt;br /&gt;
                  &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;operator_code&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;operator_name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;registration_state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;packet_service_state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;sim_path&amp;quot;: null&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;network_interfaces&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;interface&amp;quot;: &amp;quot;wwan0&amp;quot;,&lt;br /&gt;
                &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                &amp;quot;status&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;admin_up&amp;quot;: false,&lt;br /&gt;
                &amp;quot;carrier&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
                &amp;quot;type&amp;quot;: 65534,&lt;br /&gt;
                &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mac_address&amp;quot;: null,&lt;br /&gt;
                &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
                &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
                &amp;quot;network_manager&amp;quot;: null&lt;br /&gt;
              }&lt;br /&gt;
            ]&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;eth0&amp;quot;: {&lt;br /&gt;
            &amp;quot;interface&amp;quot;: &amp;quot;eth0&amp;quot;,&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;status&amp;quot;: &amp;quot;connected&amp;quot;,&lt;br /&gt;
            &amp;quot;operstate&amp;quot;: &amp;quot;up&amp;quot;,&lt;br /&gt;
            &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
            &amp;quot;carrier&amp;quot;: true,&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
            &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
            &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
            &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:3f&amp;quot;,&lt;br /&gt;
            &amp;quot;ipv4&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;address&amp;quot;: &amp;quot;172.16.20.57&amp;quot;,&lt;br /&gt;
                &amp;quot;prefixlen&amp;quot;: 24,&lt;br /&gt;
                &amp;quot;scope&amp;quot;: &amp;quot;global&amp;quot;,&lt;br /&gt;
                &amp;quot;dynamic&amp;quot;: true&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;ipv6&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;address&amp;quot;: &amp;quot;fe80::7fc1:f65f:5729:d234&amp;quot;,&lt;br /&gt;
                &amp;quot;prefixlen&amp;quot;: 64,&lt;br /&gt;
                &amp;quot;scope&amp;quot;: &amp;quot;link&amp;quot;,&lt;br /&gt;
                &amp;quot;dynamic&amp;quot;: false&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
              &amp;quot;device&amp;quot;: &amp;quot;eth0&amp;quot;,&lt;br /&gt;
              &amp;quot;type&amp;quot;: &amp;quot;ethernet&amp;quot;,&lt;br /&gt;
              &amp;quot;state&amp;quot;: &amp;quot;connected&amp;quot;,&lt;br /&gt;
              &amp;quot;connection&amp;quot;: &amp;quot;wired-ip-dynamic&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;eth1&amp;quot;: {&lt;br /&gt;
            &amp;quot;interface&amp;quot;: &amp;quot;eth1&amp;quot;,&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;status&amp;quot;: &amp;quot;unavailable&amp;quot;,&lt;br /&gt;
            &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
            &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
            &amp;quot;carrier&amp;quot;: false,&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
            &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
            &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
            &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:41&amp;quot;,&lt;br /&gt;
            &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
            &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
            &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
              &amp;quot;device&amp;quot;: &amp;quot;eth1&amp;quot;,&lt;br /&gt;
              &amp;quot;type&amp;quot;: &amp;quot;ethernet&amp;quot;,&lt;br /&gt;
              &amp;quot;state&amp;quot;: &amp;quot;unavailable&amp;quot;,&lt;br /&gt;
              &amp;quot;connection&amp;quot;: null&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;tunnel&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: false,&lt;br /&gt;
            &amp;quot;interfaces&amp;quot;: []&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string/number&lt;br /&gt;
|Request/response identifier used to correlate therequest with the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
|string&lt;br /&gt;
|Origin of the message. In the response, this is normallythe SystemHealth actor name.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|string&lt;br /&gt;
|Executed action. For this feature, the value is list_connectivity_specs.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.sysfs&lt;br /&gt;
|string&lt;br /&gt;
|Linux sysfs path used to discover network interfaces, usually/sys/class/net.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the ip command was available andexecuted successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to retrieve detailed link information,for example ip -j -d link show.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.error&lt;br /&gt;
|string/null&lt;br /&gt;
|Error returned by the ip command, or null if no erroroccurred.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether NetworkManager / nmcli was available and executed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to retrieve NetworkManager device status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.error&lt;br /&gt;
|string/null&lt;br /&gt;
|Error returned by nmcli, or null if no error occurred.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.wifi.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one Wi-Fi interface was found.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.wifi.interfaces[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected Wi-Fi interfaces, usually including &#039;&#039;&#039;wlan0&#039;&#039;&#039; when Wi-Fi exists.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|Linux interface name, for example &#039;&#039;&#039;wlan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the Wi-Fi interface exists in the system.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized interface status, for example &#039;&#039;&#039;connected, down, unavailable, no_carrier,&#039;&#039;&#039; or &#039;&#039;&#039;not_available&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux, for example &#039;&#039;&#039;up, down,&#039;&#039;&#039; or &#039;&#039;&#039;unknown&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the interface is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether carrier/link is detected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum Transmission Unit of the interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Special link type, used mainly for virtual/tunnel interfaces. Usually null for normal Wi-Fi.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of IPv4 addresses configured on the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of IPv6 addresses configured on the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.device&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager device name.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.type&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager interface type, usually &#039;&#039;&#039;wifi&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.state&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager state, for example &#039;&#039;&#039;connected&#039;&#039;&#039;, &#039;&#039;&#039;disconnected&#039;&#039;&#039;, or &#039;&#039;&#039;unavailable&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.connection&lt;br /&gt;
|string / null&lt;br /&gt;
|Active NetworkManager profile name, or null if none is active.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether Wi-Fi details could be queried using &#039;&#039;&#039;iw&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to query Wi-Fi link state, for example &#039;&#039;&#039;iw dev wlan0 link&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.connected&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the Wi-Fi interface is associated with a Wi-Fi network.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.ssid&lt;br /&gt;
|string&lt;br /&gt;
|SSID of the connected Wi-Fi network, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.bssid&lt;br /&gt;
|string&lt;br /&gt;
|BSSID/MAC address of the connected access point, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.frequency_mhz&lt;br /&gt;
|number&lt;br /&gt;
|Wi-Fi frequency in MHz, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.signal_dbm&lt;br /&gt;
|number&lt;br /&gt;
|Wi-Fi signal strength in dBm, when available.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.tx_bitrate&lt;br /&gt;
|string&lt;br /&gt;
|Wi-Fi transmit bitrate, when available.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.rx_bitrate&lt;br /&gt;
|string&lt;br /&gt;
|Wi-Fi receive bitrate, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one LTE modem was detected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.tool_available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;mmcli&#039;&#039;&#039; / ModemManager is available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to list LTE modems, usually &#039;&#039;&#039;mmcli -L&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.modems[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of LTE modems detected by ModemManager.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].id&lt;br /&gt;
|string&lt;br /&gt;
|Modem ID in ModemManager, for example &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].success&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether detailed modem information wasread successfully.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to read modem details, for example &#039;&#039;&#039;mmcli -m 0 --output-json&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].manufacturer&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem manufacturer.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem model.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].revision&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem firmware/software revision.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].hardware_revision&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem hardware revision.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].device&lt;br /&gt;
|string / null&lt;br /&gt;
|Sysfs/USB path of the modem device.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].drivers[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Linux drivers associated with the modem, for example &#039;&#039;&#039;qmi_wwan&#039;&#039;&#039; or &#039;&#039;&#039;option&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].plugin&lt;br /&gt;
|string / null&lt;br /&gt;
|ModemManager plugin used to manage the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].primary_port&lt;br /&gt;
|string / null&lt;br /&gt;
|Primary modem control port, for example &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of ports associated with the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ].name&lt;br /&gt;
|string&lt;br /&gt;
|Port/interface name, for example &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039;, &#039;&#039;&#039;ttyUSB2&#039;&#039;&#039;, or &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ].type&lt;br /&gt;
|string / null&lt;br /&gt;
|Port type, for example &#039;&#039;&#039;qmi, at, gps, audio, net&#039;&#039;&#039;, or &#039;&#039;&#039;ignored&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].state&lt;br /&gt;
|string / null&lt;br /&gt;
|General modem state according to ModemManager,for example &#039;&#039;&#039;registered&#039;&#039;&#039;, &#039;&#039;&#039;connected&#039;&#039;&#039;, or &#039;&#039;&#039;failed&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].power_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem power state, for example &#039;&#039;&#039;on, off&#039;&#039;&#039;, or &#039;&#039;&#039;low&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].access_technologies[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Current access technologies in use, for example LTE,UMTS, or GSM.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].signal_quality.recent&lt;br /&gt;
|string / null&lt;br /&gt;
|Indicates whether the signal quality value is recent.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].signal_quality.value&lt;br /&gt;
|string / number / null&lt;br /&gt;
|Signal quality value reported by the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].current_capabilities[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Current modem capabilities.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].supported_capabilities[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Capabilities supported by the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].operator_code&lt;br /&gt;
|string / null&lt;br /&gt;
|MCC/MNC operator code.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].operator_name&lt;br /&gt;
|string / null&lt;br /&gt;
|Operator name.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].registration_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile network registration state.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].packet_service_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile packet data service state.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].sim_path&lt;br /&gt;
|string / null&lt;br /&gt;
|SIM path in ModemManager, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.network_interfaces[]&lt;br /&gt;
|array&lt;br /&gt;
|List of Linux network interfaces associated with the LTE modem, usually &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|LTE network interface name, for example &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the LTE network interface exists.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized LTE network interface status.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the LTE network interface is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether carrier/link information is availableand active.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum Transmission Unit of the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind, when available.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address, when available.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for the LTE interface, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.interface&lt;br /&gt;
|string&lt;br /&gt;
|Ethernet interface name, &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; exists.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized &#039;&#039;&#039;eth0&#039;&#039;&#039; status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; has physical link.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|MTU of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind of &#039;&#039;&#039;eth0&#039;&#039;&#039;, usually &#039;&#039;&#039;null&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.interface&lt;br /&gt;
|string&lt;br /&gt;
|Ethernet interface name, &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; exists.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized &#039;&#039;&#039;eth1&#039;&#039;&#039; status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; has physical link.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|MTU of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind of &#039;&#039;&#039;eth1&#039;&#039;&#039;, usually &#039;&#039;&#039;null&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.tunnel.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one tunnel interface was detected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.tunnel.interfaces[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected tunnel interfaces, for example &#039;&#039;&#039;tun0, tap0, wg0&#039;&#039;&#039;, or &#039;&#039;&#039;tailscale0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|Tunnel interface name.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the tunnel interface exists.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized tunnel interface status.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the tunnel interface isadministratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Carrier/link information, when available.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Tunnel interface MTU.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Tunnel link kind, for example &#039;&#039;&#039;tun, tap&#039;&#039;&#039;, or &#039;&#039;&#039;wireguard&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address, when available.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on the tunnel interface.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on the tunnel interface.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for the tunnel interface, when available.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].address&lt;br /&gt;
|string&lt;br /&gt;
|IPv4 address assigned to the interface.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].prefixlen&lt;br /&gt;
|number&lt;br /&gt;
|IPv4 network prefix length. Example: &#039;&#039;&#039;24&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].scope&lt;br /&gt;
|string&lt;br /&gt;
|IPv4 scope, for example &#039;&#039;&#039;global&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].dynamic&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the IPv4 address was dynamically assigned.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].address&lt;br /&gt;
|string&lt;br /&gt;
|IPv6 address assigned to the interface.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].prefixlen&lt;br /&gt;
|number&lt;br /&gt;
|IPv6 network prefix length.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].scope&lt;br /&gt;
|string&lt;br /&gt;
|IPv6 scope, for example &#039;&#039;&#039;link&#039;&#039;&#039; or &#039;&#039;&#039;global&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[].dynamic&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the IPv6 address was dynamically assigned.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== c) Get hardware info ======&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;Dev&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_HW_INFO&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/hw/info/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;get_hw_info&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;cpu&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;ram&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;emmc&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;block_devices&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;filesystems&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;mmc_sysfs&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;emmc_extcsd&amp;quot;: {......}&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Section&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;cpu&#039;&#039;&#039;&lt;br /&gt;
|CPU and board model information.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ram&#039;&#039;&#039;&lt;br /&gt;
|RAM total, used, and free memory.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;emmc&#039;&#039;&#039;&lt;br /&gt;
|Filtered eMMC device and partition information.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;block_devices&#039;&#039;&#039;&lt;br /&gt;
|Complete block device list from &#039;&#039;&#039;lsblk&#039;&#039;&#039;, including eMMC, boot partitions, loop devices, zram, NVMe, USB storage, etc.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;filesystems&#039;&#039;&#039;&lt;br /&gt;
|Mounted filesystem usage from &#039;&#039;&#039;df -h&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;mmc_sysfs&#039;&#039;&#039;&lt;br /&gt;
|Low-level MMC/eMMC identity fields read from &#039;&#039;&#039;/sys/block/mmcblk*/device&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;emmc_extcsd&#039;&#039;&#039;&lt;br /&gt;
|Parsed eMMC EXT_CSD information from &#039;&#039;&#039;mmc extcsd read&#039;&#039;&#039;, including health, revision, RPMB, boot, and partitioning data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;CPU&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;cpu&#039;&#039;&#039; object describes the detected board and CPU.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;board_model&amp;quot;: &amp;quot;Raspberry Pi Compute Module 4 Rev 1.1&amp;quot;,&lt;br /&gt;
  &amp;quot;cpu&amp;quot;: {&lt;br /&gt;
    &amp;quot;architecture&amp;quot;: &amp;quot;aarch64&amp;quot;,&lt;br /&gt;
    &amp;quot;op_modes&amp;quot;: &amp;quot;32-bit, 64-bit&amp;quot;,&lt;br /&gt;
    &amp;quot;byte_order&amp;quot;: &amp;quot;Little Endian&amp;quot;,&lt;br /&gt;
    &amp;quot;vendor&amp;quot;: &amp;quot;ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;model_name&amp;quot;: &amp;quot;Cortex-A72&amp;quot;,&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;3&amp;quot;,&lt;br /&gt;
    &amp;quot;stepping&amp;quot;: &amp;quot;r0p3&amp;quot;,&lt;br /&gt;
    &amp;quot;cpu_count&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;online_cpus&amp;quot;: &amp;quot;0-3&amp;quot;,&lt;br /&gt;
    &amp;quot;threads_per_core&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;cores_per_cluster&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;clusters&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;frequency&amp;quot;: {&lt;br /&gt;
      &amp;quot;scaling_percent&amp;quot;: 60.0,&lt;br /&gt;
      &amp;quot;min_mhz&amp;quot;: 600.0,&lt;br /&gt;
      &amp;quot;max_mhz&amp;quot;: 1500.0,&lt;br /&gt;
      &amp;quot;bogomips&amp;quot;: 108.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|board_model&lt;br /&gt;
|string / null&lt;br /&gt;
|Hardware board model read from device-tree.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.architecture&lt;br /&gt;
|string&lt;br /&gt;
|CPU architecture, for example &#039;&#039;&#039;aarch64&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.op_modes&lt;br /&gt;
|string&lt;br /&gt;
|Supported CPU operation modes.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.byte_order&lt;br /&gt;
|string&lt;br /&gt;
|CPU byte order.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.vendor&lt;br /&gt;
|string&lt;br /&gt;
|CPU vendor.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.model_name&lt;br /&gt;
|string&lt;br /&gt;
|CPU model name.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.model&lt;br /&gt;
|string / number&lt;br /&gt;
|CPU model identifier.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.stepping&lt;br /&gt;
|string&lt;br /&gt;
|CPU stepping/revision.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.cpu_count&lt;br /&gt;
|number&lt;br /&gt;
|Number of detected CPU cores.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.online_cpus&lt;br /&gt;
|string&lt;br /&gt;
|Online CPU list.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.threads_per_core&lt;br /&gt;
|number&lt;br /&gt;
|Number of threads per core.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.cores_per_cluster&lt;br /&gt;
|number&lt;br /&gt;
|Number of cores per cluster.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.clusters&lt;br /&gt;
|number&lt;br /&gt;
|Number of CPU clusters.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.scaling_percent&lt;br /&gt;
|number / null&lt;br /&gt;
|Current CPU frequency scaling percentage.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.min_mhz&lt;br /&gt;
|number / null&lt;br /&gt;
|Minimum CPU frequency in MHz.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.max_mhz&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum CPU frequency in MHz.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.bogomips&lt;br /&gt;
|number / null&lt;br /&gt;
|BogoMIPS value reported by the system.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RAM&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;ram&#039;&#039;&#039; object reports system memory usage.&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;total&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Total system RAM.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;used&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Currently used RAM.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;free&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Currently free RAM.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;EMMC&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;emmc&#039;&#039;&#039; object is a &#039;&#039;&#039;filtered eMMC&#039;&#039;&#039; &#039;&#039;&#039;view&#039;&#039;&#039;. It focuses on the main eMMC disk and its partitions.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: null,&lt;br /&gt;
      &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29.1G&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;disk&amp;quot;,&lt;br /&gt;
      &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: null,&lt;br /&gt;
      &amp;quot;mountpoints&amp;quot;: [],&lt;br /&gt;
      &amp;quot;partitions&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p1&amp;quot;,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;512M&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;vfat&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/boot/firmware&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p2&amp;quot;,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;28.6G&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Device fields&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected main eMMC devices.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].serial&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC block device name, for example &#039;&#039;&#039;mmcblk0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].size&lt;br /&gt;
|string&lt;br /&gt;
|Device model, when available.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].type&lt;br /&gt;
|string&lt;br /&gt;
|Device serial number.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].transport&lt;br /&gt;
|string / null&lt;br /&gt;
|Device size.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Device type, usually &#039;&#039;&#039;disk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|Transport type, usually &#039;&#039;&#039;mmc&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].partitions&lt;br /&gt;
|array&lt;br /&gt;
|Filesystem directly on the disk. Usually null when partitions exist.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].name&lt;br /&gt;
|string&lt;br /&gt;
|Mountpoints directly associated with the disk.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Partitions belonging to this eMMC disk.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Partition fields&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|name&lt;br /&gt;
|string&lt;br /&gt;
|Partition name, for example &#039;&#039;&#039;mmcblk0p1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|string&lt;br /&gt;
|Partition size.&lt;br /&gt;
|-&lt;br /&gt;
|type&lt;br /&gt;
|string&lt;br /&gt;
|Partition type, usually &#039;&#039;&#039;part&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;vfat&#039;&#039;&#039; or &#039;&#039;&#039;ext4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|Mountpoints for the partition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== d) block_devices ======&lt;br /&gt;
The &#039;&#039;&#039;block_devices&#039;&#039;&#039; object is the complete storage/device tree returned by &#039;&#039;&#039;lsblk&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: null,&lt;br /&gt;
      &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29.1G&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;disk&amp;quot;,&lt;br /&gt;
      &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: null,&lt;br /&gt;
      &amp;quot;mountpoints&amp;quot;: [],&lt;br /&gt;
      &amp;quot;children&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p1&amp;quot;,&lt;br /&gt;
          &amp;quot;model&amp;quot;: null,&lt;br /&gt;
          &amp;quot;serial&amp;quot;: null,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;512M&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;vfat&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/boot/firmware&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;children&amp;quot;: []&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|devices&lt;br /&gt;
|array&lt;br /&gt;
|List of block devices.&lt;br /&gt;
|-&lt;br /&gt;
|stderr&lt;br /&gt;
|string&lt;br /&gt;
|Command error output, if any.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].name&lt;br /&gt;
|string&lt;br /&gt;
|Device name.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Device model.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].serial&lt;br /&gt;
|string / null&lt;br /&gt;
|Device serial number.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].size&lt;br /&gt;
|string&lt;br /&gt;
|Device size.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].type&lt;br /&gt;
|string&lt;br /&gt;
|Device type, for example &#039;&#039;&#039;disk&#039;&#039;&#039; , &#039;&#039;&#039;part&#039;&#039;&#039; , or &#039;&#039;&#039;loop&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].transport&lt;br /&gt;
|string / null&lt;br /&gt;
|Transport type, for example &#039;&#039;&#039;mmc&#039;&#039;&#039; , &#039;&#039;&#039;nvme&#039;&#039;&#039; , or &#039;&#039;&#039;usb&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;ext4&#039;&#039;&#039; , &#039;&#039;&#039;vfat&#039;&#039;&#039; , or &#039;&#039;&#039;swap&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|List of mountpoints. Empty if not mounted.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].children&lt;br /&gt;
|array&lt;br /&gt;
|Child block devices, usually partitions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== e) file_systems ======&lt;br /&gt;
The &#039;&#039;&#039;file_systems&#039;&#039;&#039; object reports mounted filesystem usage, equivalent to &#039;&#039;&#039;df -h&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;filesystems&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;source&amp;quot;: &amp;quot;/dev/mmcblk0p2&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29G&amp;quot;,&lt;br /&gt;
      &amp;quot;used&amp;quot;: &amp;quot;5.8G&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: &amp;quot;23G&amp;quot;,&lt;br /&gt;
      &amp;quot;use_percent&amp;quot;: &amp;quot;21%&amp;quot;,&lt;br /&gt;
      &amp;quot;mountpoint&amp;quot;: &amp;quot;/&amp;quot;,&lt;br /&gt;
      &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;source&amp;quot;: &amp;quot;/dev/nvme0n1p1&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;234G&amp;quot;,&lt;br /&gt;
      &amp;quot;used&amp;quot;: &amp;quot;2.1M&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: &amp;quot;222G&amp;quot;,&lt;br /&gt;
      &amp;quot;use_percent&amp;quot;: &amp;quot;1%&amp;quot;,&lt;br /&gt;
      &amp;quot;mountpoint&amp;quot;: &amp;quot;/mnt/nvme&amp;quot;,&lt;br /&gt;
      &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|filesystems&lt;br /&gt;
|array&lt;br /&gt;
|List of mounted filesystems.&lt;br /&gt;
|-&lt;br /&gt;
|stderr&lt;br /&gt;
|string&lt;br /&gt;
|Command error output, if any.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].source&lt;br /&gt;
|string&lt;br /&gt;
|Filesystem source, for example &#039;&#039;&#039;/dev/mmcblk0p2&#039;&#039;&#039; , &#039;&#039;&#039;tmpfs&#039;&#039;&#039; , or &#039;&#039;&#039;udev&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].filesystem&lt;br /&gt;
|string&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;ext4&#039;&#039;&#039; , &#039;&#039;&#039;vfat&#039;&#039;&#039; , &#039;&#039;&#039;tmpfs&#039;&#039;&#039; , or &#039;&#039;&#039;devtmpfs&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].size&lt;br /&gt;
|string&lt;br /&gt;
|Total filesystem size.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].used&lt;br /&gt;
|string&lt;br /&gt;
|Used space.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].available&lt;br /&gt;
|string&lt;br /&gt;
|Available space.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].use_percent&lt;br /&gt;
|string&lt;br /&gt;
|Used percentage.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].mountpoint&lt;br /&gt;
|string&lt;br /&gt;
|Mount location.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].parsed&lt;br /&gt;
|boolean&lt;br /&gt;
|&#039;&#039;&#039;true&#039;&#039;&#039; if the parser successfully parsed this filesystem entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== f) mmc_sysfs ======&lt;br /&gt;
The &#039;&#039;&#039;mmc_sysfs&#039;&#039;&#039; object exposes low-level MMC/eMMC identity fields read from:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;/sys/block/mmcblk*/device/&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is useful for production traceability, device identification and diagnostics.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;source&amp;quot;: &amp;quot;/sys/block&amp;quot;,&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    &amp;quot;name&amp;quot;,&lt;br /&gt;
    &amp;quot;cid&amp;quot;,&lt;br /&gt;
    &amp;quot;csd&amp;quot;,&lt;br /&gt;
    &amp;quot;date&amp;quot;,&lt;br /&gt;
    &amp;quot;manfid&amp;quot;,&lt;br /&gt;
    &amp;quot;oemid&amp;quot;,&lt;br /&gt;
    &amp;quot;serial&amp;quot;&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;device&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;base_path&amp;quot;: &amp;quot;/sys/block/mmcblk0/device&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: true,&lt;br /&gt;
      &amp;quot;fields&amp;quot;: {&lt;br /&gt;
        &amp;quot;name&amp;quot;: &amp;quot;BJTD4R&amp;quot;,&lt;br /&gt;
        &amp;quot;cid&amp;quot;: &amp;quot;150100424a5444345203121b491e7b00&amp;quot;,&lt;br /&gt;
        &amp;quot;csd&amp;quot;: &amp;quot;d02701320f5903fff6dbffef8e404000&amp;quot;,&lt;br /&gt;
        &amp;quot;date&amp;quot;: &amp;quot;07/2024&amp;quot;,&lt;br /&gt;
        &amp;quot;manfid&amp;quot;: &amp;quot;0x000015&amp;quot;,&lt;br /&gt;
        &amp;quot;oemid&amp;quot;: &amp;quot;0x0100&amp;quot;,&lt;br /&gt;
        &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|source&lt;br /&gt;
|string&lt;br /&gt;
|Base sysfs source path.&lt;br /&gt;
|-&lt;br /&gt;
|fields&lt;br /&gt;
|array&lt;br /&gt;
|List of sysfs fields collected.&lt;br /&gt;
|-&lt;br /&gt;
|devices&lt;br /&gt;
|array&lt;br /&gt;
|List of detected MMC/eMMC devices.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].device&lt;br /&gt;
|string&lt;br /&gt;
|MMC block device name, for example &#039;&#039;&#039;mmcblk0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].base_path&lt;br /&gt;
|string&lt;br /&gt;
|Sysfs path used for this device.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the sysfs path exists.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.name&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC product name.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.cid&lt;br /&gt;
|string / null&lt;br /&gt;
|Card Identification register.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.csd&lt;br /&gt;
|string / null&lt;br /&gt;
|Card Specific Data register.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.date&lt;br /&gt;
|string / null&lt;br /&gt;
|Manufacturing date.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.manfid&lt;br /&gt;
|string / null&lt;br /&gt;
|Manufacturer ID.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.oemid&lt;br /&gt;
|string / null&lt;br /&gt;
|OEM/application ID.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.serial&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC serial number.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== e) emmc_extcsd ======&lt;br /&gt;
The &#039;&#039;&#039;emmc_extcsd&#039;&#039;&#039; object contains parsed information from:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mmc extcsd read /dev/mmcblk0&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Category&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|revision&lt;br /&gt;
|EXT_CSD and MMC version.&lt;br /&gt;
|-&lt;br /&gt;
|health&lt;br /&gt;
|eMMC lifetime and pre-EOL state.&lt;br /&gt;
|-&lt;br /&gt;
|boot&lt;br /&gt;
|Boot partition/protection configuration.&lt;br /&gt;
|-&lt;br /&gt;
|rpmb&lt;br /&gt;
|Replay Protected Memory Block information.&lt;br /&gt;
|-&lt;br /&gt;
|sector&lt;br /&gt;
|Sector count and capacity information, when available.&lt;br /&gt;
|-&lt;br /&gt;
|partitioning&lt;br /&gt;
|Partitioning and enhanced-area information.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[&#039;&#039;&#039; &#039;&#039;&#039;].revision&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;ext_csd_revision&amp;quot;: &amp;quot;1.8&amp;quot;,&lt;br /&gt;
  &amp;quot;mmc_version&amp;quot;: &amp;quot;MMC 5.1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!Type&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ext_csd_revision&lt;br /&gt;
|string&lt;br /&gt;
|EXT_CSD revision.&lt;br /&gt;
|-&lt;br /&gt;
|mmc_version&lt;br /&gt;
|string&lt;br /&gt;
|MMC/eMMC standard version.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].health&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;life_time_estimation_a&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;DEVICE_LIFE_TIME_EST_TYP_A&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Life Time Estimation A&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;,&lt;br /&gt;
      &amp;quot;used_percent_min&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;used_percent_max&amp;quot;: 10&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;life_time_estimation_b&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;DEVICE_LIFE_TIME_EST_TYP_B&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Life Time Estimation B&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;,&lt;br /&gt;
      &amp;quot;used_percent_min&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;used_percent_max&amp;quot;: 10&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;pre_eol&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;PRE_EOL_INFO&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Pre EOL information&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|life_time_estimation_a&lt;br /&gt;
|Wear estimation for eMMC memory type A.&lt;br /&gt;
|-&lt;br /&gt;
|life_time_estimation_b&lt;br /&gt;
|Wear estimation for eMMC memory type B.&lt;br /&gt;
|-&lt;br /&gt;
|pre_eol&lt;br /&gt;
|Pre-end-of-life state.&lt;br /&gt;
|}&lt;br /&gt;
Lifetime Decoding&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Raw Value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Decoded State&#039;&#039;&#039;&lt;br /&gt;
!Meaning&lt;br /&gt;
|-&lt;br /&gt;
|0x00&lt;br /&gt;
|not_defined&lt;br /&gt;
|Not defined by device.&lt;br /&gt;
|-&lt;br /&gt;
|0x01&lt;br /&gt;
|normal&lt;br /&gt;
|0% to 10% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x02&lt;br /&gt;
|normal&lt;br /&gt;
|10% to 20% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x03&lt;br /&gt;
|normal&lt;br /&gt;
|20% to 30% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x04&lt;br /&gt;
|normal&lt;br /&gt;
|30% to 40% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x05&lt;br /&gt;
|normal&lt;br /&gt;
|40% to 50% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x06&lt;br /&gt;
|normal&lt;br /&gt;
|50% to 60% estimated lifetime used&lt;br /&gt;
|-&lt;br /&gt;
|0x07&lt;br /&gt;
|normal&lt;br /&gt;
|60% to 70% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x08&lt;br /&gt;
|normal&lt;br /&gt;
|70% to 80% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x09&lt;br /&gt;
|normal&lt;br /&gt;
|80% to 90% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x0A&lt;br /&gt;
|normal&lt;br /&gt;
|90% to 100% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x0B&lt;br /&gt;
|exceeded&lt;br /&gt;
|Estimated maximum lifetime exceeded.&lt;br /&gt;
|}&lt;br /&gt;
Pre-EOL Decoding&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Raw Value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Decoded State&#039;&#039;&#039;&lt;br /&gt;
!Meaning&lt;br /&gt;
|-&lt;br /&gt;
|0x00&lt;br /&gt;
|not_defined&lt;br /&gt;
|Not defined.&lt;br /&gt;
|-&lt;br /&gt;
|0x01&lt;br /&gt;
|normal&lt;br /&gt;
|Normal condition.&lt;br /&gt;
|-&lt;br /&gt;
|0x02&lt;br /&gt;
|warning&lt;br /&gt;
|Warning state. Monitor or plan replacement.&lt;br /&gt;
|-&lt;br /&gt;
|0x03&lt;br /&gt;
|urgent&lt;br /&gt;
|Urgent state. Replacement recommended.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].boot&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;partition_config&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: null,&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: null&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;boot_config_protection&amp;quot;: null,&lt;br /&gt;
  &amp;quot;boot_bus_conditions&amp;quot;: null,&lt;br /&gt;
  &amp;quot;boot_write_protection&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;BOOT_WP&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Boot Area Write protection&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;boot_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: null,&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|partition_config&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot partition configuration, if available.&lt;br /&gt;
|-&lt;br /&gt;
|boot_config_protection&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot configuration protection status.&lt;br /&gt;
|-&lt;br /&gt;
|boot_bus_conditions&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot bus width/mode conditions.&lt;br /&gt;
|-&lt;br /&gt;
|boot_write_protection&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot area write protection status.&lt;br /&gt;
|-&lt;br /&gt;
|boot_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot partition size, if available.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].rpmb&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
RPMB means &#039;&#039;&#039;Replay Protected Memory Block&#039;&#039;&#039;. It is a protected eMMC area often used for secure storage.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;size&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;RPMB_SIZE_MULT&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;RPMB Size&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x20&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 32,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;bytes&amp;quot;: 4194304,&lt;br /&gt;
      &amp;quot;kb&amp;quot;: 4194.3,&lt;br /&gt;
      &amp;quot;mb&amp;quot;: 4.19,&lt;br /&gt;
      &amp;quot;gb&amp;quot;: 0.0,&lt;br /&gt;
      &amp;quot;kib&amp;quot;: 4096.0,&lt;br /&gt;
      &amp;quot;mib&amp;quot;: 4.0,&lt;br /&gt;
      &amp;quot;gib&amp;quot;: 0.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|size.field&lt;br /&gt;
|object / null&lt;br /&gt;
|Raw RPMB size register information.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.bytes&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in bytes.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.kb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal KB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.mb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal MB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.gb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal GB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.kib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in KiB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.mib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in MiB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.gib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in GiB.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].sector&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;sector_count&amp;quot;: null,&lt;br /&gt;
  &amp;quot;sector_size_bytes&amp;quot;: 512,&lt;br /&gt;
  &amp;quot;user_capacity&amp;quot;: null&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|sector_count&lt;br /&gt;
|object / null&lt;br /&gt;
|Parsed sector count register, if available.&lt;br /&gt;
|-&lt;br /&gt;
|sector_size_bytes&lt;br /&gt;
|number&lt;br /&gt;
|Sector size used for capacity calculation.&lt;br /&gt;
|-&lt;br /&gt;
|user_capacity&lt;br /&gt;
|object / null&lt;br /&gt;
|Calculated user capacity, if sector count is available.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].partitioning&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;partitioning_support&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITIONING_SUPPORT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitioning Support&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x07&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x7&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;partition_setting_completed&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITION_SETTING_COMPLETED&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitioning Setting&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;partition_attribute&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITIONS_ATTRIBUTE&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitions attribute&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;max_enhanced_area_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;MAX_ENH_SIZE_MULT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Max Enhanced Area Size&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x000747&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 1863,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x747&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;enhanced_user_area_start&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;ENH_START_ADDR&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Enhanced User Data Start Address&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00000000&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;enhanced_user_area_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;ENH_SIZE_MULT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Enhanced User Data Area Size&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x000000&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|partitioning_support&lt;br /&gt;
|object / null&lt;br /&gt;
|Supported partitioning features.&lt;br /&gt;
|-&lt;br /&gt;
|partition_setting_completed&lt;br /&gt;
|object / null&lt;br /&gt;
|Indicates whether partition settings were finalized.&lt;br /&gt;
|-&lt;br /&gt;
|user_capacity&lt;br /&gt;
|object / null&lt;br /&gt;
|Partition attribute register.&lt;br /&gt;
|-&lt;br /&gt;
|max_enhanced_area_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Maximum enhanced area size multiplier.&lt;br /&gt;
|-&lt;br /&gt;
|enhanced_user_area_start&lt;br /&gt;
|object / null&lt;br /&gt;
|Enhanced user data area start address.&lt;br /&gt;
|-&lt;br /&gt;
|enhanced_user_area_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Enhanced user data area size.&lt;br /&gt;
|}&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.4 TempSensor Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.4.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set temperature sensor configurations ======&lt;br /&gt;
Req-Topic: tempSensor/config/in&lt;br /&gt;
&lt;br /&gt;
ALERT:&lt;br /&gt;
&lt;br /&gt;
* activate: true(active)/false&lt;br /&gt;
* templow: alert temperature lower limit&lt;br /&gt;
* tempHigh: alert temperature upper limit&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Read temperature sensor configurations ======&lt;br /&gt;
Req-Topic: tempSensor/config/in&lt;br /&gt;
&lt;br /&gt;
ALERT:&lt;br /&gt;
&lt;br /&gt;
* activate: true(active)/false&lt;br /&gt;
&lt;br /&gt;
LIMITS:&lt;br /&gt;
&lt;br /&gt;
* templow: alert temperature lower limit&lt;br /&gt;
* tempHigh: alert temperature upper limit&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read temperature and alert status ======&lt;br /&gt;
* unit: Temperature unit of measure&lt;br /&gt;
* alert: true (triggered) or false&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tempSensor/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;data&amp;quot;: {&lt;br /&gt;
        &amp;quot;temperature&amp;quot;: &amp;lt;_FLOAT_&amp;gt;,&lt;br /&gt;
        &amp;quot;unit&amp;quot;: &amp;quot;C&amp;quot;,&lt;br /&gt;
        &amp;quot;alert&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.5 TFT Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.5.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to control and interact with the TFT display, or frontal panel LCD screen. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
===== 24.5.2 TFT Display Actor =====&lt;br /&gt;
  The TFT Actor is responsible for:&lt;br /&gt;
&lt;br /&gt;
* Rendering static and informative screens on the TFT display&lt;br /&gt;
* Reacting to joystick input (LEFT/ RIGHT/ CENTER/ UP/ DOWN)&lt;br /&gt;
* Managing screen navigation and user confirmation flows&lt;br /&gt;
* Providing feedback to the application via MQTT&lt;br /&gt;
&lt;br /&gt;
====== a) Screen Carousel Concept ======&lt;br /&gt;
The TFT actor maintains an &#039;&#039;&#039;ordered list of screens&#039;&#039;&#039; (carousel).&lt;br /&gt;
&lt;br /&gt;
* Screens are navigated using the joystick:&lt;br /&gt;
&lt;br /&gt;
- LEFT --&amp;gt; Previous screen&lt;br /&gt;
&lt;br /&gt;
- RIGHT --&amp;gt; Next screen&lt;br /&gt;
&lt;br /&gt;
* The carousel wraps around:&lt;br /&gt;
&lt;br /&gt;
- LEFT on first screen --&amp;gt; last screen&lt;br /&gt;
&lt;br /&gt;
- RIGHT on last screen --&amp;gt; first screen&lt;br /&gt;
&lt;br /&gt;
====== b) Screen Types ======&lt;br /&gt;
The TFT actor supports the following screen types:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Image Screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Displays a static JPEG image&lt;br /&gt;
* Default screen shown at boot&lt;br /&gt;
* No user interaction required&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Network Information Screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Display a interface with information about the networks of the device&lt;br /&gt;
* Updated on load&lt;br /&gt;
* No user interaction required&lt;br /&gt;
&lt;br /&gt;
====== c) Joystick Navigation Logic ======&lt;br /&gt;
&#039;&#039;&#039;Carousel Navigation:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Joystick  Input&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Action&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|LEFT&lt;br /&gt;
|Previous screen&lt;br /&gt;
|-&lt;br /&gt;
|RIGHT&lt;br /&gt;
|Next screen&lt;br /&gt;
|-&lt;br /&gt;
|DOWN&lt;br /&gt;
|Refresh current screen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== d) Boot Behavior ======&lt;br /&gt;
At system boot:&lt;br /&gt;
&lt;br /&gt;
# TFT actor initializes the display&lt;br /&gt;
# Last available carousel is loaded&lt;br /&gt;
# First screen is rendered&lt;br /&gt;
# Joystick subscriptions are activated&lt;br /&gt;
# Actor waits for runtime commands&lt;br /&gt;
&lt;br /&gt;
====== e) Design Notes &amp;amp; Constraints ======&lt;br /&gt;
* TFT actor does not expose joystick state&lt;br /&gt;
* Joystick actor remains independent&lt;br /&gt;
* TFT actor internally consumes joystick events&lt;br /&gt;
* Carousel state is local to the TFT actor&lt;br /&gt;
* Screen rendering is synchronous; input handling is asynchronous&lt;br /&gt;
* Confirmation screens always require explicit CENTER press&lt;br /&gt;
&lt;br /&gt;
===== 24.5.3 User interaction through MQTT =====&lt;br /&gt;
Enabling interaction with the carousel using the topic tft/runtime/in . Actions available will be public to the user.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Runtime commands&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Go to screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tft/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_CAROUSEL&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;index&amp;quot;: 2&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tft/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;tft&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 2&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Set TFT Screen Carousel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tft/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;TIMESTAMP&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_CAROUSEL&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;startIndex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;screens&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;,&lt;br /&gt;
          &amp;quot;image&amp;quot;: &amp;quot;default.jpg&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;,&lt;br /&gt;
          &amp;quot;image&amp;quot;: &amp;quot;status.jpg&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;confirm&amp;quot;,&lt;br /&gt;
          &amp;quot;question&amp;quot;: &amp;quot;Do you want to continue?&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Parameters:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|screens&lt;br /&gt;
|Ordered list of screens&lt;br /&gt;
|-&lt;br /&gt;
|Start  lndex&lt;br /&gt;
|Initial active screen (optional,  default = 0)&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Reply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply-Topic: &#039;&#039;&#039;tft/runtime/out&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;TIMESTAMP&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;tft&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;activeIndex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;totalScreens&amp;quot;: 3&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.6 AnalogInputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.6.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Configurations ======&lt;br /&gt;
&#039;&#039;&#039;  Topic: analogInputs/config/in - Set ADC channels configurations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mode&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* continuous&lt;br /&gt;
* single&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;type&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* voltage&lt;br /&gt;
* current&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;voltage&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;voltage&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;current&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;current&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogInputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Runtime Data ======&lt;br /&gt;
&#039;&#039;&#039;Topic: analogInputs/runtime/in.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
action:&lt;br /&gt;
&lt;br /&gt;
* READ&lt;br /&gt;
* PAUSE (only applicable in continuous mode)&lt;br /&gt;
* RESUME (only applicable in continuous mode)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogInputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.6.2 Usage Examples =====&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.7 Analog Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.7.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set analog outputs signal ======&lt;br /&gt;
Req-Topic: analogOutputs/config/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Output:&#039;&#039;&#039; current within 0-20 mA&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; on/off&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogOutputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Set analog outputs ======&lt;br /&gt;
Req-Topic: analogOutputs/runtime/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;current:&#039;&#039;&#039; current within 0-20 mA&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analoigOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read analog outputs settings ======&lt;br /&gt;
Req-Topic: analogOutputs/runtime/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;current&#039;&#039;&#039;: current within 0-20 mA&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.8 Digital Inputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.8.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set digital input pin/pins speed fast/slow ======&lt;br /&gt;
The &#039;&#039;&#039;fast&#039;&#039;&#039; speed setting supports edge detection speed up to 100 Hz and the &#039;&#039;&#039;slow&#039;&#039;&#039; speed settings supports up to 10 Hz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fast Mode&#039;&#039;&#039; generates a message on every I/O state change, which may result in a &#039;&#039;&#039;high message payload&#039;&#039;&#039; during operation. Fast Mode should therefore only be enabled when &#039;&#039;&#039;strictly required&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalInputs/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;slow&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalInputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;slow&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Get all digital input pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalInputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalInputs/runtime/out&lt;br /&gt;
&lt;br /&gt;
state: high/low&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.9 Digital Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.9.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Get all digital output pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Set all digital output pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.9.2 Notes =====&lt;br /&gt;
If the busi2c-3 is not powered, we will get this:&lt;br /&gt;
&lt;br /&gt;
Topic: &#039;&#039;&#039;digit a lOutputs/runtime/ out&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.10 Joystick Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.10.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Get all joystick pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: joystick/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: joystick//runtime/out&lt;br /&gt;
&lt;br /&gt;
state: pressed/released&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;JLEFT&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JRIGHT&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JUP&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JDOWN&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JCENTER&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.11 Buzzer Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.11.1 Overview =====&lt;br /&gt;
The &#039;&#039;&#039;Buzzer Actor&#039;&#039;&#039; is responsible for controlling the onboard buzzer through MQTT commands. It receives runtime commands on an MQTT input topic, validates the requested buzzer operation, drives the buzzerthrough GPIO using &#039;&#039;&#039;libgpiod&#039;&#039;&#039;, and publishes status/final responses on an MQTT output topic.&lt;br /&gt;
&lt;br /&gt;
The actor currently controls &#039;&#039;&#039;GPIO line 25&#039;&#039;&#039; on &#039;&#039;&#039;/dev/gpiochip0&#039;&#039;&#039;, with &#039;&#039;&#039;ACTIVE_LOW = False&#039;&#039;&#039;. It creates a &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GpiodBuzzerDriver&#039;&#039;&#039; instance and routes incoming MQTT actions to runtime handlers.&lt;br /&gt;
&lt;br /&gt;
The supported runtime actions are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Action&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|BEEP&lt;br /&gt;
|Plays a finite beep sequence, an infinite beep sequence, or a continuous tone&lt;br /&gt;
|-&lt;br /&gt;
|STOP&lt;br /&gt;
|Stops the currently active buzzer playback&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.2 MQTT Topics =====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Topic&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Direction&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|buzzer/runtime/in&lt;br /&gt;
|Input&lt;br /&gt;
|Receives buzzer commands&lt;br /&gt;
|-&lt;br /&gt;
|buzzer/runtime/out&lt;br /&gt;
|Output&lt;br /&gt;
|Publishes status messages and final command responses&lt;br /&gt;
|}&lt;br /&gt;
The actor subscribes to &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039; and publishes all status/final replies to &#039;&#039;&#039;buzzer/runtime/out&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===== 24.11.3 Hardware and Datasheet Notes =====&lt;br /&gt;
The buzzer used is the &#039;&#039;&#039;MLT-8530 electro-magnetic SMD buzzer.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
According to the datasheet:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Rated voltage&lt;br /&gt;
|3.6 Vo-p&lt;br /&gt;
|-&lt;br /&gt;
|Operating voltage&lt;br /&gt;
|2.5 ~ 4.5 Vo-p&lt;br /&gt;
|-&lt;br /&gt;
|Rated current&lt;br /&gt;
|Max. 95 mA&lt;br /&gt;
|-&lt;br /&gt;
|Rated test frequency&lt;br /&gt;
|2700 Hz&lt;br /&gt;
|-&lt;br /&gt;
|Duty cycle&lt;br /&gt;
|50% square wave&lt;br /&gt;
|-&lt;br /&gt;
|Sound output&lt;br /&gt;
|Min. 80 dB at 10 cm&lt;br /&gt;
|-&lt;br /&gt;
|Coil resistance&lt;br /&gt;
|16 ± 3 Ω&lt;br /&gt;
|-&lt;br /&gt;
|Resonant frequency&lt;br /&gt;
|2700 Hz&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.4 BEEP =====&lt;br /&gt;
The BEEP action supports two modes:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Mode&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|sequence&lt;br /&gt;
|Plays one or more beeps with gaps between them&lt;br /&gt;
|-&lt;br /&gt;
|continuous&lt;br /&gt;
|Plays one continuous tone until &#039;&#039;&#039;STOP&#039;&#039;&#039; is received&lt;br /&gt;
|}&lt;br /&gt;
If no mode is provided, the default mode is: &#039;&#039;&#039;sequence&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
All messages should be sent to the topic &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== a) Default Datasheet-Aligned Beep ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) N Beeps ======&lt;br /&gt;
Play &#039;&#039;&#039;&amp;lt;BEEPS_QUANTITY&amp;gt;&#039;&#039;&#039; beeps at &#039;&#039;&#039;&amp;lt;FREQUENCY&amp;gt;&#039;&#039;&#039; Hz. Each beep lasts &#039;&#039;&#039;&amp;lt;BEEP_DURATION&amp;gt;&#039;&#039;&#039; seconds, with &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;GAP_BETWEEN_BEEPS&amp;gt;&#039;&#039;&#039; seconds of silence between beeps.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
   &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;frequency_hz&amp;quot;: &amp;lt;FREQUENCY&amp;gt;,&lt;br /&gt;
      &amp;quot;duration_s&amp;quot;: &amp;lt;BEEP_DURATION&amp;gt;,&lt;br /&gt;
      &amp;quot;count&amp;quot;: &amp;lt;BEEPS_QUANTITY&amp;gt;,&lt;br /&gt;
      &amp;quot;gap_s&amp;quot;: &amp;lt;GAP_BETWEEN_BEEPS&amp;gt; &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;If you want to play repeated beeps forever until a &#039;&#039;&#039;STOP&#039;&#039;&#039; command arrives then you only need to pass the &#039;&#039;&#039;count: 0&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== c) Continuous Tone ======&lt;br /&gt;
Play one continuous &amp;lt;FREQUENCY&amp;gt; Hz tone until &#039;&#039;&#039;STOP&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
   &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;continuous&amp;quot;,&lt;br /&gt;
      &amp;quot;frequency_hz&amp;quot;: &amp;lt;FREQUENCY&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;If &#039;&#039;&#039;frequency_hz&#039;&#039;&#039; is omitted, the handler uses the configured default frequency.&lt;br /&gt;
&lt;br /&gt;
====== d) Stop Buzzer ======&lt;br /&gt;
If you want to stop the beep sequence, just send this payload to the &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== e) Buzzer payload parameters table ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Required&lt;br /&gt;
!Type&lt;br /&gt;
!Default&lt;br /&gt;
!Applies to&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|Yes&lt;br /&gt;
|object&lt;br /&gt;
| -&lt;br /&gt;
|All requests&lt;br /&gt;
|Main task object. Contains the requested action and&lt;br /&gt;
optional parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|Yes&lt;br /&gt;
|string&lt;br /&gt;
| -&lt;br /&gt;
|All requests&lt;br /&gt;
|Action to execute. Supported values: &amp;quot;BEEP&amp;quot; and&lt;br /&gt;
&amp;quot;STOP&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|task.params&lt;br /&gt;
|No&lt;br /&gt;
|object&lt;br /&gt;
|{}&lt;br /&gt;
|BEEP&lt;br /&gt;
|Optional parameters for configuring the buzzer&lt;br /&gt;
behavior. Not needed for STOP.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.mode&lt;br /&gt;
|No&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sequence&amp;quot;&lt;br /&gt;
|BEEP&lt;br /&gt;
|Playback mode. Supported values: &amp;quot;sequence&amp;quot; and&lt;br /&gt;
&amp;quot;continuous&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.frequency_hz&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|2700.0&lt;br /&gt;
|BEEP&lt;br /&gt;
|Buzzer frequency in Hz. Recommended/default value&lt;br /&gt;
is 2700 Hz , matching the buzzer resonant frequency.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.duration_s&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|0.2&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Duration of each beep, in seconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.count&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Number of beeps to play. 0 means repeat forever&lt;br /&gt;
until STOP.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.gap_s&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|0.15&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Silence gap between beeps, in seconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.mode =&amp;quot;continuous&amp;quot;&lt;br /&gt;
|No&lt;br /&gt;
|string&lt;br /&gt;
| -&lt;br /&gt;
|BEEP&lt;br /&gt;
|Plays one continuous tone until STOP . In this mode,&lt;br /&gt;
duration_s , count , and gap_s are ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.5 Buzzer - diagram =====&lt;br /&gt;
[[File:Buzzer - diagram.svg|center|frameless|901x901px]]&lt;br /&gt;
&lt;br /&gt;
===== 24.11.6 Buzzer Command timing charts - Examples =====&lt;br /&gt;
The following charts represent the command-level buzzer state over time.&lt;br /&gt;
&lt;br /&gt;
They do not show the internal 2700 Hz switching frequency.&lt;br /&gt;
&lt;br /&gt;
Instead, they show when the buzzer is logically:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;State&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Buzzer active / sound ON&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Buzzer inactive / silence&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== a) Default BEEP command ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Default values used:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|duration_s&lt;br /&gt;
|0.2 s&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|gap_s&lt;br /&gt;
|0.15 s&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Default_Beep.svg|frameless]]&lt;br /&gt;
&lt;br /&gt;
duration_s = 0.2 s&lt;br /&gt;
&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
====== b) BEEP Sequence - 5 beeps ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;duration_s&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;count&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;gap_s&amp;quot;: &amp;lt;GAP_BETWEEN_BEEPS&amp;gt;&lt;br /&gt;
  } &lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
[[File:5_beeps.svg|frameless|700x700px]]&lt;br /&gt;
duration_s = 1.0s&lt;br /&gt;
&lt;br /&gt;
gap_s = 0.5s&lt;br /&gt;
&lt;br /&gt;
count = 5&lt;br /&gt;
&lt;br /&gt;
====== c) Infinite BEEP Sequence ======&lt;br /&gt;
&lt;br /&gt;
This happens when: &amp;quot;count&amp;quot;: 0&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
       &amp;quot;duration_s&amp;quot;: 1,&lt;br /&gt;
       &amp;quot;count&amp;quot;: 0,&lt;br /&gt;
       &amp;quot;gap_s&amp;quot;: 0.5&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
[[File:Infinite_Beeps.svg|frameless|606x606px]]&lt;br /&gt;
&lt;br /&gt;
duration_s = 1.0&lt;br /&gt;
gap_s = 0.5&lt;br /&gt;
&lt;br /&gt;
count = 0&lt;br /&gt;
&lt;br /&gt;
====== d) Continuous BEEP ======&lt;br /&gt;
In continuous mode, the buzzer remains ON until a STOP command is received.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
       &amp;quot;mode&amp;quot;: &amp;quot;continuous&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Continous beep.svg|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
mode = continuous&lt;br /&gt;
&lt;br /&gt;
====== e) STOP ======&lt;br /&gt;
The STOP command immediately forces the buzzer to OFF.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Stop beep.svg|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
After STOP, the buzzer is forced to OFF.&lt;br /&gt;
&lt;br /&gt;
==== 24.12 INA232 actor ====&lt;br /&gt;
&lt;br /&gt;
===== 24.12.1 Overview =====&lt;br /&gt;
The &#039;&#039;&#039;INA Actor&#039;&#039;&#039; is responsible for reading the ATLAS INA232 power monitor and publishing the measuredelectrical values through MQTT.&lt;br /&gt;
&lt;br /&gt;
The actor publishes:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Unit&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|voltage_v&lt;br /&gt;
|V&lt;br /&gt;
|Measured bus/input voltage&lt;br /&gt;
|-&lt;br /&gt;
|current_a&lt;br /&gt;
|A&lt;br /&gt;
|Measured current&lt;br /&gt;
|-&lt;br /&gt;
|power_w&lt;br /&gt;
|W&lt;br /&gt;
|Measured/calculated power&lt;br /&gt;
|}&lt;br /&gt;
The INA232 is a current, voltage, and power monitor with an I²C/SMBus interface. It reports current, busvoltage, and power values through internal registers. The calibration register must be configured to obtainvalid current and power results.&lt;br /&gt;
&lt;br /&gt;
===== 24.12.2 Actor Behaviour =====&lt;br /&gt;
The INA Actor shall:&lt;br /&gt;
&lt;br /&gt;
1. Start with a valid INA configuration.&lt;br /&gt;
&lt;br /&gt;
2. Configure the INA232 device.&lt;br /&gt;
&lt;br /&gt;
3. Read voltage, current and power once per second.&lt;br /&gt;
&lt;br /&gt;
4. Publish the values to: &#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The actor does &#039;&#039;&#039;not&#039;&#039;&#039; need a request every second.&lt;br /&gt;
&lt;br /&gt;
The publication is automatic and periodic.&lt;br /&gt;
&lt;br /&gt;
===== 24.12.3 Required Configuration =====&lt;br /&gt;
The actor requires a small configuration to correctly read and convert the INA232 measurements.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|enabled&lt;br /&gt;
|boolean&lt;br /&gt;
|Yes&lt;br /&gt;
|Enables or disables the INA actor&lt;br /&gt;
|-&lt;br /&gt;
|address&lt;br /&gt;
|string /integer&lt;br /&gt;
|Yes&lt;br /&gt;
|I²C address of the INA232 device&lt;br /&gt;
|-&lt;br /&gt;
|shunt_ohm&lt;br /&gt;
|number&lt;br /&gt;
|Yes&lt;br /&gt;
|Value of the shunt resistor in ohms&lt;br /&gt;
|-&lt;br /&gt;
|max_current_a&lt;br /&gt;
|number&lt;br /&gt;
|Yes&lt;br /&gt;
|Maximum expected current, used forcalibration&lt;br /&gt;
|-&lt;br /&gt;
|adcrange&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|INA232 shunt voltage range selection&lt;br /&gt;
|-&lt;br /&gt;
|publish_interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|Runtime publish interval in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
|rail_name&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|Logical name of the monitored power rail&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Default configuration&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
  &amp;quot;address&amp;quot;: &amp;quot;0x40&amp;quot;,&lt;br /&gt;
  &amp;quot;shunt_ohm&amp;quot;: 0.020,&lt;br /&gt;
  &amp;quot;publish_interval_ms&amp;quot;: 1000,&lt;br /&gt;
  &amp;quot;rail_name&amp;quot;: &amp;quot;atlas_input_power&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.12.4 Configuration domain =====&lt;br /&gt;
Configuration messages are sent to:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/config/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Configuration replies are published on:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/config/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;- GET_CONFIG&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Returns the current INA Actor configuration&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Request&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_CONFIG&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Response&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_CONFIG&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;configured&amp;quot;: true,&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
      &amp;quot;address&amp;quot;: &amp;quot;0x40&amp;quot;,&lt;br /&gt;
      &amp;quot;shunt_ohm&amp;quot;: 0.020,&lt;br /&gt;
      &amp;quot;publish_interval_ms&amp;quot;: 1000&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.12.5 Runtime domain =====&lt;br /&gt;
Runtime messages are sent to:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Runtime replies are published on:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;- Manual Runtime read&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Request&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_POWER&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Response&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_POWER&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;voltage_v&amp;quot;: 24.12,&lt;br /&gt;
      &amp;quot;current_a&amp;quot;: 0.481,&lt;br /&gt;
      &amp;quot;power_w&amp;quot;: 11.6&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;- Automatic Runtime Publication&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Publish topic:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Period: 1000 ms === 1s&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Response payload&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;PUBLISH_POWER&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;voltage_v&amp;quot;: 24.12,&lt;br /&gt;
      &amp;quot;current_a&amp;quot;: 0.481,&lt;br /&gt;
      &amp;quot;power_w&amp;quot;: 11.6&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|success&lt;br /&gt;
|boolean&lt;br /&gt;
| -&lt;br /&gt;
|Indicates whether the read operation succeeded&lt;br /&gt;
|-&lt;br /&gt;
|voltage_v&lt;br /&gt;
|number&lt;br /&gt;
|V&lt;br /&gt;
|Measured bus/input voltage&lt;br /&gt;
|-&lt;br /&gt;
|current_a&lt;br /&gt;
|number&lt;br /&gt;
|A&lt;br /&gt;
|Measured current&lt;br /&gt;
|-&lt;br /&gt;
|power_w&lt;br /&gt;
|number&lt;br /&gt;
|W&lt;br /&gt;
|Measured power&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.13 Modem Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.13.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtainmodem (LTE) data. Connecting to the broker for this area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
===== 24.13.2 Mobile (LTE Modem) =====&lt;br /&gt;
The Mobile actor manages the LTE modem using ModemManager (&#039;&#039;&#039;mmcli&#039;&#039;&#039;). It allows monitoring modem status, configuring connectivity (APN, operator,network mode), and performing diagnostics.&lt;br /&gt;
&lt;br /&gt;
===== 24.13.3 Scan Operators =====&lt;br /&gt;
Scans available network operators (requires SIM and modem enabled).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SCAN_OPERATORS&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;operators&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;id&amp;quot;: &amp;quot;26801&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;vodafone P&amp;quot;,&lt;br /&gt;
          &amp;quot;status&amp;quot;: &amp;quot;available&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;id&amp;quot;: &amp;quot;26806&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;MEO&amp;quot;,&lt;br /&gt;
          &amp;quot;status&amp;quot;: &amp;quot;available&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.4 Set Operator =====&lt;br /&gt;
The supported modes are:&lt;br /&gt;
&lt;br /&gt;
* auto → modem selects de operator automatically (&#039;&#039;&#039;default&#039;&#039;&#039;).&lt;br /&gt;
* manual→ user forces a specific operator using &#039;&#039;&#039;operator_id&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
- Operators are identified using &#039;&#039;&#039;MCC + MNC codes&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Operator&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Country&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Vodafone PT&lt;br /&gt;
|26801&lt;br /&gt;
|Portugal&lt;br /&gt;
|-&lt;br /&gt;
|MEO&lt;br /&gt;
|26806&lt;br /&gt;
|Portugal&lt;br /&gt;
|-&lt;br /&gt;
|NOS&lt;br /&gt;
|26803&lt;br /&gt;
|Portugal&lt;br /&gt;
|}&lt;br /&gt;
These values are obtained dynamically via SCAN_OPERATORS&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Default should always be &#039;&#039;&#039;auto&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;manual&#039;&#039;&#039; only when:&lt;br /&gt;
&lt;br /&gt;
- You need to force roaming behavior&lt;br /&gt;
&lt;br /&gt;
- You want to lock to a specific network for stability/testing&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Auto Selection&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_OPERATOR&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;auto&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Manual Selection ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_OPERATOR&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;manual&amp;quot;,&lt;br /&gt;
      &amp;quot;operator_id&amp;quot;: &amp;quot;26801&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.5 Set APN Configuration =====&lt;br /&gt;
Supports automatic (predefined APN) or custom configuration.&lt;br /&gt;
&lt;br /&gt;
====== Actual Behavior ======&lt;br /&gt;
When &#039;&#039;&#039;SET_APN&#039;&#039;&#039; is executed, the system performs the following sequence:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Disconnects the current data connection&#039;&#039;&#039; (if connected)&lt;br /&gt;
# Applies the new APN configuration&lt;br /&gt;
# Initiates a new connection using the provided APN&lt;br /&gt;
# Waits until the modem reaches &#039;&#039;&#039;connected state&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This means a &#039;&#039;&#039;full reconnection is automatically performed&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
No additional RESET or manual reconnection is required.&lt;br /&gt;
&lt;br /&gt;
====== Impact &amp;amp; Considerations ======&lt;br /&gt;
&lt;br /&gt;
* Active data connection is &#039;&#039;&#039;interrupted&#039;&#039;&#039;&lt;br /&gt;
* Ongoing communications (MQTT, HTTP, VPN, etc.) will be &#039;&#039;&#039;dropped&#039;&#039;&#039;&lt;br /&gt;
* IP address may change after reconnection&lt;br /&gt;
* Operation may take &#039;&#039;&#039;several seconds (typically 5–20s)&#039;&#039;&#039;&lt;br /&gt;
* If connection fails, the modem may remain &#039;&#039;&#039;disconnected&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== Known APNs ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Operator&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN CONF&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;NAME&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;PROXY&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;PORT&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;MCC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;MNC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;AUTH&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;TYPE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;TYPE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CARRIER&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;OBS.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|MEO, UZO&lt;br /&gt;
| --&lt;br /&gt;
|internet&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
|1nce&lt;br /&gt;
| --&lt;br /&gt;
|iot.1nce.net&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
|Vodafone&lt;br /&gt;
|Vodafone&lt;br /&gt;
Internet&lt;br /&gt;
|net2.vodafone.pt&lt;br /&gt;
|iproxy.vodafone.pt&lt;br /&gt;
|80&lt;br /&gt;
|268&lt;br /&gt;
|01&lt;br /&gt;
|PAP&lt;br /&gt;
|default&lt;br /&gt;
|unspecified&lt;br /&gt;
|[https://ajuda.vodafone.pt/manuais/vodafone/smart-4g/explorar/configure-o-telefone-para-internet Docs]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Supported Modes ======&lt;br /&gt;
&lt;br /&gt;
* auto&lt;br /&gt;
* custom&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Mode&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|auto&lt;br /&gt;
|Uses modem default / SIM-provided APN&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|Uses user-defined APN credentials&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;- Auto APN (e.g. 1NCE)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Uses the default APN embedded in the modem or provided by the SIM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_APN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;auto&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;- Custom APN&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Allows full control over APN configuration.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_APN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;custom&amp;quot;,&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;user&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
      &amp;quot;password&amp;quot;: &amp;quot;pass&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.6 Get Modem Status =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_STATUS&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;present&amp;quot;: true,&lt;br /&gt;
        &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;registered&amp;quot;,&lt;br /&gt;
        &amp;quot;signal&amp;quot;: 34,&lt;br /&gt;
        &amp;quot;access_tech&amp;quot;: &amp;quot;lte&amp;quot;,&lt;br /&gt;
        &amp;quot;operator&amp;quot;: &amp;quot;vodafone P&amp;quot;,&lt;br /&gt;
        &amp;quot;sim&amp;quot;: &amp;quot;ready&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.7 Enable / Disable Modem =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_MODEM_STATE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.8 Reset Modem =====&lt;br /&gt;
Performs a full modem reset and recovery sequence.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;RESET&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Actual Behavior ======&lt;br /&gt;
When RESET is executed, the system performs a &#039;&#039;&#039;complete modem restart flow&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# Executes system-level reset: &#039;&#039;&#039;ltectl reset-modem&#039;&#039;&#039;&lt;br /&gt;
# The modem &#039;&#039;&#039;disappears from the system (USB re-enumeration)&#039;&#039;&#039;&lt;br /&gt;
# The system waits for the modem to &#039;&#039;&#039;reappear&#039;&#039;&#039;&lt;br /&gt;
# Re-discovers the modem path&lt;br /&gt;
# Waits until the modem becomes &#039;&#039;&#039;ready&#039;&#039;&#039;&lt;br /&gt;
# Waits until the modem is &#039;&#039;&#039;connected again&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a &#039;&#039;&#039;full recovery sequence&#039;&#039;&#039;, including automatic reconnection.&lt;br /&gt;
&lt;br /&gt;
====== Impact on active connection ======&lt;br /&gt;
&lt;br /&gt;
* Active data connection is &#039;&#039;&#039;immediately terminated&#039;&#039;&#039;&lt;br /&gt;
* All ongoing communications (MQTT, VPN, HTTP, etc.) will be &#039;&#039;&#039;interrupted&#039;&#039;&#039;&lt;br /&gt;
* Modem temporarily &#039;&#039;&#039;disappears from the system&#039;&#039;&#039;&lt;br /&gt;
* A new network registration is performed&lt;br /&gt;
* IP address will &#039;&#039;&#039;likely change&#039;&#039;&#039;&lt;br /&gt;
* Total recovery time may take &#039;&#039;&#039;10–120 seconds&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== When to use ======&lt;br /&gt;
Use &#039;&#039;&#039;RESET&#039;&#039;&#039; only when:&lt;br /&gt;
&lt;br /&gt;
* Modem is stuck in &#039;&#039;&#039;searching&#039;&#039;&#039; or not registering&lt;br /&gt;
* Connected but no data traffic is possible&lt;br /&gt;
* APN/operator changes are not taking effect&lt;br /&gt;
* Modem becomes unresponsive or unstable&lt;br /&gt;
&lt;br /&gt;
====== When NOT to Use ======&lt;br /&gt;
Avoid using RESET :&lt;br /&gt;
&lt;br /&gt;
* During OTA updates or file uploads&lt;br /&gt;
* During critical real-time operations&lt;br /&gt;
* If a simple reconnect ( SET_MODEM_STATE ) is sufficient&lt;br /&gt;
&lt;br /&gt;
====== Application Considerations ======&lt;br /&gt;
&#039;&#039;&#039;Before RESET&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Ensure no critical operations are ongoing&lt;br /&gt;
* Persist any unsent or buffered data&lt;br /&gt;
* Expect loss of connectivity&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;After RESET&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Wait for modem to fully recover (can take up to ~2 minutes)&lt;br /&gt;
* Re-check modem status using: &#039;&#039;&#039;GET_STATUS&#039;&#039;&#039;&lt;br /&gt;
* Re-establish application-level connections: &#039;&#039;&#039;MQTT&#039;&#039;&#039;; &#039;&#039;&#039;VPN&#039;&#039;&#039; an &#039;&#039;&#039;Cloud sessions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.9 Set Network Mode =====&lt;br /&gt;
Configures allowed radio technologies&lt;br /&gt;
&lt;br /&gt;
Supported values:&lt;br /&gt;
&lt;br /&gt;
* 2g&lt;br /&gt;
* 3g&lt;br /&gt;
* 4g&lt;br /&gt;
* auto&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_NETWORK_MODE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;4g&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;4g&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.10 Get Signal Strength =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_SIGNAL&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;signal&amp;quot;: 34,&lt;br /&gt;
      &amp;quot;unit&amp;quot;: &amp;quot;%&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.11 Get SIM card info =====&lt;br /&gt;
&#039;&#039;&#039;GET_SIM_INFO&#039;&#039;&#039; is a &#039;&#039;&#039;runtime action&#039;&#039;&#039; used to read SIM card information from the modem through ModemManager.&lt;br /&gt;
&lt;br /&gt;
This action is &#039;&#039;&#039;read-only&#039;&#039;&#039;. It does not change the modem state, APN, operator, bearer, or NetworkManager configuration.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_SIM_INFO&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;sim&amp;quot;: {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
        &amp;quot;path&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
        &amp;quot;active&amp;quot;: true,&lt;br /&gt;
        &amp;quot;iccid&amp;quot;: &amp;quot;8935101234567890123&amp;quot;,&lt;br /&gt;
        &amp;quot;imsi&amp;quot;: &amp;quot;268060123456789&amp;quot;,&lt;br /&gt;
        &amp;quot;operator_id&amp;quot;: &amp;quot;26806&amp;quot;,&lt;br /&gt;
        &amp;quot;operator_name&amp;quot;: &amp;quot;MEO&amp;quot;,&lt;br /&gt;
        &amp;quot;emergency_numbers&amp;quot;: [&lt;br /&gt;
          &amp;quot;112&amp;quot;&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;preferred_networks&amp;quot;: [&lt;br /&gt;
          &amp;quot;operator-code: 42507, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 20810, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 64710, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 37001, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 34002, access-technologies: gsm, umts, lte&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| number / string&lt;br /&gt;
|Same request ID received in the input payload.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|Actor name, usually &#039;&#039;&#039;modem-actor&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates if the SIM information was read successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.id&lt;br /&gt;
|string&lt;br /&gt;
|SIM object ID used by ModemManager. Usually 0.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.path&lt;br /&gt;
|string&lt;br /&gt;
|ModemManager DBus path for the SIM object.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.active&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates if the SIM is active, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.iccid&lt;br /&gt;
|string / null&lt;br /&gt;
|SIM ICCID / SIM identifier. This is the physical SIM card identifier.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.imsi&lt;br /&gt;
|string / null&lt;br /&gt;
|IMSI associated with the SIM subscription.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.operator_id&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile operator identifier from the SIM, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.operator_name&lt;br /&gt;
|string / null&lt;br /&gt;
|Operator name from the SIM, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.emergency_numbers&lt;br /&gt;
|array&lt;br /&gt;
|Emergency numbers reported by the SIM/modem.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.preferred_networks&lt;br /&gt;
|array&lt;br /&gt;
|Preferred networks stored on the SIM, when available.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.13.12 Test Modem =====&lt;br /&gt;
Performs a basic diagnostic test:&lt;br /&gt;
&lt;br /&gt;
* Modem detection&lt;br /&gt;
* SIM presence&lt;br /&gt;
* Network registration&lt;br /&gt;
* Data connectivity&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;TEST&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;hw&amp;quot;: true,&lt;br /&gt;
      &amp;quot;sim&amp;quot;: true,&lt;br /&gt;
      &amp;quot;network&amp;quot;: true,&lt;br /&gt;
      &amp;quot;data&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.13 Speed Test =====&lt;br /&gt;
Performs a &#039;&#039;&#039;low-data network speed test&#039;&#039;&#039; over the modem interface.&lt;br /&gt;
&lt;br /&gt;
This command does &#039;&#039;&#039;not&#039;&#039;&#039; run a full bandwidth benchmark.&lt;br /&gt;
&lt;br /&gt;
Instead, it performs a &#039;&#039;&#039;short and capped download burst&#039;&#039;&#039; on interface &#039;&#039;&#039;wwan0&#039;&#039;&#039; , measures the number of received bytes during a fixed time window, and&lt;br /&gt;
&lt;br /&gt;
returns an &#039;&#039;&#039;estimated download speed&#039;&#039;&#039; together with &#039;&#039;&#039;latency&#039;&#039;&#039; and a &#039;&#039;&#039;confidence level&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This approach is designed for IoT / field devices using &#039;&#039;&#039;capped cellular SIM cards&#039;&#039;&#039;, where a classic speed test would consume too much data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SPEED_TEST&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Success reply&#039;&#039;&#039;:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;download_mbps&amp;quot;: 12.4,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Error reply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example when the modem is not connected:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;download_mbps&amp;quot;: 12.4,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Example when an unexpected internal error occurs:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: false,&lt;br /&gt;
      &amp;quot;reason&amp;quot;: &amp;quot;unexpected_exception&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Reply parameters&#039;&#039;&#039; ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|success&lt;br /&gt;
| boolean&lt;br /&gt;
|Indicates whether the speed test completed successfully. true = test executed, false = failed (see reason ).&lt;br /&gt;
|-&lt;br /&gt;
|download_mbps&lt;br /&gt;
| number&lt;br /&gt;
|Estimated download speed in &#039;&#039;&#039;megabits per second (Mbps)&#039;&#039;&#039;. Calculated from the number of bytes received on interface&lt;br /&gt;
&#039;&#039;&#039;wwan0&#039;&#039;&#039; during the measurement window.&lt;br /&gt;
|-&lt;br /&gt;
|bytes_sampled&lt;br /&gt;
|number&lt;br /&gt;
|Total number of &#039;&#039;&#039;received bytes&#039;&#039;&#039; measured on the modem interface ( &#039;&#039;&#039;wwan0&#039;&#039;&#039; ) during the test window. Used as the raw input&lt;br /&gt;
for speed calculation.&lt;br /&gt;
|-&lt;br /&gt;
|duration_s&lt;br /&gt;
|number&lt;br /&gt;
|Measurement window duration in seconds. Current implementation uses &#039;&#039;&#039;5 seconds&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|latency_ms&lt;br /&gt;
|number&lt;br /&gt;
|null&lt;br /&gt;
|-&lt;br /&gt;
|confidence&lt;br /&gt;
|string&lt;br /&gt;
|Qualitative indicator of measurement reliability based on sampled bytes:• &#039;&#039;&#039;low&#039;&#039;&#039; → &amp;lt; 50,000 bytes• &#039;&#039;&#039;medium&#039;&#039;&#039; → 50,000–&lt;br /&gt;
299,999 bytes• &#039;&#039;&#039;high&#039;&#039;&#039; → ≥ 300,000 bytes&lt;br /&gt;
|-&lt;br /&gt;
|reason&lt;br /&gt;
|string&lt;br /&gt;
|Present only when &#039;&#039;&#039;success=false&#039;&#039;&#039; . Provides failure reason (e.g., &#039;&#039;&#039;not_connected (&amp;lt;state&amp;gt;)&#039;&#039;&#039; , &#039;&#039;&#039;unexpected_exception&#039;&#039;&#039; ).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Data consumption notice ======&lt;br /&gt;
This command performs a &#039;&#039;&#039;real network download&#039;&#039;&#039; and therefore consumes mobile data.&lt;br /&gt;
&lt;br /&gt;
Although the test is designed to be &#039;&#039;&#039;low-data&#039;&#039;&#039;, it still generates traffic:&lt;br /&gt;
&lt;br /&gt;
* Typical consumption per test: &#039;&#039;&#039;~100 KB to ~500 KB&#039;&#039;&#039;&lt;br /&gt;
* Latency measurement adds a negligible amount (ICMP ping)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Estimated data usage&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Frequency&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Estimated consumption&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~100 KB)&lt;br /&gt;
| ~3 MB/month&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~250 KB)&lt;br /&gt;
| ~7.5 MB/month&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~500 KB)&lt;br /&gt;
|~15 MB/month&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Recommendation ======&lt;br /&gt;
For devices using &#039;&#039;&#039;capped SIM cards&#039;&#039;&#039;, it is recommended to:&lt;br /&gt;
&lt;br /&gt;
* Avoid running this test at high frequency&lt;br /&gt;
* Use signal and modem status ( &#039;&#039;&#039;mmcli&#039;&#039;&#039; ) for regular monitoring&lt;br /&gt;
* Reserve speed tests for:&lt;br /&gt;
&lt;br /&gt;
- commissioning&lt;br /&gt;
&lt;br /&gt;
- troubleshooting&lt;br /&gt;
&lt;br /&gt;
- periodic health checks&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Running frequent or extended tests may significantly impact the data allowance.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.14 Get Raw Modem Info (Reserved) =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: reserved/modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: false,&lt;br /&gt;
      &amp;quot;reason&amp;quot;: &amp;quot;not_connected (registered)&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: reserved/modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;DEV&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;raw&amp;quot;: &amp;quot;mmcli -m 0 output...&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.15 Example: Raw Modem Output ( mmcli ) =====&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
mmcli -m 0 --output-json&lt;br /&gt;
&lt;br /&gt;
Example output:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;modem&amp;quot;: {&lt;br /&gt;
    &amp;quot;3gpp&amp;quot;: {&lt;br /&gt;
      &amp;quot;5gnr&amp;quot;: {&lt;br /&gt;
        &amp;quot;registration-settings&amp;quot;: {&lt;br /&gt;
          &amp;quot;drx-cycle&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
          &amp;quot;mico-mode&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;enabled-locks&amp;quot;: [],&lt;br /&gt;
      &amp;quot;eps&amp;quot;: {&lt;br /&gt;
        &amp;quot;initial-bearer&amp;quot;: {&lt;br /&gt;
          &amp;quot;dbus-path&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
          &amp;quot;settings&amp;quot;: {&lt;br /&gt;
            &amp;quot;apn&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;ip-type&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;password&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;ue-mode-operation&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;imei&amp;quot;: &amp;quot;862636056280785&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-access-technology&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-error&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-operator-id&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-operator-name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;operator-code&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;operator-name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;packet-service-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;pco&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;registration-state&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;cdma&amp;quot;: {&lt;br /&gt;
      &amp;quot;activation-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;cdma1x-registration-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;esn&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;evdo-registration-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;meid&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;nid&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;sid&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;dbus-path&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/Modem/0&amp;quot;,&lt;br /&gt;
    &amp;quot;generic&amp;quot;: {&lt;br /&gt;
      &amp;quot;access-technologies&amp;quot;: [],&lt;br /&gt;
      &amp;quot;bearers&amp;quot;: [],&lt;br /&gt;
      &amp;quot;carrier-configuration&amp;quot;: &amp;quot;ROW_Gen_VoLTE&amp;quot;,&lt;br /&gt;
      &amp;quot;carrier-configuration-revision&amp;quot;: &amp;quot;05010822&amp;quot;,&lt;br /&gt;
      &amp;quot;current-bands&amp;quot;: [&lt;br /&gt;
        &amp;quot;egsm&amp;quot;,&lt;br /&gt;
        &amp;quot;dcs&amp;quot;,&lt;br /&gt;
        &amp;quot;pcs&amp;quot;,&lt;br /&gt;
        &amp;quot;g850&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-6&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-3&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-7&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-12&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-13&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-18&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-19&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-20&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-25&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-26&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-28&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-34&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-38&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-39&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-40&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-41&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-66&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-19&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;current-capabilities&amp;quot;: [&lt;br /&gt;
        &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;current-modes&amp;quot;: &amp;quot;allowed: 4g; preferred: none&amp;quot;,&lt;br /&gt;
      &amp;quot;device&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
      &amp;quot;device-identifier&amp;quot;: &amp;quot;2c759b7021f62d2e26973150063ea040b3662a65&amp;quot;,&lt;br /&gt;
      &amp;quot;drivers&amp;quot;: [&lt;br /&gt;
        &amp;quot;option&amp;quot;,&lt;br /&gt;
        &amp;quot;qmi_wwan&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;equipment-identifier&amp;quot;: &amp;quot;862636056280785&amp;quot;,&lt;br /&gt;
      &amp;quot;hardware-revision&amp;quot;: &amp;quot;10000&amp;quot;,&lt;br /&gt;
      &amp;quot;manufacturer&amp;quot;: &amp;quot;QUALCOMM INCORPORATED&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: &amp;quot;SIMCOM_SIM7600G-H&amp;quot;,&lt;br /&gt;
      &amp;quot;own-numbers&amp;quot;: [],&lt;br /&gt;
      &amp;quot;physdev&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
      &amp;quot;plugin&amp;quot;: &amp;quot;simtech&amp;quot;,&lt;br /&gt;
      &amp;quot;ports&amp;quot;: [&lt;br /&gt;
        &amp;quot;cdc-wdm0 (qmi)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB0 (ignored)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB1 (gps)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB2 (at)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB3 (at)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB4 (audio)&amp;quot;,&lt;br /&gt;
        &amp;quot;wwan0 (net)&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;power-state&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;primary-port&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
      &amp;quot;primary-sim-slot&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
      &amp;quot;revision&amp;quot;: &amp;quot;LE20B04SIM7600G22&amp;quot;,&lt;br /&gt;
      &amp;quot;signal-quality&amp;quot;: {&lt;br /&gt;
        &amp;quot;recent&amp;quot;: &amp;quot;yes&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;0&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;sim&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
      &amp;quot;sim-slots&amp;quot;: [&lt;br /&gt;
        &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
        &amp;quot;/&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;failed&amp;quot;,&lt;br /&gt;
      &amp;quot;state-failed-reason&amp;quot;: &amp;quot;sim-missing&amp;quot;,&lt;br /&gt;
      &amp;quot;supported-bands&amp;quot;: [&lt;br /&gt;
        &amp;quot;egsm&amp;quot;,&lt;br /&gt;
        &amp;quot;dcs&amp;quot;,&lt;br /&gt;
        &amp;quot;pcs&amp;quot;,&lt;br /&gt;
        &amp;quot;g850&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-6&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-3&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-7&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-12&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-13&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-18&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-19&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-20&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-25&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-26&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-28&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-34&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-38&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-39&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-40&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-41&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-66&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-19&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-capabilities&amp;quot;: [&lt;br /&gt;
        &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-ip-families&amp;quot;: [&lt;br /&gt;
        &amp;quot;ipv4&amp;quot;,&lt;br /&gt;
        &amp;quot;ipv6&amp;quot;,&lt;br /&gt;
        &amp;quot;ipv4v6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-modes&amp;quot;: [&lt;br /&gt;
        &amp;quot;allowed: 2g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 4g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g; preferred: 2g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 4g; preferred: 2g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g, 4g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 2g&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;unlock-required&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;unlock-retries&amp;quot;: []&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Field Reference - mmcli -m 0 --output-json ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;JSON Path&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example Value&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Notes / Interpretation&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|modem.dbus-path&lt;br /&gt;
| Internal modem path&lt;br /&gt;
|/org/.../Modem/0&lt;br /&gt;
|Used by mmcli ( -m 0 )&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.manufacturer&lt;br /&gt;
| Modem vendor&lt;br /&gt;
|QUALCOMM INCORPORATED&lt;br /&gt;
|Hardware info&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.model&lt;br /&gt;
|Modem model&lt;br /&gt;
|SIM7600G-H&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.revision&lt;br /&gt;
|Firmware version&lt;br /&gt;
|LE20B04SIM7600G22&lt;br /&gt;
|Useful for debugging&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.device&lt;br /&gt;
|Linux device path&lt;br /&gt;
|/sys/devices/...&lt;br /&gt;
|USB device&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.drivers&lt;br /&gt;
|Kernel drivers&lt;br /&gt;
|option, qmi_wwan&lt;br /&gt;
|Must be present&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.primary-port&lt;br /&gt;
|Control interface&lt;br /&gt;
|cdc-wdm0&lt;br /&gt;
|Critical (QMI control)&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.ports&lt;br /&gt;
|Available interfaces&lt;br /&gt;
|ttyUSB*, wwan0&lt;br /&gt;
|Data + AT + GPS&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.power-state&lt;br /&gt;
|Power status&lt;br /&gt;
|on&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.state&lt;br /&gt;
|Modem state&lt;br /&gt;
|failed&lt;br /&gt;
|Main status field&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.state-failed-reason&lt;br /&gt;
|Failure reason&lt;br /&gt;
|sim-missing&lt;br /&gt;
|Root cause of failure&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.signal-quality.value&lt;br /&gt;
|Signal strength (%)&lt;br /&gt;
|0&lt;br /&gt;
|0 = no signal&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-capabilities&lt;br /&gt;
|Active radio tech&lt;br /&gt;
|gsm-umts, lte&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-modes&lt;br /&gt;
|Active mode&lt;br /&gt;
|allowed: 4g&lt;br /&gt;
|Controlled via API&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-bands&lt;br /&gt;
|Active frequency bands&lt;br /&gt;
|[eutran-1, ...]&lt;br /&gt;
|Coverage related&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.supported-bands&lt;br /&gt;
|Supported bands&lt;br /&gt;
|[eutran-*, utran-*]&lt;br /&gt;
|Hardware capability&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.supported-ip-families&lt;br /&gt;
|IP support&lt;br /&gt;
|ipv4, ipv6, ipv4v6&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.sim&lt;br /&gt;
|SIM path&lt;br /&gt;
|/org/.../SIM/0&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.sim-slots&lt;br /&gt;
|SIM slots&lt;br /&gt;
|[slot1, slot2]&lt;br /&gt;
|Slot 2 empty here&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.primary-sim-slot&lt;br /&gt;
|Active SIM slot&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.bearers&lt;br /&gt;
|Active data sessions&lt;br /&gt;
|[ ]&lt;br /&gt;
|Empty = no connection&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.imei&lt;br /&gt;
|Device IMEI&lt;br /&gt;
|862636056280785&lt;br /&gt;
|Unique identifier&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.operator-name&lt;br /&gt;
|Network name&lt;br /&gt;
| --&lt;br /&gt;
|Not available (no SIM)&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.operator-code&lt;br /&gt;
|MCC/MNC&lt;br /&gt;
| --&lt;br /&gt;
|Not available&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.registration-state&lt;br /&gt;
|Network state&lt;br /&gt;
| --&lt;br /&gt;
|Not registered&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.packet-service-state&lt;br /&gt;
|Data service state&lt;br /&gt;
| --&lt;br /&gt;
|No data session&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.eps.initial-bearer.settings.apn&lt;br /&gt;
|APN&lt;br /&gt;
| --&lt;br /&gt;
|Not set / no connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.13.16 Notes: =====&lt;br /&gt;
&lt;br /&gt;
* If no modem is detected: &#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;present&amp;quot;: false&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If SIM is locked or missing: &#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;sim&amp;quot;: &amp;quot;locked&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Operator scan may take several seconds and should be handled asynchronously.&lt;br /&gt;
* Some actions require:&lt;br /&gt;
&lt;br /&gt;
- SIM card inserted&lt;br /&gt;
&lt;br /&gt;
- Modem enabled&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039; interface available&lt;br /&gt;
&lt;br /&gt;
* Signal strength is reported as percentage and may be cached by ModemActor.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.14 CANopen Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.14.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker.&lt;br /&gt;
&lt;br /&gt;
The CANopen Actor provides a generic protocol interface to CANopen devices.&lt;br /&gt;
&lt;br /&gt;
The actor does NOT interpret device-specific meaning (Object Dictionary semantics).&lt;br /&gt;
&lt;br /&gt;
It only handles communication (HOW to talk).&lt;br /&gt;
&lt;br /&gt;
===== 24.14.2 Configuration =====&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Configure CANopen Nodes&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/config/in&lt;br /&gt;
&lt;br /&gt;
Stores CANopen defaults and logical node configuration inside the actor.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;sdo_timeout&amp;quot;: &amp;quot;&amp;lt;SDO_TIMEOUT&amp;gt;&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;nodes&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;NODE_NAME&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;node_id&amp;quot;: &amp;quot;&amp;lt;NODE_ID&amp;gt;&amp;quot;,&lt;br /&gt;
          &amp;quot;steps_per_rev&amp;quot;: &amp;quot;&amp;lt;STEPS_PER_REV&amp;gt;&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;motor_1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;1777041089180&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value isreturned in the response, allowing the applicationto match requests and responses.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies who sent the request. Common values canbe&lt;br /&gt;
&#039;&#039;&#039;APP&#039;&#039;&#039;, &#039;&#039;&#039;NodeRED&#039;&#039;&#039;, &#039;&#039;&#039;CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the CANopencommand alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;CONFIG_CANOPEN&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this section,the alias must be&lt;br /&gt;
&#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the configuration data to store inside theCANopen actor.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.defaults&lt;br /&gt;
|object&lt;br /&gt;
|No&lt;br /&gt;
|{ &amp;quot;sdo_timeout&amp;quot;:2.0 }&lt;br /&gt;
|Defines default CANopen settings used by the actorwhen no command-specific value is provided.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.defaults.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Default timeout, in seconds, used for SDOoperations. For example, &#039;&#039;&#039;2.0&#039;&#039;&#039;&lt;br /&gt;
means the actor waitsup to 2 seconds for an SDO response.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;{ &amp;quot;motor_1&amp;quot;: {...}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|List of logical CANopen nodes known by the actor.Each key is a user-defined node name.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical name used to reference a node later withoutrepeatedly sending its&lt;br /&gt;
&#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID on the CAN bus. Valid CANopennode IDs are normally in the range&lt;br /&gt;
&#039;&#039;&#039;1..127&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Recommended&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw position counts corresponding toone full mechanical revolution, 360°. The actor usesthis later to convert raw position into revolutions and angle_deg.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;1777041089180&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate the&lt;br /&gt;
response with the original command.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response. For successful&lt;br /&gt;
handler replies, this is canopen-actor.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object containing the executed alias and the command&lt;br /&gt;
result.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;CONFIG_CANOPEN&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the configuration outcome.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.defaults.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the &#039;&#039;&#039;defaults&#039;&#039;&#039; configuration was successfully stored. This&lt;br /&gt;
field is present only if &#039;&#039;&#039;defaults&#039;&#039;&#039; was included in the request.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.&amp;lt;NODE_NAME&amp;gt;.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the logical node configuration was successfully stored.&lt;br /&gt;
Example: &#039;&#039;&#039;taskResult.motor_1.success = true&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Generic success field. This appears when no specific &#039;&#039;&#039;defaults&#039;&#039;&#039; or &#039;&#039;&#039;nodes&#039;&#039;&#039;&lt;br /&gt;
result is generated.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;unknown alias&lt;br /&gt;
CONFIG_X&amp;quot;&lt;br /&gt;
|Error description. This field is present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039; does not communicate with the CANopen device directly. It stores logical node configuration inside the actor so that later runtime&lt;br /&gt;
&lt;br /&gt;
commands can refer to nodes by name instead of always sending the numeric &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====== Configure one CANopen Transmit PDO ======&lt;br /&gt;
Configures a TPDO to transmit position data.&lt;br /&gt;
&lt;br /&gt;
The handler validates &#039;&#039;&#039;pdo_num&#039;&#039;&#039; as &#039;&#039;&#039;1..4&#039;&#039;&#039;, defaults &#039;&#039;&#039;map_index&#039;&#039;&#039; to &#039;&#039;&#039;0x6004&#039;&#039;&#039;, &#039;&#039;&#039;map_subindex&#039;&#039;&#039; to &#039;&#039;&#039;0x00&#039;&#039;&#039;, &#039;&#039;&#039;map_bits&#039;&#039;&#039; to &#039;&#039;&#039;32&#039;&#039;&#039;, &#039;&#039;&#039;transmission_type&#039;&#039;&#039; to &#039;&#039;&#039;255&#039;&#039;&#039; , &#039;&#039;&#039;event_timer_ms&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
to &#039;&#039;&#039;20&#039;&#039;&#039;, and &#039;&#039;&#039;inhibit_time_100us&#039;&#039;&#039; to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_POSITION_TPDO&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;map_index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;map_subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;map_bits&amp;quot;: 32,&lt;br /&gt;
      &amp;quot;transmission_type&amp;quot;: 255,&lt;br /&gt;
      &amp;quot;event_timer_ms&amp;quot;: 2,&lt;br /&gt;
      &amp;quot;inhibit_time_100us&amp;quot;: 20,&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_POSITION_TPDO&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;comm_index&amp;quot;: 6144,&lt;br /&gt;
      &amp;quot;map_index&amp;quot;: 6656,&lt;br /&gt;
      &amp;quot;mapped_object&amp;quot;: &amp;quot;0x6004:00/32&amp;quot;,&lt;br /&gt;
      &amp;quot;transmission_type&amp;quot;: 255,&lt;br /&gt;
      &amp;quot;event_timer_ms&amp;quot;: 2,&lt;br /&gt;
      &amp;quot;inhibit_time_100us&amp;quot;: 20,&lt;br /&gt;
      &amp;quot;cob_id&amp;quot;: 389&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Parameter description ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Default&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|node_id&lt;br /&gt;
| int&lt;br /&gt;
|Yes*&lt;br /&gt;
|—&lt;br /&gt;
|CANopen node ID.&lt;br /&gt;
|-&lt;br /&gt;
|node&lt;br /&gt;
| string&lt;br /&gt;
|Yes*&lt;br /&gt;
|—&lt;br /&gt;
|Logical node name configured previously with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|pdo_num&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number. Valid range: &#039;&#039;&#039;1..4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|map_index&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0x6004&lt;br /&gt;
|Object dictionary index to map. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6004&#039;&#039;&#039;&amp;quot; are&lt;br /&gt;
supported.&lt;br /&gt;
|-&lt;br /&gt;
|map_subindex&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0x00&lt;br /&gt;
|Object dictionary subindex.&lt;br /&gt;
|-&lt;br /&gt;
|map_bits&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|32&lt;br /&gt;
|Number of mapped bits.&lt;br /&gt;
|-&lt;br /&gt;
|transmission_type&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|255&lt;br /&gt;
|CANopen TPDO transmission type.&lt;br /&gt;
|-&lt;br /&gt;
|event_timer_ms&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|TPDO event timer in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|inhibit_time_100us&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Inhibit time in 100 μs units.&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset used later when decoding PDO position.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes used later when decoding PDO position.&lt;br /&gt;
|-&lt;br /&gt;
|signed&lt;br /&gt;
|bool&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|Whether decoded raw position should be interpreted as signed.&lt;br /&gt;
|-&lt;br /&gt;
|steps_per_rev&lt;br /&gt;
|int&lt;br /&gt;
|Recommended&lt;br /&gt;
|&#039;&#039;&#039;4096&#039;&#039;&#039; if saved into node&lt;br /&gt;
&lt;br /&gt;
config&lt;br /&gt;
|Encoder steps per revolution.&lt;br /&gt;
|-&lt;br /&gt;
|timeout&lt;br /&gt;
|float&lt;br /&gt;
|No&lt;br /&gt;
|actor default&lt;br /&gt;
|SDO/NMT operation timeout.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.14.3 Runtime Operations =====&lt;br /&gt;
Supported runtime aliases include &amp;lt;small&amp;gt;&#039;&#039;&#039;READ, READ_CONTINUOUS, STOP_READ_CONTINUOUS, READ_PDO_CONTINUOUS, STOP_READ_PDO_CONTINUOUS, PING, NMT_COMMAND, SDO_READ, SDO_WRITE, READ_HEARTBEAT, RECV_PDO, RECV_EMCY&#039;&#039;&#039;&amp;lt;/small&amp;gt;, and &amp;lt;small&amp;gt;&#039;&#039;&#039;QUERY_NODE_INFO&#039;&#039;&#039;&amp;lt;/small&amp;gt;&amp;lt;small&amp;gt;&#039;&#039;&#039;.&#039;&#039;&#039;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== NMT Control ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;sdo_timeout&amp;quot;: &amp;quot;&amp;lt;SDO_TIMEOUT&amp;gt;&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;nodes&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;NODE_NAME&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;node_id&amp;quot;: &amp;quot;&amp;lt;NODE_ID&amp;gt;&amp;quot;,&lt;br /&gt;
          &amp;quot;steps_per_rev&amp;quot;: &amp;quot;&amp;lt;STEPS_PER_REV&amp;gt;&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;NMT_COMMAND&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;nmt-start-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;command&amp;quot;: &amp;quot;START&amp;quot;,&lt;br /&gt;
      &amp;quot;confirmed&amp;quot;: true,&lt;br /&gt;
      &amp;quot;state&amp;quot;: null&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Supported NMT Commands&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|START&lt;br /&gt;
| Puts the node into Operational state.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat state &#039;&#039;&#039;OPERATIONAL&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|STOP&lt;br /&gt;
| Puts the node into Stopped state.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat state &#039;&#039;&#039;STOPPED&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|PRE_OP&lt;br /&gt;
|Puts the node into Pre-Operational state.&lt;br /&gt;
|Used before operations such as PDO remapping.&lt;br /&gt;
|-&lt;br /&gt;
|PRE-OP&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|PREOP&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|PRE_OPERATIONAL&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|RESET_NODE&lt;br /&gt;
|Resets the CANopen node application.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for boot-up heartbeat.&lt;br /&gt;
|-&lt;br /&gt;
|RESET&lt;br /&gt;
|Same as &#039;&#039;&#039;RESET_NODE&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|RESET_COMM&lt;br /&gt;
|Resets CANopen communication.&lt;br /&gt;
|Sends NMT reset communication command.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;NMT_COMMAND&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&#039;&#039;&#039;NMT_COMMAND&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the NMT command parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID that will receive the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.command&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|NMT command to send. If omitted, the actor defaults to &#039;&#039;&#039;START&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.wait&lt;br /&gt;
|boolean&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|If &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat/state confirmation when supported. If&lt;br /&gt;
&#039;&#039;&#039;false&#039;&#039;&#039;, the command is sent without waiting for confirmation.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|5.0&lt;br /&gt;
|Timeout, in seconds, used when waiting for NMT confirmation. &lt;br /&gt;
Default is &#039;&#039;&#039;5.0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Internal timeout used when creating/updating the CANopen node wrapper.&lt;br /&gt;
Usually not required for basic NMT usage.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request and&lt;br /&gt;
response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;NMT_COMMAND&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the NMT command result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the actor successfully executed the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;nmt-start-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches the&lt;br /&gt;
original request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that received the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.command&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|NMT command that was executed. For aliases such as &#039;&#039;&#039;RESET&#039;&#039;&#039; , the response may&lt;br /&gt;
normalize the command to &#039;&#039;&#039;RESET_NODE&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.confirmed&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the command was considered successful. If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;false&#039;&#039;&#039; , this&lt;br /&gt;
usually means the command was sent successfully. If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039; , this means&lt;br /&gt;
&lt;br /&gt;
the expected heartbeat/state confirmation was received.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.state&lt;br /&gt;
|string/null&lt;br /&gt;
|null&lt;br /&gt;
|Confirmed NMT state when &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039; and state confirmation is available.&lt;br /&gt;
Otherwise it is &#039;&#039;&#039;null&#039;&#039;&#039; . Possible values include &#039;&#039;&#039;OPERATIONAL&#039;&#039;&#039; , &#039;&#039;&#039;STOPPED&#039;&#039;&#039; , and &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;unsupported NMT&lt;br /&gt;
command X&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== SDO Read ======&lt;br /&gt;
Reads an object dictionary value using SDO upload.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;sdo-read-position-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 123456&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;SDO_READ&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be &#039;&#039;&#039;SDO_READ&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the SDO read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index to read. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6004&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
are supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex to read. If omitted, defaults to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the SDO read operation. If omitted, the&lt;br /&gt;
actor default SDO timeout is used.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request and&lt;br /&gt;
response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO_READ&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the SDO read result.&lt;br /&gt;
task&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the SDO read was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sdo-read-positionnode5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches the&lt;br /&gt;
original request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index that was read, returned as decimal. Example: &#039;&#039;&#039;24580&#039;&#039;&#039; =&lt;br /&gt;
&#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.value&lt;br /&gt;
|integer&lt;br /&gt;
|123456&lt;br /&gt;
|Raw value returned by the SDO read operation.&lt;br /&gt;
task.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO timeout&lt;br /&gt;
0x6004:00&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
SDO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* SDO Write&lt;br /&gt;
&lt;br /&gt;
Writes an object dictionary value using SDO download.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_WRITE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6003&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_WRITE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;sdo-write-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24579,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Parameter descirption&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Default&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|node_id / nodeId / node&lt;br /&gt;
| int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|CANopen node reference.&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
| int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|Object dictionary index.&lt;br /&gt;
|-&lt;br /&gt;
|subindex&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex.&lt;br /&gt;
|-&lt;br /&gt;
|value&lt;br /&gt;
|int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|Value to write.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes: usually &#039;&#039;&#039;1&#039;&#039;&#039; , &#039;&#039;&#039;2&#039;&#039;&#039; , or &#039;&#039;&#039;4.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|timeout&lt;br /&gt;
|float&lt;br /&gt;
|No&lt;br /&gt;
|actor default&lt;br /&gt;
|SDO timeout in seconds.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;SDO_WRITE&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SDO_WRITE&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the SDO write parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to write to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;0x6003&amp;quot;&lt;br /&gt;
|CANopen object dictionary index to write. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6003&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
are supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex to write. If omitted, defaults to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.value&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|0&lt;br /&gt;
|Value to write into the selected object dictionary entry. Hex strings are&lt;br /&gt;
&lt;br /&gt;
also supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.size&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes to write. Valid values are normally &#039;&#039;&#039;1&#039;&#039;&#039; , &#039;&#039;&#039;2&#039;&#039;&#039; , &#039;&#039;&#039;3&#039;&#039;&#039; , or &#039;&#039;&#039;4&#039;&#039;&#039; . If&lt;br /&gt;
&lt;br /&gt;
omitted, defaults to &#039;&#039;&#039;4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the SDO write operation. If omitted, the&lt;br /&gt;
&lt;br /&gt;
actor default SDO timeout is used.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request andresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO_WRITE&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the SDO write result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the SDO write was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sdo-write-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call.&lt;br /&gt;
&lt;br /&gt;
Usually matches theoriginal request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was written to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24579&lt;br /&gt;
|Object dictionary index that was written, returned as decimal.&lt;br /&gt;
&lt;br /&gt;
Example: &#039;&#039;&#039;24579 =0x6003&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex that was written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.value&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Value that was written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.size&lt;br /&gt;
|integer&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO abort 0x6003:00 -&amp;gt;...&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Read Node State ======&lt;br /&gt;
Reads position and returns raw value, revolutions, and angle. Internally, this reads the configured position object, defaulting to&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;0x6004:00&#039;&#039;&#039;. &#039;&#039;&#039;If&#039;&#039;&#039; &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039; is not provided, the owner reads &#039;&#039;&#039;0x6501:00&#039;&#039;&#039; to obtain it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;read-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in theresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP, NodeRED, CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias andparameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be &#039;&#039;&#039;READ&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the position read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index used as the raw positionsource. If omitted, defaults to &#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex used as the raw positionsource. If omitted, defaults to &#039;&#039;&#039;0x00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Recommended&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per mechanical revolution. Used tocalculate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;revolutions&#039;&#039;&#039; and &#039;&#039;&#039;angle_deg&#039;&#039;&#039;. If omitted, the ownerattempts to read &#039;&#039;&#039;0x6501:00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the internal SDO reads. Ifomitted, the actor default SDO timeout is used.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Internal SDO timeout used when creating/updating the nodewrapper. Usually not required.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request andresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the position read result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the position read was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches theoriginal request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Raw position value read from the selected object dictionary entry.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for the conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions. Example: &#039;&#039;&#039;1024 / 4096 = 0.25&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees. Example: &#039;&#039;&#039;0.25 × 360 = 90°&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index read as the raw position source. Example: &#039;&#039;&#039;24580 =0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex read as the raw position source.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO timeout0x6004:00&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== READ SDO Continuous ======&lt;br /&gt;
Starts continuous SDO-based position reading.&lt;br /&gt;
&lt;br /&gt;
The initial command returns an acknowledgement. After that, continuous samples are published repeatedly to &#039;&#039;&#039;canopen/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The continuous loop requires a single node reference and requires &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start request&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 0.2,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
// Start acknowledgement&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: true,&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
// Continuous sample response&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;continuous&amp;quot;: true,&lt;br /&gt;
      &amp;quot;request_id&amp;quot;: &amp;quot;read-cont-node5&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. Continuous sample responses include&lt;br /&gt;
&lt;br /&gt;
this value as &#039;&#039;&#039;request_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039;, &#039;&#039;&#039;NodeRED&#039;&#039;&#039;,&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and&lt;br /&gt;
&lt;br /&gt;
parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the continuous read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read continuously.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Yes**&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per mechanical revolution. Required by&lt;br /&gt;
&lt;br /&gt;
the fast continuous read loop to calculate &#039;&#039;&#039;revolutions&#039;&#039;&#039; and&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;angle_deg&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index used as the raw position&lt;br /&gt;
&lt;br /&gt;
source. If omitted, defaults to &#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex used as the raw position&lt;br /&gt;
&lt;br /&gt;
source. If omitted, defaults to &#039;&#039;&#039;0x00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|0.2&lt;br /&gt;
|Timeout, in seconds, used for each fast SDO read cycle. If&lt;br /&gt;
&lt;br /&gt;
omitted, defaults to &#039;&#039;&#039;0.2&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|Delay between continuous read cycles, in milliseconds. If &#039;&#039;&#039;0&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
loop runs again immediately after each cycle yields control.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|Optional action. If set to &#039;&#039;&#039;STOP&#039;&#039;&#039; , &#039;&#039;&#039;OFF&#039;&#039;&#039; , &#039;&#039;&#039;CANCEL&#039;&#039;&#039; , or &#039;&#039;&#039;DISABLE&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
actor stops the continuous read loop instead of starting it.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the start request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object confirming that continuous reading was started.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the start command was accepted.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the continuous read loop is running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.mode&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;single&amp;quot;&lt;br /&gt;
|Read mode. In this fast continuous path, a single node is used when &#039;&#039;&#039;node_id&#039;&#039;&#039; ,&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nodeId&#039;&#039;&#039; , or &#039;&#039;&#039;node&#039;&#039;&#039; is provided.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|20&lt;br /&gt;
|Configured delay between continuous read cycles, in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;no configured nodes&amp;quot;&lt;br /&gt;
|Error description. Present only when the start command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| integer/string&lt;br /&gt;
|1777041089180&lt;br /&gt;
|Sample response ID generated by the actor for each read cycle.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the sample response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the running continuous command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing one continuous position sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether this specific read cycle was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Raw position value read from the node.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index read as the raw position source. Example: &#039;&#039;&#039;24580 =&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex read as the raw position source.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.continuous&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Marks this response as a continuous sample, not just the initial&lt;br /&gt;
&lt;br /&gt;
acknowledgement.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.request_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-cont-node5&amp;quot;&lt;br /&gt;
|Original request &#039;&#039;&#039;id&#039;&#039;&#039; that started the continuous loop. Useful to correlate&lt;br /&gt;
&lt;br /&gt;
samples with the start command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;operation failed&amp;quot;&lt;br /&gt;
|Error description for a failed sample. Present only when a read cycle fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Stop request ======&lt;br /&gt;
You can stop using either &#039;&#039;&#039;STOP_READ_CONTINUOUS&#039;&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;STOP_READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {}&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Or by sending &#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039; with &#039;&#039;&#039;action: &amp;quot;STOP&amp;quot;&#039;&#039;&#039; :&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-read-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-read-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stopped&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;stop-read-cont&amp;quot;&lt;br /&gt;
|Unique request identifier.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot; or&lt;br /&gt;
&lt;br /&gt;
&amp;quot;STOP_READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Command used to stop the continuous read loop.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;STOP&amp;quot;&lt;br /&gt;
|When using &#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039; , set &#039;&#039;&#039;action&#039;&#039;&#039; to &#039;&#039;&#039;STOP&#039;&#039;&#039; , &#039;&#039;&#039;OFF&#039;&#039;&#039; , &#039;&#039;&#039;CANCEL&#039;&#039;&#039; ,&lt;br /&gt;
&lt;br /&gt;
or &#039;&#039;&#039;DISABLE&#039;&#039;&#039; to stop the loop. Not required when using&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;STOP_READ_CONTINUOUS&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;stop-read-cont&amp;quot;&lt;br /&gt;
|Same request identifier received in the stop request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias returned by the stop handler.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the stop request was processed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates that the continuous read loop is no longer running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.stopped&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether there was an active task that was actually stopped. If no continuous&lt;br /&gt;
&lt;br /&gt;
task was running, this may be &#039;&#039;&#039;false&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Continuous PDO Reading ======&lt;br /&gt;
Starts continuous PDO-based position reading.&lt;br /&gt;
&lt;br /&gt;
This command does not perform repeated SDO reads. Instead, it waits for TPDO frames already being transmitted by the CANopen node.&lt;br /&gt;
&lt;br /&gt;
Normally, the TPDO should be configured first using &#039;&#039;&#039;CONFIG_POSITION_TPDO&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The initial command returns an acknowledgement. After that, continuous sample responses are published repeatedly to: &#039;&#039;&#039;canopenRM8007/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Request&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 1.0,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: true,&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;pdo&amp;quot;,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;data&amp;quot;: [0, 4, 0, 0],&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;continuous&amp;quot;: true,&lt;br /&gt;
      &amp;quot;request_id&amp;quot;: &amp;quot;read-pdo-cont-node5&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Start Request Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. Continuous sample responses include&lt;br /&gt;
&lt;br /&gt;
this value as &#039;&#039;&#039;request_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP , NodeRED ,&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CLI , or TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and&lt;br /&gt;
&lt;br /&gt;
parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Defines the command to execute.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the PDO continuous read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;. If&lt;br /&gt;
&lt;br /&gt;
used, the actor can reuse saved &#039;&#039;&#039;steps_per_rev , pdo_num ,&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;offset , size&#039;&#039;&#039; , and &#039;&#039;&#039;signed&#039;&#039;&#039; values from the node configuration.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number to listen to. If omitted, defaults to &#039;&#039;&#039;1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Yes**&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw position counts per mechanical revolution. Used&lt;br /&gt;
&lt;br /&gt;
to convert &#039;&#039;&#039;raw&#039;&#039;&#039; into &#039;&#039;&#039;revolutions&#039;&#039;&#039; and &#039;&#039;&#039;angle_deg&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.offset&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset inside the PDO payload where the position value&lt;br /&gt;
&lt;br /&gt;
starts.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.size&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes to decode from the PDO payload. For a 32-bit&lt;br /&gt;
&lt;br /&gt;
position value, use &#039;&#039;&#039;4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.signed&lt;br /&gt;
|boolean&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|Defines whether the raw value should be decoded as signed or&lt;br /&gt;
&lt;br /&gt;
unsigned.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|1.0&lt;br /&gt;
|Timeout, in seconds, while waiting for each TPDO frame. If no&lt;br /&gt;
&lt;br /&gt;
TPDO is received within this time, the cycle fails.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|Delay between read cycles, in milliseconds. If &#039;&#039;&#039;0&#039;&#039;&#039; , the loop&lt;br /&gt;
&lt;br /&gt;
immediately starts the next cycle after yielding control.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|Optional action. If set to &#039;&#039;&#039;STOP , OFF , CANCEL , or DISABLE&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
actor stops the continuous loop instead of starting it.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement Response Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the start request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object confirming whether the continuous PDO read&lt;br /&gt;
&lt;br /&gt;
was started.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the start command was accepted.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the continuous PDO read loop is running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.mode&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;pdo&amp;quot;&lt;br /&gt;
|Indicates that the loop is using PDO reception mode.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number being listened to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|20&lt;br /&gt;
|Configured delay between read cycles, in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;&#039;&#039;&#039;READ_PDO_CONTINUOUS&#039;&#039;&#039; requires a single&lt;br /&gt;
&lt;br /&gt;
node&amp;quot;&lt;br /&gt;
|Error description. Present only when the start command&lt;br /&gt;
&lt;br /&gt;
fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| integer/string&lt;br /&gt;
|1777041089180&lt;br /&gt;
|Sample response ID generated by the actor for each PDO read cycle.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the sample.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the running continuous command.&lt;br /&gt;
&lt;br /&gt;
task.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing one decoded PDO position sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether this specific PDO read cycle was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that produced the TPDO.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number received and decoded.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions. Example: &#039;&#039;&#039;1024 / 4096 = 0.25&#039;&#039;&#039; .&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Decoded raw position value from the PDO payload.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.data&lt;br /&gt;
|array&lt;br /&gt;
|[0, 4, 0, 0]&lt;br /&gt;
|Raw PDO payload bytes received from the CANopen node.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.offset&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset used to extract the raw position value from &#039;&#039;&#039;data.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.size&lt;br /&gt;
|integer&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes decoded from &#039;&#039;&#039;data&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.signed&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates whether the raw value was decoded as signed or unsigned.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.continuous&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Marks this response as a continuous sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.request_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-pdo-cont-node5&amp;quot;&lt;br /&gt;
|Original request &#039;&#039;&#039;id&#039;&#039;&#039; that started the continuous loop. Useful to&lt;br /&gt;
&lt;br /&gt;
correlate samples with the start command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;pdo operation failed&amp;quot;&lt;br /&gt;
|Error description. Present only when a sample fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Stop Request ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;STOP_READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {}&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Alternative stop request using &#039;&#039;&#039;READ_PDO_CONTINUOUS&#039;&#039;&#039;:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Stop Response&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stopped&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;stop-pdo-cont&amp;quot;&lt;br /&gt;
|Same request identifier received in the stop request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias returned by the stop handler.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the stop request was processed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates that the continuous PDO loop is no longer running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.stopped&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether there was an active continuous task that was actually stopped. If&lt;br /&gt;
&lt;br /&gt;
no task was running, this may be &#039;&#039;&#039;false&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Decode Logic ======&lt;br /&gt;
The received PDO payload is decoded using:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;: first byte to read from the PDO payload;&lt;br /&gt;
* &#039;&#039;&#039;size&#039;&#039;&#039;: number of bytes to read;&lt;br /&gt;
* &#039;&#039;&#039;signed&#039;&#039;&#039;: whether the value is signed or unsigned;&lt;br /&gt;
* &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039;: scaling factor used to calculate revolutions and angle.&lt;br /&gt;
&lt;br /&gt;
The raw value is decoded as little-endian:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;raw = int.from_bytes(data[offset : offset + size], byteorder=&amp;quot;little&amp;quot;, signed=signed)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;revolutions = raw / steps_per_rev&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;angle_deg = ((raw % steps_per_rev) / steps_per_rev) * 360.0&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.14.4 Design Principles =====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Protocol-Only Actor&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The CANopen Actor is responsible for:&lt;br /&gt;
&lt;br /&gt;
- CAN frame encoding/decoding;&lt;br /&gt;
&lt;br /&gt;
- SDO communication;&lt;br /&gt;
&lt;br /&gt;
- PDO reception (raw);&lt;br /&gt;
&lt;br /&gt;
- NMT control;&lt;br /&gt;
&lt;br /&gt;
- Heartbeat monitoring.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;No Device Semantics&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The actor:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Does NOT know&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
- What 0x6004 represents;&lt;br /&gt;
&lt;br /&gt;
- Units (RPM, mm, °C, etc.);&lt;br /&gt;
&lt;br /&gt;
- Device-specific logic.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Only returns&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
- Raw values;&lt;br /&gt;
&lt;br /&gt;
- Protocol-level responses.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Node Management&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Nodes must be defined via configuration;&lt;br /&gt;
&lt;br /&gt;
- Actor maintains node state internally;&lt;br /&gt;
&lt;br /&gt;
- Supports multiple nodes simultaneously.&lt;br /&gt;
&lt;br /&gt;
===== Summary =====&lt;br /&gt;
The CANopen Actor:&lt;br /&gt;
&lt;br /&gt;
- Implements &#039;&#039;&#039;CANopen protocol communication;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Provides &#039;&#039;&#039;generic MQTT interface;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Supports &#039;&#039;&#039;multi-node networks;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Keeps &#039;&#039;&#039;strict separation between transport and semantics.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 25. Included Software Stack ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:AtlasCode.svg|center|frameless|583x583px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 26. Software Stack and IPC Architecture ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hardware Peripherals Library Architecture.svg|center|frameless|1934x1934px]]&lt;br /&gt;
&lt;br /&gt;
=== 27. Related Products ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;PA&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000074&lt;br /&gt;
|[[SENSBLUE MONARCH|SENSBLUE MONARCH Gateway]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
{{SimilarProductsTable}}&lt;br /&gt;
&lt;br /&gt;
=== 28. Accessories ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;PA&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 29. Document History ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Version&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Date&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|SBADATAv0.1&lt;br /&gt;
|First  version of SENSBLUE ATLAS Datasheet&lt;br /&gt;
|11/03/2026&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 30. SENSBLUE ATLAS in-the-field ===&lt;br /&gt;
[IMAGE PLACEHOLDER]&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1917</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1917"/>
		<updated>2026-06-30T09:35:34Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Wiki Main Page Banner.svg|center|frameless|1153x1153px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welcome to the ATRONIA´s Wiki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is where tech makes sense.&lt;br /&gt;
&lt;br /&gt;
Here you will find our product´s datasheets, manuals, integration architectures, firmware releases, and engineering insights that will help you better understand what we do.&lt;br /&gt;
&lt;br /&gt;
We document with purpose. We design with clarity.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gateways &amp;amp; Single Board Computers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch|SENSBLUE MONARCH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateway&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:ATLAS.svg|frameless|106x106px|class=product-image|link=SENSBLUE ATLAS]]&lt;br /&gt;
&#039;&#039;&#039;[[SENSBLUE ATLAS]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;SBC&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- == Solutions ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Probes ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
    [[File:Dissolved Oxygen.svg|center|frameless|106x106px|class=product-image|link=Dissolved Oxygen]]&lt;br /&gt;
        &#039;&#039;&#039;[[Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-customtoggle-1 variations-toggle&amp;quot; style=&amp;quot;cursor: pointer; display: inline-block;height:2rem;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; flex-direction: row; justify-content: center;&amp;quot; class=&amp;quot;product-subtitle&amp;quot;&amp;gt;&lt;br /&gt;
  All Models &lt;br /&gt;
             &amp;lt;span class=&amp;quot;material-symbols-rounded arrow-icon&amp;quot;&amp;gt;&lt;br /&gt;
                   keyboard_arrow_down&lt;br /&gt;
             &amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-1&amp;quot; style=&amp;quot;line-height: 1.8 rem; font-size: 0.85em; &amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;variations-list&amp;quot; style=&amp;quot;overflow: visible !important;&amp;quot;&amp;gt;&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|DO Probe]]&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|DO Titanium]]&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Conductivity.svg|center|frameless|106x106px|class=product-image|link=Low Conductivity Probe AT-SB-PROBE-LC-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Conductivity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px|class=product-image|link=Multiparameter Probe AT-SB-PROBE-MP-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:NO3-.svg|center|frameless|106x106px|class=product-image|link=RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Nitrates (NO3) Probe AT-SB-PROBENO3-P|Nitrates(NO3-)]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:PH.svg|center|frameless|106x106px|class=product-image|link=RS-485 pH Probe AT-SB-PROBE-pH-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 pH Probe AT-SB-PROBE-pH-P|pH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Turbidity.svg|center|frameless|106x106px|class=product-image|link=RS-485 Turbidity Probe AT-SB-PROBE-T-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|Turbidity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Salinity.svg|center|frameless|106x106px|class=product-image|link=Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|Salinity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessories ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Straight N-Type Outdoor Antenna.svg|frameless|106x106px|class=product-image|link=Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;[[Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Accessories&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1916</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=Main_Page&amp;diff=1916"/>
		<updated>2026-06-30T09:30:55Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:ATRONIA Wiki}}&lt;br /&gt;
&lt;br /&gt;
[[File:Wiki Main Page Banner.svg|center|frameless|1153x1153px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Welcome to the ATRONIA´s Wiki&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is where tech makes sense.&lt;br /&gt;
&lt;br /&gt;
Here you will find our product´s datasheets, manuals, integration architectures, firmware releases, and engineering insights that will help you better understand what we do.&lt;br /&gt;
&lt;br /&gt;
We document with purpose. We design with clarity.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Gateways &amp;amp; Single Board Computers ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch|SENSBLUE MONARCH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateway&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:ATLAS.svg|frameless|106x106px|class=product-image|link=SENSBLUE ATLAS]]&lt;br /&gt;
&#039;&#039;&#039;[[SENSBLUE ATLAS]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;SBC&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;!-- == Solutions ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
[[File:Monarch.svg|frameless|106x106px|class=product-image|link=Monarch]]&lt;br /&gt;
&#039;&#039;&#039;[[Monarch]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Gateways&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Probes ==&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;&lt;br /&gt;
    [[File:Dissolved Oxygen.svg|center|frameless|106x106px|class=product-image|link=Dissolved Oxygen]]&lt;br /&gt;
        &#039;&#039;&#039;[[Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-customtoggle-1 variations-toggle&amp;quot; style=&amp;quot;cursor: pointer; display: inline-block;height:2rem;&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div style=&amp;quot;display: flex; flex-direction: row; justify-content: center;&amp;quot; class=&amp;quot;product-subtitle&amp;quot;&amp;gt;&lt;br /&gt;
  All Models &lt;br /&gt;
             &amp;lt;span class=&amp;quot;material-symbols-rounded arrow-icon&amp;quot;&amp;gt;&lt;br /&gt;
                   keyboard_arrow_down&lt;br /&gt;
             &amp;lt;/span&amp;gt;&lt;br /&gt;
        &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot; id=&amp;quot;mw-customcollapsible-1&amp;quot; style=&amp;quot;line-height: 1.8 rem; font-size: 0.85em; &amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;div class=&amp;quot;variations-list&amp;quot; style=&amp;quot;overflow: visible !important;&amp;quot;&amp;gt;&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-P-C1|DO Probe]]&lt;br /&gt;
        [[Dissolved Oxygen Probe AT-SB-PROBE-DO-T-C1|DO Titanium]]&lt;br /&gt;
          &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Conductivity.svg|center|frameless|106x106px|class=product-image|link=Low Conductivity Probe AT-SB-PROBE-LC-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Conductivity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px|class=product-image|link=Multiparameter Probe AT-SB-PROBE-MP-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:NO3-.svg|center|frameless|106x106px|class=product-image|link=RS-485 Nitrates (NO3) Probe AT-SB-PROBE-NO3-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Nitrates (NO3) Probe AT-SB-PROBENO3-P|Nitrates(NO3-)]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:PH.svg|center|frameless|106x106px|class=product-image|link=RS-485 pH Probe AT-SB-PROBE-pH-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 pH Probe AT-SB-PROBE-pH-P|pH]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Turbidity.svg|center|frameless|106x106px|class=product-image|link=RS-485 Turbidity Probe AT-SB-PROBE-T-P]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[RS-485 Turbidity Probe AT-SB-PROBE-T-P|Turbidity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Salinity.svg|center|frameless|106x106px|class=product-image|link=Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;[[Salinity Conductivity TDS Probe AT-SB-PROBE-S-P-C1|Salinity]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Accessories ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;mw-collapsible&amp;quot; data-collapsetext=&amp;quot;Collapse&amp;quot; data-expandtext=&amp;quot;Expand&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;products-grid&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Straight N-Type Outdoor Antenna.svg|frameless|106x106px|class=product-image|link=Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;[[Straight N-Type Outdoor Antenna]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Accessories&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:Multiparameter.svg|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Multiparameter]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;product-item&amp;quot;&amp;gt;[[File:|center|frameless|106x106px]]&#039;&#039;&#039;[[Monarch|Dissolved Oxygen]]&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;span class=&amp;quot;product-subtitle&amp;quot;&amp;gt;Probes&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt; --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1915</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1915"/>
		<updated>2026-06-30T09:28:44Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Força o menu lateral a expandir (Vector 2022) se estiver colapsado&lt;br /&gt;
mw.hook(&#039;wikipage.content&#039;).add(function () {&lt;br /&gt;
    if (document.documentElement.classList.contains(&#039;vector-feature-main-menu-pinned-disabled&#039;)) {&lt;br /&gt;
        var pinButton = document.getElementById(&#039;vector-main-menu-dropdown-checkbox&#039;);&lt;br /&gt;
        if (pinButton) {&lt;br /&gt;
            // Remove a classe de desativado e força o estado expandido&lt;br /&gt;
            document.documentElement.classList.remove(&#039;vector-feature-main-menu-pinned-disabled&#039;);&lt;br /&gt;
            document.documentElement.classList.add(&#039;vector-feature-main-menu-pinned-enabled&#039;);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Força o MediaWiki a carregar os módulos básicos em qualquer tipo de sessão (anónima ou registada)&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    &lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        // Alvo exclusivo: Apenas o menu de navegação da skin, ignorando o índice de conteúdos (Contents) da página&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas apenas no menu lateral&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var text = $li.text().trim();&lt;br /&gt;
            &lt;br /&gt;
            // Verifica se apanha as subpáginas pelo URL ou pelo texto exato&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || text === &#039;Datasheet&#039; &lt;br /&gt;
                             || text === &#039;Release Notes&#039;;&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !text.includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS) na barra lateral&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // 3. Injeta a seta nativa se encontrar o link&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                $(this).toggleClass(&#039;is-active&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // GATILHO COMPATÍVEL COM ANÓNIMOS: Executa em múltiplos estágios do carregamento&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
    mw.hook(&#039;wikipage.content&#039;).add(setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1914</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1914"/>
		<updated>2026-06-30T09:06:50Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// Força o MediaWiki a carregar os módulos básicos em qualquer tipo de sessão (anónima ou registada)&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    &lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        // Alvo exclusivo: Apenas o menu de navegação da skin, ignorando o índice de conteúdos (Contents) da página&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas apenas no menu lateral&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var text = $li.text().trim();&lt;br /&gt;
            &lt;br /&gt;
            // Verifica se apanha as subpáginas pelo URL ou pelo texto exato&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || text === &#039;Datasheet&#039; &lt;br /&gt;
                             || text === &#039;Release Notes&#039;;&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !text.includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS) na barra lateral&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // 3. Injeta a seta nativa se encontrar o link&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                $(this).toggleClass(&#039;is-active&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // GATILHO COMPATÍVEL COM ANÓNIMOS: Executa em múltiplos estágios do carregamento&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
    mw.hook(&#039;wikipage.content&#039;).add(setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1913</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1913"/>
		<updated>2026-06-30T09:02:56Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&amp;quot;);&lt;br /&gt;
@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&amp;quot;);&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Esconde as subpáginas */&lt;br /&gt;
.atlas-submenu {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    padding-left: 15px !important;&lt;br /&gt;
    font-size: 0.95em !important;&lt;br /&gt;
    opacity: 0.85;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atlas-submenu.is-open {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* O Segredo: Desenha a seta idêntica à do índice da Datasheet */&lt;br /&gt;
.atlas-toggle-btn {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 12px;&lt;br /&gt;
    height: 12px;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    /* Usa o SVG oficial do MediaWiki para garantir o mesmo design */&lt;br /&gt;
    background-image: url(data:image/svg+xml;utf8,&amp;lt;svg xmlns=&amp;quot;http://www.w3.org/2000/svg&amp;quot; width=&amp;quot;12&amp;quot; height=&amp;quot;12&amp;quot; viewBox=&amp;quot;0 0 12 12&amp;quot;&amp;gt;&amp;lt;path d=&amp;quot;M3.22 2.22a.75.75 0 011.06 0l3.5 3.5a.75.75 0 010 1.06l-3.5 3.5a.75.75 0 11-1.06-1.06L6.19 6 3.22 3.03a.75.75 0 010-1.06z&amp;quot; fill=&amp;quot;%2354595d&amp;quot;/&amp;gt;&amp;lt;/svg&amp;gt;);&lt;br /&gt;
    background-repeat: no-repeat;&lt;br /&gt;
    background-position: center;&lt;br /&gt;
    background-size: contain;&lt;br /&gt;
    transition: transform 0.2s ease-in-out;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Quando clicado (Aberto), roda para baixo igual à imagem image_5452b6.png */&lt;br /&gt;
.atlas-toggle-btn.is-active {&lt;br /&gt;
    transform: rotate(90deg);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   ÍNDICE LATERAL (TOC) - DESIGN FINAL REFINADO COM HOVER E ANIMAÇÃO RÁPIDA&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Oculta as sublistas por padrão */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Mostra a sublista quando expandido */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .vector-toc-list {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Posicionamento relativo das linhas do menu */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list-item {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Container do botão da seta (Área clicável com efeito Hover) */&lt;br /&gt;
.toc-toggle-arrow {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    left: -18px !important;    /* Ajuste para centralizar o quadrado do hover à esquerda */&lt;br /&gt;
    top: 3px !important;       /* Alinha perfeitamente ao centro da linha de texto */&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    cursor: pointer !important;&lt;br /&gt;
    width: 18px !important;    /* Tamanho do quadrado do hover */&lt;br /&gt;
    height: 18px !important;&lt;br /&gt;
    border-radius: 2px;        /* Cantos levemente suavizados para o quadrado */&lt;br /&gt;
    z-index: 50 !important;&lt;br /&gt;
    transition: background-color 0.1s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Quadrado cinza clarinho ao passar o rato */&lt;br /&gt;
.toc-toggle-arrow:hover {&lt;br /&gt;
    background-color: #e2e4e8 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. O Desenho da Seta (Estilo Chevron - Cor Preta Forte) */&lt;br /&gt;
.toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 5px;&lt;br /&gt;
    height: 5px;&lt;br /&gt;
    border-right: 1.5px solid #202122; /* Preto forte igual aos cabeçalhos da wiki */&lt;br /&gt;
    border-bottom: 1.5px solid #202122;&lt;br /&gt;
    transform: rotate(-45deg);         /* Aponta para a direita */&lt;br /&gt;
    transition: transform 0.1s ease-in-out; /* Animação ultra rápida */&lt;br /&gt;
    margin-left: -2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Rotação rápida quando o menu abre (roda para baixo) */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    transform: rotate(45deg) !important;&lt;br /&gt;
    margin-top: -2px;&lt;br /&gt;
    margin-left: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Indentação interna limpa para os subcapítulos */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    padding-left: 12px !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Proteção absoluta para o cabeçalho principal &amp;quot;Datasheet&amp;quot; */&lt;br /&gt;
.vector-toc-header .toc-toggle-arrow,&lt;br /&gt;
.vector-toc-title .toc-toggle-arrow,&lt;br /&gt;
#vector-toc-collapsed-button .toc-toggle-arrow {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    opacity: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Contentor do bloco de código */&lt;br /&gt;
.mw-highlight, .syntaxhighlight {&lt;br /&gt;
    position: relative; /* Necessário para o posicionamento do botão */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo do Botão Copy */&lt;br /&gt;
.copy-code-button {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 5px;&lt;br /&gt;
    right: 5px;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    padding: 4px 8px;&lt;br /&gt;
    background-color: #f8f9fa;&lt;br /&gt;
    border: 1px solid #a2a9b1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #202122;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.copy-code-button:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
    border-color: #447ff5;&lt;br /&gt;
    color: #447ff5;&lt;br /&gt;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTES RESPONSIVOS ATRONIA --- */&lt;br /&gt;
&lt;br /&gt;
@media only screen and (max-width: 768px) {&lt;br /&gt;
&lt;br /&gt;
    #custom-atronia-footer img[src*=&amp;quot;Igus.svg&amp;quot;] {&lt;br /&gt;
        max-width: 120px !important; /* Ajusta este valor (ex: 100px ou 120px) até gostares */&lt;br /&gt;
        margin-bottom: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 1. Forçar menus a empilhar no mobile */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;justify-content: space-between&amp;quot;] {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: flex-start !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 2. Grelha de Logos: Passa de 2 colunas para 1 no mobile para não esmagar */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;display: grid&amp;quot;] {&lt;br /&gt;
        grid-template-columns: 1fr !important; &lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 3. Logos: Garante que as imagens não saem do ecrã */&lt;br /&gt;
    #custom-atronia-footer img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 4. Botões Flutuantes: Evitar que tapem os logos no fundo */&lt;br /&gt;
    #atronia-floating-nav {&lt;br /&gt;
        bottom: 15px !important;&lt;br /&gt;
        right: 10px !important;&lt;br /&gt;
        transform: scale(0.85); /* Ficam ligeiramente menores */&lt;br /&gt;
        transform-origin: bottom right;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 5. Scrolling Text: Diminuir um pouco no mobile */&lt;br /&gt;
    .atronia-scrolling-container {&lt;br /&gt;
        height: 80px !important;&lt;br /&gt;
        line-height: 80px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Aplicar a fonte a todo o footer */&lt;br /&gt;
#custom-atronia-footer, &lt;br /&gt;
#custom-atronia-footer * {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
/* --- ESTRUTURA BASE --- */&lt;br /&gt;
#custom-atronia-footer {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    clear: both !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Scrolling Text Estilo &amp;quot;Vazado&amp;quot; */&lt;br /&gt;
.atronia-scrolling-container {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    padding: 20px 0;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    border-bottom: 1px solid #ffffff !important; /* Separador abaixo do scroll */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atronia-scrolling-content span {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif;&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: transparent !important; /* Mantém o interior vazio */&lt;br /&gt;
    -webkit-text-stroke: 1.5px #ffffff; /* Branco puro e um pouco mais grosso */&lt;br /&gt;
    opacity: 1 !important; /* Garante que o contorno não seja translúcido */&lt;br /&gt;
    padding-right: 50px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    letter-spacing: 1px; /* Melhora a leitura em letras vazadas */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes atronia-scroll {&lt;br /&gt;
    0% { transform: translateX(0); }&lt;br /&gt;
    100% { transform: translateX(-50%); }&lt;br /&gt;
}&lt;br /&gt;
.atronia-scrolling-content { display: inline-block; animation: atronia-scroll 15s linear infinite; }&lt;br /&gt;
&lt;br /&gt;
/* Esconder elementos nativos */&lt;br /&gt;
#footer, .mw-footer, #catlinks { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
/* Forçar underline no hover e limpar estilos nativos da Wiki */&lt;br /&gt;
#custom-atronia-footer a {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    background: none !important; /* Remove blocos de cor que a wiki possa inserir */&lt;br /&gt;
    transition: text-decoration 0.2s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#custom-atronia-footer a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Linha de largura total absoluta */&lt;br /&gt;
.atronia-full-width-line {&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    width: 100vw !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    right: 50% !important;&lt;br /&gt;
    margin-left: -50vw !important;&lt;br /&gt;
    margin-right: -50vw !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Fim do Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botão de Seta para o Topo */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important; /* Mesmo verde */&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    border-radius: 50% !important; /* Circular */&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    font-size: 20px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.footer-top-button:hover {&lt;br /&gt;
    transform: scale(1.1) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o container se alinha bem no mobile */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do botão Buy Now (MONARCH) - Alinhado à direita */&lt;br /&gt;
.buy-now-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    justify-content: right !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Estilo do Botão - Base e Centralização */&lt;br /&gt;
.button-buy-now a.external {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
&lt;br /&gt;
    background-color: #d1ff00 !important; /* Verde néon */&lt;br /&gt;
    color: #000 !important; /* Texto preto */&lt;br /&gt;
    &lt;br /&gt;
    /* PADDING IGUAL DOS DOIS LADOS (Essencial para centrar) */&lt;br /&gt;
    padding: 7px 25px !important; &lt;br /&gt;
    &lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
&lt;br /&gt;
    /* Remove a seta e o espaço fantasma do MediaWiki */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    text-indent: 0 !important;&lt;br /&gt;
    letter-spacing: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Forçar anulação de regras do sistema (mw-parser-output) */&lt;br /&gt;
.mw-parser-output .button-buy-now a.external {&lt;br /&gt;
    padding-right: 25px !important; /* Força a simetria com a esquerda */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Efeito ao passar o rato */&lt;br /&gt;
.button-buy-now a.external:hover {&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   RODAPÉ (Footer) - Versão Final Limpa&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do Rodapé - Permite que os itens respirem e alinhem */&lt;br /&gt;
#footer-places {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    flex-wrap: nowrap !important;&lt;br /&gt;
    padding: 10px 25px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Links da Esquerda (Privacy, About, etc) */&lt;br /&gt;
#footer-places li {&lt;br /&gt;
    margin-right: 15px !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. NOVO CONTENTOR DOS BOTÕES (Seta + Link) &lt;br /&gt;
   O &amp;quot;margin-left: auto&amp;quot; é o íman que empurra o grupo para a direita */&lt;br /&gt;
#footer-custom-buttons-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    gap: 12px !important; /* Espaço entre a seta e o botão */&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    margin-left: auto !important; &lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Estilo Comum para Seta e Botão (Cápsula Verde) */&lt;br /&gt;
.footer-top-button,&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important;&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: all 0.2s ease-in-out !important;&lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. Especificações da Seta (Circular) */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    font-size: 18px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Especificações do Botão do Site */&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    padding: 7px 25px !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    white-space: nowrap !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Hover para os dois */&lt;br /&gt;
.footer-top-button:hover,&lt;br /&gt;
.footer-button-atronia-real:hover {&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Remover ícones de link externo do MediaWiki */&lt;br /&gt;
.footer-button-atronia-real.external,&lt;br /&gt;
.footer-button-atronia-real.external:after {&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 25px !important; /* Mantém igual à esquerda para centrar */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTE PARA MOBILE (Ecrãs até 720px) --- */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-places {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: center !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    #footer-places li {&lt;br /&gt;
        margin-right: 0 !important;&lt;br /&gt;
        margin-bottom: 10px !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* No mobile, os botões ficam centrados em baixo dos textos */&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        margin-left: 0 !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Destacar o item principal ativo */&lt;br /&gt;
.vector-toc-list-item-active &amp;gt; .vector-toc-link .vector-toc-text {&lt;br /&gt;
    font-weight: 700 !important; /* Força o negrito máximo */&lt;br /&gt;
    color: #000000 !important;   /* Cor preta forte para contraste */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Remove qualquer preenchimento extra de tags pre ou code que a wiki insira */&lt;br /&gt;
.variations-toggle pre,&lt;br /&gt;
.variations-toggle code {&lt;br /&gt;
  display: contents !important;&lt;br /&gt;
  background: none !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
  display: inline-flex; /* important */&lt;br /&gt;
  align-items: center; /* vertical centering */&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
&lt;br /&gt;
  width: 24px; /* lock size */&lt;br /&gt;
  height: 24px;&lt;br /&gt;
&lt;br /&gt;
  line-height: 1; /* remove font baseline weirdness */&lt;br /&gt;
&lt;br /&gt;
  transition: transform 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
.arrow-icon.rotated {&lt;br /&gt;
    transform: rotate(180deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esta regra garante transição suave mesmo se o MediaWiki interferir */&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
    transition: transform 0.25s ease-in-out !important;&lt;br /&gt;
    transform-origin: center center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.variations-list &amp;gt; pre,&lt;br /&gt;
.variations-toggle &amp;gt; pre {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.mw-highlight &amp;gt; pre {&lt;br /&gt;
  margin: 1em 0;&lt;br /&gt;
  padding: 12px 16px;&lt;br /&gt;
  background-color: #f6f6f6; /* restore */&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
&lt;br /&gt;
  overflow-x: auto;&lt;br /&gt;
  white-space: pre;&lt;br /&gt;
&lt;br /&gt;
  font-family: &amp;quot;Roboto Mono&amp;quot;, monospace;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  line-height: 1.5;&lt;br /&gt;
&lt;br /&gt;
  display: block; /* IMPORTANT */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  margin: 0;&lt;br /&gt;
  padding: 0;&lt;br /&gt;
  padding-top: 1rem;&lt;br /&gt;
  background-color: transparent;&lt;br /&gt;
  border: transparent;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: space-around;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Limpeza profunda do collapsible na grelha de produtos */&lt;br /&gt;
.product-item .mw-collapsible {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item .mw-collapsible-content {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove o ícone padrão de &amp;quot;seta&amp;quot; ou [Expandir] que o MediaWiki cria */&lt;br /&gt;
.product-item .mw-collapsible-toggle {&lt;br /&gt;
  float: none !important;&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esconde o link automático de texto que o MediaWiki pode injetar */&lt;br /&gt;
.product-item .mw-collapsible-toggle-default {&lt;br /&gt;
  display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-dropdown-checkbox {&lt;br /&gt;
  background-color: red !important;&lt;br /&gt;
  color: red !important;&lt;br /&gt;
}&lt;br /&gt;
.products-grid {&lt;br /&gt;
  display: grid;&lt;br /&gt;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));&lt;br /&gt;
  gap: 30px;&lt;br /&gt;
  margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-image {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 0 auto 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-title {&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
  margin-top: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  color: #666;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item strong {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Garante que o título do Datasheet e outros itens mantenham a consistência */&lt;br /&gt;
.vector-toc-link .vector-toc-text {&lt;br /&gt;
  font-weight: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Botão Técnico Atlas - Cores Customizadas */&lt;br /&gt;
.mw-parser-output .atlas-btn {&lt;br /&gt;
  display: inline-block !important;&lt;br /&gt;
  padding: 10px 22px !important;&lt;br /&gt;
  background-color: #1b2826 !important; /* Cor base escura */&lt;br /&gt;
  border: 1px solid #1b2826 !important;&lt;br /&gt;
  border-radius: 4px !important;&lt;br /&gt;
  transition: all 0.25s ease !important;&lt;br /&gt;
  cursor: pointer !important;&lt;br /&gt;
  text-align: center !important;&lt;br /&gt;
  border-bottom: 1px solid #1b2826 !important; /* Remove qualquer traço de link */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Link dentro do botão - Forçar branco em todos os estados*/&lt;br /&gt;
.mw-parser-output .atlas-btn a,&lt;br /&gt;
.mw-parser-output .atlas-btn a:link,&lt;br /&gt;
.mw-parser-output .atlas-btn a:visited,&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover,&lt;br /&gt;
.mw-parser-output .atlas-btn a:active {&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  font-weight: bold !important;&lt;br /&gt;
  font-size: 0.95em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Versão levemente mais clara */&lt;br /&gt;
.mw-parser-output .atlas-btn:hover {&lt;br /&gt;
  background-color: #3e524f !important; /* Tom mais claro */&lt;br /&gt;
  border-color: #2a3b38 !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* Sombra leve para profundidade */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o link não mude de cor ou sublinhe no hover */&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover {&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Forçar a fonte Rubik no título principal */&lt;br /&gt;
#firstHeading {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-weight: 600 !important;&lt;br /&gt;
  color: #202122 !important;&lt;br /&gt;
  letter-spacing: -0.01em !important;&lt;br /&gt;
  /* Removemos a nossa borda manual para usar apenas a da Wiki */&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  margin-bottom: 0 !important;&lt;br /&gt;
  padding-bottom: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o breadcrumb (&amp;lt; SENSBLUE ATLAS) também use a Rubik */&lt;br /&gt;
#contentSub,&lt;br /&gt;
#contentSub2 {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-size: 0.85em !important;&lt;br /&gt;
  color: #54595d !important;&lt;br /&gt;
  margin-top: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, sans-serif !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1912</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1912"/>
		<updated>2026-06-30T09:02:36Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria o elemento do botão (vazio, pois o CSS vai colocar a imagem idêntica à Datasheet)&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Coloca do lado direito&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                // Abre/fecha o menu e roda a seta ao mesmo tempo via CSS&lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                $(this).toggleClass(&#039;is-active&#039;);&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1911</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1911"/>
		<updated>2026-06-30T09:00:29Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria o chevron (com margem à esquerda para dar o espaço correto)&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none; font-weight:bold; font-size:1.1em; color:#54595d;&amp;quot;&amp;gt;›&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Injeta DEPOIS do texto (à direita)&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;›&#039;) {&lt;br /&gt;
                    $(this).text(&#039;˅&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;›&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1910</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1910"/>
		<updated>2026-06-30T08:59:53Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria o chevron inicial fechado (›)&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-right:8px; user-select:none; font-weight:bold; font-size:1.1em; color:#54595d;&amp;quot;&amp;gt;›&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Injeta à esquerda&lt;br /&gt;
            $mainAtlasLi.prepend($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                // Alterna entre o chevron para a direita (›) e para baixo (˅)&lt;br /&gt;
                if ($(this).text() === &#039;›&#039;) {&lt;br /&gt;
                    $(this).text(&#039;˅&#039;); // Igual ao formato de image_4a7113.png&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;›&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1909</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1909"/>
		<updated>2026-06-30T08:59:32Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&amp;quot;);&lt;br /&gt;
@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&amp;quot;);&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Esconde as subpáginas do Atlas por defeito */&lt;br /&gt;
.atlas-submenu {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    padding-left: 22px !important; /* Alinha o texto das subpáginas com o título principal */&lt;br /&gt;
    font-size: 0.95em !important;&lt;br /&gt;
    opacity: 0.85;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Mostra as subpáginas quando o menu estiver aberto */&lt;br /&gt;
.atlas-submenu.is-open {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Ajusta o tamanho e o alinhamento vertical do chevron */&lt;br /&gt;
.atlas-toggle-btn {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    line-height: 1;&lt;br /&gt;
    vertical-align: middle;&lt;br /&gt;
    margin-top: -2px; /* Pequeno ajuste para centrar com o texto */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   ÍNDICE LATERAL (TOC) - DESIGN FINAL REFINADO COM HOVER E ANIMAÇÃO RÁPIDA&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Oculta as sublistas por padrão */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Mostra a sublista quando expandido */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .vector-toc-list {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Posicionamento relativo das linhas do menu */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list-item {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Container do botão da seta (Área clicável com efeito Hover) */&lt;br /&gt;
.toc-toggle-arrow {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    left: -18px !important;    /* Ajuste para centralizar o quadrado do hover à esquerda */&lt;br /&gt;
    top: 3px !important;       /* Alinha perfeitamente ao centro da linha de texto */&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    cursor: pointer !important;&lt;br /&gt;
    width: 18px !important;    /* Tamanho do quadrado do hover */&lt;br /&gt;
    height: 18px !important;&lt;br /&gt;
    border-radius: 2px;        /* Cantos levemente suavizados para o quadrado */&lt;br /&gt;
    z-index: 50 !important;&lt;br /&gt;
    transition: background-color 0.1s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Quadrado cinza clarinho ao passar o rato */&lt;br /&gt;
.toc-toggle-arrow:hover {&lt;br /&gt;
    background-color: #e2e4e8 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. O Desenho da Seta (Estilo Chevron - Cor Preta Forte) */&lt;br /&gt;
.toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 5px;&lt;br /&gt;
    height: 5px;&lt;br /&gt;
    border-right: 1.5px solid #202122; /* Preto forte igual aos cabeçalhos da wiki */&lt;br /&gt;
    border-bottom: 1.5px solid #202122;&lt;br /&gt;
    transform: rotate(-45deg);         /* Aponta para a direita */&lt;br /&gt;
    transition: transform 0.1s ease-in-out; /* Animação ultra rápida */&lt;br /&gt;
    margin-left: -2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Rotação rápida quando o menu abre (roda para baixo) */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    transform: rotate(45deg) !important;&lt;br /&gt;
    margin-top: -2px;&lt;br /&gt;
    margin-left: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Indentação interna limpa para os subcapítulos */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    padding-left: 12px !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Proteção absoluta para o cabeçalho principal &amp;quot;Datasheet&amp;quot; */&lt;br /&gt;
.vector-toc-header .toc-toggle-arrow,&lt;br /&gt;
.vector-toc-title .toc-toggle-arrow,&lt;br /&gt;
#vector-toc-collapsed-button .toc-toggle-arrow {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    opacity: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Contentor do bloco de código */&lt;br /&gt;
.mw-highlight, .syntaxhighlight {&lt;br /&gt;
    position: relative; /* Necessário para o posicionamento do botão */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo do Botão Copy */&lt;br /&gt;
.copy-code-button {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 5px;&lt;br /&gt;
    right: 5px;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    padding: 4px 8px;&lt;br /&gt;
    background-color: #f8f9fa;&lt;br /&gt;
    border: 1px solid #a2a9b1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #202122;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.copy-code-button:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
    border-color: #447ff5;&lt;br /&gt;
    color: #447ff5;&lt;br /&gt;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTES RESPONSIVOS ATRONIA --- */&lt;br /&gt;
&lt;br /&gt;
@media only screen and (max-width: 768px) {&lt;br /&gt;
&lt;br /&gt;
    #custom-atronia-footer img[src*=&amp;quot;Igus.svg&amp;quot;] {&lt;br /&gt;
        max-width: 120px !important; /* Ajusta este valor (ex: 100px ou 120px) até gostares */&lt;br /&gt;
        margin-bottom: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 1. Forçar menus a empilhar no mobile */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;justify-content: space-between&amp;quot;] {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: flex-start !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 2. Grelha de Logos: Passa de 2 colunas para 1 no mobile para não esmagar */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;display: grid&amp;quot;] {&lt;br /&gt;
        grid-template-columns: 1fr !important; &lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 3. Logos: Garante que as imagens não saem do ecrã */&lt;br /&gt;
    #custom-atronia-footer img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 4. Botões Flutuantes: Evitar que tapem os logos no fundo */&lt;br /&gt;
    #atronia-floating-nav {&lt;br /&gt;
        bottom: 15px !important;&lt;br /&gt;
        right: 10px !important;&lt;br /&gt;
        transform: scale(0.85); /* Ficam ligeiramente menores */&lt;br /&gt;
        transform-origin: bottom right;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 5. Scrolling Text: Diminuir um pouco no mobile */&lt;br /&gt;
    .atronia-scrolling-container {&lt;br /&gt;
        height: 80px !important;&lt;br /&gt;
        line-height: 80px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Aplicar a fonte a todo o footer */&lt;br /&gt;
#custom-atronia-footer, &lt;br /&gt;
#custom-atronia-footer * {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
/* --- ESTRUTURA BASE --- */&lt;br /&gt;
#custom-atronia-footer {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    clear: both !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Scrolling Text Estilo &amp;quot;Vazado&amp;quot; */&lt;br /&gt;
.atronia-scrolling-container {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    padding: 20px 0;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    border-bottom: 1px solid #ffffff !important; /* Separador abaixo do scroll */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atronia-scrolling-content span {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif;&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: transparent !important; /* Mantém o interior vazio */&lt;br /&gt;
    -webkit-text-stroke: 1.5px #ffffff; /* Branco puro e um pouco mais grosso */&lt;br /&gt;
    opacity: 1 !important; /* Garante que o contorno não seja translúcido */&lt;br /&gt;
    padding-right: 50px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    letter-spacing: 1px; /* Melhora a leitura em letras vazadas */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes atronia-scroll {&lt;br /&gt;
    0% { transform: translateX(0); }&lt;br /&gt;
    100% { transform: translateX(-50%); }&lt;br /&gt;
}&lt;br /&gt;
.atronia-scrolling-content { display: inline-block; animation: atronia-scroll 15s linear infinite; }&lt;br /&gt;
&lt;br /&gt;
/* Esconder elementos nativos */&lt;br /&gt;
#footer, .mw-footer, #catlinks { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
/* Forçar underline no hover e limpar estilos nativos da Wiki */&lt;br /&gt;
#custom-atronia-footer a {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    background: none !important; /* Remove blocos de cor que a wiki possa inserir */&lt;br /&gt;
    transition: text-decoration 0.2s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#custom-atronia-footer a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Linha de largura total absoluta */&lt;br /&gt;
.atronia-full-width-line {&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    width: 100vw !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    right: 50% !important;&lt;br /&gt;
    margin-left: -50vw !important;&lt;br /&gt;
    margin-right: -50vw !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Fim do Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botão de Seta para o Topo */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important; /* Mesmo verde */&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    border-radius: 50% !important; /* Circular */&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    font-size: 20px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.footer-top-button:hover {&lt;br /&gt;
    transform: scale(1.1) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o container se alinha bem no mobile */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do botão Buy Now (MONARCH) - Alinhado à direita */&lt;br /&gt;
.buy-now-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    justify-content: right !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Estilo do Botão - Base e Centralização */&lt;br /&gt;
.button-buy-now a.external {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
&lt;br /&gt;
    background-color: #d1ff00 !important; /* Verde néon */&lt;br /&gt;
    color: #000 !important; /* Texto preto */&lt;br /&gt;
    &lt;br /&gt;
    /* PADDING IGUAL DOS DOIS LADOS (Essencial para centrar) */&lt;br /&gt;
    padding: 7px 25px !important; &lt;br /&gt;
    &lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
&lt;br /&gt;
    /* Remove a seta e o espaço fantasma do MediaWiki */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    text-indent: 0 !important;&lt;br /&gt;
    letter-spacing: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Forçar anulação de regras do sistema (mw-parser-output) */&lt;br /&gt;
.mw-parser-output .button-buy-now a.external {&lt;br /&gt;
    padding-right: 25px !important; /* Força a simetria com a esquerda */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Efeito ao passar o rato */&lt;br /&gt;
.button-buy-now a.external:hover {&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   RODAPÉ (Footer) - Versão Final Limpa&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do Rodapé - Permite que os itens respirem e alinhem */&lt;br /&gt;
#footer-places {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    flex-wrap: nowrap !important;&lt;br /&gt;
    padding: 10px 25px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Links da Esquerda (Privacy, About, etc) */&lt;br /&gt;
#footer-places li {&lt;br /&gt;
    margin-right: 15px !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. NOVO CONTENTOR DOS BOTÕES (Seta + Link) &lt;br /&gt;
   O &amp;quot;margin-left: auto&amp;quot; é o íman que empurra o grupo para a direita */&lt;br /&gt;
#footer-custom-buttons-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    gap: 12px !important; /* Espaço entre a seta e o botão */&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    margin-left: auto !important; &lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Estilo Comum para Seta e Botão (Cápsula Verde) */&lt;br /&gt;
.footer-top-button,&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important;&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: all 0.2s ease-in-out !important;&lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. Especificações da Seta (Circular) */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    font-size: 18px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Especificações do Botão do Site */&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    padding: 7px 25px !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    white-space: nowrap !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Hover para os dois */&lt;br /&gt;
.footer-top-button:hover,&lt;br /&gt;
.footer-button-atronia-real:hover {&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Remover ícones de link externo do MediaWiki */&lt;br /&gt;
.footer-button-atronia-real.external,&lt;br /&gt;
.footer-button-atronia-real.external:after {&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 25px !important; /* Mantém igual à esquerda para centrar */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTE PARA MOBILE (Ecrãs até 720px) --- */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-places {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: center !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    #footer-places li {&lt;br /&gt;
        margin-right: 0 !important;&lt;br /&gt;
        margin-bottom: 10px !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* No mobile, os botões ficam centrados em baixo dos textos */&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        margin-left: 0 !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Destacar o item principal ativo */&lt;br /&gt;
.vector-toc-list-item-active &amp;gt; .vector-toc-link .vector-toc-text {&lt;br /&gt;
    font-weight: 700 !important; /* Força o negrito máximo */&lt;br /&gt;
    color: #000000 !important;   /* Cor preta forte para contraste */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Remove qualquer preenchimento extra de tags pre ou code que a wiki insira */&lt;br /&gt;
.variations-toggle pre,&lt;br /&gt;
.variations-toggle code {&lt;br /&gt;
  display: contents !important;&lt;br /&gt;
  background: none !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
  display: inline-flex; /* important */&lt;br /&gt;
  align-items: center; /* vertical centering */&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
&lt;br /&gt;
  width: 24px; /* lock size */&lt;br /&gt;
  height: 24px;&lt;br /&gt;
&lt;br /&gt;
  line-height: 1; /* remove font baseline weirdness */&lt;br /&gt;
&lt;br /&gt;
  transition: transform 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
.arrow-icon.rotated {&lt;br /&gt;
    transform: rotate(180deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esta regra garante transição suave mesmo se o MediaWiki interferir */&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
    transition: transform 0.25s ease-in-out !important;&lt;br /&gt;
    transform-origin: center center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.variations-list &amp;gt; pre,&lt;br /&gt;
.variations-toggle &amp;gt; pre {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.mw-highlight &amp;gt; pre {&lt;br /&gt;
  margin: 1em 0;&lt;br /&gt;
  padding: 12px 16px;&lt;br /&gt;
  background-color: #f6f6f6; /* restore */&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
&lt;br /&gt;
  overflow-x: auto;&lt;br /&gt;
  white-space: pre;&lt;br /&gt;
&lt;br /&gt;
  font-family: &amp;quot;Roboto Mono&amp;quot;, monospace;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  line-height: 1.5;&lt;br /&gt;
&lt;br /&gt;
  display: block; /* IMPORTANT */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  margin: 0;&lt;br /&gt;
  padding: 0;&lt;br /&gt;
  padding-top: 1rem;&lt;br /&gt;
  background-color: transparent;&lt;br /&gt;
  border: transparent;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: space-around;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Limpeza profunda do collapsible na grelha de produtos */&lt;br /&gt;
.product-item .mw-collapsible {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item .mw-collapsible-content {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove o ícone padrão de &amp;quot;seta&amp;quot; ou [Expandir] que o MediaWiki cria */&lt;br /&gt;
.product-item .mw-collapsible-toggle {&lt;br /&gt;
  float: none !important;&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esconde o link automático de texto que o MediaWiki pode injetar */&lt;br /&gt;
.product-item .mw-collapsible-toggle-default {&lt;br /&gt;
  display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-dropdown-checkbox {&lt;br /&gt;
  background-color: red !important;&lt;br /&gt;
  color: red !important;&lt;br /&gt;
}&lt;br /&gt;
.products-grid {&lt;br /&gt;
  display: grid;&lt;br /&gt;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));&lt;br /&gt;
  gap: 30px;&lt;br /&gt;
  margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-image {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 0 auto 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-title {&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
  margin-top: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  color: #666;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item strong {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Garante que o título do Datasheet e outros itens mantenham a consistência */&lt;br /&gt;
.vector-toc-link .vector-toc-text {&lt;br /&gt;
  font-weight: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Botão Técnico Atlas - Cores Customizadas */&lt;br /&gt;
.mw-parser-output .atlas-btn {&lt;br /&gt;
  display: inline-block !important;&lt;br /&gt;
  padding: 10px 22px !important;&lt;br /&gt;
  background-color: #1b2826 !important; /* Cor base escura */&lt;br /&gt;
  border: 1px solid #1b2826 !important;&lt;br /&gt;
  border-radius: 4px !important;&lt;br /&gt;
  transition: all 0.25s ease !important;&lt;br /&gt;
  cursor: pointer !important;&lt;br /&gt;
  text-align: center !important;&lt;br /&gt;
  border-bottom: 1px solid #1b2826 !important; /* Remove qualquer traço de link */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Link dentro do botão - Forçar branco em todos os estados*/&lt;br /&gt;
.mw-parser-output .atlas-btn a,&lt;br /&gt;
.mw-parser-output .atlas-btn a:link,&lt;br /&gt;
.mw-parser-output .atlas-btn a:visited,&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover,&lt;br /&gt;
.mw-parser-output .atlas-btn a:active {&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  font-weight: bold !important;&lt;br /&gt;
  font-size: 0.95em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Versão levemente mais clara */&lt;br /&gt;
.mw-parser-output .atlas-btn:hover {&lt;br /&gt;
  background-color: #3e524f !important; /* Tom mais claro */&lt;br /&gt;
  border-color: #2a3b38 !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* Sombra leve para profundidade */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o link não mude de cor ou sublinhe no hover */&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover {&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Forçar a fonte Rubik no título principal */&lt;br /&gt;
#firstHeading {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-weight: 600 !important;&lt;br /&gt;
  color: #202122 !important;&lt;br /&gt;
  letter-spacing: -0.01em !important;&lt;br /&gt;
  /* Removemos a nossa borda manual para usar apenas a da Wiki */&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  margin-bottom: 0 !important;&lt;br /&gt;
  padding-bottom: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o breadcrumb (&amp;lt; SENSBLUE ATLAS) também use a Rubik */&lt;br /&gt;
#contentSub,&lt;br /&gt;
#contentSub2 {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-size: 0.85em !important;&lt;br /&gt;
  color: #54595d !important;&lt;br /&gt;
  margin-top: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, sans-serif !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1908</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1908"/>
		<updated>2026-06-30T08:56:44Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039; // Move tudo para a esquerda juntinho&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta colada ao texto&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none; font-weight:bold;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1907</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1907"/>
		<updated>2026-06-30T08:56:07Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            // Força o item da lista a alinhar à esquerda&lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // Força o link/texto interno a não expandir para 100%&lt;br /&gt;
            $mainAtlasLi.find(&#039;a, .mw-selflink, span&#039;).css({&lt;br /&gt;
                &#039;display&#039;: &#039;inline&#039;,&lt;br /&gt;
                &#039;width&#039;: &#039;auto&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta (com margem à direita para empurrar o texto)&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-right:8px; user-select:none; font-weight:bold;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Injeta ANTES do texto (à esquerda)&lt;br /&gt;
            $mainAtlasLi.prepend($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1906</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1906"/>
		<updated>2026-06-30T08:55:12Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;flex-start&#039; // Move tudo para a esquerda juntinho&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta colada ao texto&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none; font-weight:bold;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn); &lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1905</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1905"/>
		<updated>2026-06-30T08:53:14Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Identifica e esconde as subpáginas (procura por links ou links ativos que contenham a barra /)&lt;br /&gt;
        $sidebar.find(&#039;li&#039;).each(function() {&lt;br /&gt;
            var $li = $(this);&lt;br /&gt;
            var hasSubpage = $li.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;], .mw-selflink[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).length &amp;gt; 0 &lt;br /&gt;
                             || $li.text().includes(&#039;Datasheet&#039;) &lt;br /&gt;
                             || $li.text().includes(&#039;Release Notes&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Garante que não apanha a página principal&lt;br /&gt;
            if (hasSubpage &amp;amp;&amp;amp; !$li.text().includes(&#039;SENSBLUE ATLAS&#039;)) {&lt;br /&gt;
                $li.addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura o item pai (SENSBLUE ATLAS) pelo texto, independentemente de ser link ou texto estático&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;li&#039;).filter(function() {&lt;br /&gt;
            var text = $(this).clone().children().remove().end().text().trim() || $(this).text().trim();&lt;br /&gt;
            return text === &#039;SENSBLUE ATLAS&#039;;&lt;br /&gt;
        }).first();&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;space-between&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none; font-weight:bold;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn);&lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1904</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1904"/>
		<updated>2026-06-30T08:51:27Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Esconde as subpáginas (procura por qualquer link que tenha a subpágina no URL)&lt;br /&gt;
        $sidebar.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).closest(&#039;li&#039;).addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura a página principal do Atlas (procura se o URL CONTÉM SENSBLUE_ATLAS mas NÃO contém a barra da subpágina)&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS&amp;quot;]&#039;).filter(function() {&lt;br /&gt;
            return !$(this).attr(&#039;href&#039;).includes(&#039;SENSBLUE_ATLAS/&#039;);&lt;br /&gt;
        }).closest(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn);&lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1903</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1903"/>
		<updated>2026-06-30T08:49:51Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.loader.using([&#039;mediawiki.util&#039;, &#039;jquery&#039;], function () {&lt;br /&gt;
    // Função principal que injeta a lógica do dropdown&lt;br /&gt;
    function setupAtlasDropdown() {&lt;br /&gt;
        // Encontra o menu lateral do Vector 2022&lt;br /&gt;
        var $sidebar = $(&#039;.vector-main-menu, #mw-panel, .mw-table-of-contents-container&#039;);&lt;br /&gt;
        if (!$sidebar.length) return;&lt;br /&gt;
&lt;br /&gt;
        // 1. Esconde as subpáginas aplicando a classe CSS&lt;br /&gt;
        $sidebar.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).closest(&#039;li&#039;).addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
&lt;br /&gt;
        // 2. Procura a página principal do Atlas&lt;br /&gt;
        var $mainAtlasLi = $sidebar.find(&#039;a[href$=&amp;quot;SENSBLUE_ATLAS&amp;quot;]&#039;).closest(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
        // Se encontrou e ainda não tem a seta injetada&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            &lt;br /&gt;
            // Garante que o texto e a seta ficam alinhados na mesma linha&lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria a seta&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn);&lt;br /&gt;
&lt;br /&gt;
            // 4. Evento do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                // Abre/fecha as subpáginas&lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                // Roda a seta&lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // Executa imediatamente e também se houver mudanças na página&lt;br /&gt;
    $(document).ready(setupAtlasDropdown);&lt;br /&gt;
    $(window).on(&#039;load&#039;, setupAtlasDropdown);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1902</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1902"/>
		<updated>2026-06-30T08:48:54Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
mw.hook(&#039;wikipage.content&#039;).add(function() {&lt;br /&gt;
    // Garante que o menu lateral do Vector já existe no HTML&lt;br /&gt;
    var $menu = $(&#039;.mw-table-of-contents-container, .vector-main-menu, #mw-panel&#039;);&lt;br /&gt;
    &lt;br /&gt;
    if ($menu.length) {&lt;br /&gt;
        // 1. Procura as subpáginas e adiciona a classe para esconder&lt;br /&gt;
        $menu.find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;).closest(&#039;li&#039;).addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
&lt;br /&gt;
        // 2. Encontra o link principal do Atlas (garantindo que não adiciona duplicados)&lt;br /&gt;
        var $mainAtlasLi = $menu.find(&#039;a[href$=&amp;quot;SENSBLUE_ATLAS&amp;quot;]&#039;).closest(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
        if ($mainAtlasLi.length &amp;amp;&amp;amp; !$mainAtlasLi.find(&#039;.atlas-toggle-btn&#039;).length) {&lt;br /&gt;
            // Ajusta o alinhamento para a seta ficar ao lado&lt;br /&gt;
            $mainAtlasLi.css({&lt;br /&gt;
                &#039;display&#039;: &#039;flex&#039;,&lt;br /&gt;
                &#039;align-items&#039;: &#039;center&#039;,&lt;br /&gt;
                &#039;justify-content&#039;: &#039;间的&#039;&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
            // 3. Cria e injeta a seta&lt;br /&gt;
            var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot; style=&amp;quot;cursor:pointer; margin-left:8px; user-select:none;&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
            $mainAtlasLi.append($toggleBtn);&lt;br /&gt;
&lt;br /&gt;
            // 4. Lógica do clique&lt;br /&gt;
            $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
                e.preventDefault();&lt;br /&gt;
                e.stopPropagation();&lt;br /&gt;
                &lt;br /&gt;
                $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
                &lt;br /&gt;
                if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                    $(this).text(&#039;▼&#039;);&lt;br /&gt;
                } else {&lt;br /&gt;
                    $(this).text(&#039;▶&#039;);&lt;br /&gt;
                }&lt;br /&gt;
            });&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1901</id>
		<title>MediaWiki:Common.js</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.js&amp;diff=1901"/>
		<updated>2026-06-30T08:47:04Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Any JavaScript here will be loaded for all users on every page load. */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(document).ready(function() {&lt;br /&gt;
    // 1. Procura todas as subpáginas do Atlas no menu lateral e esconde-as&lt;br /&gt;
    $(&#039;.mw-table-of-contents-container, .vector-main-menu&#039;)&lt;br /&gt;
        .find(&#039;a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;]&#039;)&lt;br /&gt;
        .closest(&#039;li&#039;)&lt;br /&gt;
        .addClass(&#039;atlas-submenu&#039;);&lt;br /&gt;
&lt;br /&gt;
    // 2. Encontra o item de lista (li) que contém o link principal do Atlas&lt;br /&gt;
    var $mainAtlasLi = $(&#039;.mw-table-of-contents-container, .vector-main-menu&#039;)&lt;br /&gt;
        .find(&#039;a[href$=&amp;quot;SENSBLUE_ATLAS&amp;quot;]&#039;)&lt;br /&gt;
        .closest(&#039;li&#039;);&lt;br /&gt;
&lt;br /&gt;
    if ($mainAtlasLi.length) {&lt;br /&gt;
        // Alinha o conteúdo original para podermos meter a seta ao lado&lt;br /&gt;
        $mainAtlasLi.css(&#039;display&#039;, &#039;flex&#039;).css(&#039;align-items&#039;, &#039;center&#039;);&lt;br /&gt;
&lt;br /&gt;
        // 3. Injeta a seta ao lado do link principal&lt;br /&gt;
        var $toggleBtn = $(&#039;&amp;lt;span class=&amp;quot;atlas-toggle-btn&amp;quot;&amp;gt;▶&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
        $mainAtlasLi.append($toggleBtn);&lt;br /&gt;
&lt;br /&gt;
        // 4. Lógica de clique para abrir/fechar&lt;br /&gt;
        $toggleBtn.on(&#039;click&#039;, function(e) {&lt;br /&gt;
            e.preventDefault();&lt;br /&gt;
            e.stopPropagation();&lt;br /&gt;
            &lt;br /&gt;
            // Abre ou fecha o submenu&lt;br /&gt;
            $(&#039;.atlas-submenu&#039;).toggleClass(&#039;is-open&#039;);&lt;br /&gt;
            &lt;br /&gt;
            // Alterna o símbolo da seta&lt;br /&gt;
            if ($(this).text() === &#039;▶&#039;) {&lt;br /&gt;
                $(this).text(&#039;▼&#039;);&lt;br /&gt;
            } else {&lt;br /&gt;
                $(this).text(&#039;▶&#039;);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
// CONTROLADOR DE DROPDOWN NO ÍNDICE (TOC) - VERSÃO VISUAL FINAL&lt;br /&gt;
// ==========================================================================&lt;br /&gt;
    &lt;br /&gt;
    $(&#039;.vector-toc-contents .vector-toc-list .vector-toc-list-item&#039;).each(function() {&lt;br /&gt;
        var $listItem = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Proteção total ao cabeçalho global&lt;br /&gt;
        if ($listItem.find(&#039;.vector-toc-title, #vector-toc-collapsed-button, .vector-toc-header&#039;).length &amp;gt; 0 || $listItem.hasClass(&#039;vector-toc-title&#039;)) {&lt;br /&gt;
            return;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        var $subList = $listItem.children(&#039;.vector-toc-list, ul&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Só injeta o botão se contiver subcapítulos&lt;br /&gt;
        if ($subList.length &amp;gt; 0 &amp;amp;&amp;amp; $subList.children(&#039;.vector-toc-list-item, li&#039;).length &amp;gt; 0) {&lt;br /&gt;
            &lt;br /&gt;
            if ($listItem.children(&#039;.toc-toggle-arrow&#039;).length === 0) {&lt;br /&gt;
                // Injeta o container da seta preparado para renderizar o SVG do CSS&lt;br /&gt;
                var $arrow = $(&#039;&amp;lt;span class=&amp;quot;toc-toggle-arrow&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;arrow-icon&amp;quot;&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;);&lt;br /&gt;
                &lt;br /&gt;
                $arrow.click(function(e) {&lt;br /&gt;
                    e.preventDefault();&lt;br /&gt;
                    e.stopPropagation();&lt;br /&gt;
                    $listItem.toggleClass(&#039;toc-expanded&#039;);&lt;br /&gt;
                });&lt;br /&gt;
                &lt;br /&gt;
                $listItem.prepend($arrow);&lt;br /&gt;
            }&lt;br /&gt;
        }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 2. LÓGICA DA SETA (ALL MODELS)&lt;br /&gt;
    // Deteta o clique no contentor nativo do MediaWiki que criaste&lt;br /&gt;
    $(&#039;.variations-toggle&#039;).css(&#039;cursor&#039;, &#039;pointer&#039;).click(function() {&lt;br /&gt;
        // Encontra a seta com a classe .arrow-icon dentro do bloco clicado&lt;br /&gt;
        var $arrow = $(this).find(&#039;.arrow-icon&#039;);&lt;br /&gt;
        &lt;br /&gt;
        // Alterna a classe de rotação configurada no CSS&lt;br /&gt;
        $arrow.toggleClass(&#039;rotated&#039;);&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    // Procura apenas por blocos de código técnicos e ignora a área de produtos&lt;br /&gt;
    $(&#039;.mw-highlight pre, .syntaxhighlight pre, pre.mw-code-example&#039;).each(function() {&lt;br /&gt;
        var $this = $(this);&lt;br /&gt;
        &lt;br /&gt;
        // Verifica se o elemento já tem um botão para não duplicar&lt;br /&gt;
        if ($this.parent().find(&#039;.copy-code-button&#039;).length &amp;gt; 0) return;&lt;br /&gt;
&lt;br /&gt;
        var $button = $(&#039;&amp;lt;button&amp;gt;&#039;)&lt;br /&gt;
            .text(&#039;Copy&#039;)&lt;br /&gt;
            .addClass(&#039;copy-code-button&#039;)&lt;br /&gt;
            .click(function() {&lt;br /&gt;
                var text = $this.text();&lt;br /&gt;
                navigator.clipboard.writeText(text).then(function() {&lt;br /&gt;
                    $button.text(&#039;Copied!&#039;);&lt;br /&gt;
                    setTimeout(function() { $button.text(&#039;Copy&#039;); }, 2000);&lt;br /&gt;
                });&lt;br /&gt;
            });&lt;br /&gt;
&lt;br /&gt;
        // Insere o botão antes do bloco de código&lt;br /&gt;
        $this.before($button);&lt;br /&gt;
    });&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*FOOTER*/&lt;br /&gt;
&lt;br /&gt;
$(function() {&lt;br /&gt;
    var imgBase = &amp;quot;https://wiki.atronia.eu/images/&amp;quot;;&lt;br /&gt;
    var img = {&lt;br /&gt;
        fb: imgBase + &amp;quot;5/55/Facebook.png&amp;quot;,&lt;br /&gt;
        ln: imgBase + &amp;quot;9/99/Linkdin.png&amp;quot;,&lt;br /&gt;
        ig: imgBase + &amp;quot;b/b7/Instagram.png&amp;quot;,&lt;br /&gt;
        igus: imgBase + &amp;quot;2/2b/Igus.svg&amp;quot;,&lt;br /&gt;
        selo: imgBase + &amp;quot;2/23/Selo_ID_reconhecimento_idoneidade_branco_.png&amp;quot;,&lt;br /&gt;
        cp: imgBase + &amp;quot;9/92/Compete.png&amp;quot;,&lt;br /&gt;
        ce: imgBase + &amp;quot;c/ce/Centro.png&amp;quot;,&lt;br /&gt;
        ps: imgBase + &amp;quot;2/20/Pessoas.png&amp;quot;,&lt;br /&gt;
        pr: imgBase + &amp;quot;4/42/Prr.png&amp;quot;&lt;br /&gt;
    };&lt;br /&gt;
&lt;br /&gt;
    var linkStyle = &#039;style=&amp;quot;color: #ffffff !important; display: block; margin-bottom: 10px; font-size: 14px; text-decoration: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
    var titleStyle = &#039;style=&amp;quot;color: #ffffff !important; font-weight: bold; margin-bottom: 20px; font-size: 16px; border: none; text-transform: none; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&#039;;&lt;br /&gt;
&lt;br /&gt;
    var html = &lt;br /&gt;
    &#039;&amp;lt;div id=&amp;quot;custom-atronia-footer&amp;quot; style=&amp;quot;background-color: #111; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        // 1. SCROLLING TEXT&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-container&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;div class=&amp;quot;atronia-scrolling-content&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;span&amp;gt;TECH THAT MAKES SENSE. • TECH THAT MAKES SENSE. • &amp;lt;/span&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 2. CONTEÚDO PRINCIPAL (CONTACTOS E MENUS)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;display: flex; flex-wrap: wrap; justify-content: space-between; max-width: 1300px; margin: 0 auto; padding: 60px 20px; color: #ffffff; gap: 40px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            // Contactos&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 1.5; min-width: 280px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Visit but keep in mind we\&#039;re busy&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;Rua do Norte 9,&amp;lt;br&amp;gt;Ílhavo, 3830-167, Portugal&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;h4 &#039;+titleStyle+&#039; style=&amp;quot;margin-top:30px&amp;quot;&amp;gt;Contact Us&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 5px;&amp;quot;&amp;gt;+351 934 886 253&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important; margin-bottom: 15px;&amp;quot;&amp;gt;(Custo de chamada para rede móvel nacional)&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;color: #ffffff !important;&amp;quot;&amp;gt;info@atronia.eu&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display:flex; gap:15px; margin-top:20px&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.facebook.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.fb+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.linkedin.com/company/atroniaeu/?originalSubdomain=pt&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ln+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://www.instagram.com/atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ig+&#039;&amp;quot; width=&amp;quot;25&amp;quot; style=&amp;quot;filter: brightness(0) invert(1) !important;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            // Menus&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 3; display: flex; justify-content: space-between; flex-wrap: wrap; gap: 20px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Menu&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/about-us/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;About us&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Hardware&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Solutions&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Hardware&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/monarch/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Monarch&amp;lt;/a&amp;gt;&#039; +                    &lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/hardware/atlas/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Atlas&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Probes&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039;  target=&amp;quot;_blank&amp;quot;&amp;gt;Accessories&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Solutions&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/aquaguard/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Aquaguard&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/firefly/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Firefly&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/melisafe/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Melisafe&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://atronia.eu/solutions/prevent/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;Prevent&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div&amp;gt;&amp;lt;h4 &#039;+titleStyle+&#039;&amp;gt;Knowledge&amp;lt;/h4&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a &#039;+linkStyle+&#039; href=&amp;quot;https://wiki.atronia.eu&amp;quot;&amp;gt;Wiki&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;div class=&amp;quot;atronia-full-width-line&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // 4. SECÇÃO FINAL (LOGOS COM ESPAÇAMENTO REDUZIDO)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 40px 20px; max-width: 1300px; margin: 0 auto; display: flex; flex-wrap: wrap; align-items: flex-start; justify-content: flex-start; gap: 60px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &lt;br /&gt;
            // 1. Approved by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 120px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Approved by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;img src=&amp;quot;&#039;+img.selo+&#039;&amp;quot; style=&amp;quot;height: auto; width: 90px; display: block; border:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 2. Powered by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 150px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Powered by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;a href=&amp;quot;https://www.igus.pt/&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.igus+&#039;&amp;quot; style=&amp;quot;height: auto; width: 130px; display: block; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
            // 3. Co-sponsored by&lt;br /&gt;
            &#039;&amp;lt;div style=&amp;quot;flex: 0 1 auto; min-width: 300px;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;p style=&amp;quot;font-size:11px; opacity:0.6; color:#ffffff !important; margin-bottom:15px; font-weight:bold; text-transform: uppercase;&amp;quot;&amp;gt;Co-sponsored by:&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;div style=&amp;quot;display: grid; grid-template-columns: repeat(2, auto); gap: 15px 30px; justify-content: start; align-items: center;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/12/Ficha-do-projeto-ATRONIA-LDA.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.cp+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/09/Ficha-de-Operacao_Tilt-Wind.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ce+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/01/Pessoas2030.jpg&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.ps+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                    &#039;&amp;lt;a href=&amp;quot;https://atronia.eu/wp-content/uploads/2025/02/Ficha-de-Projeto.pdf&amp;quot; target=&amp;quot;_blank&amp;quot;&amp;gt;&amp;lt;img src=&amp;quot;&#039;+img.pr+&#039;&amp;quot; style=&amp;quot;height: 40px; max-width: 250px; width: auto; object-fit: contain; border:none;&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
        // Links Legais (alinhados abaixo dos logos)&lt;br /&gt;
        &#039;&amp;lt;div style=&amp;quot;padding: 0 20px 40px 20px; max-width: 1300px; margin: 0 auto;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;p style=&amp;quot;font-size: 13px; color: #ffffff !important;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
                &#039;&amp;lt;strong&amp;gt;&amp;lt;a href=&amp;quot;https://www.livroreclamacoes.pt/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Livro de Reclamações&amp;lt;/a&amp;gt; | &amp;lt;a href=&amp;quot;https://atronia.eu/privacy-policy/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;color: #ffffff !important; text-decoration: underline;&amp;quot;&amp;gt;Privacy Policy&amp;lt;/a&amp;gt;&amp;lt;/strong&amp;gt;&#039; +&lt;br /&gt;
            &#039;&amp;lt;/p&amp;gt;&#039; +&lt;br /&gt;
        &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039;;&lt;br /&gt;
&lt;br /&gt;
    $(&#039;#custom-atronia-footer&#039;).remove();&lt;br /&gt;
    $(&#039;body&#039;).append(html);&lt;br /&gt;
&lt;br /&gt;
    /* BOTÕES FLUTUANTES */&lt;br /&gt;
    var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
    var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;atronia.eu&amp;lt;/div&amp;gt;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
    floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
    $(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
    $(window).scroll(function() {&lt;br /&gt;
        if ($(window).scrollTop() &amp;gt; 300) { floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;); } else { floatingNav.fadeOut(); }&lt;br /&gt;
    });&lt;br /&gt;
&lt;br /&gt;
    backToTop.click(function() { $(&#039;html, body&#039;).animate({scrollTop: 0}, 600); });&lt;br /&gt;
    $(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); },&lt;br /&gt;
        function() { $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); }&lt;br /&gt;
    );&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
/*FIM DO FOOTER*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botões Flutuantes: Voltar ao Topo (Esquerda) + Website (Direita) */&lt;br /&gt;
var floatingNav = $(&#039;&amp;lt;div id=&amp;quot;atronia-floating-nav&amp;quot; style=&amp;quot;display:none; position:fixed; bottom:40px; right:40px; display:flex; gap:12px; z-index:9999; align-items:center;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 1. Botão de Topo (Agora configurado para aparecer primeiro na fila)&lt;br /&gt;
var backToTop = $(&#039;&amp;lt;div id=&amp;quot;back-to-top&amp;quot; style=&amp;quot;width:50px; height:50px; background-color:#BFFF00; color:#000000; border-radius:50%; text-align:center; line-height:50px; font-size:24px; cursor:pointer; box-shadow:0 4px 12px rgba(0,0,0,0.3); transition:all 0.3s ease;&amp;quot;&amp;gt;↑&amp;lt;/div&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// 2. Botão do Website&lt;br /&gt;
var siteBtn = $(&#039;&amp;lt;a href=&amp;quot;https://atronia.eu/&amp;quot; target=&amp;quot;_blank&amp;quot; style=&amp;quot;text-decoration:none;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
    &#039;&amp;lt;div style=&amp;quot;height:50px; padding:0 25px; background-color:#BFFF00; color:#000000; border-radius:25px; line-height:50px; font-weight:bold; font-size:14px; box-shadow:0 4px 12px rgba(0,0,0,0.3); cursor:pointer; transition:all 0.3s ease; font-family:\&#039;Rubik\&#039;, sans-serif;&amp;quot;&amp;gt;&#039; +&lt;br /&gt;
        &#039;atronia.eu&#039; +&lt;br /&gt;
    &#039;&amp;lt;/div&amp;gt;&#039; +&lt;br /&gt;
&#039;&amp;lt;/a&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
// Montagem: Primeiro o backToTop, depois o siteBtn&lt;br /&gt;
floatingNav.append(backToTop).append(siteBtn);&lt;br /&gt;
$(&#039;body&#039;).append(floatingNav);&lt;br /&gt;
&lt;br /&gt;
// Lógica de Scroll&lt;br /&gt;
$(window).scroll(function() {&lt;br /&gt;
    if ($(window).scrollTop() &amp;gt; 300) {&lt;br /&gt;
        floatingNav.fadeIn().css(&#039;display&#039;, &#039;flex&#039;);&lt;br /&gt;
    } else {&lt;br /&gt;
        floatingNav.fadeOut();&lt;br /&gt;
    }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Ação de Clique&lt;br /&gt;
backToTop.click(function() {&lt;br /&gt;
    $(&#039;html, body&#039;).animate({scrollTop: 0}, 600);&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
// Efeito de Hover&lt;br /&gt;
$(&#039;#atronia-floating-nav &amp;gt; a &amp;gt; div, #back-to-top&#039;).hover(&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.1)&#039;, &#039;background-color&#039;: &#039;#A0D500&#039; }); &lt;br /&gt;
    },&lt;br /&gt;
    function() { &lt;br /&gt;
        $(this).css({ &#039;transform&#039;: &#039;scale(1.0)&#039;, &#039;background-color&#039;: &#039;#BFFF00&#039; }); &lt;br /&gt;
    }&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// 4. GOOGLE ANALYTICS (Fora do $(function) para carregar logo)&lt;br /&gt;
var gaScript = document.createElement(&#039;script&#039;);&lt;br /&gt;
gaScript.src = &amp;quot;https://www.googletagmanager.com/gtag/js?id=G-MX174P23PW&amp;quot;;&lt;br /&gt;
gaScript.async = true;&lt;br /&gt;
document.head.appendChild(gaScript);&lt;br /&gt;
window.dataLayer = window.dataLayer || [];&lt;br /&gt;
function gtag(){dataLayer.push(arguments);}&lt;br /&gt;
gtag(&#039;js&#039;, new Date());&lt;br /&gt;
gtag(&#039;config&#039;, &#039;G-MX174P23PW&#039;);&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1900</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1900"/>
		<updated>2026-06-30T08:46:34Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&amp;quot;);&lt;br /&gt;
@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&amp;quot;);&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Esconde as subpáginas do Atlas por defeito no Vector Moderno */&lt;br /&gt;
.atlas-submenu {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    padding-left: 15px !important;&lt;br /&gt;
    font-size: 0.95em !important;&lt;br /&gt;
    opacity: 0.85;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Mostra as subpáginas quando o menu estiver aberto */&lt;br /&gt;
.atlas-submenu.is-open {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo para a seta do dropdown */&lt;br /&gt;
.atlas-toggle-btn {&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    margin-left: 8px;&lt;br /&gt;
    font-size: 0.75em;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    color: #646464;&lt;br /&gt;
    user-select: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   ÍNDICE LATERAL (TOC) - DESIGN FINAL REFINADO COM HOVER E ANIMAÇÃO RÁPIDA&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Oculta as sublistas por padrão */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Mostra a sublista quando expandido */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .vector-toc-list {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Posicionamento relativo das linhas do menu */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list-item {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Container do botão da seta (Área clicável com efeito Hover) */&lt;br /&gt;
.toc-toggle-arrow {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    left: -18px !important;    /* Ajuste para centralizar o quadrado do hover à esquerda */&lt;br /&gt;
    top: 3px !important;       /* Alinha perfeitamente ao centro da linha de texto */&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    cursor: pointer !important;&lt;br /&gt;
    width: 18px !important;    /* Tamanho do quadrado do hover */&lt;br /&gt;
    height: 18px !important;&lt;br /&gt;
    border-radius: 2px;        /* Cantos levemente suavizados para o quadrado */&lt;br /&gt;
    z-index: 50 !important;&lt;br /&gt;
    transition: background-color 0.1s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Quadrado cinza clarinho ao passar o rato */&lt;br /&gt;
.toc-toggle-arrow:hover {&lt;br /&gt;
    background-color: #e2e4e8 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. O Desenho da Seta (Estilo Chevron - Cor Preta Forte) */&lt;br /&gt;
.toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 5px;&lt;br /&gt;
    height: 5px;&lt;br /&gt;
    border-right: 1.5px solid #202122; /* Preto forte igual aos cabeçalhos da wiki */&lt;br /&gt;
    border-bottom: 1.5px solid #202122;&lt;br /&gt;
    transform: rotate(-45deg);         /* Aponta para a direita */&lt;br /&gt;
    transition: transform 0.1s ease-in-out; /* Animação ultra rápida */&lt;br /&gt;
    margin-left: -2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Rotação rápida quando o menu abre (roda para baixo) */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    transform: rotate(45deg) !important;&lt;br /&gt;
    margin-top: -2px;&lt;br /&gt;
    margin-left: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Indentação interna limpa para os subcapítulos */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    padding-left: 12px !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Proteção absoluta para o cabeçalho principal &amp;quot;Datasheet&amp;quot; */&lt;br /&gt;
.vector-toc-header .toc-toggle-arrow,&lt;br /&gt;
.vector-toc-title .toc-toggle-arrow,&lt;br /&gt;
#vector-toc-collapsed-button .toc-toggle-arrow {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    opacity: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Contentor do bloco de código */&lt;br /&gt;
.mw-highlight, .syntaxhighlight {&lt;br /&gt;
    position: relative; /* Necessário para o posicionamento do botão */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo do Botão Copy */&lt;br /&gt;
.copy-code-button {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 5px;&lt;br /&gt;
    right: 5px;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    padding: 4px 8px;&lt;br /&gt;
    background-color: #f8f9fa;&lt;br /&gt;
    border: 1px solid #a2a9b1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #202122;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.copy-code-button:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
    border-color: #447ff5;&lt;br /&gt;
    color: #447ff5;&lt;br /&gt;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTES RESPONSIVOS ATRONIA --- */&lt;br /&gt;
&lt;br /&gt;
@media only screen and (max-width: 768px) {&lt;br /&gt;
&lt;br /&gt;
    #custom-atronia-footer img[src*=&amp;quot;Igus.svg&amp;quot;] {&lt;br /&gt;
        max-width: 120px !important; /* Ajusta este valor (ex: 100px ou 120px) até gostares */&lt;br /&gt;
        margin-bottom: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 1. Forçar menus a empilhar no mobile */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;justify-content: space-between&amp;quot;] {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: flex-start !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 2. Grelha de Logos: Passa de 2 colunas para 1 no mobile para não esmagar */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;display: grid&amp;quot;] {&lt;br /&gt;
        grid-template-columns: 1fr !important; &lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 3. Logos: Garante que as imagens não saem do ecrã */&lt;br /&gt;
    #custom-atronia-footer img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 4. Botões Flutuantes: Evitar que tapem os logos no fundo */&lt;br /&gt;
    #atronia-floating-nav {&lt;br /&gt;
        bottom: 15px !important;&lt;br /&gt;
        right: 10px !important;&lt;br /&gt;
        transform: scale(0.85); /* Ficam ligeiramente menores */&lt;br /&gt;
        transform-origin: bottom right;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 5. Scrolling Text: Diminuir um pouco no mobile */&lt;br /&gt;
    .atronia-scrolling-container {&lt;br /&gt;
        height: 80px !important;&lt;br /&gt;
        line-height: 80px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Aplicar a fonte a todo o footer */&lt;br /&gt;
#custom-atronia-footer, &lt;br /&gt;
#custom-atronia-footer * {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
/* --- ESTRUTURA BASE --- */&lt;br /&gt;
#custom-atronia-footer {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    clear: both !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Scrolling Text Estilo &amp;quot;Vazado&amp;quot; */&lt;br /&gt;
.atronia-scrolling-container {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    padding: 20px 0;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    border-bottom: 1px solid #ffffff !important; /* Separador abaixo do scroll */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atronia-scrolling-content span {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif;&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: transparent !important; /* Mantém o interior vazio */&lt;br /&gt;
    -webkit-text-stroke: 1.5px #ffffff; /* Branco puro e um pouco mais grosso */&lt;br /&gt;
    opacity: 1 !important; /* Garante que o contorno não seja translúcido */&lt;br /&gt;
    padding-right: 50px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    letter-spacing: 1px; /* Melhora a leitura em letras vazadas */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes atronia-scroll {&lt;br /&gt;
    0% { transform: translateX(0); }&lt;br /&gt;
    100% { transform: translateX(-50%); }&lt;br /&gt;
}&lt;br /&gt;
.atronia-scrolling-content { display: inline-block; animation: atronia-scroll 15s linear infinite; }&lt;br /&gt;
&lt;br /&gt;
/* Esconder elementos nativos */&lt;br /&gt;
#footer, .mw-footer, #catlinks { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
/* Forçar underline no hover e limpar estilos nativos da Wiki */&lt;br /&gt;
#custom-atronia-footer a {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    background: none !important; /* Remove blocos de cor que a wiki possa inserir */&lt;br /&gt;
    transition: text-decoration 0.2s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#custom-atronia-footer a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Linha de largura total absoluta */&lt;br /&gt;
.atronia-full-width-line {&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    width: 100vw !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    right: 50% !important;&lt;br /&gt;
    margin-left: -50vw !important;&lt;br /&gt;
    margin-right: -50vw !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Fim do Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botão de Seta para o Topo */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important; /* Mesmo verde */&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    border-radius: 50% !important; /* Circular */&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    font-size: 20px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.footer-top-button:hover {&lt;br /&gt;
    transform: scale(1.1) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o container se alinha bem no mobile */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do botão Buy Now (MONARCH) - Alinhado à direita */&lt;br /&gt;
.buy-now-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    justify-content: right !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Estilo do Botão - Base e Centralização */&lt;br /&gt;
.button-buy-now a.external {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
&lt;br /&gt;
    background-color: #d1ff00 !important; /* Verde néon */&lt;br /&gt;
    color: #000 !important; /* Texto preto */&lt;br /&gt;
    &lt;br /&gt;
    /* PADDING IGUAL DOS DOIS LADOS (Essencial para centrar) */&lt;br /&gt;
    padding: 7px 25px !important; &lt;br /&gt;
    &lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
&lt;br /&gt;
    /* Remove a seta e o espaço fantasma do MediaWiki */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    text-indent: 0 !important;&lt;br /&gt;
    letter-spacing: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Forçar anulação de regras do sistema (mw-parser-output) */&lt;br /&gt;
.mw-parser-output .button-buy-now a.external {&lt;br /&gt;
    padding-right: 25px !important; /* Força a simetria com a esquerda */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Efeito ao passar o rato */&lt;br /&gt;
.button-buy-now a.external:hover {&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   RODAPÉ (Footer) - Versão Final Limpa&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do Rodapé - Permite que os itens respirem e alinhem */&lt;br /&gt;
#footer-places {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    flex-wrap: nowrap !important;&lt;br /&gt;
    padding: 10px 25px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Links da Esquerda (Privacy, About, etc) */&lt;br /&gt;
#footer-places li {&lt;br /&gt;
    margin-right: 15px !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. NOVO CONTENTOR DOS BOTÕES (Seta + Link) &lt;br /&gt;
   O &amp;quot;margin-left: auto&amp;quot; é o íman que empurra o grupo para a direita */&lt;br /&gt;
#footer-custom-buttons-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    gap: 12px !important; /* Espaço entre a seta e o botão */&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    margin-left: auto !important; &lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Estilo Comum para Seta e Botão (Cápsula Verde) */&lt;br /&gt;
.footer-top-button,&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important;&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: all 0.2s ease-in-out !important;&lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. Especificações da Seta (Circular) */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    font-size: 18px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Especificações do Botão do Site */&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    padding: 7px 25px !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    white-space: nowrap !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Hover para os dois */&lt;br /&gt;
.footer-top-button:hover,&lt;br /&gt;
.footer-button-atronia-real:hover {&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Remover ícones de link externo do MediaWiki */&lt;br /&gt;
.footer-button-atronia-real.external,&lt;br /&gt;
.footer-button-atronia-real.external:after {&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 25px !important; /* Mantém igual à esquerda para centrar */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTE PARA MOBILE (Ecrãs até 720px) --- */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-places {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: center !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    #footer-places li {&lt;br /&gt;
        margin-right: 0 !important;&lt;br /&gt;
        margin-bottom: 10px !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* No mobile, os botões ficam centrados em baixo dos textos */&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        margin-left: 0 !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Destacar o item principal ativo */&lt;br /&gt;
.vector-toc-list-item-active &amp;gt; .vector-toc-link .vector-toc-text {&lt;br /&gt;
    font-weight: 700 !important; /* Força o negrito máximo */&lt;br /&gt;
    color: #000000 !important;   /* Cor preta forte para contraste */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Remove qualquer preenchimento extra de tags pre ou code que a wiki insira */&lt;br /&gt;
.variations-toggle pre,&lt;br /&gt;
.variations-toggle code {&lt;br /&gt;
  display: contents !important;&lt;br /&gt;
  background: none !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
  display: inline-flex; /* important */&lt;br /&gt;
  align-items: center; /* vertical centering */&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
&lt;br /&gt;
  width: 24px; /* lock size */&lt;br /&gt;
  height: 24px;&lt;br /&gt;
&lt;br /&gt;
  line-height: 1; /* remove font baseline weirdness */&lt;br /&gt;
&lt;br /&gt;
  transition: transform 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
.arrow-icon.rotated {&lt;br /&gt;
    transform: rotate(180deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esta regra garante transição suave mesmo se o MediaWiki interferir */&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
    transition: transform 0.25s ease-in-out !important;&lt;br /&gt;
    transform-origin: center center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.variations-list &amp;gt; pre,&lt;br /&gt;
.variations-toggle &amp;gt; pre {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.mw-highlight &amp;gt; pre {&lt;br /&gt;
  margin: 1em 0;&lt;br /&gt;
  padding: 12px 16px;&lt;br /&gt;
  background-color: #f6f6f6; /* restore */&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
&lt;br /&gt;
  overflow-x: auto;&lt;br /&gt;
  white-space: pre;&lt;br /&gt;
&lt;br /&gt;
  font-family: &amp;quot;Roboto Mono&amp;quot;, monospace;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  line-height: 1.5;&lt;br /&gt;
&lt;br /&gt;
  display: block; /* IMPORTANT */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  margin: 0;&lt;br /&gt;
  padding: 0;&lt;br /&gt;
  padding-top: 1rem;&lt;br /&gt;
  background-color: transparent;&lt;br /&gt;
  border: transparent;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: space-around;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Limpeza profunda do collapsible na grelha de produtos */&lt;br /&gt;
.product-item .mw-collapsible {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item .mw-collapsible-content {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove o ícone padrão de &amp;quot;seta&amp;quot; ou [Expandir] que o MediaWiki cria */&lt;br /&gt;
.product-item .mw-collapsible-toggle {&lt;br /&gt;
  float: none !important;&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esconde o link automático de texto que o MediaWiki pode injetar */&lt;br /&gt;
.product-item .mw-collapsible-toggle-default {&lt;br /&gt;
  display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-dropdown-checkbox {&lt;br /&gt;
  background-color: red !important;&lt;br /&gt;
  color: red !important;&lt;br /&gt;
}&lt;br /&gt;
.products-grid {&lt;br /&gt;
  display: grid;&lt;br /&gt;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));&lt;br /&gt;
  gap: 30px;&lt;br /&gt;
  margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-image {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 0 auto 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-title {&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
  margin-top: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  color: #666;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item strong {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Garante que o título do Datasheet e outros itens mantenham a consistência */&lt;br /&gt;
.vector-toc-link .vector-toc-text {&lt;br /&gt;
  font-weight: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Botão Técnico Atlas - Cores Customizadas */&lt;br /&gt;
.mw-parser-output .atlas-btn {&lt;br /&gt;
  display: inline-block !important;&lt;br /&gt;
  padding: 10px 22px !important;&lt;br /&gt;
  background-color: #1b2826 !important; /* Cor base escura */&lt;br /&gt;
  border: 1px solid #1b2826 !important;&lt;br /&gt;
  border-radius: 4px !important;&lt;br /&gt;
  transition: all 0.25s ease !important;&lt;br /&gt;
  cursor: pointer !important;&lt;br /&gt;
  text-align: center !important;&lt;br /&gt;
  border-bottom: 1px solid #1b2826 !important; /* Remove qualquer traço de link */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Link dentro do botão - Forçar branco em todos os estados*/&lt;br /&gt;
.mw-parser-output .atlas-btn a,&lt;br /&gt;
.mw-parser-output .atlas-btn a:link,&lt;br /&gt;
.mw-parser-output .atlas-btn a:visited,&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover,&lt;br /&gt;
.mw-parser-output .atlas-btn a:active {&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  font-weight: bold !important;&lt;br /&gt;
  font-size: 0.95em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Versão levemente mais clara */&lt;br /&gt;
.mw-parser-output .atlas-btn:hover {&lt;br /&gt;
  background-color: #3e524f !important; /* Tom mais claro */&lt;br /&gt;
  border-color: #2a3b38 !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* Sombra leve para profundidade */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o link não mude de cor ou sublinhe no hover */&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover {&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Forçar a fonte Rubik no título principal */&lt;br /&gt;
#firstHeading {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-weight: 600 !important;&lt;br /&gt;
  color: #202122 !important;&lt;br /&gt;
  letter-spacing: -0.01em !important;&lt;br /&gt;
  /* Removemos a nossa borda manual para usar apenas a da Wiki */&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  margin-bottom: 0 !important;&lt;br /&gt;
  padding-bottom: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o breadcrumb (&amp;lt; SENSBLUE ATLAS) também use a Rubik */&lt;br /&gt;
#contentSub,&lt;br /&gt;
#contentSub2 {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-size: 0.85em !important;&lt;br /&gt;
  color: #54595d !important;&lt;br /&gt;
  margin-top: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, sans-serif !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1899</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1899"/>
		<updated>2026-06-30T08:41:49Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&amp;quot;);&lt;br /&gt;
@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&amp;quot;);&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Recuo visual para subpáginas do Atlas no menu lateral */&lt;br /&gt;
#mw-panel a[href*=&amp;quot;SENSBLUE_ATLAS/&amp;quot;] {&lt;br /&gt;
    padding-left: 15px !important;&lt;br /&gt;
    font-size: 0.9em !important;&lt;br /&gt;
    opacity: 0.85;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   ÍNDICE LATERAL (TOC) - DESIGN FINAL REFINADO COM HOVER E ANIMAÇÃO RÁPIDA&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Oculta as sublistas por padrão */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Mostra a sublista quando expandido */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .vector-toc-list {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Posicionamento relativo das linhas do menu */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list-item {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Container do botão da seta (Área clicável com efeito Hover) */&lt;br /&gt;
.toc-toggle-arrow {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    left: -18px !important;    /* Ajuste para centralizar o quadrado do hover à esquerda */&lt;br /&gt;
    top: 3px !important;       /* Alinha perfeitamente ao centro da linha de texto */&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    cursor: pointer !important;&lt;br /&gt;
    width: 18px !important;    /* Tamanho do quadrado do hover */&lt;br /&gt;
    height: 18px !important;&lt;br /&gt;
    border-radius: 2px;        /* Cantos levemente suavizados para o quadrado */&lt;br /&gt;
    z-index: 50 !important;&lt;br /&gt;
    transition: background-color 0.1s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Quadrado cinza clarinho ao passar o rato */&lt;br /&gt;
.toc-toggle-arrow:hover {&lt;br /&gt;
    background-color: #e2e4e8 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. O Desenho da Seta (Estilo Chevron - Cor Preta Forte) */&lt;br /&gt;
.toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 5px;&lt;br /&gt;
    height: 5px;&lt;br /&gt;
    border-right: 1.5px solid #202122; /* Preto forte igual aos cabeçalhos da wiki */&lt;br /&gt;
    border-bottom: 1.5px solid #202122;&lt;br /&gt;
    transform: rotate(-45deg);         /* Aponta para a direita */&lt;br /&gt;
    transition: transform 0.1s ease-in-out; /* Animação ultra rápida */&lt;br /&gt;
    margin-left: -2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Rotação rápida quando o menu abre (roda para baixo) */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    transform: rotate(45deg) !important;&lt;br /&gt;
    margin-top: -2px;&lt;br /&gt;
    margin-left: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Indentação interna limpa para os subcapítulos */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    padding-left: 12px !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Proteção absoluta para o cabeçalho principal &amp;quot;Datasheet&amp;quot; */&lt;br /&gt;
.vector-toc-header .toc-toggle-arrow,&lt;br /&gt;
.vector-toc-title .toc-toggle-arrow,&lt;br /&gt;
#vector-toc-collapsed-button .toc-toggle-arrow {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    opacity: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Contentor do bloco de código */&lt;br /&gt;
.mw-highlight, .syntaxhighlight {&lt;br /&gt;
    position: relative; /* Necessário para o posicionamento do botão */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo do Botão Copy */&lt;br /&gt;
.copy-code-button {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 5px;&lt;br /&gt;
    right: 5px;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    padding: 4px 8px;&lt;br /&gt;
    background-color: #f8f9fa;&lt;br /&gt;
    border: 1px solid #a2a9b1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #202122;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.copy-code-button:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
    border-color: #447ff5;&lt;br /&gt;
    color: #447ff5;&lt;br /&gt;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTES RESPONSIVOS ATRONIA --- */&lt;br /&gt;
&lt;br /&gt;
@media only screen and (max-width: 768px) {&lt;br /&gt;
&lt;br /&gt;
    #custom-atronia-footer img[src*=&amp;quot;Igus.svg&amp;quot;] {&lt;br /&gt;
        max-width: 120px !important; /* Ajusta este valor (ex: 100px ou 120px) até gostares */&lt;br /&gt;
        margin-bottom: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 1. Forçar menus a empilhar no mobile */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;justify-content: space-between&amp;quot;] {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: flex-start !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 2. Grelha de Logos: Passa de 2 colunas para 1 no mobile para não esmagar */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;display: grid&amp;quot;] {&lt;br /&gt;
        grid-template-columns: 1fr !important; &lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 3. Logos: Garante que as imagens não saem do ecrã */&lt;br /&gt;
    #custom-atronia-footer img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 4. Botões Flutuantes: Evitar que tapem os logos no fundo */&lt;br /&gt;
    #atronia-floating-nav {&lt;br /&gt;
        bottom: 15px !important;&lt;br /&gt;
        right: 10px !important;&lt;br /&gt;
        transform: scale(0.85); /* Ficam ligeiramente menores */&lt;br /&gt;
        transform-origin: bottom right;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 5. Scrolling Text: Diminuir um pouco no mobile */&lt;br /&gt;
    .atronia-scrolling-container {&lt;br /&gt;
        height: 80px !important;&lt;br /&gt;
        line-height: 80px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Aplicar a fonte a todo o footer */&lt;br /&gt;
#custom-atronia-footer, &lt;br /&gt;
#custom-atronia-footer * {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
/* --- ESTRUTURA BASE --- */&lt;br /&gt;
#custom-atronia-footer {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    clear: both !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Scrolling Text Estilo &amp;quot;Vazado&amp;quot; */&lt;br /&gt;
.atronia-scrolling-container {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    padding: 20px 0;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    border-bottom: 1px solid #ffffff !important; /* Separador abaixo do scroll */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atronia-scrolling-content span {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif;&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: transparent !important; /* Mantém o interior vazio */&lt;br /&gt;
    -webkit-text-stroke: 1.5px #ffffff; /* Branco puro e um pouco mais grosso */&lt;br /&gt;
    opacity: 1 !important; /* Garante que o contorno não seja translúcido */&lt;br /&gt;
    padding-right: 50px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    letter-spacing: 1px; /* Melhora a leitura em letras vazadas */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes atronia-scroll {&lt;br /&gt;
    0% { transform: translateX(0); }&lt;br /&gt;
    100% { transform: translateX(-50%); }&lt;br /&gt;
}&lt;br /&gt;
.atronia-scrolling-content { display: inline-block; animation: atronia-scroll 15s linear infinite; }&lt;br /&gt;
&lt;br /&gt;
/* Esconder elementos nativos */&lt;br /&gt;
#footer, .mw-footer, #catlinks { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
/* Forçar underline no hover e limpar estilos nativos da Wiki */&lt;br /&gt;
#custom-atronia-footer a {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    background: none !important; /* Remove blocos de cor que a wiki possa inserir */&lt;br /&gt;
    transition: text-decoration 0.2s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#custom-atronia-footer a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Linha de largura total absoluta */&lt;br /&gt;
.atronia-full-width-line {&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    width: 100vw !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    right: 50% !important;&lt;br /&gt;
    margin-left: -50vw !important;&lt;br /&gt;
    margin-right: -50vw !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Fim do Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botão de Seta para o Topo */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important; /* Mesmo verde */&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    border-radius: 50% !important; /* Circular */&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    font-size: 20px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.footer-top-button:hover {&lt;br /&gt;
    transform: scale(1.1) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o container se alinha bem no mobile */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do botão Buy Now (MONARCH) - Alinhado à direita */&lt;br /&gt;
.buy-now-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    justify-content: right !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Estilo do Botão - Base e Centralização */&lt;br /&gt;
.button-buy-now a.external {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
&lt;br /&gt;
    background-color: #d1ff00 !important; /* Verde néon */&lt;br /&gt;
    color: #000 !important; /* Texto preto */&lt;br /&gt;
    &lt;br /&gt;
    /* PADDING IGUAL DOS DOIS LADOS (Essencial para centrar) */&lt;br /&gt;
    padding: 7px 25px !important; &lt;br /&gt;
    &lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
&lt;br /&gt;
    /* Remove a seta e o espaço fantasma do MediaWiki */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    text-indent: 0 !important;&lt;br /&gt;
    letter-spacing: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Forçar anulação de regras do sistema (mw-parser-output) */&lt;br /&gt;
.mw-parser-output .button-buy-now a.external {&lt;br /&gt;
    padding-right: 25px !important; /* Força a simetria com a esquerda */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Efeito ao passar o rato */&lt;br /&gt;
.button-buy-now a.external:hover {&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   RODAPÉ (Footer) - Versão Final Limpa&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do Rodapé - Permite que os itens respirem e alinhem */&lt;br /&gt;
#footer-places {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    flex-wrap: nowrap !important;&lt;br /&gt;
    padding: 10px 25px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Links da Esquerda (Privacy, About, etc) */&lt;br /&gt;
#footer-places li {&lt;br /&gt;
    margin-right: 15px !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. NOVO CONTENTOR DOS BOTÕES (Seta + Link) &lt;br /&gt;
   O &amp;quot;margin-left: auto&amp;quot; é o íman que empurra o grupo para a direita */&lt;br /&gt;
#footer-custom-buttons-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    gap: 12px !important; /* Espaço entre a seta e o botão */&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    margin-left: auto !important; &lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Estilo Comum para Seta e Botão (Cápsula Verde) */&lt;br /&gt;
.footer-top-button,&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important;&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: all 0.2s ease-in-out !important;&lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. Especificações da Seta (Circular) */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    font-size: 18px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Especificações do Botão do Site */&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    padding: 7px 25px !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    white-space: nowrap !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Hover para os dois */&lt;br /&gt;
.footer-top-button:hover,&lt;br /&gt;
.footer-button-atronia-real:hover {&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Remover ícones de link externo do MediaWiki */&lt;br /&gt;
.footer-button-atronia-real.external,&lt;br /&gt;
.footer-button-atronia-real.external:after {&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 25px !important; /* Mantém igual à esquerda para centrar */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTE PARA MOBILE (Ecrãs até 720px) --- */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-places {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: center !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    #footer-places li {&lt;br /&gt;
        margin-right: 0 !important;&lt;br /&gt;
        margin-bottom: 10px !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* No mobile, os botões ficam centrados em baixo dos textos */&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        margin-left: 0 !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Destacar o item principal ativo */&lt;br /&gt;
.vector-toc-list-item-active &amp;gt; .vector-toc-link .vector-toc-text {&lt;br /&gt;
    font-weight: 700 !important; /* Força o negrito máximo */&lt;br /&gt;
    color: #000000 !important;   /* Cor preta forte para contraste */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Remove qualquer preenchimento extra de tags pre ou code que a wiki insira */&lt;br /&gt;
.variations-toggle pre,&lt;br /&gt;
.variations-toggle code {&lt;br /&gt;
  display: contents !important;&lt;br /&gt;
  background: none !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
  display: inline-flex; /* important */&lt;br /&gt;
  align-items: center; /* vertical centering */&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
&lt;br /&gt;
  width: 24px; /* lock size */&lt;br /&gt;
  height: 24px;&lt;br /&gt;
&lt;br /&gt;
  line-height: 1; /* remove font baseline weirdness */&lt;br /&gt;
&lt;br /&gt;
  transition: transform 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
.arrow-icon.rotated {&lt;br /&gt;
    transform: rotate(180deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esta regra garante transição suave mesmo se o MediaWiki interferir */&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
    transition: transform 0.25s ease-in-out !important;&lt;br /&gt;
    transform-origin: center center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.variations-list &amp;gt; pre,&lt;br /&gt;
.variations-toggle &amp;gt; pre {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.mw-highlight &amp;gt; pre {&lt;br /&gt;
  margin: 1em 0;&lt;br /&gt;
  padding: 12px 16px;&lt;br /&gt;
  background-color: #f6f6f6; /* restore */&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
&lt;br /&gt;
  overflow-x: auto;&lt;br /&gt;
  white-space: pre;&lt;br /&gt;
&lt;br /&gt;
  font-family: &amp;quot;Roboto Mono&amp;quot;, monospace;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  line-height: 1.5;&lt;br /&gt;
&lt;br /&gt;
  display: block; /* IMPORTANT */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  margin: 0;&lt;br /&gt;
  padding: 0;&lt;br /&gt;
  padding-top: 1rem;&lt;br /&gt;
  background-color: transparent;&lt;br /&gt;
  border: transparent;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: space-around;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Limpeza profunda do collapsible na grelha de produtos */&lt;br /&gt;
.product-item .mw-collapsible {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item .mw-collapsible-content {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove o ícone padrão de &amp;quot;seta&amp;quot; ou [Expandir] que o MediaWiki cria */&lt;br /&gt;
.product-item .mw-collapsible-toggle {&lt;br /&gt;
  float: none !important;&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esconde o link automático de texto que o MediaWiki pode injetar */&lt;br /&gt;
.product-item .mw-collapsible-toggle-default {&lt;br /&gt;
  display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-dropdown-checkbox {&lt;br /&gt;
  background-color: red !important;&lt;br /&gt;
  color: red !important;&lt;br /&gt;
}&lt;br /&gt;
.products-grid {&lt;br /&gt;
  display: grid;&lt;br /&gt;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));&lt;br /&gt;
  gap: 30px;&lt;br /&gt;
  margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-image {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 0 auto 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-title {&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
  margin-top: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  color: #666;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item strong {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Garante que o título do Datasheet e outros itens mantenham a consistência */&lt;br /&gt;
.vector-toc-link .vector-toc-text {&lt;br /&gt;
  font-weight: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Botão Técnico Atlas - Cores Customizadas */&lt;br /&gt;
.mw-parser-output .atlas-btn {&lt;br /&gt;
  display: inline-block !important;&lt;br /&gt;
  padding: 10px 22px !important;&lt;br /&gt;
  background-color: #1b2826 !important; /* Cor base escura */&lt;br /&gt;
  border: 1px solid #1b2826 !important;&lt;br /&gt;
  border-radius: 4px !important;&lt;br /&gt;
  transition: all 0.25s ease !important;&lt;br /&gt;
  cursor: pointer !important;&lt;br /&gt;
  text-align: center !important;&lt;br /&gt;
  border-bottom: 1px solid #1b2826 !important; /* Remove qualquer traço de link */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Link dentro do botão - Forçar branco em todos os estados*/&lt;br /&gt;
.mw-parser-output .atlas-btn a,&lt;br /&gt;
.mw-parser-output .atlas-btn a:link,&lt;br /&gt;
.mw-parser-output .atlas-btn a:visited,&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover,&lt;br /&gt;
.mw-parser-output .atlas-btn a:active {&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  font-weight: bold !important;&lt;br /&gt;
  font-size: 0.95em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Versão levemente mais clara */&lt;br /&gt;
.mw-parser-output .atlas-btn:hover {&lt;br /&gt;
  background-color: #3e524f !important; /* Tom mais claro */&lt;br /&gt;
  border-color: #2a3b38 !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* Sombra leve para profundidade */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o link não mude de cor ou sublinhe no hover */&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover {&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Forçar a fonte Rubik no título principal */&lt;br /&gt;
#firstHeading {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-weight: 600 !important;&lt;br /&gt;
  color: #202122 !important;&lt;br /&gt;
  letter-spacing: -0.01em !important;&lt;br /&gt;
  /* Removemos a nossa borda manual para usar apenas a da Wiki */&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  margin-bottom: 0 !important;&lt;br /&gt;
  padding-bottom: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o breadcrumb (&amp;lt; SENSBLUE ATLAS) também use a Rubik */&lt;br /&gt;
#contentSub,&lt;br /&gt;
#contentSub2 {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-size: 0.85em !important;&lt;br /&gt;
  color: #54595d !important;&lt;br /&gt;
  margin-top: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, sans-serif !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1898</id>
		<title>MediaWiki:Common.css</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Common.css&amp;diff=1898"/>
		<updated>2026-06-30T08:41:03Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined&amp;quot;);&lt;br /&gt;
@import url(&amp;quot;https://fonts.googleapis.com/css2?family=Material+Symbols+Rounded:FILL@0..1&amp;quot;);&lt;br /&gt;
@import url(&#039;https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;700&amp;amp;display=swap&#039;);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Recuo para as subpáginas do Atlas no menu lateral */&lt;br /&gt;
#n-SENSBLUE-ATLAS-Datasheet, &lt;br /&gt;
#n-SENSBLUE-ATLAS-Realease-Notes {&lt;br /&gt;
    padding-left: 15px !important;&lt;br /&gt;
    font-size: 0.9em;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   ÍNDICE LATERAL (TOC) - DESIGN FINAL REFINADO COM HOVER E ANIMAÇÃO RÁPIDA&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Oculta as sublistas por padrão */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Mostra a sublista quando expandido */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .vector-toc-list {&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Posicionamento relativo das linhas do menu */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list-item {&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Container do botão da seta (Área clicável com efeito Hover) */&lt;br /&gt;
.toc-toggle-arrow {&lt;br /&gt;
    position: absolute !important;&lt;br /&gt;
    left: -18px !important;    /* Ajuste para centralizar o quadrado do hover à esquerda */&lt;br /&gt;
    top: 3px !important;       /* Alinha perfeitamente ao centro da linha de texto */&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center;&lt;br /&gt;
    justify-content: center;&lt;br /&gt;
    cursor: pointer !important;&lt;br /&gt;
    width: 18px !important;    /* Tamanho do quadrado do hover */&lt;br /&gt;
    height: 18px !important;&lt;br /&gt;
    border-radius: 2px;        /* Cantos levemente suavizados para o quadrado */&lt;br /&gt;
    z-index: 50 !important;&lt;br /&gt;
    transition: background-color 0.1s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Quadrado cinza clarinho ao passar o rato */&lt;br /&gt;
.toc-toggle-arrow:hover {&lt;br /&gt;
    background-color: #e2e4e8 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. O Desenho da Seta (Estilo Chevron - Cor Preta Forte) */&lt;br /&gt;
.toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    width: 5px;&lt;br /&gt;
    height: 5px;&lt;br /&gt;
    border-right: 1.5px solid #202122; /* Preto forte igual aos cabeçalhos da wiki */&lt;br /&gt;
    border-bottom: 1.5px solid #202122;&lt;br /&gt;
    transform: rotate(-45deg);         /* Aponta para a direita */&lt;br /&gt;
    transition: transform 0.1s ease-in-out; /* Animação ultra rápida */&lt;br /&gt;
    margin-left: -2px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Rotação rápida quando o menu abre (roda para baixo) */&lt;br /&gt;
.vector-toc-list-item.toc-expanded &amp;gt; .toc-toggle-arrow .arrow-icon {&lt;br /&gt;
    transform: rotate(45deg) !important;&lt;br /&gt;
    margin-top: -2px;&lt;br /&gt;
    margin-left: 0px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Indentação interna limpa para os subcapítulos */&lt;br /&gt;
.vector-toc-contents .vector-toc-list .vector-toc-list {&lt;br /&gt;
    padding-left: 12px !important;&lt;br /&gt;
    margin-top: 4px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Proteção absoluta para o cabeçalho principal &amp;quot;Datasheet&amp;quot; */&lt;br /&gt;
.vector-toc-header .toc-toggle-arrow,&lt;br /&gt;
.vector-toc-title .toc-toggle-arrow,&lt;br /&gt;
#vector-toc-collapsed-button .toc-toggle-arrow {&lt;br /&gt;
    display: none !important;&lt;br /&gt;
    opacity: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Contentor do bloco de código */&lt;br /&gt;
.mw-highlight, .syntaxhighlight {&lt;br /&gt;
    position: relative; /* Necessário para o posicionamento do botão */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Estilo do Botão Copy */&lt;br /&gt;
.copy-code-button {&lt;br /&gt;
    position: absolute;&lt;br /&gt;
    top: 5px;&lt;br /&gt;
    right: 5px;&lt;br /&gt;
    z-index: 100;&lt;br /&gt;
    padding: 4px 8px;&lt;br /&gt;
    background-color: #f8f9fa;&lt;br /&gt;
    border: 1px solid #a2a9b1;&lt;br /&gt;
    border-radius: 4px;&lt;br /&gt;
    color: #202122;&lt;br /&gt;
    font-size: 11px;&lt;br /&gt;
    font-family: sans-serif;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
    opacity: 0.8;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.copy-code-button:hover {&lt;br /&gt;
    opacity: 1;&lt;br /&gt;
    background-color: #ffffff;&lt;br /&gt;
    border-color: #447ff5;&lt;br /&gt;
    color: #447ff5;&lt;br /&gt;
    box-shadow: 0 1px 2px rgba(0,0,0,0.1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTES RESPONSIVOS ATRONIA --- */&lt;br /&gt;
&lt;br /&gt;
@media only screen and (max-width: 768px) {&lt;br /&gt;
&lt;br /&gt;
    #custom-atronia-footer img[src*=&amp;quot;Igus.svg&amp;quot;] {&lt;br /&gt;
        max-width: 120px !important; /* Ajusta este valor (ex: 100px ou 120px) até gostares */&lt;br /&gt;
        margin-bottom: 10px;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 1. Forçar menus a empilhar no mobile */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;justify-content: space-between&amp;quot;] {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: flex-start !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 2. Grelha de Logos: Passa de 2 colunas para 1 no mobile para não esmagar */&lt;br /&gt;
    #custom-atronia-footer div[style*=&amp;quot;display: grid&amp;quot;] {&lt;br /&gt;
        grid-template-columns: 1fr !important; &lt;br /&gt;
        width: 100% !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 3. Logos: Garante que as imagens não saem do ecrã */&lt;br /&gt;
    #custom-atronia-footer img {&lt;br /&gt;
        max-width: 100% !important;&lt;br /&gt;
        height: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* 4. Botões Flutuantes: Evitar que tapem os logos no fundo */&lt;br /&gt;
    #atronia-floating-nav {&lt;br /&gt;
        bottom: 15px !important;&lt;br /&gt;
        right: 10px !important;&lt;br /&gt;
        transform: scale(0.85); /* Ficam ligeiramente menores */&lt;br /&gt;
        transform-origin: bottom right;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    /* 5. Scrolling Text: Diminuir um pouco no mobile */&lt;br /&gt;
    .atronia-scrolling-container {&lt;br /&gt;
        height: 80px !important;&lt;br /&gt;
        line-height: 80px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#back-to-top {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Aplicar a fonte a todo o footer */&lt;br /&gt;
#custom-atronia-footer, &lt;br /&gt;
#custom-atronia-footer * {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
/* --- ESTRUTURA BASE --- */&lt;br /&gt;
#custom-atronia-footer {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    clear: both !important;&lt;br /&gt;
    display: block !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Scrolling Text Estilo &amp;quot;Vazado&amp;quot; */&lt;br /&gt;
.atronia-scrolling-container {&lt;br /&gt;
    background-color: #121e1c !important;&lt;br /&gt;
    overflow: hidden;&lt;br /&gt;
    white-space: nowrap;&lt;br /&gt;
    padding: 20px 0;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    border-bottom: 1px solid #ffffff !important; /* Separador abaixo do scroll */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.atronia-scrolling-content span {&lt;br /&gt;
    font-family: &#039;Rubik&#039;, sans-serif;&lt;br /&gt;
    font-size: 50px;&lt;br /&gt;
    font-weight: bold;&lt;br /&gt;
    color: transparent !important; /* Mantém o interior vazio */&lt;br /&gt;
    -webkit-text-stroke: 1.5px #ffffff; /* Branco puro e um pouco mais grosso */&lt;br /&gt;
    opacity: 1 !important; /* Garante que o contorno não seja translúcido */&lt;br /&gt;
    padding-right: 50px;&lt;br /&gt;
    display: inline-block;&lt;br /&gt;
    letter-spacing: 1px; /* Melhora a leitura em letras vazadas */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
@keyframes atronia-scroll {&lt;br /&gt;
    0% { transform: translateX(0); }&lt;br /&gt;
    100% { transform: translateX(-50%); }&lt;br /&gt;
}&lt;br /&gt;
.atronia-scrolling-content { display: inline-block; animation: atronia-scroll 15s linear infinite; }&lt;br /&gt;
&lt;br /&gt;
/* Esconder elementos nativos */&lt;br /&gt;
#footer, .mw-footer, #catlinks { display: none !important; }&lt;br /&gt;
&lt;br /&gt;
/* Forçar underline no hover e limpar estilos nativos da Wiki */&lt;br /&gt;
#custom-atronia-footer a {&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    background: none !important; /* Remove blocos de cor que a wiki possa inserir */&lt;br /&gt;
    transition: text-decoration 0.2s ease;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#custom-atronia-footer a:hover {&lt;br /&gt;
    text-decoration: underline !important;&lt;br /&gt;
    color: #ffffff !important;&lt;br /&gt;
    background: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Linha de largura total absoluta */&lt;br /&gt;
.atronia-full-width-line {&lt;br /&gt;
    border: 0 !important;&lt;br /&gt;
    border-top: 1px solid #ffffff !important;&lt;br /&gt;
    width: 100vw !important;&lt;br /&gt;
    position: relative !important;&lt;br /&gt;
    left: 50% !important;&lt;br /&gt;
    right: 50% !important;&lt;br /&gt;
    margin-left: -50vw !important;&lt;br /&gt;
    margin-right: -50vw !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Fim do Footer Atronia Website */&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Botão de Seta para o Topo */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important; /* Mesmo verde */&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    border-radius: 50% !important; /* Circular */&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    font-size: 20px !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
    cursor: pointer;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.footer-top-button:hover {&lt;br /&gt;
    transform: scale(1.1) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o container se alinha bem no mobile */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do botão Buy Now (MONARCH) - Alinhado à direita */&lt;br /&gt;
.buy-now-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    justify-content: right !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Estilo do Botão - Base e Centralização */&lt;br /&gt;
.button-buy-now a.external {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
&lt;br /&gt;
    background-color: #d1ff00 !important; /* Verde néon */&lt;br /&gt;
    color: #000 !important; /* Texto preto */&lt;br /&gt;
    &lt;br /&gt;
    /* PADDING IGUAL DOS DOIS LADOS (Essencial para centrar) */&lt;br /&gt;
    padding: 7px 25px !important; &lt;br /&gt;
    &lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: transform 0.2s ease !important;&lt;br /&gt;
&lt;br /&gt;
    /* Remove a seta e o espaço fantasma do MediaWiki */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    text-indent: 0 !important;&lt;br /&gt;
    letter-spacing: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. Forçar anulação de regras do sistema (mw-parser-output) */&lt;br /&gt;
.mw-parser-output .button-buy-now a.external {&lt;br /&gt;
    padding-right: 25px !important; /* Força a simetria com a esquerda */&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Efeito ao passar o rato */&lt;br /&gt;
.button-buy-now a.external:hover {&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ==========================================================================&lt;br /&gt;
   RODAPÉ (Footer) - Versão Final Limpa&lt;br /&gt;
   ========================================================================== */&lt;br /&gt;
&lt;br /&gt;
/* 1. Contentor do Rodapé - Permite que os itens respirem e alinhem */&lt;br /&gt;
#footer-places {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    width: 100% !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    flex-wrap: nowrap !important;&lt;br /&gt;
    padding: 10px 25px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 2. Links da Esquerda (Privacy, About, etc) */&lt;br /&gt;
#footer-places li {&lt;br /&gt;
    margin-right: 15px !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 3. NOVO CONTENTOR DOS BOTÕES (Seta + Link) &lt;br /&gt;
   O &amp;quot;margin-left: auto&amp;quot; é o íman que empurra o grupo para a direita */&lt;br /&gt;
#footer-custom-buttons-container {&lt;br /&gt;
    display: flex !important;&lt;br /&gt;
    gap: 12px !important; /* Espaço entre a seta e o botão */&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    margin-left: auto !important; &lt;br /&gt;
    margin-right: 0 !important;&lt;br /&gt;
    list-style: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 4. Estilo Comum para Seta e Botão (Cápsula Verde) */&lt;br /&gt;
.footer-top-button,&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    display: inline-flex !important;&lt;br /&gt;
    align-items: center !important;&lt;br /&gt;
    justify-content: center !important;&lt;br /&gt;
    background-color: #d1ff00 !important;&lt;br /&gt;
    color: #000 !important;&lt;br /&gt;
    font-weight: bold !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
    box-shadow: 0 4px 8px rgba(0,0,0,0.15) !important;&lt;br /&gt;
    transition: all 0.2s ease-in-out !important;&lt;br /&gt;
    border-radius: 50px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 5. Especificações da Seta (Circular) */&lt;br /&gt;
.footer-top-button {&lt;br /&gt;
    width: 40px !important;&lt;br /&gt;
    height: 40px !important;&lt;br /&gt;
    font-size: 18px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 6. Especificações do Botão do Site */&lt;br /&gt;
.footer-button-atronia-real {&lt;br /&gt;
    padding: 7px 25px !important;&lt;br /&gt;
    font-size: 1.0em !important;&lt;br /&gt;
    font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
    white-space: nowrap !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 7. Hover para os dois */&lt;br /&gt;
.footer-top-button:hover,&lt;br /&gt;
.footer-button-atronia-real:hover {&lt;br /&gt;
    background-color: #e2ff33 !important;&lt;br /&gt;
    transform: scale(1.05) !important;&lt;br /&gt;
    text-decoration: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* 8. Remover ícones de link externo do MediaWiki */&lt;br /&gt;
.footer-button-atronia-real.external,&lt;br /&gt;
.footer-button-atronia-real.external:after {&lt;br /&gt;
    background-image: none !important;&lt;br /&gt;
    padding-right: 25px !important; /* Mantém igual à esquerda para centrar */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* --- AJUSTE PARA MOBILE (Ecrãs até 720px) --- */&lt;br /&gt;
@media screen and (max-width: 720px) {&lt;br /&gt;
    #footer-places {&lt;br /&gt;
        flex-direction: column !important;&lt;br /&gt;
        align-items: center !important;&lt;br /&gt;
        text-align: center !important;&lt;br /&gt;
        width: auto !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    #footer-places li {&lt;br /&gt;
        margin-right: 0 !important;&lt;br /&gt;
        margin-bottom: 10px !important;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /* No mobile, os botões ficam centrados em baixo dos textos */&lt;br /&gt;
    #footer-custom-buttons-container {&lt;br /&gt;
        margin-left: 0 !important;&lt;br /&gt;
        margin-top: 15px !important;&lt;br /&gt;
        justify-content: center !important;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* 1. Destacar o item principal ativo */&lt;br /&gt;
.vector-toc-list-item-active &amp;gt; .vector-toc-link .vector-toc-text {&lt;br /&gt;
    font-weight: 700 !important; /* Força o negrito máximo */&lt;br /&gt;
    color: #000000 !important;   /* Cor preta forte para contraste */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Remove qualquer preenchimento extra de tags pre ou code que a wiki insira */&lt;br /&gt;
.variations-toggle pre,&lt;br /&gt;
.variations-toggle code {&lt;br /&gt;
  display: contents !important;&lt;br /&gt;
  background: none !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
  display: inline-flex; /* important */&lt;br /&gt;
  align-items: center; /* vertical centering */&lt;br /&gt;
  justify-content: center;&lt;br /&gt;
&lt;br /&gt;
  width: 24px; /* lock size */&lt;br /&gt;
  height: 24px;&lt;br /&gt;
&lt;br /&gt;
  line-height: 1; /* remove font baseline weirdness */&lt;br /&gt;
&lt;br /&gt;
  transition: transform 0.25s ease;&lt;br /&gt;
}&lt;br /&gt;
.arrow-icon.rotated {&lt;br /&gt;
    transform: rotate(180deg) !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esta regra garante transição suave mesmo se o MediaWiki interferir */&lt;br /&gt;
.arrow-icon {&lt;br /&gt;
    transition: transform 0.25s ease-in-out !important;&lt;br /&gt;
    transform-origin: center center !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.variations-list &amp;gt; pre,&lt;br /&gt;
.variations-toggle &amp;gt; pre {&lt;br /&gt;
  display: flex;&lt;br /&gt;
  flex-direction: column;&lt;br /&gt;
  padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.mw-highlight &amp;gt; pre {&lt;br /&gt;
  margin: 1em 0;&lt;br /&gt;
  padding: 12px 16px;&lt;br /&gt;
  background-color: #f6f6f6; /* restore */&lt;br /&gt;
  border: 1px solid #ddd;&lt;br /&gt;
  border-radius: 6px;&lt;br /&gt;
&lt;br /&gt;
  overflow-x: auto;&lt;br /&gt;
  white-space: pre;&lt;br /&gt;
&lt;br /&gt;
  font-family: &amp;quot;Roboto Mono&amp;quot;, monospace;&lt;br /&gt;
  font-size: 13px;&lt;br /&gt;
  line-height: 1.5;&lt;br /&gt;
&lt;br /&gt;
  display: block; /* IMPORTANT */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  margin: 0;&lt;br /&gt;
  padding: 0;&lt;br /&gt;
  padding-top: 1rem;&lt;br /&gt;
  background-color: transparent;&lt;br /&gt;
  border: transparent;&lt;br /&gt;
  display: flex;&lt;br /&gt;
  justify-content: space-around;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Limpeza profunda do collapsible na grelha de produtos */&lt;br /&gt;
.product-item .mw-collapsible {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  width: 100% !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item .mw-collapsible-content {&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
  margin: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Remove o ícone padrão de &amp;quot;seta&amp;quot; ou [Expandir] que o MediaWiki cria */&lt;br /&gt;
.product-item .mw-collapsible-toggle {&lt;br /&gt;
  float: none !important;&lt;br /&gt;
  background: transparent !important;&lt;br /&gt;
  border: none !important;&lt;br /&gt;
  padding: 0 !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Esconde o link automático de texto que o MediaWiki pode injetar */&lt;br /&gt;
.product-item .mw-collapsible-toggle-default {&lt;br /&gt;
  display: none !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.vector-dropdown-checkbox {&lt;br /&gt;
  background-color: red !important;&lt;br /&gt;
  color: red !important;&lt;br /&gt;
}&lt;br /&gt;
.products-grid {&lt;br /&gt;
  display: grid;&lt;br /&gt;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));&lt;br /&gt;
  gap: 30px;&lt;br /&gt;
  margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item {&lt;br /&gt;
  text-align: center;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-image {&lt;br /&gt;
  display: block;&lt;br /&gt;
  margin: 0 auto 10px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-title {&lt;br /&gt;
  font-weight: 600;&lt;br /&gt;
  margin-top: 6px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  font-size: 14px;&lt;br /&gt;
  color: #666;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-item strong {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.product-subtitle {&lt;br /&gt;
  display: block;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* Garante que o título do Datasheet e outros itens mantenham a consistência */&lt;br /&gt;
.vector-toc-link .vector-toc-text {&lt;br /&gt;
  font-weight: normal !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Botão Técnico Atlas - Cores Customizadas */&lt;br /&gt;
.mw-parser-output .atlas-btn {&lt;br /&gt;
  display: inline-block !important;&lt;br /&gt;
  padding: 10px 22px !important;&lt;br /&gt;
  background-color: #1b2826 !important; /* Cor base escura */&lt;br /&gt;
  border: 1px solid #1b2826 !important;&lt;br /&gt;
  border-radius: 4px !important;&lt;br /&gt;
  transition: all 0.25s ease !important;&lt;br /&gt;
  cursor: pointer !important;&lt;br /&gt;
  text-align: center !important;&lt;br /&gt;
  border-bottom: 1px solid #1b2826 !important; /* Remove qualquer traço de link */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Link dentro do botão - Forçar branco em todos os estados*/&lt;br /&gt;
.mw-parser-output .atlas-btn a,&lt;br /&gt;
.mw-parser-output .atlas-btn a:link,&lt;br /&gt;
.mw-parser-output .atlas-btn a:visited,&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover,&lt;br /&gt;
.mw-parser-output .atlas-btn a:active {&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  font-weight: bold !important;&lt;br /&gt;
  font-size: 0.95em !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Efeito Hover: Versão levemente mais clara */&lt;br /&gt;
.mw-parser-output .atlas-btn:hover {&lt;br /&gt;
  background-color: #3e524f !important; /* Tom mais claro */&lt;br /&gt;
  border-color: #2a3b38 !important;&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2) !important; /* Sombra leve para profundidade */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o link não mude de cor ou sublinhe no hover */&lt;br /&gt;
.mw-parser-output .atlas-btn a:hover {&lt;br /&gt;
  text-decoration: none !important;&lt;br /&gt;
  color: #ffffff !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Forçar a fonte Rubik no título principal */&lt;br /&gt;
#firstHeading {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-weight: 600 !important;&lt;br /&gt;
  color: #202122 !important;&lt;br /&gt;
  letter-spacing: -0.01em !important;&lt;br /&gt;
  /* Removemos a nossa borda manual para usar apenas a da Wiki */&lt;br /&gt;
  border-bottom: none !important;&lt;br /&gt;
  margin-bottom: 0 !important;&lt;br /&gt;
  padding-bottom: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Garante que o breadcrumb (&amp;lt; SENSBLUE ATLAS) também use a Rubik */&lt;br /&gt;
#contentSub,&lt;br /&gt;
#contentSub2 {&lt;br /&gt;
  font-family: &amp;quot;Rubik&amp;quot;, sans-serif !important;&lt;br /&gt;
  font-size: 0.85em !important;&lt;br /&gt;
  color: #54595d !important;&lt;br /&gt;
  margin-top: 5px !important;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
pre {&lt;br /&gt;
  font-family: &amp;quot;Roboto&amp;quot;, sans-serif !important;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=MediaWiki:Sidebar&amp;diff=1897</id>
		<title>MediaWiki:Sidebar</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=MediaWiki:Sidebar&amp;diff=1897"/>
		<updated>2026-06-30T08:35:28Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* navigation&lt;br /&gt;
** mainpage|mainpage-description&lt;br /&gt;
** monarch|SENSBLUE MONARCH&lt;br /&gt;
** SENSBLUE ATLAS|SENSBLUE ATLAS&lt;br /&gt;
*** SENSBLUE ATLAS/Datasheet|Datasheet&lt;br /&gt;
*** SENSBLUE ATLAS/Realease Notes|Release Notes&lt;br /&gt;
** Main Page#Probes|PROBES&lt;br /&gt;
** recentchanges-url|recentchanges&lt;br /&gt;
** helppage|help-mediawiki&lt;br /&gt;
** specialpages-url|specialpages&lt;br /&gt;
* SEARCH&lt;br /&gt;
* TOOLBOX&lt;br /&gt;
* LANGUAGES&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
	<entry>
		<id>https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Datasheet&amp;diff=1896</id>
		<title>SENSBLUE ATLAS/Datasheet</title>
		<link rel="alternate" type="text/html" href="https://wiki.atronia.eu/index.php?title=SENSBLUE_ATLAS/Datasheet&amp;diff=1896"/>
		<updated>2026-06-30T08:33:23Z</updated>

		<summary type="html">&lt;p&gt;WikiManagement: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{DISPLAYTITLE:Datasheet}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;buy-now-container&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;button-buy-now&amp;quot;&amp;gt;[https://atronia.eu/product/sensblue-atlas/ Buy Now]&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:SENSBLUE-ATLAS-Gateway.png|center|frameless|360x360px]]&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;&#039;Datasheet&#039;&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
=== 1. Table of SENSBLUE ATLAS Reference ID Model Number ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Reference Number&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Version&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;RAM&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Modem&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;PiggyBack&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000102&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 2GB M2.0 M1 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|2GB&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|PA000000103&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 2GB M2.0 M0 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|2GB&lt;br /&gt;
|Yes&lt;br /&gt;
|No&lt;br /&gt;
|-&lt;br /&gt;
|PA000000104&lt;br /&gt;
|ATLAS IoT SBC V1 CM4. 4GB M2.0 M1 PB0&lt;br /&gt;
|V1&lt;br /&gt;
|4GB&lt;br /&gt;
|No&lt;br /&gt;
|No&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 2. General Description ===&lt;br /&gt;
SENSBLUE ATLAS is a single board computer that connects sensors and assets, runs control logic and ships to production without platform changes.&lt;br /&gt;
&lt;br /&gt;
Designed for industrial teams who need one dependable path from experiments to operations.&lt;br /&gt;
&lt;br /&gt;
==== 2.1 Key Features ====&lt;br /&gt;
&#039;&#039;&#039;Processor:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Raspberry Pi CM4 (quad-core Cortex-A72)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;I/O:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 12 DIO (8 Digital Outputs and 4 Digital Input)&lt;br /&gt;
* 6 AIO (4 Analog Inputs and 2 Analog Outputs)&lt;br /&gt;
* 2 relays&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Industrial Bus:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* RS-485&lt;br /&gt;
* CAN&lt;br /&gt;
* 2× Ethernet port (Independently managed)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Communication:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Integrated LTE&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
* BLE&lt;br /&gt;
* USB&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Interface &amp;amp; Services:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* 1.47″ IPS TFT display + joystick for local setup and feedback.&lt;br /&gt;
* Includes 1 GB of data (up to 500 MB LTE + 500 MB DB storage) via sensblue.cloud — no external SIM required.&lt;br /&gt;
* EU-hosted servers, TLS, weekly backups, VPN on request.&lt;br /&gt;
* Other versions under request.&lt;br /&gt;
&lt;br /&gt;
=== 3. Hardware Specifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Platform&lt;br /&gt;
|Raspberry  Pi Compute Module 4 (CM4)&lt;br /&gt;
|-&lt;br /&gt;
|Processor&lt;br /&gt;
|Broadcom  BCM2711 Quad-core Cortex-A72 (ARM v8)&lt;br /&gt;
|-&lt;br /&gt;
|CPU Frequency&lt;br /&gt;
|1.5  GHz&lt;br /&gt;
|-&lt;br /&gt;
|RAM&lt;br /&gt;
|2GB, 4GB  LPDDR4&lt;br /&gt;
|-&lt;br /&gt;
|Storage&lt;br /&gt;
|32  GB eMMC&lt;br /&gt;
|-&lt;br /&gt;
|Selected Variant&lt;br /&gt;
|CM4102032-4  GB RAM/ 32 GB eMMC / Wi-Fi / BLE&lt;br /&gt;
|-&lt;br /&gt;
|PCle&lt;br /&gt;
|1  x PCle Gen 2.0 (1 lane)&lt;br /&gt;
|-&lt;br /&gt;
|HDMI&lt;br /&gt;
|1  interfaces&lt;br /&gt;
|-&lt;br /&gt;
|USB&lt;br /&gt;
|2  x USB 2.0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 4. Power ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Input  voltage&lt;br /&gt;
|12-24  VDC ± 5%&lt;br /&gt;
|-&lt;br /&gt;
|Reverse polarity protection&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|Overcurrent protection&lt;br /&gt;
|Resettable  PTC fuse&lt;br /&gt;
|-&lt;br /&gt;
|Surge protection&lt;br /&gt;
|TVS  clamp for transient events&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|No  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Typical consumption&lt;br /&gt;
|&amp;lt;  15 W&lt;br /&gt;
|-&lt;br /&gt;
|Maximum consumption&lt;br /&gt;
|25  W (all peripherals active)&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 5. Digital Inputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|Input voltage&lt;br /&gt;
|0-24  VDC&lt;br /&gt;
|-&lt;br /&gt;
|Logic LOW&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Logic HIGH&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Input type&lt;br /&gt;
|Sourcing  (PNP)&lt;br /&gt;
|-&lt;br /&gt;
|Input current&lt;br /&gt;
|Acording  to EN 61131-2 Type I and Ill&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage&lt;br /&gt;
|Functional  isolation between channels on the field side +- 60V&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-11&lt;br /&gt;
|Maximum  working isolation voltage 400V RMS&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-11&lt;br /&gt;
|Maximum  surge  isolation voltage 1 kV RMS&lt;br /&gt;
|-&lt;br /&gt;
|Special feature&lt;br /&gt;
|Can  be used as fast inputs until 100Hz&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 5.1 Wiring ====&lt;br /&gt;
[[File:DIG IN.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 6. Digital Outputs (Relay) ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot; style=&amp;quot;width: 100%;&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|Mechanical  relay&lt;br /&gt;
|-&lt;br /&gt;
|Switching capacity&lt;br /&gt;
|2  A@ 30 VDC&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|1000  VAC galvanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Lifetime (nominal load)&lt;br /&gt;
|≥  100,000 cycles&lt;br /&gt;
|-&lt;br /&gt;
|Lifetime (no load)&lt;br /&gt;
|≥  100,000,000  cycles&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 6.1 Wiring ====&lt;br /&gt;
[[File:RELAY.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 7. Digital Outputs (Transistor/ SSR) ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|8&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|PNP  (sourcing) SSR&lt;br /&gt;
|-&lt;br /&gt;
|Maximum current&lt;br /&gt;
|300  mA per channel&lt;br /&gt;
|-&lt;br /&gt;
|Maximum voltage&lt;br /&gt;
|24  VDC&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic  isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation Voltage DIN VDE V  0884-17&lt;br /&gt;
|Maximum  transient isolation voltage 1 kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 7.1 Wiring ====&lt;br /&gt;
[[File:DIG OUT.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 8. Analog Inputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|4&lt;br /&gt;
|-&lt;br /&gt;
|Mode &lt;br /&gt;
|Voltage or current configurable  per channel&lt;br /&gt;
|-&lt;br /&gt;
|Voltage  range&lt;br /&gt;
|0-10 V&lt;br /&gt;
|-&lt;br /&gt;
|Current  range&lt;br /&gt;
|0/4-20 mA&lt;br /&gt;
|-&lt;br /&gt;
|ADC  resolution&lt;br /&gt;
|16 bits&lt;br /&gt;
|-&lt;br /&gt;
|ADC  Sample Rate&lt;br /&gt;
|32 samples/sec&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|≤  ±1.0% FSR&lt;br /&gt;
|-&lt;br /&gt;
|Input  impedance (voltage)&lt;br /&gt;
|&amp;gt; 100 k&#039;&#039;&#039;Ω&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Input  impedance (current)&lt;br /&gt;
|100  &#039;&#039;&#039;Ω&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|TVS  + analog filtering&lt;br /&gt;
|-&lt;br /&gt;
|Sampling  rate&lt;br /&gt;
|≥  10 Hz per channel&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional  Safety Gavanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation  Voltage&lt;br /&gt;
|Maximum  transient isolation voltage 1 kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 8.1 Wiring ====&lt;br /&gt;
[[File:ANL IN.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 9. Analog Outputs ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Channels&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Output  type&lt;br /&gt;
|Current&lt;br /&gt;
|-&lt;br /&gt;
|Range&lt;br /&gt;
|0-20 mA&lt;br /&gt;
|-&lt;br /&gt;
|Optional  range&lt;br /&gt;
|4-20 mA (software configurable)&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|12&lt;br /&gt;
|-&lt;br /&gt;
|Accuracy&lt;br /&gt;
|≤ ±1.0%  FSR&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|Funcional Safety Gavanic isolation&lt;br /&gt;
|-&lt;br /&gt;
|Isolation  Voltage&lt;br /&gt;
|Maximum transient isolation voltage 1  kV RMS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 9.1 Wiring ====&lt;br /&gt;
[[File:ANL OUT.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
=== 10. Communication Interfaces ===&lt;br /&gt;
&lt;br /&gt;
==== 10.1 Ethernet ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | &#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
! style=&amp;quot;width: 50%;&amp;quot; | &#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|2 x RJ45&lt;br /&gt;
|-&lt;br /&gt;
|Port  1&lt;br /&gt;
|10/100 Mbps&lt;br /&gt;
|-&lt;br /&gt;
|Port  2&lt;br /&gt;
|0/100/1000 Mbps (native CM4)&lt;br /&gt;
|-&lt;br /&gt;
|Indicators&lt;br /&gt;
|Link + Activity LEDs&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 10.2 RS-485 ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Mode&lt;br /&gt;
|Half-duplex&lt;br /&gt;
|-&lt;br /&gt;
|Control&lt;br /&gt;
|TX_EN line&lt;br /&gt;
|-&lt;br /&gt;
|Protocol&lt;br /&gt;
|Transparent/ any&lt;br /&gt;
|-&lt;br /&gt;
|Isolation&lt;br /&gt;
|None&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 10.2.1 Wiring =====&lt;br /&gt;
[[File:RS485.svg|center|frameless|500x500px]]&lt;br /&gt;
&lt;br /&gt;
==== 10.3 USB ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|2&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|USB-A&lt;br /&gt;
|-&lt;br /&gt;
|Standard&lt;br /&gt;
|USB 2.0 Host&lt;br /&gt;
|-&lt;br /&gt;
|Maximum  current&lt;br /&gt;
|400 mA per port&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|Overcurrent protection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 10.4 HDMI ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Ports&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|Connector&lt;br /&gt;
|HDMI full-size &lt;br /&gt;
|-&lt;br /&gt;
|Maximum  resolution&lt;br /&gt;
|Depends on CM4 and OS&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 11. RF Communications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Technology&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Wi-Fi&lt;br /&gt;
|Integrated in CM4&lt;br /&gt;
|-&lt;br /&gt;
|BLE&lt;br /&gt;
|Integrated in CM4&lt;br /&gt;
|-&lt;br /&gt;
|LTE&lt;br /&gt;
|M.2 NGFF modem SIM7600G&lt;br /&gt;
|-&lt;br /&gt;
|SIM&lt;br /&gt;
|External access&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 11.1  Antenna Connectors ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Connector&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Usage&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|RP-SMA&lt;br /&gt;
|Wi-Fi / BLE&lt;br /&gt;
|-&lt;br /&gt;
|SMA&lt;br /&gt;
|LTE&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 12. Local Peripherals ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Peripheral&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Description&#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Temperature  sensor&lt;br /&gt;
|Internal board temperature monitoring&lt;br /&gt;
|-&lt;br /&gt;
|Non-volatile  memory&lt;br /&gt;
|Persistent storage&lt;br /&gt;
|-&lt;br /&gt;
|Security  IC&lt;br /&gt;
|Microchip ATECC608A&lt;br /&gt;
|-&lt;br /&gt;
|RTC&lt;br /&gt;
|Real Time Clock with battery  backup&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 13. HDMI ===&lt;br /&gt;
&lt;br /&gt;
==== 13. 1 Display ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|IPS TFT LCD&lt;br /&gt;
|-&lt;br /&gt;
|Interface&lt;br /&gt;
|SPI&lt;br /&gt;
|-&lt;br /&gt;
|Size&lt;br /&gt;
|1.47&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|Resolution&lt;br /&gt;
|≥ 172 X 320&lt;br /&gt;
|-&lt;br /&gt;
|Backlight&lt;br /&gt;
|LED&lt;br /&gt;
|-&lt;br /&gt;
|Mounting&lt;br /&gt;
|Front mounted with transparent  window&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== 13. 2 Joystick ====&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Positions&lt;br /&gt;
|5 (Up/ Down/ Left/ Right/ Enter)&lt;br /&gt;
|-&lt;br /&gt;
|Type&lt;br /&gt;
|Mechanical tactile switch&lt;br /&gt;
|-&lt;br /&gt;
|Interface&lt;br /&gt;
|GPIO Expander&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 14. Mechanical ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Mounting&lt;br /&gt;
|DIN rail (EN 60715)&lt;br /&gt;
|-&lt;br /&gt;
|Enclosure&lt;br /&gt;
|MAT0091092 (same as iSense / iCee)&lt;br /&gt;
|-&lt;br /&gt;
|Protection  rating&lt;br /&gt;
|IP20&lt;br /&gt;
|-&lt;br /&gt;
|Mounting  method&lt;br /&gt;
|DIN rail snap-fit&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 15. Environmental ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Specification &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Operating  temperature&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-10 °C to +60 °C&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Storage  temperature&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;-20 °C to +80 °C&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|Humidity&lt;br /&gt;
|5-95% non-condensing&lt;br /&gt;
|-&lt;br /&gt;
|Vibration&lt;br /&gt;
|IEC 60068-2-6&lt;br /&gt;
|-&lt;br /&gt;
|Shock&lt;br /&gt;
|IEC 60068-2-27&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 16. Certifications ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Certification&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Standard  &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|CE&lt;br /&gt;
|Yes&lt;br /&gt;
|-&lt;br /&gt;
|EMC&lt;br /&gt;
|2014/30/EU&lt;br /&gt;
|-&lt;br /&gt;
|Radio&lt;br /&gt;
|2014/53/EU (RED)&lt;br /&gt;
|-&lt;br /&gt;
|Ro  HS&lt;br /&gt;
|2011/65/EU&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 17. Connectivity ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Specification  &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Connector  type&lt;br /&gt;
|Pluggable System Terminal Block&lt;br /&gt;
|-&lt;br /&gt;
|Pitch&lt;br /&gt;
|3.5 mm&lt;br /&gt;
|-&lt;br /&gt;
|Layout&lt;br /&gt;
|Dual-row&lt;br /&gt;
|-&lt;br /&gt;
|Identification&lt;br /&gt;
|Side panel silk screen&lt;br /&gt;
|-&lt;br /&gt;
|Fixation&lt;br /&gt;
|Mechanical locking or spring  clamp&lt;br /&gt;
|-&lt;br /&gt;
|Protection&lt;br /&gt;
|Mechanical reverse insertion  protection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 18. Expansion ===&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Feature&#039;&#039;&#039; &lt;br /&gt;
!style=&amp;quot;width: 50%;&amp;quot;|&#039;&#039;&#039;Description &#039;&#039;&#039; &lt;br /&gt;
|-&lt;br /&gt;
|Piggyback  area&lt;br /&gt;
|Reserved PCB area&lt;br /&gt;
|-&lt;br /&gt;
|Compatibility&lt;br /&gt;
|Fully compatible with existing FW&lt;br /&gt;
|-&lt;br /&gt;
|Power  rails available&lt;br /&gt;
|Vin, 5 V, 3.3 V&lt;br /&gt;
|-&lt;br /&gt;
|Interfaces  available&lt;br /&gt;
|12C, SPI, UART, GPIO&lt;br /&gt;
|-&lt;br /&gt;
|External  1/0 lines&lt;br /&gt;
|32 lines routed to external  connectors&lt;br /&gt;
|-&lt;br /&gt;
|Storage  expansion&lt;br /&gt;
|M.2 NVMe SSD connector&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 19. External Interfaces ===&lt;br /&gt;
&lt;br /&gt;
==== Front View ====&lt;br /&gt;
[[File:Atlas FrontView.png|center|frameless|670x670px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Bottom View ====&lt;br /&gt;
[[File:Atlas bottomview.png|center|frameless|590x590px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 20. Pinouts ===&lt;br /&gt;
&lt;br /&gt;
==== Top View ====&lt;br /&gt;
[[File:Atlas topview.png|center|frameless|688x688px]]&lt;br /&gt;
&lt;br /&gt;
=== 21. System Type ===&lt;br /&gt;
&#039;&#039;&#039;Raspian&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Debian GNU/Linux 13 (trixie) Version 13.2 Linux atlas 6.12.47 +rpt-rpi-v8 #1 SMP PREEMPT&lt;br /&gt;
&lt;br /&gt;
Debian 1 :6.12.47-1 +rpt1 (2025-09-16) aarch64 GNU/Linux.&lt;br /&gt;
&lt;br /&gt;
=== 22. Network Information ===&lt;br /&gt;
There is three ways to connect to the device. IP and state of the connection be checked on the LCD Network Interface.&lt;br /&gt;
&lt;br /&gt;
==== 22.1 Eth1 (ethO) ====&lt;br /&gt;
Client dynamic IP obtained by DHCP server.&lt;br /&gt;
&lt;br /&gt;
==== 22.2 Eth2 (eth1) ====&lt;br /&gt;
Static IP: &#039;&#039;&#039;93.48.86.253&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==== 22.3 Access Point (wlanO) ====&lt;br /&gt;
IP: &#039;&#039;&#039;192.168.30.1&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== 23. Software Information ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&lt;br /&gt;
|&#039;&#039;&#039;Node-Red&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Grafana&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;lnfluxDB&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Version&lt;br /&gt;
|4.1.4&lt;br /&gt;
|12.3.1&lt;br /&gt;
|2.8.0&lt;br /&gt;
|-&lt;br /&gt;
|Port&lt;br /&gt;
|1880&lt;br /&gt;
|3000&lt;br /&gt;
|8086&lt;br /&gt;
|-&lt;br /&gt;
|State&lt;br /&gt;
|Clean&lt;br /&gt;
|Clean&lt;br /&gt;
|Clean&lt;br /&gt;
|-&lt;br /&gt;
|Authentication&lt;br /&gt;
|None&lt;br /&gt;
|User/Pass  (admin/admin)&lt;br /&gt;
|Not  defined, configured on first time interface login.&lt;br /&gt;
|-&lt;br /&gt;
|GUI on&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:1880&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:3000&lt;br /&gt;
|http://&amp;lt;device-ip&amp;gt;:8086&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 24. MQTT Broker ===&lt;br /&gt;
port: 1883&lt;br /&gt;
&lt;br /&gt;
address: AP-&amp;gt; 192.168.30.1&lt;br /&gt;
&lt;br /&gt;
Eth1: &#039;&#039;&#039;93.48.86.253&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
user: &amp;lt; not needed&amp;gt;&lt;br /&gt;
&lt;br /&gt;
login &amp;lt;not needed&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.1 Relay Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.1.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set/reset digital output pin/pins state ======&lt;br /&gt;
Both relays &#039;&#039;&#039;default&#039;&#039;&#039; state is &#039;&#039;&#039;open&#039;&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/config/in&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/config/out&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Get all relays state ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/runtime/out &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Set all relays state ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: relayOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: relayOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;open&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;close&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.2 RTC Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.2.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set timer/alarm interruption ======&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; Timer, alarm or none.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alarmSet:&#039;&#039;&#039; Date and time for alarm interruption (No effect if mode is timer or none). &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;timerSetSeconds:&#039;&#039;&#039; Period in seconds for timer interruption (No effect if mode is alarm or none).&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;CLOCK_SET_MODE&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Req-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;CLOCK_SET_MODE&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Toggle RTC sync logic (described below) ======&lt;br /&gt;
&#039;&#039;&#039;tcState:&#039;&#039;&#039; State of the synchronization logic of the RTC, this value is &#039;&#039;&#039;non-persistent&#039;&#039;&#039; so every-time a reboot happens the value return to default (by default the value is &#039;&#039;&#039;ON&#039;&#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;TOGGLE&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Req-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;rtcState&amp;quot;: &amp;quot;OFF&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read clock configs ======&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; Timer, alarm or none.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;alarmSet:&#039;&#039;&#039; Date and time for alarm interruption (No effect if mode is timer or none).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;timerSetSeconds:&#039;&#039;&#039; Period in seconds for timer interruption (No effect if mode is alarm or none).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;rtcState:&#039;&#039;&#039; Current state of the synchronization logic of the RTC.&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: clock/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;CLOCK_CONFIGS&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;timer&amp;quot;,&lt;br /&gt;
        &amp;quot;alarmSet&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;,&lt;br /&gt;
        &amp;quot;timerSetSeconds&amp;quot;: &amp;quot;&amp;lt;INT&amp;gt;&amp;quot;,&lt;br /&gt;
        &amp;quot;rtcState&amp;quot;: &amp;quot;ON&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== d) Read clock ======&lt;br /&gt;
&lt;br /&gt;
Req-Topic: clock/runtime/in &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;timestamp&amp;quot;: &amp;quot;[timestamp epoch ms]&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.2.2 Synchronization loop flowchart (every 30 seconds) =====&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RTC Actor - Overview&#039;&#039;&#039;&lt;br /&gt;
[[File:RTCActor Overview.svg|center|frameless|903x903px]]&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.3 Core System Health Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.3.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker.&lt;br /&gt;
&lt;br /&gt;
This interface allows any external App to &#039;&#039;&#039;receive system-level metrics&#039;&#039;&#039; such as CPU load, RAM usage, disk usage, temperature, core frequency, system throttle status and uptime.&lt;br /&gt;
&lt;br /&gt;
No credentials are required to subscribe to this topic.&lt;br /&gt;
&lt;br /&gt;
The System Health Actor &#039;&#039;&#039;does not receive commands&#039;&#039;&#039;. It is fully autonomous and publishes its metrics every &#039;&#039;&#039;1 second&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===== 24.3.2 Runtime Data =====&lt;br /&gt;
&#039;&#039;&#039;Topic: systemHealth/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Publish rate: &#039;&#039;&#039;1 Hz&#039;&#039;&#039; (one message per second, clock-jump safe)&lt;br /&gt;
&lt;br /&gt;
====== a) Metrics Provided ======&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Key&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Unit&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|cpu_percent&lt;br /&gt;
|Current  CPU load&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|cpu_tempC&lt;br /&gt;
|CPU  temperature read from Linux thermal zones&lt;br /&gt;
|ºC&lt;br /&gt;
|-&lt;br /&gt;
|cpu0_freq&lt;br /&gt;
|CPU Core O current  frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpul_freq&lt;br /&gt;
|CPU  Core 1 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu2_freq&lt;br /&gt;
|CPU Core 2 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu3_freq&lt;br /&gt;
|CPU  Core 3 current frequency&lt;br /&gt;
|Hz&lt;br /&gt;
|-&lt;br /&gt;
|cpu0_throttle&lt;br /&gt;
|System  throttle status register&lt;br /&gt;
|Hex&lt;br /&gt;
|-&lt;br /&gt;
|ram_percent&lt;br /&gt;
|RAM  usage&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|disk_percent&lt;br /&gt;
|Disk  usage for filesystem root /&lt;br /&gt;
|%&lt;br /&gt;
|-&lt;br /&gt;
|uptime_sec&lt;br /&gt;
|Time  since last reboot&lt;br /&gt;
|seconds&lt;br /&gt;
|}&lt;br /&gt;
Example Payload (systemHealth/runtime/out) &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;cpu_percent&amp;quot;: 7.1,&lt;br /&gt;
      &amp;quot;cpu_tempC&amp;quot;: 47.3,&lt;br /&gt;
      &amp;quot;cpu0_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu1_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu2_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu3_freq&amp;quot;: 1500000000,&lt;br /&gt;
      &amp;quot;cpu0_throttle&amp;quot;: &amp;quot;0x0&amp;quot;,&lt;br /&gt;
      &amp;quot;ram_percent&amp;quot;: 32.9,&lt;br /&gt;
      &amp;quot;disk_percent&amp;quot;: 41.2,&lt;br /&gt;
      &amp;quot;uptime_sec&amp;quot;: 5321&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.3.3 Peripherals health =====&lt;br /&gt;
  In order get the peripherals health we had to implement a SystemHealth actor in each bus manager (busi2c­O, busi2c-1, etc. ... ).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Peripherals health.svg|center|frameless|792x792px]]&lt;br /&gt;
&lt;br /&gt;
====== a) Example ======&lt;br /&gt;
&#039;&#039;&#039;For busi2c-0:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply topic: &#039;&#039;&#039;systemHealth/busi2c-0/runtime/out&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Payload:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health-busi2c-0&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;ADC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;ERROR&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;IRQ Retrying&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378753006,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760548,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253313&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760475,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253314&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760528,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253313&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 563154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 760549,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 253312&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DAC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running....&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752576,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 240755,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 240755,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;RTC&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752094,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;samples&amp;quot;: 248710,&lt;br /&gt;
          &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
          &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;TEMP&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770378752579,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;samples&amp;quot;: 240754,&lt;br /&gt;
          &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
          &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;For busi2c-1:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply topic: &#039;&#039;&#039;systemHealth/busi2c-1/runtime/out&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
Payload:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health-busi2c-1&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;JOYSTICK&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running....&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770382405050,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 410154,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;read_raw&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;buttons&amp;quot;: {&lt;br /&gt;
            &amp;quot;JDOWN&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JRIGHT&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JUP&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JLEFT&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;JCENTER&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 410154,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;RELAYS&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Relay Output MQTT connected&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770298859099,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;set&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;set_many&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;raw_read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;outputs&amp;quot;: {&lt;br /&gt;
          &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
            &amp;quot;writes&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;last_state&amp;quot;: &amp;quot;unknown&amp;quot;&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
            &amp;quot;writes&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;last_state&amp;quot;: &amp;quot;unknown&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI&amp;quot;: {&lt;br /&gt;
        &amp;quot;status&amp;quot;: &amp;quot;OK&amp;quot;,&lt;br /&gt;
        &amp;quot;description&amp;quot;: &amp;quot;Running&amp;quot;,&lt;br /&gt;
        &amp;quot;last_report&amp;quot;: 1770382404832,&lt;br /&gt;
        &amp;quot;stats&amp;quot;: {&lt;br /&gt;
          &amp;quot;read_all&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 181758,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;read_raw&amp;quot;: {&lt;br /&gt;
            &amp;quot;samples&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;retries&amp;quot;: 0,&lt;br /&gt;
            &amp;quot;discards&amp;quot;: 0&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;inputs&amp;quot;: {&lt;br /&gt;
            &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            },&lt;br /&gt;
            &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
              &amp;quot;reads&amp;quot;: 181758,&lt;br /&gt;
              &amp;quot;last_state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.3.4 Commands =====&lt;br /&gt;
&lt;br /&gt;
====== a) List usb devices ======&lt;br /&gt;
The list_usb_devices action returns a parsed list of USB devices detected on the system using the lsusb command. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;Dev&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;LIST_USB_DEVICES&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/usb/devices/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;list_usb_devices&amp;quot;,&lt;br /&gt;
  &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
     &amp;quot;usb_devices&amp;quot;: {&lt;br /&gt;
       &amp;quot;success&amp;quot;: true,&lt;br /&gt;
       &amp;quot;command&amp;quot;: &amp;quot;lsusb&amp;quot;,&lt;br /&gt;
       &amp;quot;returncode&amp;quot;: 0,&lt;br /&gt;
       &amp;quot;devices&amp;quot;: [ &lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;1d6b&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;0002&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Linux Foundation 2.0 root hub&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;002&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;0424&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;9514&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;003&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;0424&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;ec00&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         },&lt;br /&gt;
         {&lt;br /&gt;
           &amp;quot;bus&amp;quot;: &amp;quot;001&amp;quot;,&lt;br /&gt;
           &amp;quot;device&amp;quot;: &amp;quot;004&amp;quot;,&lt;br /&gt;
           &amp;quot;vendor_id&amp;quot;: &amp;quot;1e0e&amp;quot;,&lt;br /&gt;
           &amp;quot;product_id&amp;quot;: &amp;quot;9001&amp;quot;,&lt;br /&gt;
           &amp;quot;description&amp;quot;: &amp;quot;Qualcomm / Option SimTech, Incorporated&amp;quot;,&lt;br /&gt;
           &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
         }&lt;br /&gt;
       ],&lt;br /&gt;
       &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;JSON Path&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Example&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string /number&lt;br /&gt;
|&amp;quot;get-hw-info-001&amp;quot;&lt;br /&gt;
|Request identifier echoed back in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;system-health&amp;quot;&lt;br /&gt;
|Actor/device that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Container for the action response.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;list_usb_devices&amp;quot;&lt;br /&gt;
|Action executed by the actor.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main result object for the action.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the USB device scan result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the lsusb&lt;br /&gt;
commandexecuted successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.command&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;lsusb&amp;quot;&lt;br /&gt;
|Command used to collect USB information.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.returncode&lt;br /&gt;
|number /null&lt;br /&gt;
|0&lt;br /&gt;
|Process return code. 0 means success. null&lt;br /&gt;
means the command was not executed ortimed out.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices&lt;br /&gt;
|array&lt;br /&gt;
|[...]&lt;br /&gt;
|List of USB devices detected by lsusb.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].bus&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;001&amp;quot;&lt;br /&gt;
|USB bus number where the device wasdetected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].device&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;004&amp;quot;&lt;br /&gt;
|USB device number assigned on that bus.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].vendor_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;1e0e&amp;quot;&lt;br /&gt;
|USB vendor ID in hexadecimal format.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].product_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;9001&amp;quot;&lt;br /&gt;
|USB product ID in hexadecimal format.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].description&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;Qualcomm / Option SimTech,Incorporated&amp;quot;&lt;br /&gt;
|Human-readable device description returnedby lsusb.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].parsed&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the lsusb line was parsed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.devices[ ].raw&lt;br /&gt;
|string&lt;br /&gt;
|Optional&lt;br /&gt;
|Present only when a device line could not beparsed.&lt;br /&gt;
Contains the original raw lsusb line.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.usb_devices.stderr&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot; &amp;quot;&lt;br /&gt;
|Error output from the command. Empty stringmeans no error.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== b) List connectivity specs ======&lt;br /&gt;
The list_connectivity_specs action allows the &#039;&#039;&#039;SystemHealth&#039;&#039;&#039; Actor to return connectivity information for the device, including the status of:&lt;br /&gt;
&lt;br /&gt;
* Wi-Fi&lt;br /&gt;
* LTE modem&lt;br /&gt;
* eth0&lt;br /&gt;
* eth1&lt;br /&gt;
* Tunnel interfaces, for possible commissioning use&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;quot;connectivity-001&amp;quot;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;list_connectivity_specs&amp;quot;&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/connectivity/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;list_connectivity_specs&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;connectivity&amp;quot;: {&lt;br /&gt;
        &amp;quot;sources&amp;quot;: {&lt;br /&gt;
          &amp;quot;sysfs&amp;quot;: &amp;quot;/sys/class/net&amp;quot;,&lt;br /&gt;
          &amp;quot;ip_link&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;ip -j -d link show&amp;quot;,&lt;br /&gt;
            &amp;quot;error&amp;quot;: null&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;nmcli -t -f DEVICE,TYPE,STATE,CONNECTION device status&amp;quot;,&lt;br /&gt;
            &amp;quot;error&amp;quot;: null&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;interfaces&amp;quot;: {&lt;br /&gt;
          &amp;quot;wifi&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;interfaces&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;interface&amp;quot;: &amp;quot;wlan0&amp;quot;,&lt;br /&gt;
                &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                &amp;quot;status&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
                &amp;quot;carrier&amp;quot;: false,&lt;br /&gt;
                &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
                &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
                &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:40&amp;quot;,&lt;br /&gt;
                &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
                &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
                &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
                  &amp;quot;device&amp;quot;: &amp;quot;wlan0&amp;quot;,&lt;br /&gt;
                  &amp;quot;type&amp;quot;: &amp;quot;wifi&amp;quot;,&lt;br /&gt;
                  &amp;quot;state&amp;quot;: &amp;quot;disconnected&amp;quot;,&lt;br /&gt;
                  &amp;quot;connection&amp;quot;: null&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;wifi&amp;quot;: {&lt;br /&gt;
                  &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                  &amp;quot;command&amp;quot;: &amp;quot;iw dev wlan0 link&amp;quot;,&lt;br /&gt;
                  &amp;quot;connected&amp;quot;: false&lt;br /&gt;
                }&lt;br /&gt;
              }&lt;br /&gt;
            ]&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;lte_modem&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;tool_available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;command&amp;quot;: &amp;quot;mmcli -L&amp;quot;,&lt;br /&gt;
            &amp;quot;modems&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;id&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
                &amp;quot;success&amp;quot;: true,&lt;br /&gt;
                &amp;quot;command&amp;quot;: &amp;quot;mmcli -m 0 --output-json&amp;quot;,&lt;br /&gt;
                &amp;quot;manufacturer&amp;quot;: &amp;quot;QUALCOMM INCORPORATED&amp;quot;,&lt;br /&gt;
                &amp;quot;model&amp;quot;: &amp;quot;SIMCOM_SIM7600G-H&amp;quot;,&lt;br /&gt;
                &amp;quot;revision&amp;quot;: &amp;quot;LE20B04SIM7600G22&amp;quot;,&lt;br /&gt;
                &amp;quot;hardware_revision&amp;quot;: &amp;quot;10000&amp;quot;,&lt;br /&gt;
                &amp;quot;device&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
                &amp;quot;drivers&amp;quot;: [&lt;br /&gt;
                  &amp;quot;qmi_wwan&amp;quot;,&lt;br /&gt;
                  &amp;quot;option&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;plugin&amp;quot;: &amp;quot;simtech&amp;quot;,&lt;br /&gt;
                &amp;quot;primary_port&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
                &amp;quot;ports&amp;quot;: [&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;qmi&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;ignored&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB1&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;gps&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB2&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;at&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB3&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;at&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;ttyUSB4&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;audio&amp;quot;&lt;br /&gt;
                  },&lt;br /&gt;
                  {&lt;br /&gt;
                    &amp;quot;name&amp;quot;: &amp;quot;wwan0&amp;quot;,&lt;br /&gt;
                    &amp;quot;type&amp;quot;: &amp;quot;net&amp;quot;&lt;br /&gt;
                  }&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;state&amp;quot;: &amp;quot;failed&amp;quot;,&lt;br /&gt;
                &amp;quot;power_state&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
                &amp;quot;access_technologies&amp;quot;: [],&lt;br /&gt;
                &amp;quot;signal_quality&amp;quot;: {&lt;br /&gt;
                  &amp;quot;recent&amp;quot;: &amp;quot;yes&amp;quot;,&lt;br /&gt;
                  &amp;quot;value&amp;quot;: &amp;quot;0&amp;quot;&lt;br /&gt;
                },&lt;br /&gt;
                &amp;quot;current_capabilities&amp;quot;: [&lt;br /&gt;
                  &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;supported_capabilities&amp;quot;: [&lt;br /&gt;
                  &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
                ],&lt;br /&gt;
                &amp;quot;operator_code&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;operator_name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;registration_state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;packet_service_state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
                &amp;quot;sim_path&amp;quot;: null&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;network_interfaces&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;interface&amp;quot;: &amp;quot;wwan0&amp;quot;,&lt;br /&gt;
                &amp;quot;available&amp;quot;: true,&lt;br /&gt;
                &amp;quot;status&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
                &amp;quot;admin_up&amp;quot;: false,&lt;br /&gt;
                &amp;quot;carrier&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
                &amp;quot;type&amp;quot;: 65534,&lt;br /&gt;
                &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
                &amp;quot;mac_address&amp;quot;: null,&lt;br /&gt;
                &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
                &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
                &amp;quot;network_manager&amp;quot;: null&lt;br /&gt;
              }&lt;br /&gt;
            ]&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;eth0&amp;quot;: {&lt;br /&gt;
            &amp;quot;interface&amp;quot;: &amp;quot;eth0&amp;quot;,&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;status&amp;quot;: &amp;quot;connected&amp;quot;,&lt;br /&gt;
            &amp;quot;operstate&amp;quot;: &amp;quot;up&amp;quot;,&lt;br /&gt;
            &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
            &amp;quot;carrier&amp;quot;: true,&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
            &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
            &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
            &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:3f&amp;quot;,&lt;br /&gt;
            &amp;quot;ipv4&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;address&amp;quot;: &amp;quot;172.16.20.57&amp;quot;,&lt;br /&gt;
                &amp;quot;prefixlen&amp;quot;: 24,&lt;br /&gt;
                &amp;quot;scope&amp;quot;: &amp;quot;global&amp;quot;,&lt;br /&gt;
                &amp;quot;dynamic&amp;quot;: true&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;ipv6&amp;quot;: [&lt;br /&gt;
              {&lt;br /&gt;
                &amp;quot;address&amp;quot;: &amp;quot;fe80::7fc1:f65f:5729:d234&amp;quot;,&lt;br /&gt;
                &amp;quot;prefixlen&amp;quot;: 64,&lt;br /&gt;
                &amp;quot;scope&amp;quot;: &amp;quot;link&amp;quot;,&lt;br /&gt;
                &amp;quot;dynamic&amp;quot;: false&lt;br /&gt;
              }&lt;br /&gt;
            ],&lt;br /&gt;
            &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
              &amp;quot;device&amp;quot;: &amp;quot;eth0&amp;quot;,&lt;br /&gt;
              &amp;quot;type&amp;quot;: &amp;quot;ethernet&amp;quot;,&lt;br /&gt;
              &amp;quot;state&amp;quot;: &amp;quot;connected&amp;quot;,&lt;br /&gt;
              &amp;quot;connection&amp;quot;: &amp;quot;wired-ip-dynamic&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;eth1&amp;quot;: {&lt;br /&gt;
            &amp;quot;interface&amp;quot;: &amp;quot;eth1&amp;quot;,&lt;br /&gt;
            &amp;quot;available&amp;quot;: true,&lt;br /&gt;
            &amp;quot;status&amp;quot;: &amp;quot;unavailable&amp;quot;,&lt;br /&gt;
            &amp;quot;operstate&amp;quot;: &amp;quot;down&amp;quot;,&lt;br /&gt;
            &amp;quot;admin_up&amp;quot;: true,&lt;br /&gt;
            &amp;quot;carrier&amp;quot;: false,&lt;br /&gt;
            &amp;quot;mtu&amp;quot;: 1500,&lt;br /&gt;
            &amp;quot;type&amp;quot;: 1,&lt;br /&gt;
            &amp;quot;link_kind&amp;quot;: null,&lt;br /&gt;
            &amp;quot;mac_address&amp;quot;: &amp;quot;2c:cf:67:fd:60:41&amp;quot;,&lt;br /&gt;
            &amp;quot;ipv4&amp;quot;: [],&lt;br /&gt;
            &amp;quot;ipv6&amp;quot;: [],&lt;br /&gt;
            &amp;quot;network_manager&amp;quot;: {&lt;br /&gt;
              &amp;quot;device&amp;quot;: &amp;quot;eth1&amp;quot;,&lt;br /&gt;
              &amp;quot;type&amp;quot;: &amp;quot;ethernet&amp;quot;,&lt;br /&gt;
              &amp;quot;state&amp;quot;: &amp;quot;unavailable&amp;quot;,&lt;br /&gt;
              &amp;quot;connection&amp;quot;: null&lt;br /&gt;
            }&lt;br /&gt;
          },&lt;br /&gt;
          &amp;quot;tunnel&amp;quot;: {&lt;br /&gt;
            &amp;quot;available&amp;quot;: false,&lt;br /&gt;
            &amp;quot;interfaces&amp;quot;: []&lt;br /&gt;
          }&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
|string/number&lt;br /&gt;
|Request/response identifier used to correlate therequest with the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
|string&lt;br /&gt;
|Origin of the message. In the response, this is normallythe SystemHealth actor name.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|string&lt;br /&gt;
|Executed action. For this feature, the value is list_connectivity_specs.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.sysfs&lt;br /&gt;
|string&lt;br /&gt;
|Linux sysfs path used to discover network interfaces, usually/sys/class/net.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the ip command was available andexecuted successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to retrieve detailed link information,for example ip -j -d link show.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.ip_link.error&lt;br /&gt;
|string/null&lt;br /&gt;
|Error returned by the ip command, or null if no erroroccurred.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether NetworkManager / nmcli was available and executed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to retrieve NetworkManager device status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.sources.network_manager.error&lt;br /&gt;
|string/null&lt;br /&gt;
|Error returned by nmcli, or null if no error occurred.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.wifi.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one Wi-Fi interface was found.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.wifi.interfaces[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected Wi-Fi interfaces, usually including &#039;&#039;&#039;wlan0&#039;&#039;&#039; when Wi-Fi exists.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|Linux interface name, for example &#039;&#039;&#039;wlan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the Wi-Fi interface exists in the system.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized interface status, for example &#039;&#039;&#039;connected, down, unavailable, no_carrier,&#039;&#039;&#039; or &#039;&#039;&#039;not_available&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux, for example &#039;&#039;&#039;up, down,&#039;&#039;&#039; or &#039;&#039;&#039;unknown&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the interface is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether carrier/link is detected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum Transmission Unit of the interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Special link type, used mainly for virtual/tunnel interfaces. Usually null for normal Wi-Fi.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of IPv4 addresses configured on the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of IPv6 addresses configured on the Wi-Fi interface.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.device&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager device name.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.type&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager interface type, usually &#039;&#039;&#039;wifi&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.state&lt;br /&gt;
|string&lt;br /&gt;
|NetworkManager state, for example &#039;&#039;&#039;connected&#039;&#039;&#039;, &#039;&#039;&#039;disconnected&#039;&#039;&#039;, or &#039;&#039;&#039;unavailable&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].network_manager.connection&lt;br /&gt;
|string / null&lt;br /&gt;
|Active NetworkManager profile name, or null if none is active.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether Wi-Fi details could be queried using &#039;&#039;&#039;iw&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to query Wi-Fi link state, for example &#039;&#039;&#039;iw dev wlan0 link&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.connected&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the Wi-Fi interface is associated with a Wi-Fi network.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.ssid&lt;br /&gt;
|string&lt;br /&gt;
|SSID of the connected Wi-Fi network, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.bssid&lt;br /&gt;
|string&lt;br /&gt;
|BSSID/MAC address of the connected access point, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.frequency_mhz&lt;br /&gt;
|number&lt;br /&gt;
|Wi-Fi frequency in MHz, when connected.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.signal_dbm&lt;br /&gt;
|number&lt;br /&gt;
|Wi-Fi signal strength in dBm, when available.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.tx_bitrate&lt;br /&gt;
|string&lt;br /&gt;
|Wi-Fi transmit bitrate, when available.&lt;br /&gt;
|-&lt;br /&gt;
|wifi.interfaces[ ].wifi.rx_bitrate&lt;br /&gt;
|string&lt;br /&gt;
|Wi-Fi receive bitrate, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one LTE modem was detected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.tool_available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;mmcli&#039;&#039;&#039; / ModemManager is available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to list LTE modems, usually &#039;&#039;&#039;mmcli -L&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.modems[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of LTE modems detected by ModemManager.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].id&lt;br /&gt;
|string&lt;br /&gt;
|Modem ID in ModemManager, for example &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].success&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether detailed modem information wasread successfully.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].command&lt;br /&gt;
|string&lt;br /&gt;
|Command used to read modem details, for example &#039;&#039;&#039;mmcli -m 0 --output-json&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].manufacturer&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem manufacturer.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem model.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].revision&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem firmware/software revision.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].hardware_revision&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem hardware revision.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].device&lt;br /&gt;
|string / null&lt;br /&gt;
|Sysfs/USB path of the modem device.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].drivers[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Linux drivers associated with the modem, for example &#039;&#039;&#039;qmi_wwan&#039;&#039;&#039; or &#039;&#039;&#039;option&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].plugin&lt;br /&gt;
|string / null&lt;br /&gt;
|ModemManager plugin used to manage the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].primary_port&lt;br /&gt;
|string / null&lt;br /&gt;
|Primary modem control port, for example &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of ports associated with the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ].name&lt;br /&gt;
|string&lt;br /&gt;
|Port/interface name, for example &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039;, &#039;&#039;&#039;ttyUSB2&#039;&#039;&#039;, or &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].ports[ ].type&lt;br /&gt;
|string / null&lt;br /&gt;
|Port type, for example &#039;&#039;&#039;qmi, at, gps, audio, net&#039;&#039;&#039;, or &#039;&#039;&#039;ignored&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].state&lt;br /&gt;
|string / null&lt;br /&gt;
|General modem state according to ModemManager,for example &#039;&#039;&#039;registered&#039;&#039;&#039;, &#039;&#039;&#039;connected&#039;&#039;&#039;, or &#039;&#039;&#039;failed&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].power_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Modem power state, for example &#039;&#039;&#039;on, off&#039;&#039;&#039;, or &#039;&#039;&#039;low&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].access_technologies[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Current access technologies in use, for example LTE,UMTS, or GSM.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].signal_quality.recent&lt;br /&gt;
|string / null&lt;br /&gt;
|Indicates whether the signal quality value is recent.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].signal_quality.value&lt;br /&gt;
|string / number / null&lt;br /&gt;
|Signal quality value reported by the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].current_capabilities[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Current modem capabilities.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].supported_capabilities[ ]&lt;br /&gt;
|array&lt;br /&gt;
|Capabilities supported by the modem.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].operator_code&lt;br /&gt;
|string / null&lt;br /&gt;
|MCC/MNC operator code.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].operator_name&lt;br /&gt;
|string / null&lt;br /&gt;
|Operator name.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].registration_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile network registration state.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].packet_service_state&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile packet data service state.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.modems[ ].sim_path&lt;br /&gt;
|string / null&lt;br /&gt;
|SIM path in ModemManager, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.lte_modem.network_interfaces[]&lt;br /&gt;
|array&lt;br /&gt;
|List of Linux network interfaces associated with the LTE modem, usually &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|LTE network interface name, for example &#039;&#039;&#039;wwan0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the LTE network interface exists.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized LTE network interface status.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the LTE network interface is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether carrier/link information is availableand active.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum Transmission Unit of the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind, when available.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address, when available.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on the LTE network interface.&lt;br /&gt;
|-&lt;br /&gt;
|lte_modem.network_interfaces[ ].network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for the LTE interface, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.interface&lt;br /&gt;
|string&lt;br /&gt;
|Ethernet interface name, &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; exists.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized &#039;&#039;&#039;eth0&#039;&#039;&#039; status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth0&#039;&#039;&#039; has physical link.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|MTU of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind of &#039;&#039;&#039;eth0&#039;&#039;&#039;, usually &#039;&#039;&#039;null&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth0.network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for &#039;&#039;&#039;eth0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.interface&lt;br /&gt;
|string&lt;br /&gt;
|Ethernet interface name, &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; exists.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized &#039;&#039;&#039;eth1&#039;&#039;&#039; status.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; is administratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether &#039;&#039;&#039;eth1&#039;&#039;&#039; has physical link.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|MTU of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Link kind of &#039;&#039;&#039;eth1&#039;&#039;&#039;, usually &#039;&#039;&#039;null&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address of &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.eth1.network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for &#039;&#039;&#039;eth1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.tunnel.available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether at least one tunnel interface was detected.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.connectivity.interfaces.tunnel.interfaces[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected tunnel interfaces, for example &#039;&#039;&#039;tun0, tap0, wg0&#039;&#039;&#039;, or &#039;&#039;&#039;tailscale0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].interface&lt;br /&gt;
|string&lt;br /&gt;
|Tunnel interface name.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the tunnel interface exists.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].status&lt;br /&gt;
|string&lt;br /&gt;
|Normalized tunnel interface status.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].operstate&lt;br /&gt;
|string / null&lt;br /&gt;
|Operational state reported by Linux.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].admin_up&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates whether the tunnel interface isadministratively enabled.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].carrier&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Carrier/link information, when available.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].mtu&lt;br /&gt;
|number / null&lt;br /&gt;
|Tunnel interface MTU.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].type&lt;br /&gt;
|number / null&lt;br /&gt;
|Linux interface type.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].link_kind&lt;br /&gt;
|string / null&lt;br /&gt;
|Tunnel link kind, for example &#039;&#039;&#039;tun, tap&#039;&#039;&#039;, or &#039;&#039;&#039;wireguard&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].mac_address&lt;br /&gt;
|string / null&lt;br /&gt;
|MAC address, when available.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].ipv4[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv4 addresses configured on the tunnel interface.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].ipv6[ ]&lt;br /&gt;
|array&lt;br /&gt;
|IPv6 addresses configured on the tunnel interface.&lt;br /&gt;
|-&lt;br /&gt;
|tunnel.interfaces[ ].network_manager&lt;br /&gt;
|object / null&lt;br /&gt;
|NetworkManager information for the tunnel interface, when available.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].address&lt;br /&gt;
|string&lt;br /&gt;
|IPv4 address assigned to the interface.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].prefixlen&lt;br /&gt;
|number&lt;br /&gt;
|IPv4 network prefix length. Example: &#039;&#039;&#039;24&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].scope&lt;br /&gt;
|string&lt;br /&gt;
|IPv4 scope, for example &#039;&#039;&#039;global&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv4[ ].dynamic&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the IPv4 address was dynamically assigned.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].address&lt;br /&gt;
|string&lt;br /&gt;
|IPv6 address assigned to the interface.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].prefixlen&lt;br /&gt;
|number&lt;br /&gt;
|IPv6 network prefix length.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[ ].scope&lt;br /&gt;
|string&lt;br /&gt;
|IPv6 scope, for example &#039;&#039;&#039;link&#039;&#039;&#039; or &#039;&#039;&#039;global&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|ipv6[].dynamic&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the IPv6 address was dynamically assigned.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== c) Get hardware info ======&lt;br /&gt;
&#039;&#039;&#039;Req-topic&#039;&#039;&#039;: systemHealth/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;Dev&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_HW_INFO&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-topic&#039;&#039;&#039;: systemHealth/runtime/hw/info/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;system-health&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;get_hw_info&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;cpu&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;ram&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;emmc&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;block_devices&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;filesystems&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;mmc_sysfs&amp;quot;: {......},&lt;br /&gt;
      &amp;quot;emmc_extcsd&amp;quot;: {......}&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;Section&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;cpu&#039;&#039;&#039;&lt;br /&gt;
|CPU and board model information.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;ram&#039;&#039;&#039;&lt;br /&gt;
|RAM total, used, and free memory.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;emmc&#039;&#039;&#039;&lt;br /&gt;
|Filtered eMMC device and partition information.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;block_devices&#039;&#039;&#039;&lt;br /&gt;
|Complete block device list from &#039;&#039;&#039;lsblk&#039;&#039;&#039;, including eMMC, boot partitions, loop devices, zram, NVMe, USB storage, etc.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;filesystems&#039;&#039;&#039;&lt;br /&gt;
|Mounted filesystem usage from &#039;&#039;&#039;df -h&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;mmc_sysfs&#039;&#039;&#039;&lt;br /&gt;
|Low-level MMC/eMMC identity fields read from &#039;&#039;&#039;/sys/block/mmcblk*/device&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;emmc_extcsd&#039;&#039;&#039;&lt;br /&gt;
|Parsed eMMC EXT_CSD information from &#039;&#039;&#039;mmc extcsd read&#039;&#039;&#039;, including health, revision, RPMB, boot, and partitioning data.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;CPU&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;cpu&#039;&#039;&#039; object describes the detected board and CPU.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;board_model&amp;quot;: &amp;quot;Raspberry Pi Compute Module 4 Rev 1.1&amp;quot;,&lt;br /&gt;
  &amp;quot;cpu&amp;quot;: {&lt;br /&gt;
    &amp;quot;architecture&amp;quot;: &amp;quot;aarch64&amp;quot;,&lt;br /&gt;
    &amp;quot;op_modes&amp;quot;: &amp;quot;32-bit, 64-bit&amp;quot;,&lt;br /&gt;
    &amp;quot;byte_order&amp;quot;: &amp;quot;Little Endian&amp;quot;,&lt;br /&gt;
    &amp;quot;vendor&amp;quot;: &amp;quot;ARM&amp;quot;,&lt;br /&gt;
    &amp;quot;model_name&amp;quot;: &amp;quot;Cortex-A72&amp;quot;,&lt;br /&gt;
    &amp;quot;model&amp;quot;: &amp;quot;3&amp;quot;,&lt;br /&gt;
    &amp;quot;stepping&amp;quot;: &amp;quot;r0p3&amp;quot;,&lt;br /&gt;
    &amp;quot;cpu_count&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;online_cpus&amp;quot;: &amp;quot;0-3&amp;quot;,&lt;br /&gt;
    &amp;quot;threads_per_core&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;cores_per_cluster&amp;quot;: 4,&lt;br /&gt;
    &amp;quot;clusters&amp;quot;: 1,&lt;br /&gt;
    &amp;quot;frequency&amp;quot;: {&lt;br /&gt;
      &amp;quot;scaling_percent&amp;quot;: 60.0,&lt;br /&gt;
      &amp;quot;min_mhz&amp;quot;: 600.0,&lt;br /&gt;
      &amp;quot;max_mhz&amp;quot;: 1500.0,&lt;br /&gt;
      &amp;quot;bogomips&amp;quot;: 108.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|board_model&lt;br /&gt;
|string / null&lt;br /&gt;
|Hardware board model read from device-tree.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.architecture&lt;br /&gt;
|string&lt;br /&gt;
|CPU architecture, for example &#039;&#039;&#039;aarch64&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.op_modes&lt;br /&gt;
|string&lt;br /&gt;
|Supported CPU operation modes.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.byte_order&lt;br /&gt;
|string&lt;br /&gt;
|CPU byte order.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.vendor&lt;br /&gt;
|string&lt;br /&gt;
|CPU vendor.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.model_name&lt;br /&gt;
|string&lt;br /&gt;
|CPU model name.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.model&lt;br /&gt;
|string / number&lt;br /&gt;
|CPU model identifier.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.stepping&lt;br /&gt;
|string&lt;br /&gt;
|CPU stepping/revision.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.cpu_count&lt;br /&gt;
|number&lt;br /&gt;
|Number of detected CPU cores.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.online_cpus&lt;br /&gt;
|string&lt;br /&gt;
|Online CPU list.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.threads_per_core&lt;br /&gt;
|number&lt;br /&gt;
|Number of threads per core.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.cores_per_cluster&lt;br /&gt;
|number&lt;br /&gt;
|Number of cores per cluster.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.clusters&lt;br /&gt;
|number&lt;br /&gt;
|Number of CPU clusters.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.scaling_percent&lt;br /&gt;
|number / null&lt;br /&gt;
|Current CPU frequency scaling percentage.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.min_mhz&lt;br /&gt;
|number / null&lt;br /&gt;
|Minimum CPU frequency in MHz.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.max_mhz&lt;br /&gt;
|number / null&lt;br /&gt;
|Maximum CPU frequency in MHz.&lt;br /&gt;
|-&lt;br /&gt;
|cpu.frequency.bogomips&lt;br /&gt;
|number / null&lt;br /&gt;
|BogoMIPS value reported by the system.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;RAM&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;ram&#039;&#039;&#039; object reports system memory usage.&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;total&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Total system RAM.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;used&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Currently used RAM.&lt;br /&gt;
|-&lt;br /&gt;
|&#039;&#039;&#039;free&#039;&#039;&#039;&lt;br /&gt;
|string&lt;br /&gt;
|Currently free RAM.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;EMMC&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;emmc&#039;&#039;&#039; object is a &#039;&#039;&#039;filtered eMMC&#039;&#039;&#039; &#039;&#039;&#039;view&#039;&#039;&#039;. It focuses on the main eMMC disk and its partitions.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: null,&lt;br /&gt;
      &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29.1G&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;disk&amp;quot;,&lt;br /&gt;
      &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: null,&lt;br /&gt;
      &amp;quot;mountpoints&amp;quot;: [],&lt;br /&gt;
      &amp;quot;partitions&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p1&amp;quot;,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;512M&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;vfat&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/boot/firmware&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p2&amp;quot;,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;28.6G&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/&amp;quot;&lt;br /&gt;
          ]&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Device fields&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ]&lt;br /&gt;
|array&lt;br /&gt;
|List of detected main eMMC devices.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].serial&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC block device name, for example &#039;&#039;&#039;mmcblk0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].size&lt;br /&gt;
|string&lt;br /&gt;
|Device model, when available.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].type&lt;br /&gt;
|string&lt;br /&gt;
|Device serial number.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].transport&lt;br /&gt;
|string / null&lt;br /&gt;
|Device size.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Device type, usually &#039;&#039;&#039;disk&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|Transport type, usually &#039;&#039;&#039;mmc&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].partitions&lt;br /&gt;
|array&lt;br /&gt;
|Filesystem directly on the disk. Usually null when partitions exist.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].name&lt;br /&gt;
|string&lt;br /&gt;
|Mountpoints directly associated with the disk.&lt;br /&gt;
|-&lt;br /&gt;
|devices[ ].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Partitions belonging to this eMMC disk.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Partition fields&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|name&lt;br /&gt;
|string&lt;br /&gt;
|Partition name, for example &#039;&#039;&#039;mmcblk0p1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|string&lt;br /&gt;
|Partition size.&lt;br /&gt;
|-&lt;br /&gt;
|type&lt;br /&gt;
|string&lt;br /&gt;
|Partition type, usually &#039;&#039;&#039;part&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;vfat&#039;&#039;&#039; or &#039;&#039;&#039;ext4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|Mountpoints for the partition.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== d) block_devices ======&lt;br /&gt;
The &#039;&#039;&#039;block_devices&#039;&#039;&#039; object is the complete storage/device tree returned by &#039;&#039;&#039;lsblk&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: null,&lt;br /&gt;
      &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29.1G&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;disk&amp;quot;,&lt;br /&gt;
      &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: null,&lt;br /&gt;
      &amp;quot;mountpoints&amp;quot;: [],&lt;br /&gt;
      &amp;quot;children&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;mmcblk0p1&amp;quot;,&lt;br /&gt;
          &amp;quot;model&amp;quot;: null,&lt;br /&gt;
          &amp;quot;serial&amp;quot;: null,&lt;br /&gt;
          &amp;quot;size&amp;quot;: &amp;quot;512M&amp;quot;,&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;part&amp;quot;,&lt;br /&gt;
          &amp;quot;transport&amp;quot;: &amp;quot;mmc&amp;quot;,&lt;br /&gt;
          &amp;quot;filesystem&amp;quot;: &amp;quot;vfat&amp;quot;,&lt;br /&gt;
          &amp;quot;mountpoints&amp;quot;: [&lt;br /&gt;
            &amp;quot;/boot/firmware&amp;quot;&lt;br /&gt;
          ],&lt;br /&gt;
          &amp;quot;children&amp;quot;: []&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|devices&lt;br /&gt;
|array&lt;br /&gt;
|List of block devices.&lt;br /&gt;
|-&lt;br /&gt;
|stderr&lt;br /&gt;
|string&lt;br /&gt;
|Command error output, if any.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].name&lt;br /&gt;
|string&lt;br /&gt;
|Device name.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].model&lt;br /&gt;
|string / null&lt;br /&gt;
|Device model.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].serial&lt;br /&gt;
|string / null&lt;br /&gt;
|Device serial number.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].size&lt;br /&gt;
|string&lt;br /&gt;
|Device size.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].type&lt;br /&gt;
|string&lt;br /&gt;
|Device type, for example &#039;&#039;&#039;disk&#039;&#039;&#039; , &#039;&#039;&#039;part&#039;&#039;&#039; , or &#039;&#039;&#039;loop&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].transport&lt;br /&gt;
|string / null&lt;br /&gt;
|Transport type, for example &#039;&#039;&#039;mmc&#039;&#039;&#039; , &#039;&#039;&#039;nvme&#039;&#039;&#039; , or &#039;&#039;&#039;usb&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].filesystem&lt;br /&gt;
|string / null&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;ext4&#039;&#039;&#039; , &#039;&#039;&#039;vfat&#039;&#039;&#039; , or &#039;&#039;&#039;swap&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].mountpoints&lt;br /&gt;
|array&lt;br /&gt;
|List of mountpoints. Empty if not mounted.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].children&lt;br /&gt;
|array&lt;br /&gt;
|Child block devices, usually partitions.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== e) file_systems ======&lt;br /&gt;
The &#039;&#039;&#039;file_systems&#039;&#039;&#039; object reports mounted filesystem usage, equivalent to &#039;&#039;&#039;df -h&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;filesystems&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;source&amp;quot;: &amp;quot;/dev/mmcblk0p2&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;29G&amp;quot;,&lt;br /&gt;
      &amp;quot;used&amp;quot;: &amp;quot;5.8G&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: &amp;quot;23G&amp;quot;,&lt;br /&gt;
      &amp;quot;use_percent&amp;quot;: &amp;quot;21%&amp;quot;,&lt;br /&gt;
      &amp;quot;mountpoint&amp;quot;: &amp;quot;/&amp;quot;,&lt;br /&gt;
      &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;source&amp;quot;: &amp;quot;/dev/nvme0n1p1&amp;quot;,&lt;br /&gt;
      &amp;quot;filesystem&amp;quot;: &amp;quot;ext4&amp;quot;,&lt;br /&gt;
      &amp;quot;size&amp;quot;: &amp;quot;234G&amp;quot;,&lt;br /&gt;
      &amp;quot;used&amp;quot;: &amp;quot;2.1M&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: &amp;quot;222G&amp;quot;,&lt;br /&gt;
      &amp;quot;use_percent&amp;quot;: &amp;quot;1%&amp;quot;,&lt;br /&gt;
      &amp;quot;mountpoint&amp;quot;: &amp;quot;/mnt/nvme&amp;quot;,&lt;br /&gt;
      &amp;quot;parsed&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;stderr&amp;quot;: &amp;quot;&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|filesystems&lt;br /&gt;
|array&lt;br /&gt;
|List of mounted filesystems.&lt;br /&gt;
|-&lt;br /&gt;
|stderr&lt;br /&gt;
|string&lt;br /&gt;
|Command error output, if any.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].source&lt;br /&gt;
|string&lt;br /&gt;
|Filesystem source, for example &#039;&#039;&#039;/dev/mmcblk0p2&#039;&#039;&#039; , &#039;&#039;&#039;tmpfs&#039;&#039;&#039; , or &#039;&#039;&#039;udev&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].filesystem&lt;br /&gt;
|string&lt;br /&gt;
|Filesystem type, for example &#039;&#039;&#039;ext4&#039;&#039;&#039; , &#039;&#039;&#039;vfat&#039;&#039;&#039; , &#039;&#039;&#039;tmpfs&#039;&#039;&#039; , or &#039;&#039;&#039;devtmpfs&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].size&lt;br /&gt;
|string&lt;br /&gt;
|Total filesystem size.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].used&lt;br /&gt;
|string&lt;br /&gt;
|Used space.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].available&lt;br /&gt;
|string&lt;br /&gt;
|Available space.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].use_percent&lt;br /&gt;
|string&lt;br /&gt;
|Used percentage.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].mountpoint&lt;br /&gt;
|string&lt;br /&gt;
|Mount location.&lt;br /&gt;
|-&lt;br /&gt;
|filesystems[index].parsed&lt;br /&gt;
|boolean&lt;br /&gt;
|&#039;&#039;&#039;true&#039;&#039;&#039; if the parser successfully parsed this filesystem entry.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== f) mmc_sysfs ======&lt;br /&gt;
The &#039;&#039;&#039;mmc_sysfs&#039;&#039;&#039; object exposes low-level MMC/eMMC identity fields read from:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;/sys/block/mmcblk*/device/&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is useful for production traceability, device identification and diagnostics.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;source&amp;quot;: &amp;quot;/sys/block&amp;quot;,&lt;br /&gt;
  &amp;quot;fields&amp;quot;: [&lt;br /&gt;
    &amp;quot;name&amp;quot;,&lt;br /&gt;
    &amp;quot;cid&amp;quot;,&lt;br /&gt;
    &amp;quot;csd&amp;quot;,&lt;br /&gt;
    &amp;quot;date&amp;quot;,&lt;br /&gt;
    &amp;quot;manfid&amp;quot;,&lt;br /&gt;
    &amp;quot;oemid&amp;quot;,&lt;br /&gt;
    &amp;quot;serial&amp;quot;&lt;br /&gt;
  ],&lt;br /&gt;
  &amp;quot;devices&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;device&amp;quot;: &amp;quot;mmcblk0&amp;quot;,&lt;br /&gt;
      &amp;quot;base_path&amp;quot;: &amp;quot;/sys/block/mmcblk0/device&amp;quot;,&lt;br /&gt;
      &amp;quot;available&amp;quot;: true,&lt;br /&gt;
      &amp;quot;fields&amp;quot;: {&lt;br /&gt;
        &amp;quot;name&amp;quot;: &amp;quot;BJTD4R&amp;quot;,&lt;br /&gt;
        &amp;quot;cid&amp;quot;: &amp;quot;150100424a5444345203121b491e7b00&amp;quot;,&lt;br /&gt;
        &amp;quot;csd&amp;quot;: &amp;quot;d02701320f5903fff6dbffef8e404000&amp;quot;,&lt;br /&gt;
        &amp;quot;date&amp;quot;: &amp;quot;07/2024&amp;quot;,&lt;br /&gt;
        &amp;quot;manfid&amp;quot;: &amp;quot;0x000015&amp;quot;,&lt;br /&gt;
        &amp;quot;oemid&amp;quot;: &amp;quot;0x0100&amp;quot;,&lt;br /&gt;
        &amp;quot;serial&amp;quot;: &amp;quot;0x121b491e&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|source&lt;br /&gt;
|string&lt;br /&gt;
|Base sysfs source path.&lt;br /&gt;
|-&lt;br /&gt;
|fields&lt;br /&gt;
|array&lt;br /&gt;
|List of sysfs fields collected.&lt;br /&gt;
|-&lt;br /&gt;
|devices&lt;br /&gt;
|array&lt;br /&gt;
|List of detected MMC/eMMC devices.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].device&lt;br /&gt;
|string&lt;br /&gt;
|MMC block device name, for example &#039;&#039;&#039;mmcblk0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].base_path&lt;br /&gt;
|string&lt;br /&gt;
|Sysfs path used for this device.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].available&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates whether the sysfs path exists.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.name&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC product name.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.cid&lt;br /&gt;
|string / null&lt;br /&gt;
|Card Identification register.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.csd&lt;br /&gt;
|string / null&lt;br /&gt;
|Card Specific Data register.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.date&lt;br /&gt;
|string / null&lt;br /&gt;
|Manufacturing date.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.manfid&lt;br /&gt;
|string / null&lt;br /&gt;
|Manufacturer ID.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.oemid&lt;br /&gt;
|string / null&lt;br /&gt;
|OEM/application ID.&lt;br /&gt;
|-&lt;br /&gt;
|devices[index].fields.serial&lt;br /&gt;
|string / null&lt;br /&gt;
|eMMC serial number.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== e) emmc_extcsd ======&lt;br /&gt;
The &#039;&#039;&#039;emmc_extcsd&#039;&#039;&#039; object contains parsed information from:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mmc extcsd read /dev/mmcblk0&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Category&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|revision&lt;br /&gt;
|EXT_CSD and MMC version.&lt;br /&gt;
|-&lt;br /&gt;
|health&lt;br /&gt;
|eMMC lifetime and pre-EOL state.&lt;br /&gt;
|-&lt;br /&gt;
|boot&lt;br /&gt;
|Boot partition/protection configuration.&lt;br /&gt;
|-&lt;br /&gt;
|rpmb&lt;br /&gt;
|Replay Protected Memory Block information.&lt;br /&gt;
|-&lt;br /&gt;
|sector&lt;br /&gt;
|Sector count and capacity information, when available.&lt;br /&gt;
|-&lt;br /&gt;
|partitioning&lt;br /&gt;
|Partitioning and enhanced-area information.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[&#039;&#039;&#039; &#039;&#039;&#039;].revision&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;ext_csd_revision&amp;quot;: &amp;quot;1.8&amp;quot;,&lt;br /&gt;
  &amp;quot;mmc_version&amp;quot;: &amp;quot;MMC 5.1&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!Type&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|ext_csd_revision&lt;br /&gt;
|string&lt;br /&gt;
|EXT_CSD revision.&lt;br /&gt;
|-&lt;br /&gt;
|mmc_version&lt;br /&gt;
|string&lt;br /&gt;
|MMC/eMMC standard version.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].health&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;life_time_estimation_a&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;DEVICE_LIFE_TIME_EST_TYP_A&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Life Time Estimation A&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;,&lt;br /&gt;
      &amp;quot;used_percent_min&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;used_percent_max&amp;quot;: 10&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;life_time_estimation_b&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;DEVICE_LIFE_TIME_EST_TYP_B&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Life Time Estimation B&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;,&lt;br /&gt;
      &amp;quot;used_percent_min&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;used_percent_max&amp;quot;: 10&lt;br /&gt;
    }&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;pre_eol&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;PRE_EOL_INFO&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;eMMC Pre EOL information&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x01&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x1&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;normal&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|life_time_estimation_a&lt;br /&gt;
|Wear estimation for eMMC memory type A.&lt;br /&gt;
|-&lt;br /&gt;
|life_time_estimation_b&lt;br /&gt;
|Wear estimation for eMMC memory type B.&lt;br /&gt;
|-&lt;br /&gt;
|pre_eol&lt;br /&gt;
|Pre-end-of-life state.&lt;br /&gt;
|}&lt;br /&gt;
Lifetime Decoding&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Raw Value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Decoded State&#039;&#039;&#039;&lt;br /&gt;
!Meaning&lt;br /&gt;
|-&lt;br /&gt;
|0x00&lt;br /&gt;
|not_defined&lt;br /&gt;
|Not defined by device.&lt;br /&gt;
|-&lt;br /&gt;
|0x01&lt;br /&gt;
|normal&lt;br /&gt;
|0% to 10% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x02&lt;br /&gt;
|normal&lt;br /&gt;
|10% to 20% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x03&lt;br /&gt;
|normal&lt;br /&gt;
|20% to 30% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x04&lt;br /&gt;
|normal&lt;br /&gt;
|30% to 40% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x05&lt;br /&gt;
|normal&lt;br /&gt;
|40% to 50% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x06&lt;br /&gt;
|normal&lt;br /&gt;
|50% to 60% estimated lifetime used&lt;br /&gt;
|-&lt;br /&gt;
|0x07&lt;br /&gt;
|normal&lt;br /&gt;
|60% to 70% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x08&lt;br /&gt;
|normal&lt;br /&gt;
|70% to 80% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x09&lt;br /&gt;
|normal&lt;br /&gt;
|80% to 90% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x0A&lt;br /&gt;
|normal&lt;br /&gt;
|90% to 100% estimated lifetime used.&lt;br /&gt;
|-&lt;br /&gt;
|0x0B&lt;br /&gt;
|exceeded&lt;br /&gt;
|Estimated maximum lifetime exceeded.&lt;br /&gt;
|}&lt;br /&gt;
Pre-EOL Decoding&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Raw Value&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Decoded State&#039;&#039;&#039;&lt;br /&gt;
!Meaning&lt;br /&gt;
|-&lt;br /&gt;
|0x00&lt;br /&gt;
|not_defined&lt;br /&gt;
|Not defined.&lt;br /&gt;
|-&lt;br /&gt;
|0x01&lt;br /&gt;
|normal&lt;br /&gt;
|Normal condition.&lt;br /&gt;
|-&lt;br /&gt;
|0x02&lt;br /&gt;
|warning&lt;br /&gt;
|Warning state. Monitor or plan replacement.&lt;br /&gt;
|-&lt;br /&gt;
|0x03&lt;br /&gt;
|urgent&lt;br /&gt;
|Urgent state. Replacement recommended.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].boot&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;partition_config&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: null,&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: null&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;boot_config_protection&amp;quot;: null,&lt;br /&gt;
  &amp;quot;boot_bus_conditions&amp;quot;: null,&lt;br /&gt;
  &amp;quot;boot_write_protection&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;BOOT_WP&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Boot Area Write protection&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;boot_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: null,&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: null&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|partition_config&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot partition configuration, if available.&lt;br /&gt;
|-&lt;br /&gt;
|boot_config_protection&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot configuration protection status.&lt;br /&gt;
|-&lt;br /&gt;
|boot_bus_conditions&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot bus width/mode conditions.&lt;br /&gt;
|-&lt;br /&gt;
|boot_write_protection&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot area write protection status.&lt;br /&gt;
|-&lt;br /&gt;
|boot_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Boot partition size, if available.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].rpmb&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
RPMB means &#039;&#039;&#039;Replay Protected Memory Block&#039;&#039;&#039;. It is a protected eMMC area often used for secure storage.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;size&amp;quot;: {&lt;br /&gt;
    &amp;quot;field&amp;quot;: {&lt;br /&gt;
      &amp;quot;register&amp;quot;: &amp;quot;RPMB_SIZE_MULT&amp;quot;,&lt;br /&gt;
      &amp;quot;index&amp;quot;: null,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;RPMB Size&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: &amp;quot;0x20&amp;quot;,&lt;br /&gt;
      &amp;quot;value_int&amp;quot;: 32,&lt;br /&gt;
      &amp;quot;value_hex&amp;quot;: &amp;quot;0x20&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;decoded&amp;quot;: {&lt;br /&gt;
      &amp;quot;bytes&amp;quot;: 4194304,&lt;br /&gt;
      &amp;quot;kb&amp;quot;: 4194.3,&lt;br /&gt;
      &amp;quot;mb&amp;quot;: 4.19,&lt;br /&gt;
      &amp;quot;gb&amp;quot;: 0.0,&lt;br /&gt;
      &amp;quot;kib&amp;quot;: 4096.0,&lt;br /&gt;
      &amp;quot;mib&amp;quot;: 4.0,&lt;br /&gt;
      &amp;quot;gib&amp;quot;: 0.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|size.field&lt;br /&gt;
|object / null&lt;br /&gt;
|Raw RPMB size register information.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.bytes&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in bytes.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.kb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal KB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.mb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal MB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.gb&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in decimal GB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.kib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in KiB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.mib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in MiB.&lt;br /&gt;
|-&lt;br /&gt;
|size.decoded.gib&lt;br /&gt;
|number&lt;br /&gt;
|RPMB size in GiB.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].sector&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;sector_count&amp;quot;: null,&lt;br /&gt;
  &amp;quot;sector_size_bytes&amp;quot;: 512,&lt;br /&gt;
  &amp;quot;user_capacity&amp;quot;: null&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|sector_count&lt;br /&gt;
|object / null&lt;br /&gt;
|Parsed sector count register, if available.&lt;br /&gt;
|-&lt;br /&gt;
|sector_size_bytes&lt;br /&gt;
|number&lt;br /&gt;
|Sector size used for capacity calculation.&lt;br /&gt;
|-&lt;br /&gt;
|user_capacity&lt;br /&gt;
|object / null&lt;br /&gt;
|Calculated user capacity, if sector count is available.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;emmc_extcsd.devices[ ].partitioning&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;partitioning_support&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITIONING_SUPPORT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitioning Support&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x07&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 7,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x7&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;partition_setting_completed&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITION_SETTING_COMPLETED&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitioning Setting&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;partition_attribute&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;PARTITIONS_ATTRIBUTE&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Partitions attribute&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;max_enhanced_area_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;MAX_ENH_SIZE_MULT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Max Enhanced Area Size&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x000747&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 1863,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x747&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;enhanced_user_area_start&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;ENH_START_ADDR&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Enhanced User Data Start Address&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x00000000&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;enhanced_user_area_size&amp;quot;: {&lt;br /&gt;
    &amp;quot;register&amp;quot;: &amp;quot;ENH_SIZE_MULT&amp;quot;,&lt;br /&gt;
    &amp;quot;index&amp;quot;: null,&lt;br /&gt;
    &amp;quot;description&amp;quot;: &amp;quot;Enhanced User Data Area Size&amp;quot;,&lt;br /&gt;
    &amp;quot;value&amp;quot;: &amp;quot;0x000000&amp;quot;,&lt;br /&gt;
    &amp;quot;value_int&amp;quot;: 0,&lt;br /&gt;
    &amp;quot;value_hex&amp;quot;: &amp;quot;0x0&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable tech-table&amp;quot;&lt;br /&gt;
!&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
!&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|partitioning_support&lt;br /&gt;
|object / null&lt;br /&gt;
|Supported partitioning features.&lt;br /&gt;
|-&lt;br /&gt;
|partition_setting_completed&lt;br /&gt;
|object / null&lt;br /&gt;
|Indicates whether partition settings were finalized.&lt;br /&gt;
|-&lt;br /&gt;
|user_capacity&lt;br /&gt;
|object / null&lt;br /&gt;
|Partition attribute register.&lt;br /&gt;
|-&lt;br /&gt;
|max_enhanced_area_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Maximum enhanced area size multiplier.&lt;br /&gt;
|-&lt;br /&gt;
|enhanced_user_area_start&lt;br /&gt;
|object / null&lt;br /&gt;
|Enhanced user data area start address.&lt;br /&gt;
|-&lt;br /&gt;
|enhanced_user_area_size&lt;br /&gt;
|object / null&lt;br /&gt;
|Enhanced user data area size.&lt;br /&gt;
|}&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.4 TempSensor Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.4.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set temperature sensor configurations ======&lt;br /&gt;
Req-Topic: tempSensor/config/in&lt;br /&gt;
&lt;br /&gt;
ALERT:&lt;br /&gt;
&lt;br /&gt;
* activate: true(active)/false&lt;br /&gt;
* templow: alert temperature lower limit&lt;br /&gt;
* tempHigh: alert temperature upper limit&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Read temperature sensor configurations ======&lt;br /&gt;
Req-Topic: tempSensor/config/in&lt;br /&gt;
&lt;br /&gt;
ALERT:&lt;br /&gt;
&lt;br /&gt;
* activate: true(active)/false&lt;br /&gt;
&lt;br /&gt;
LIMITS:&lt;br /&gt;
&lt;br /&gt;
* templow: alert temperature lower limit&lt;br /&gt;
* tempHigh: alert temperature upper limit&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;ALERT&amp;quot;: {&lt;br /&gt;
        &amp;quot;activate&amp;quot;: true,&lt;br /&gt;
        &amp;quot;tempLow&amp;quot;: 0,&lt;br /&gt;
        &amp;quot;tempHigh&amp;quot;: 80&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read temperature and alert status ======&lt;br /&gt;
* unit: Temperature unit of measure&lt;br /&gt;
* alert: true (triggered) or false&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tempSensor/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tempSensor/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;data&amp;quot;: {&lt;br /&gt;
        &amp;quot;temperature&amp;quot;: &amp;lt;_FLOAT_&amp;gt;,&lt;br /&gt;
        &amp;quot;unit&amp;quot;: &amp;quot;C&amp;quot;,&lt;br /&gt;
        &amp;quot;alert&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.5 TFT Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.5.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to control and interact with the TFT display, or frontal panel LCD screen. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
===== 24.5.2 TFT Display Actor =====&lt;br /&gt;
  The TFT Actor is responsible for:&lt;br /&gt;
&lt;br /&gt;
* Rendering static and informative screens on the TFT display&lt;br /&gt;
* Reacting to joystick input (LEFT/ RIGHT/ CENTER/ UP/ DOWN)&lt;br /&gt;
* Managing screen navigation and user confirmation flows&lt;br /&gt;
* Providing feedback to the application via MQTT&lt;br /&gt;
&lt;br /&gt;
====== a) Screen Carousel Concept ======&lt;br /&gt;
The TFT actor maintains an &#039;&#039;&#039;ordered list of screens&#039;&#039;&#039; (carousel).&lt;br /&gt;
&lt;br /&gt;
* Screens are navigated using the joystick:&lt;br /&gt;
&lt;br /&gt;
- LEFT --&amp;gt; Previous screen&lt;br /&gt;
&lt;br /&gt;
- RIGHT --&amp;gt; Next screen&lt;br /&gt;
&lt;br /&gt;
* The carousel wraps around:&lt;br /&gt;
&lt;br /&gt;
- LEFT on first screen --&amp;gt; last screen&lt;br /&gt;
&lt;br /&gt;
- RIGHT on last screen --&amp;gt; first screen&lt;br /&gt;
&lt;br /&gt;
====== b) Screen Types ======&lt;br /&gt;
The TFT actor supports the following screen types:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Image Screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Displays a static JPEG image&lt;br /&gt;
* Default screen shown at boot&lt;br /&gt;
* No user interaction required&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Network Information Screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Display a interface with information about the networks of the device&lt;br /&gt;
* Updated on load&lt;br /&gt;
* No user interaction required&lt;br /&gt;
&lt;br /&gt;
====== c) Joystick Navigation Logic ======&lt;br /&gt;
&#039;&#039;&#039;Carousel Navigation:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Joystick  Input&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Action&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|LEFT&lt;br /&gt;
|Previous screen&lt;br /&gt;
|-&lt;br /&gt;
|RIGHT&lt;br /&gt;
|Next screen&lt;br /&gt;
|-&lt;br /&gt;
|DOWN&lt;br /&gt;
|Refresh current screen&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== d) Boot Behavior ======&lt;br /&gt;
At system boot:&lt;br /&gt;
&lt;br /&gt;
# TFT actor initializes the display&lt;br /&gt;
# Last available carousel is loaded&lt;br /&gt;
# First screen is rendered&lt;br /&gt;
# Joystick subscriptions are activated&lt;br /&gt;
# Actor waits for runtime commands&lt;br /&gt;
&lt;br /&gt;
====== e) Design Notes &amp;amp; Constraints ======&lt;br /&gt;
* TFT actor does not expose joystick state&lt;br /&gt;
* Joystick actor remains independent&lt;br /&gt;
* TFT actor internally consumes joystick events&lt;br /&gt;
* Carousel state is local to the TFT actor&lt;br /&gt;
* Screen rendering is synchronous; input handling is asynchronous&lt;br /&gt;
* Confirmation screens always require explicit CENTER press&lt;br /&gt;
&lt;br /&gt;
===== 24.5.3 User interaction through MQTT =====&lt;br /&gt;
Enabling interaction with the carousel using the topic tft/runtime/in . Actions available will be public to the user.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Runtime commands&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Go to screen&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tft/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_CAROUSEL&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;index&amp;quot;: 2&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: tft/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;tft&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 2&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Set TFT Screen Carousel&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Req-Topic: tft/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;TIMESTAMP&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_CAROUSEL&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;startIndex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;screens&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;,&lt;br /&gt;
          &amp;quot;image&amp;quot;: &amp;quot;default.jpg&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;image&amp;quot;,&lt;br /&gt;
          &amp;quot;image&amp;quot;: &amp;quot;status.jpg&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;type&amp;quot;: &amp;quot;confirm&amp;quot;,&lt;br /&gt;
          &amp;quot;question&amp;quot;: &amp;quot;Do you want to continue?&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Parameters:&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|screens&lt;br /&gt;
|Ordered list of screens&lt;br /&gt;
|-&lt;br /&gt;
|Start  lndex&lt;br /&gt;
|Initial active screen (optional,  default = 0)&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Reply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reply-Topic: &#039;&#039;&#039;tft/runtime/out&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;TIMESTAMP&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;tft&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;activeIndex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;totalScreens&amp;quot;: 3&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.6 AnalogInputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.6.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Configurations ======&lt;br /&gt;
&#039;&#039;&#039;  Topic: analogInputs/config/in - Set ADC channels configurations&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mode&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* continuous&lt;br /&gt;
* single&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;type&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* voltage&lt;br /&gt;
* current&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;voltage&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;voltage&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;current&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
        &amp;quot;type&amp;quot;: &amp;quot;current&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogInputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Runtime Data ======&lt;br /&gt;
&#039;&#039;&#039;Topic: analogInputs/runtime/in.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
action:&lt;br /&gt;
&lt;br /&gt;
* READ&lt;br /&gt;
* PAUSE (only applicable in continuous mode)&lt;br /&gt;
* RESUME (only applicable in continuous mode)&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogInputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.6.2 Usage Examples =====&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.7 Analog Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.7.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set analog outputs signal ======&lt;br /&gt;
Req-Topic: analogOutputs/config/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Output:&#039;&#039;&#039; current within 0-20 mA&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;mode:&#039;&#039;&#039; on/off&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogOutputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Set analog outputs ======&lt;br /&gt;
Req-Topic: analogOutputs/runtime/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;current:&#039;&#039;&#039; current within 0-20 mA&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analoigOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== c) Read analog outputs settings ======&lt;br /&gt;
Req-Topic: analogOutputs/runtime/in&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;current&#039;&#039;&#039;: current within 0-20 mA&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: analogOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;AO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;AO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;current&amp;quot;: &amp;lt;_FLOAT_&amp;gt;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.8 Digital Inputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.8.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
====== a) Set digital input pin/pins speed fast/slow ======&lt;br /&gt;
The &#039;&#039;&#039;fast&#039;&#039;&#039; speed setting supports edge detection speed up to 100 Hz and the &#039;&#039;&#039;slow&#039;&#039;&#039; speed settings supports up to 10 Hz.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Fast Mode&#039;&#039;&#039; generates a message on every I/O state change, which may result in a &#039;&#039;&#039;high message payload&#039;&#039;&#039; during operation. Fast Mode should therefore only be enabled when &#039;&#039;&#039;strictly required&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalInputs/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;slow&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalInputs/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;slow&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;speed&amp;quot;: &amp;quot;fast&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Get all digital input pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalInputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalInputs/runtime/out&lt;br /&gt;
&lt;br /&gt;
state: high/low&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DI1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DI4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.9 Digital Outputs Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.9.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Get all digital output pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) Set all digital output pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: digitalOutputs/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;action&amp;quot;: &amp;quot;SET&amp;quot;,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: digitalOutputs/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;high&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;low&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
} &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.9.2 Notes =====&lt;br /&gt;
If the busi2c-3 is not powered, we will get this:&lt;br /&gt;
&lt;br /&gt;
Topic: &#039;&#039;&#039;digit a lOutputs/runtime/ out&#039;&#039;&#039; &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;DO1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO2&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO3&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO4&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO5&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO6&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO7&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;DO8&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: false,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;DO_not_powered&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.10 Joystick Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.10.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtain peripherals data. Connecting to the broker for this Area requires no credencials.&lt;br /&gt;
&lt;br /&gt;
====== a) Get all joystick pins state ======&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Req-Topic: joystick/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;READ&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Reply-Topic: joystick//runtime/out&lt;br /&gt;
&lt;br /&gt;
state: pressed/released&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;JLEFT&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;pressed&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JRIGHT&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JUP&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JDOWN&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;JCENTER&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;released&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.11 Buzzer Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.11.1 Overview =====&lt;br /&gt;
The &#039;&#039;&#039;Buzzer Actor&#039;&#039;&#039; is responsible for controlling the onboard buzzer through MQTT commands. It receives runtime commands on an MQTT input topic, validates the requested buzzer operation, drives the buzzerthrough GPIO using &#039;&#039;&#039;libgpiod&#039;&#039;&#039;, and publishes status/final responses on an MQTT output topic.&lt;br /&gt;
&lt;br /&gt;
The actor currently controls &#039;&#039;&#039;GPIO line 25&#039;&#039;&#039; on &#039;&#039;&#039;/dev/gpiochip0&#039;&#039;&#039;, with &#039;&#039;&#039;ACTIVE_LOW = False&#039;&#039;&#039;. It creates a &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GpiodBuzzerDriver&#039;&#039;&#039; instance and routes incoming MQTT actions to runtime handlers.&lt;br /&gt;
&lt;br /&gt;
The supported runtime actions are:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Action&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|BEEP&lt;br /&gt;
|Plays a finite beep sequence, an infinite beep sequence, or a continuous tone&lt;br /&gt;
|-&lt;br /&gt;
|STOP&lt;br /&gt;
|Stops the currently active buzzer playback&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.2 MQTT Topics =====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Topic&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Direction&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|buzzer/runtime/in&lt;br /&gt;
|Input&lt;br /&gt;
|Receives buzzer commands&lt;br /&gt;
|-&lt;br /&gt;
|buzzer/runtime/out&lt;br /&gt;
|Output&lt;br /&gt;
|Publishes status messages and final command responses&lt;br /&gt;
|}&lt;br /&gt;
The actor subscribes to &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039; and publishes all status/final replies to &#039;&#039;&#039;buzzer/runtime/out&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
===== 24.11.3 Hardware and Datasheet Notes =====&lt;br /&gt;
The buzzer used is the &#039;&#039;&#039;MLT-8530 electro-magnetic SMD buzzer.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
According to the datasheet:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Rated voltage&lt;br /&gt;
|3.6 Vo-p&lt;br /&gt;
|-&lt;br /&gt;
|Operating voltage&lt;br /&gt;
|2.5 ~ 4.5 Vo-p&lt;br /&gt;
|-&lt;br /&gt;
|Rated current&lt;br /&gt;
|Max. 95 mA&lt;br /&gt;
|-&lt;br /&gt;
|Rated test frequency&lt;br /&gt;
|2700 Hz&lt;br /&gt;
|-&lt;br /&gt;
|Duty cycle&lt;br /&gt;
|50% square wave&lt;br /&gt;
|-&lt;br /&gt;
|Sound output&lt;br /&gt;
|Min. 80 dB at 10 cm&lt;br /&gt;
|-&lt;br /&gt;
|Coil resistance&lt;br /&gt;
|16 ± 3 Ω&lt;br /&gt;
|-&lt;br /&gt;
|Resonant frequency&lt;br /&gt;
|2700 Hz&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.4 BEEP =====&lt;br /&gt;
The BEEP action supports two modes:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Mode&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|sequence&lt;br /&gt;
|Plays one or more beeps with gaps between them&lt;br /&gt;
|-&lt;br /&gt;
|continuous&lt;br /&gt;
|Plays one continuous tone until &#039;&#039;&#039;STOP&#039;&#039;&#039; is received&lt;br /&gt;
|}&lt;br /&gt;
If no mode is provided, the default mode is: &#039;&#039;&#039;sequence&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
All messages should be sent to the topic &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== a) Default Datasheet-Aligned Beep ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== b) N Beeps ======&lt;br /&gt;
Play &#039;&#039;&#039;&amp;lt;BEEPS_QUANTITY&amp;gt;&#039;&#039;&#039; beeps at &#039;&#039;&#039;&amp;lt;FREQUENCY&amp;gt;&#039;&#039;&#039; Hz. Each beep lasts &#039;&#039;&#039;&amp;lt;BEEP_DURATION&amp;gt;&#039;&#039;&#039; seconds, with &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;GAP_BETWEEN_BEEPS&amp;gt;&#039;&#039;&#039; seconds of silence between beeps.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
   &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;frequency_hz&amp;quot;: &amp;lt;FREQUENCY&amp;gt;,&lt;br /&gt;
      &amp;quot;duration_s&amp;quot;: &amp;lt;BEEP_DURATION&amp;gt;,&lt;br /&gt;
      &amp;quot;count&amp;quot;: &amp;lt;BEEPS_QUANTITY&amp;gt;,&lt;br /&gt;
      &amp;quot;gap_s&amp;quot;: &amp;lt;GAP_BETWEEN_BEEPS&amp;gt; &lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;If you want to play repeated beeps forever until a &#039;&#039;&#039;STOP&#039;&#039;&#039; command arrives then you only need to pass the &#039;&#039;&#039;count: 0&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== c) Continuous Tone ======&lt;br /&gt;
Play one continuous &amp;lt;FREQUENCY&amp;gt; Hz tone until &#039;&#039;&#039;STOP&#039;&#039;&#039;.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
   &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;continuous&amp;quot;,&lt;br /&gt;
      &amp;quot;frequency_hz&amp;quot;: &amp;lt;FREQUENCY&amp;gt;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;If &#039;&#039;&#039;frequency_hz&#039;&#039;&#039; is omitted, the handler uses the configured default frequency.&lt;br /&gt;
&lt;br /&gt;
====== d) Stop Buzzer ======&lt;br /&gt;
If you want to stop the beep sequence, just send this payload to the &#039;&#039;&#039;buzzer/runtime/in&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== e) Buzzer payload parameters table ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!Field&lt;br /&gt;
!Required&lt;br /&gt;
!Type&lt;br /&gt;
!Default&lt;br /&gt;
!Applies to&lt;br /&gt;
!Description&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|Yes&lt;br /&gt;
|object&lt;br /&gt;
| -&lt;br /&gt;
|All requests&lt;br /&gt;
|Main task object. Contains the requested action and&lt;br /&gt;
optional parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.action&lt;br /&gt;
|Yes&lt;br /&gt;
|string&lt;br /&gt;
| -&lt;br /&gt;
|All requests&lt;br /&gt;
|Action to execute. Supported values: &amp;quot;BEEP&amp;quot; and&lt;br /&gt;
&amp;quot;STOP&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|task.params&lt;br /&gt;
|No&lt;br /&gt;
|object&lt;br /&gt;
|{}&lt;br /&gt;
|BEEP&lt;br /&gt;
|Optional parameters for configuring the buzzer&lt;br /&gt;
behavior. Not needed for STOP.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.mode&lt;br /&gt;
|No&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sequence&amp;quot;&lt;br /&gt;
|BEEP&lt;br /&gt;
|Playback mode. Supported values: &amp;quot;sequence&amp;quot; and&lt;br /&gt;
&amp;quot;continuous&amp;quot;.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.frequency_hz&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|2700.0&lt;br /&gt;
|BEEP&lt;br /&gt;
|Buzzer frequency in Hz. Recommended/default value&lt;br /&gt;
is 2700 Hz , matching the buzzer resonant frequency.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.duration_s&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|0.2&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Duration of each beep, in seconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.count&lt;br /&gt;
|No&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Number of beeps to play. 0 means repeat forever&lt;br /&gt;
until STOP.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.gap_s&lt;br /&gt;
|No&lt;br /&gt;
|number&lt;br /&gt;
|0.15&lt;br /&gt;
|BEEP with&lt;br /&gt;
mode=&amp;quot;sequence&amp;quot;&lt;br /&gt;
|Silence gap between beeps, in seconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.params.mode =&amp;quot;continuous&amp;quot;&lt;br /&gt;
|No&lt;br /&gt;
|string&lt;br /&gt;
| -&lt;br /&gt;
|BEEP&lt;br /&gt;
|Plays one continuous tone until STOP . In this mode,&lt;br /&gt;
duration_s , count , and gap_s are ignored.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.11.5 Buzzer - diagram =====&lt;br /&gt;
[[File:Buzzer - diagram.svg|center|frameless|901x901px]]&lt;br /&gt;
&lt;br /&gt;
===== 24.11.6 Buzzer Command timing charts - Examples =====&lt;br /&gt;
The following charts represent the command-level buzzer state over time.&lt;br /&gt;
&lt;br /&gt;
They do not show the internal 2700 Hz switching frequency.&lt;br /&gt;
&lt;br /&gt;
Instead, they show when the buzzer is logically:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;State&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1&lt;br /&gt;
|Buzzer active / sound ON&lt;br /&gt;
|-&lt;br /&gt;
|0&lt;br /&gt;
|Buzzer inactive / silence&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== a) Default BEEP command ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;lt;TIMESTAMP&amp;gt;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
   &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Default values used:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|duration_s&lt;br /&gt;
|0.2 s&lt;br /&gt;
|-&lt;br /&gt;
|count&lt;br /&gt;
|1&lt;br /&gt;
|-&lt;br /&gt;
|gap_s&lt;br /&gt;
|0.15 s&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Default_Beep.svg|frameless]]&lt;br /&gt;
&lt;br /&gt;
duration_s = 0.2 s&lt;br /&gt;
&lt;br /&gt;
count = 1&lt;br /&gt;
&lt;br /&gt;
====== b) BEEP Sequence - 5 beeps ======&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
      &amp;quot;duration_s&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;count&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;gap_s&amp;quot;: &amp;lt;GAP_BETWEEN_BEEPS&amp;gt;&lt;br /&gt;
  } &lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
[[File:5_beeps.svg|frameless|700x700px]]&lt;br /&gt;
duration_s = 1.0s&lt;br /&gt;
&lt;br /&gt;
gap_s = 0.5s&lt;br /&gt;
&lt;br /&gt;
count = 5&lt;br /&gt;
&lt;br /&gt;
====== c) Infinite BEEP Sequence ======&lt;br /&gt;
&lt;br /&gt;
This happens when: &amp;quot;count&amp;quot;: 0&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
       &amp;quot;duration_s&amp;quot;: 1,&lt;br /&gt;
       &amp;quot;count&amp;quot;: 0,&lt;br /&gt;
       &amp;quot;gap_s&amp;quot;: 0.5&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
[[File:Infinite_Beeps.svg|frameless|606x606px]]&lt;br /&gt;
&lt;br /&gt;
duration_s = 1.0&lt;br /&gt;
gap_s = 0.5&lt;br /&gt;
&lt;br /&gt;
count = 0&lt;br /&gt;
&lt;br /&gt;
====== d) Continuous BEEP ======&lt;br /&gt;
In continuous mode, the buzzer remains ON until a STOP command is received.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: 1779789836000,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;BEEP&amp;quot;,&lt;br /&gt;
    &amp;quot;params&amp;quot;: {&lt;br /&gt;
       &amp;quot;mode&amp;quot;: &amp;quot;continuous&amp;quot;,&lt;br /&gt;
  }&lt;br /&gt;
 }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Continous beep.svg|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
mode = continuous&lt;br /&gt;
&lt;br /&gt;
====== e) STOP ======&lt;br /&gt;
The STOP command immediately forces the buzzer to OFF.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Buzzer State&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
[[File:Stop beep.svg|frameless|600x600px]]&lt;br /&gt;
&lt;br /&gt;
After STOP, the buzzer is forced to OFF.&lt;br /&gt;
&lt;br /&gt;
==== 24.12 INA232 actor ====&lt;br /&gt;
&lt;br /&gt;
===== 24.12.1 Overview =====&lt;br /&gt;
The &#039;&#039;&#039;INA Actor&#039;&#039;&#039; is responsible for reading the ATLAS INA232 power monitor and publishing the measuredelectrical values through MQTT.&lt;br /&gt;
&lt;br /&gt;
The actor publishes:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Value&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Unit&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|voltage_v&lt;br /&gt;
|V&lt;br /&gt;
|Measured bus/input voltage&lt;br /&gt;
|-&lt;br /&gt;
|current_a&lt;br /&gt;
|A&lt;br /&gt;
|Measured current&lt;br /&gt;
|-&lt;br /&gt;
|power_w&lt;br /&gt;
|W&lt;br /&gt;
|Measured/calculated power&lt;br /&gt;
|}&lt;br /&gt;
The INA232 is a current, voltage, and power monitor with an I²C/SMBus interface. It reports current, busvoltage, and power values through internal registers. The calibration register must be configured to obtainvalid current and power results.&lt;br /&gt;
&lt;br /&gt;
===== 24.12.2 Actor Behaviour =====&lt;br /&gt;
The INA Actor shall:&lt;br /&gt;
&lt;br /&gt;
1. Start with a valid INA configuration.&lt;br /&gt;
&lt;br /&gt;
2. Configure the INA232 device.&lt;br /&gt;
&lt;br /&gt;
3. Read voltage, current and power once per second.&lt;br /&gt;
&lt;br /&gt;
4. Publish the values to: &#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The actor does &#039;&#039;&#039;not&#039;&#039;&#039; need a request every second.&lt;br /&gt;
&lt;br /&gt;
The publication is automatic and periodic.&lt;br /&gt;
&lt;br /&gt;
===== 24.12.3 Required Configuration =====&lt;br /&gt;
The actor requires a small configuration to correctly read and convert the INA232 measurements.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|enabled&lt;br /&gt;
|boolean&lt;br /&gt;
|Yes&lt;br /&gt;
|Enables or disables the INA actor&lt;br /&gt;
|-&lt;br /&gt;
|address&lt;br /&gt;
|string /integer&lt;br /&gt;
|Yes&lt;br /&gt;
|I²C address of the INA232 device&lt;br /&gt;
|-&lt;br /&gt;
|shunt_ohm&lt;br /&gt;
|number&lt;br /&gt;
|Yes&lt;br /&gt;
|Value of the shunt resistor in ohms&lt;br /&gt;
|-&lt;br /&gt;
|max_current_a&lt;br /&gt;
|number&lt;br /&gt;
|Yes&lt;br /&gt;
|Maximum expected current, used forcalibration&lt;br /&gt;
|-&lt;br /&gt;
|adcrange&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|INA232 shunt voltage range selection&lt;br /&gt;
|-&lt;br /&gt;
|publish_interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|Runtime publish interval in milliseconds&lt;br /&gt;
|-&lt;br /&gt;
|rail_name&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|Logical name of the monitored power rail&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Default configuration&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
  &amp;quot;address&amp;quot;: &amp;quot;0x40&amp;quot;,&lt;br /&gt;
  &amp;quot;shunt_ohm&amp;quot;: 0.020,&lt;br /&gt;
  &amp;quot;publish_interval_ms&amp;quot;: 1000,&lt;br /&gt;
  &amp;quot;rail_name&amp;quot;: &amp;quot;atlas_input_power&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.12.4 Configuration domain =====&lt;br /&gt;
Configuration messages are sent to:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/config/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Configuration replies are published on:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/config/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;- GET_CONFIG&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Returns the current INA Actor configuration&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Request&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_CONFIG&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Response&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_CONFIG&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;configured&amp;quot;: true,&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
      &amp;quot;address&amp;quot;: &amp;quot;0x40&amp;quot;,&lt;br /&gt;
      &amp;quot;shunt_ohm&amp;quot;: 0.020,&lt;br /&gt;
      &amp;quot;publish_interval_ms&amp;quot;: 1000&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.12.5 Runtime domain =====&lt;br /&gt;
Runtime messages are sent to:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/in&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Runtime replies are published on:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;- Manual Runtime read&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Request&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_POWER&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Response&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_POWER&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;voltage_v&amp;quot;: 24.12,&lt;br /&gt;
      &amp;quot;current_a&amp;quot;: 0.481,&lt;br /&gt;
      &amp;quot;power_w&amp;quot;: 11.6&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;- Automatic Runtime Publication&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Publish topic:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ina/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Period: 1000 ms === 1s&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Response payload&#039;&#039;&#039;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;INA&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;PUBLISH_POWER&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;voltage_v&amp;quot;: 24.12,&lt;br /&gt;
      &amp;quot;current_a&amp;quot;: 0.481,&lt;br /&gt;
      &amp;quot;power_w&amp;quot;: 11.6&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|success&lt;br /&gt;
|boolean&lt;br /&gt;
| -&lt;br /&gt;
|Indicates whether the read operation succeeded&lt;br /&gt;
|-&lt;br /&gt;
|voltage_v&lt;br /&gt;
|number&lt;br /&gt;
|V&lt;br /&gt;
|Measured bus/input voltage&lt;br /&gt;
|-&lt;br /&gt;
|current_a&lt;br /&gt;
|number&lt;br /&gt;
|A&lt;br /&gt;
|Measured current&lt;br /&gt;
|-&lt;br /&gt;
|power_w&lt;br /&gt;
|number&lt;br /&gt;
|W&lt;br /&gt;
|Measured power&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.13 Modem Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.13.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker. Simplified interface to configure and obtainmodem (LTE) data. Connecting to the broker for this area requires no credentials.&lt;br /&gt;
&lt;br /&gt;
===== 24.13.2 Mobile (LTE Modem) =====&lt;br /&gt;
The Mobile actor manages the LTE modem using ModemManager (&#039;&#039;&#039;mmcli&#039;&#039;&#039;). It allows monitoring modem status, configuring connectivity (APN, operator,network mode), and performing diagnostics.&lt;br /&gt;
&lt;br /&gt;
===== 24.13.3 Scan Operators =====&lt;br /&gt;
Scans available network operators (requires SIM and modem enabled).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SCAN_OPERATORS&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;operators&amp;quot;: [&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;id&amp;quot;: &amp;quot;26801&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;vodafone P&amp;quot;,&lt;br /&gt;
          &amp;quot;status&amp;quot;: &amp;quot;available&amp;quot;&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
          &amp;quot;id&amp;quot;: &amp;quot;26806&amp;quot;,&lt;br /&gt;
          &amp;quot;name&amp;quot;: &amp;quot;MEO&amp;quot;,&lt;br /&gt;
          &amp;quot;status&amp;quot;: &amp;quot;available&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      ]&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.4 Set Operator =====&lt;br /&gt;
The supported modes are:&lt;br /&gt;
&lt;br /&gt;
* auto → modem selects de operator automatically (&#039;&#039;&#039;default&#039;&#039;&#039;).&lt;br /&gt;
* manual→ user forces a specific operator using &#039;&#039;&#039;operator_id&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
- Operators are identified using &#039;&#039;&#039;MCC + MNC codes&#039;&#039;&#039;:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Operator&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Code&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Country&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|Vodafone PT&lt;br /&gt;
|26801&lt;br /&gt;
|Portugal&lt;br /&gt;
|-&lt;br /&gt;
|MEO&lt;br /&gt;
|26806&lt;br /&gt;
|Portugal&lt;br /&gt;
|-&lt;br /&gt;
|NOS&lt;br /&gt;
|26803&lt;br /&gt;
|Portugal&lt;br /&gt;
|}&lt;br /&gt;
These values are obtained dynamically via SCAN_OPERATORS&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Recommendations:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Default should always be &#039;&#039;&#039;auto&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;manual&#039;&#039;&#039; only when:&lt;br /&gt;
&lt;br /&gt;
- You need to force roaming behavior&lt;br /&gt;
&lt;br /&gt;
- You want to lock to a specific network for stability/testing&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Auto Selection&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_OPERATOR&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;auto&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Manual Selection ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_OPERATOR&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;manual&amp;quot;,&lt;br /&gt;
      &amp;quot;operator_id&amp;quot;: &amp;quot;26801&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.5 Set APN Configuration =====&lt;br /&gt;
Supports automatic (predefined APN) or custom configuration.&lt;br /&gt;
&lt;br /&gt;
====== Actual Behavior ======&lt;br /&gt;
When &#039;&#039;&#039;SET_APN&#039;&#039;&#039; is executed, the system performs the following sequence:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;Disconnects the current data connection&#039;&#039;&#039; (if connected)&lt;br /&gt;
# Applies the new APN configuration&lt;br /&gt;
# Initiates a new connection using the provided APN&lt;br /&gt;
# Waits until the modem reaches &#039;&#039;&#039;connected state&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This means a &#039;&#039;&#039;full reconnection is automatically performed&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
No additional RESET or manual reconnection is required.&lt;br /&gt;
&lt;br /&gt;
====== Impact &amp;amp; Considerations ======&lt;br /&gt;
&lt;br /&gt;
* Active data connection is &#039;&#039;&#039;interrupted&#039;&#039;&#039;&lt;br /&gt;
* Ongoing communications (MQTT, HTTP, VPN, etc.) will be &#039;&#039;&#039;dropped&#039;&#039;&#039;&lt;br /&gt;
* IP address may change after reconnection&lt;br /&gt;
* Operation may take &#039;&#039;&#039;several seconds (typically 5–20s)&#039;&#039;&#039;&lt;br /&gt;
* If connection fails, the modem may remain &#039;&#039;&#039;disconnected&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== Known APNs ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Operator&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN CONF&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;NAME&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;PROXY&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;PORT&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;MCC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;MNC&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;AUTH&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;TYPE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;APN&#039;&#039;&#039;&lt;br /&gt;
&#039;&#039;&#039;TYPE&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;CARRIER&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;OBS.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|MEO, UZO&lt;br /&gt;
| --&lt;br /&gt;
|internet&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
|1nce&lt;br /&gt;
| --&lt;br /&gt;
|iot.1nce.net&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
| --&lt;br /&gt;
|-&lt;br /&gt;
|Vodafone&lt;br /&gt;
|Vodafone&lt;br /&gt;
Internet&lt;br /&gt;
|net2.vodafone.pt&lt;br /&gt;
|iproxy.vodafone.pt&lt;br /&gt;
|80&lt;br /&gt;
|268&lt;br /&gt;
|01&lt;br /&gt;
|PAP&lt;br /&gt;
|default&lt;br /&gt;
|unspecified&lt;br /&gt;
|[https://ajuda.vodafone.pt/manuais/vodafone/smart-4g/explorar/configure-o-telefone-para-internet Docs]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Supported Modes ======&lt;br /&gt;
&lt;br /&gt;
* auto&lt;br /&gt;
* custom&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Mode&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|auto&lt;br /&gt;
|Uses modem default / SIM-provided APN&lt;br /&gt;
|-&lt;br /&gt;
|custom&lt;br /&gt;
|Uses user-defined APN credentials&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;- Auto APN (e.g. 1NCE)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Uses the default APN embedded in the modem or provided by the SIM.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_APN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;auto&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;- Custom APN&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Allows full control over APN configuration.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_APN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;custom&amp;quot;,&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;user&amp;quot;: &amp;quot;user&amp;quot;,&lt;br /&gt;
      &amp;quot;password&amp;quot;: &amp;quot;pass&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;apn&amp;quot;: &amp;quot;internet&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.6 Get Modem Status =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_STATUS&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;present&amp;quot;: true,&lt;br /&gt;
        &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
        &amp;quot;state&amp;quot;: &amp;quot;registered&amp;quot;,&lt;br /&gt;
        &amp;quot;signal&amp;quot;: 34,&lt;br /&gt;
        &amp;quot;access_tech&amp;quot;: &amp;quot;lte&amp;quot;,&lt;br /&gt;
        &amp;quot;operator&amp;quot;: &amp;quot;vodafone P&amp;quot;,&lt;br /&gt;
        &amp;quot;sim&amp;quot;: &amp;quot;ready&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.7 Enable / Disable Modem =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_MODEM_STATE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;enabled&amp;quot;: true,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.8 Reset Modem =====&lt;br /&gt;
Performs a full modem reset and recovery sequence.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;RESET&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Actual Behavior ======&lt;br /&gt;
When RESET is executed, the system performs a &#039;&#039;&#039;complete modem restart flow&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
# Executes system-level reset: &#039;&#039;&#039;ltectl reset-modem&#039;&#039;&#039;&lt;br /&gt;
# The modem &#039;&#039;&#039;disappears from the system (USB re-enumeration)&#039;&#039;&#039;&lt;br /&gt;
# The system waits for the modem to &#039;&#039;&#039;reappear&#039;&#039;&#039;&lt;br /&gt;
# Re-discovers the modem path&lt;br /&gt;
# Waits until the modem becomes &#039;&#039;&#039;ready&#039;&#039;&#039;&lt;br /&gt;
# Waits until the modem is &#039;&#039;&#039;connected again&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
This is a &#039;&#039;&#039;full recovery sequence&#039;&#039;&#039;, including automatic reconnection.&lt;br /&gt;
&lt;br /&gt;
====== Impact on active connection ======&lt;br /&gt;
&lt;br /&gt;
* Active data connection is &#039;&#039;&#039;immediately terminated&#039;&#039;&#039;&lt;br /&gt;
* All ongoing communications (MQTT, VPN, HTTP, etc.) will be &#039;&#039;&#039;interrupted&#039;&#039;&#039;&lt;br /&gt;
* Modem temporarily &#039;&#039;&#039;disappears from the system&#039;&#039;&#039;&lt;br /&gt;
* A new network registration is performed&lt;br /&gt;
* IP address will &#039;&#039;&#039;likely change&#039;&#039;&#039;&lt;br /&gt;
* Total recovery time may take &#039;&#039;&#039;10–120 seconds&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====== When to use ======&lt;br /&gt;
Use &#039;&#039;&#039;RESET&#039;&#039;&#039; only when:&lt;br /&gt;
&lt;br /&gt;
* Modem is stuck in &#039;&#039;&#039;searching&#039;&#039;&#039; or not registering&lt;br /&gt;
* Connected but no data traffic is possible&lt;br /&gt;
* APN/operator changes are not taking effect&lt;br /&gt;
* Modem becomes unresponsive or unstable&lt;br /&gt;
&lt;br /&gt;
====== When NOT to Use ======&lt;br /&gt;
Avoid using RESET :&lt;br /&gt;
&lt;br /&gt;
* During OTA updates or file uploads&lt;br /&gt;
* During critical real-time operations&lt;br /&gt;
* If a simple reconnect ( SET_MODEM_STATE ) is sufficient&lt;br /&gt;
&lt;br /&gt;
====== Application Considerations ======&lt;br /&gt;
&#039;&#039;&#039;Before RESET&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Ensure no critical operations are ongoing&lt;br /&gt;
* Persist any unsent or buffered data&lt;br /&gt;
* Expect loss of connectivity&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;After RESET&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Wait for modem to fully recover (can take up to ~2 minutes)&lt;br /&gt;
* Re-check modem status using: &#039;&#039;&#039;GET_STATUS&#039;&#039;&#039;&lt;br /&gt;
* Re-establish application-level connections: &#039;&#039;&#039;MQTT&#039;&#039;&#039;; &#039;&#039;&#039;VPN&#039;&#039;&#039; an &#039;&#039;&#039;Cloud sessions&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.9 Set Network Mode =====&lt;br /&gt;
Configures allowed radio technologies&lt;br /&gt;
&lt;br /&gt;
Supported values:&lt;br /&gt;
&lt;br /&gt;
* 2g&lt;br /&gt;
* 3g&lt;br /&gt;
* 4g&lt;br /&gt;
* auto&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SET_NETWORK_MODE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;4g&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;4g&amp;quot;,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.10 Get Signal Strength =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_SIGNAL&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;signal&amp;quot;: 34,&lt;br /&gt;
      &amp;quot;unit&amp;quot;: &amp;quot;%&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.11 Get SIM card info =====&lt;br /&gt;
&#039;&#039;&#039;GET_SIM_INFO&#039;&#039;&#039; is a &#039;&#039;&#039;runtime action&#039;&#039;&#039; used to read SIM card information from the modem through ModemManager.&lt;br /&gt;
&lt;br /&gt;
This action is &#039;&#039;&#039;read-only&#039;&#039;&#039;. It does not change the modem state, APN, operator, bearer, or NetworkManager configuration.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;GET_SIM_INFO&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;sim&amp;quot;: {&lt;br /&gt;
        &amp;quot;id&amp;quot;: &amp;quot;0&amp;quot;,&lt;br /&gt;
        &amp;quot;path&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
        &amp;quot;active&amp;quot;: true,&lt;br /&gt;
        &amp;quot;iccid&amp;quot;: &amp;quot;8935101234567890123&amp;quot;,&lt;br /&gt;
        &amp;quot;imsi&amp;quot;: &amp;quot;268060123456789&amp;quot;,&lt;br /&gt;
        &amp;quot;operator_id&amp;quot;: &amp;quot;26806&amp;quot;,&lt;br /&gt;
        &amp;quot;operator_name&amp;quot;: &amp;quot;MEO&amp;quot;,&lt;br /&gt;
        &amp;quot;emergency_numbers&amp;quot;: [&lt;br /&gt;
          &amp;quot;112&amp;quot;&lt;br /&gt;
        ],&lt;br /&gt;
        &amp;quot;preferred_networks&amp;quot;: [&lt;br /&gt;
          &amp;quot;operator-code: 42507, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 20810, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 64710, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 37001, access-technologies: gsm, umts, lte&amp;quot;,&lt;br /&gt;
          &amp;quot;operator-code: 34002, access-technologies: gsm, umts, lte&amp;quot;&lt;br /&gt;
        ]&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Field&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| number / string&lt;br /&gt;
|Same request ID received in the input payload.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|Actor name, usually &#039;&#039;&#039;modem-actor&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|Indicates if the SIM information was read successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.id&lt;br /&gt;
|string&lt;br /&gt;
|SIM object ID used by ModemManager. Usually 0.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.path&lt;br /&gt;
|string&lt;br /&gt;
|ModemManager DBus path for the SIM object.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.active&lt;br /&gt;
|boolean / null&lt;br /&gt;
|Indicates if the SIM is active, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.iccid&lt;br /&gt;
|string / null&lt;br /&gt;
|SIM ICCID / SIM identifier. This is the physical SIM card identifier.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.imsi&lt;br /&gt;
|string / null&lt;br /&gt;
|IMSI associated with the SIM subscription.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.operator_id&lt;br /&gt;
|string / null&lt;br /&gt;
|Mobile operator identifier from the SIM, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.operator_name&lt;br /&gt;
|string / null&lt;br /&gt;
|Operator name from the SIM, when available.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.emergency_numbers&lt;br /&gt;
|array&lt;br /&gt;
|Emergency numbers reported by the SIM/modem.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.sim.preferred_networks&lt;br /&gt;
|array&lt;br /&gt;
|Preferred networks stored on the SIM, when available.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.13.12 Test Modem =====&lt;br /&gt;
Performs a basic diagnostic test:&lt;br /&gt;
&lt;br /&gt;
* Modem detection&lt;br /&gt;
* SIM presence&lt;br /&gt;
* Network registration&lt;br /&gt;
* Data connectivity&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
&amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
&amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
&amp;quot;task&amp;quot;: {&lt;br /&gt;
  &amp;quot;action&amp;quot;: &amp;quot;TEST&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;hw&amp;quot;: true,&lt;br /&gt;
      &amp;quot;sim&amp;quot;: true,&lt;br /&gt;
      &amp;quot;network&amp;quot;: true,&lt;br /&gt;
      &amp;quot;data&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.13 Speed Test =====&lt;br /&gt;
Performs a &#039;&#039;&#039;low-data network speed test&#039;&#039;&#039; over the modem interface.&lt;br /&gt;
&lt;br /&gt;
This command does &#039;&#039;&#039;not&#039;&#039;&#039; run a full bandwidth benchmark.&lt;br /&gt;
&lt;br /&gt;
Instead, it performs a &#039;&#039;&#039;short and capped download burst&#039;&#039;&#039; on interface &#039;&#039;&#039;wwan0&#039;&#039;&#039; , measures the number of received bytes during a fixed time window, and&lt;br /&gt;
&lt;br /&gt;
returns an &#039;&#039;&#039;estimated download speed&#039;&#039;&#039; together with &#039;&#039;&#039;latency&#039;&#039;&#039; and a &#039;&#039;&#039;confidence level&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This approach is designed for IoT / field devices using &#039;&#039;&#039;capped cellular SIM cards&#039;&#039;&#039;, where a classic speed test would consume too much data.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;action&amp;quot;: &amp;quot;SPEED_TEST&amp;quot;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Success reply&#039;&#039;&#039;:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;download_mbps&amp;quot;: 12.4,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Error reply&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Example when the modem is not connected:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;download_mbps&amp;quot;: 12.4,&lt;br /&gt;
      &amp;quot;success&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Example when an unexpected internal error occurs:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: false,&lt;br /&gt;
      &amp;quot;reason&amp;quot;: &amp;quot;unexpected_exception&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Reply parameters&#039;&#039;&#039; ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|success&lt;br /&gt;
| boolean&lt;br /&gt;
|Indicates whether the speed test completed successfully. true = test executed, false = failed (see reason ).&lt;br /&gt;
|-&lt;br /&gt;
|download_mbps&lt;br /&gt;
| number&lt;br /&gt;
|Estimated download speed in &#039;&#039;&#039;megabits per second (Mbps)&#039;&#039;&#039;. Calculated from the number of bytes received on interface&lt;br /&gt;
&#039;&#039;&#039;wwan0&#039;&#039;&#039; during the measurement window.&lt;br /&gt;
|-&lt;br /&gt;
|bytes_sampled&lt;br /&gt;
|number&lt;br /&gt;
|Total number of &#039;&#039;&#039;received bytes&#039;&#039;&#039; measured on the modem interface ( &#039;&#039;&#039;wwan0&#039;&#039;&#039; ) during the test window. Used as the raw input&lt;br /&gt;
for speed calculation.&lt;br /&gt;
|-&lt;br /&gt;
|duration_s&lt;br /&gt;
|number&lt;br /&gt;
|Measurement window duration in seconds. Current implementation uses &#039;&#039;&#039;5 seconds&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|latency_ms&lt;br /&gt;
|number&lt;br /&gt;
|null&lt;br /&gt;
|-&lt;br /&gt;
|confidence&lt;br /&gt;
|string&lt;br /&gt;
|Qualitative indicator of measurement reliability based on sampled bytes:• &#039;&#039;&#039;low&#039;&#039;&#039; → &amp;lt; 50,000 bytes• &#039;&#039;&#039;medium&#039;&#039;&#039; → 50,000–&lt;br /&gt;
299,999 bytes• &#039;&#039;&#039;high&#039;&#039;&#039; → ≥ 300,000 bytes&lt;br /&gt;
|-&lt;br /&gt;
|reason&lt;br /&gt;
|string&lt;br /&gt;
|Present only when &#039;&#039;&#039;success=false&#039;&#039;&#039; . Provides failure reason (e.g., &#039;&#039;&#039;not_connected (&amp;lt;state&amp;gt;)&#039;&#039;&#039; , &#039;&#039;&#039;unexpected_exception&#039;&#039;&#039; ).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Data consumption notice ======&lt;br /&gt;
This command performs a &#039;&#039;&#039;real network download&#039;&#039;&#039; and therefore consumes mobile data.&lt;br /&gt;
&lt;br /&gt;
Although the test is designed to be &#039;&#039;&#039;low-data&#039;&#039;&#039;, it still generates traffic:&lt;br /&gt;
&lt;br /&gt;
* Typical consumption per test: &#039;&#039;&#039;~100 KB to ~500 KB&#039;&#039;&#039;&lt;br /&gt;
* Latency measurement adds a negligible amount (ICMP ping)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Estimated data usage&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Frequency&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Estimated consumption&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~100 KB)&lt;br /&gt;
| ~3 MB/month&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~250 KB)&lt;br /&gt;
| ~7.5 MB/month&lt;br /&gt;
|-&lt;br /&gt;
|1 test/day (~500 KB)&lt;br /&gt;
|~15 MB/month&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Recommendation ======&lt;br /&gt;
For devices using &#039;&#039;&#039;capped SIM cards&#039;&#039;&#039;, it is recommended to:&lt;br /&gt;
&lt;br /&gt;
* Avoid running this test at high frequency&lt;br /&gt;
* Use signal and modem status ( &#039;&#039;&#039;mmcli&#039;&#039;&#039; ) for regular monitoring&lt;br /&gt;
* Reserve speed tests for:&lt;br /&gt;
&lt;br /&gt;
- commissioning&lt;br /&gt;
&lt;br /&gt;
- troubleshooting&lt;br /&gt;
&lt;br /&gt;
- periodic health checks&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Running frequent or extended tests may significantly impact the data allowance.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.14 Get Raw Modem Info (Reserved) =====&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: reserved/modem/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;modem-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: false,&lt;br /&gt;
      &amp;quot;reason&amp;quot;: &amp;quot;not_connected (registered)&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: reserved/modem/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;DEV&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;raw&amp;quot;: &amp;quot;mmcli -m 0 output...&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== 24.13.15 Example: Raw Modem Output ( mmcli ) =====&lt;br /&gt;
Command:&lt;br /&gt;
&lt;br /&gt;
mmcli -m 0 --output-json&lt;br /&gt;
&lt;br /&gt;
Example output:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;modem&amp;quot;: {&lt;br /&gt;
    &amp;quot;3gpp&amp;quot;: {&lt;br /&gt;
      &amp;quot;5gnr&amp;quot;: {&lt;br /&gt;
        &amp;quot;registration-settings&amp;quot;: {&lt;br /&gt;
          &amp;quot;drx-cycle&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
          &amp;quot;mico-mode&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;enabled-locks&amp;quot;: [],&lt;br /&gt;
      &amp;quot;eps&amp;quot;: {&lt;br /&gt;
        &amp;quot;initial-bearer&amp;quot;: {&lt;br /&gt;
          &amp;quot;dbus-path&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
          &amp;quot;settings&amp;quot;: {&lt;br /&gt;
            &amp;quot;apn&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;ip-type&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;password&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
            &amp;quot;user&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
          }&lt;br /&gt;
        },&lt;br /&gt;
        &amp;quot;ue-mode-operation&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;imei&amp;quot;: &amp;quot;862636056280785&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-access-technology&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-error&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-operator-id&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;network-rejection-operator-name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;operator-code&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;operator-name&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;packet-service-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;pco&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;registration-state&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;cdma&amp;quot;: {&lt;br /&gt;
      &amp;quot;activation-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;cdma1x-registration-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;esn&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;evdo-registration-state&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;meid&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;nid&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;sid&amp;quot;: &amp;quot;--&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;dbus-path&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/Modem/0&amp;quot;,&lt;br /&gt;
    &amp;quot;generic&amp;quot;: {&lt;br /&gt;
      &amp;quot;access-technologies&amp;quot;: [],&lt;br /&gt;
      &amp;quot;bearers&amp;quot;: [],&lt;br /&gt;
      &amp;quot;carrier-configuration&amp;quot;: &amp;quot;ROW_Gen_VoLTE&amp;quot;,&lt;br /&gt;
      &amp;quot;carrier-configuration-revision&amp;quot;: &amp;quot;05010822&amp;quot;,&lt;br /&gt;
      &amp;quot;current-bands&amp;quot;: [&lt;br /&gt;
        &amp;quot;egsm&amp;quot;,&lt;br /&gt;
        &amp;quot;dcs&amp;quot;,&lt;br /&gt;
        &amp;quot;pcs&amp;quot;,&lt;br /&gt;
        &amp;quot;g850&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-6&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-3&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-7&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-12&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-13&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-18&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-19&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-20&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-25&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-26&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-28&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-34&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-38&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-39&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-40&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-41&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-66&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-19&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;current-capabilities&amp;quot;: [&lt;br /&gt;
        &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;current-modes&amp;quot;: &amp;quot;allowed: 4g; preferred: none&amp;quot;,&lt;br /&gt;
      &amp;quot;device&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
      &amp;quot;device-identifier&amp;quot;: &amp;quot;2c759b7021f62d2e26973150063ea040b3662a65&amp;quot;,&lt;br /&gt;
      &amp;quot;drivers&amp;quot;: [&lt;br /&gt;
        &amp;quot;option&amp;quot;,&lt;br /&gt;
        &amp;quot;qmi_wwan&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;equipment-identifier&amp;quot;: &amp;quot;862636056280785&amp;quot;,&lt;br /&gt;
      &amp;quot;hardware-revision&amp;quot;: &amp;quot;10000&amp;quot;,&lt;br /&gt;
      &amp;quot;manufacturer&amp;quot;: &amp;quot;QUALCOMM INCORPORATED&amp;quot;,&lt;br /&gt;
      &amp;quot;model&amp;quot;: &amp;quot;SIMCOM_SIM7600G-H&amp;quot;,&lt;br /&gt;
      &amp;quot;own-numbers&amp;quot;: [],&lt;br /&gt;
      &amp;quot;physdev&amp;quot;: &amp;quot;/sys/devices/platform/scb/fe9c0000.xhci/usb1/1-1/1-1.4&amp;quot;,&lt;br /&gt;
      &amp;quot;plugin&amp;quot;: &amp;quot;simtech&amp;quot;,&lt;br /&gt;
      &amp;quot;ports&amp;quot;: [&lt;br /&gt;
        &amp;quot;cdc-wdm0 (qmi)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB0 (ignored)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB1 (gps)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB2 (at)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB3 (at)&amp;quot;,&lt;br /&gt;
        &amp;quot;ttyUSB4 (audio)&amp;quot;,&lt;br /&gt;
        &amp;quot;wwan0 (net)&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;power-state&amp;quot;: &amp;quot;on&amp;quot;,&lt;br /&gt;
      &amp;quot;primary-port&amp;quot;: &amp;quot;cdc-wdm0&amp;quot;,&lt;br /&gt;
      &amp;quot;primary-sim-slot&amp;quot;: &amp;quot;1&amp;quot;,&lt;br /&gt;
      &amp;quot;revision&amp;quot;: &amp;quot;LE20B04SIM7600G22&amp;quot;,&lt;br /&gt;
      &amp;quot;signal-quality&amp;quot;: {&lt;br /&gt;
        &amp;quot;recent&amp;quot;: &amp;quot;yes&amp;quot;,&lt;br /&gt;
        &amp;quot;value&amp;quot;: &amp;quot;0&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;sim&amp;quot;: &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
      &amp;quot;sim-slots&amp;quot;: [&lt;br /&gt;
        &amp;quot;/org/freedesktop/ModemManager1/SIM/0&amp;quot;,&lt;br /&gt;
        &amp;quot;/&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;state&amp;quot;: &amp;quot;failed&amp;quot;,&lt;br /&gt;
      &amp;quot;state-failed-reason&amp;quot;: &amp;quot;sim-missing&amp;quot;,&lt;br /&gt;
      &amp;quot;supported-bands&amp;quot;: [&lt;br /&gt;
        &amp;quot;egsm&amp;quot;,&lt;br /&gt;
        &amp;quot;dcs&amp;quot;,&lt;br /&gt;
        &amp;quot;pcs&amp;quot;,&lt;br /&gt;
        &amp;quot;g850&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-6&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-1&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-2&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-3&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-4&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-5&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-7&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-8&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-12&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-13&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-18&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-19&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-20&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-25&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-26&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-28&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-34&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-38&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-39&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-40&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-41&amp;quot;,&lt;br /&gt;
        &amp;quot;eutran-66&amp;quot;,&lt;br /&gt;
        &amp;quot;utran-19&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-capabilities&amp;quot;: [&lt;br /&gt;
        &amp;quot;gsm-umts, lte&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-ip-families&amp;quot;: [&lt;br /&gt;
        &amp;quot;ipv4&amp;quot;,&lt;br /&gt;
        &amp;quot;ipv6&amp;quot;,&lt;br /&gt;
        &amp;quot;ipv4v6&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;supported-modes&amp;quot;: [&lt;br /&gt;
        &amp;quot;allowed: 2g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 4g; preferred: none&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g; preferred: 2g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 4g; preferred: 2g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 3g, 4g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 4g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 3g&amp;quot;,&lt;br /&gt;
        &amp;quot;allowed: 2g, 3g, 4g; preferred: 2g&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;unlock-required&amp;quot;: &amp;quot;--&amp;quot;,&lt;br /&gt;
      &amp;quot;unlock-retries&amp;quot;: []&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Field Reference - mmcli -m 0 --output-json ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;JSON Path&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example Value&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Notes / Interpretation&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|modem.dbus-path&lt;br /&gt;
| Internal modem path&lt;br /&gt;
|/org/.../Modem/0&lt;br /&gt;
|Used by mmcli ( -m 0 )&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.manufacturer&lt;br /&gt;
| Modem vendor&lt;br /&gt;
|QUALCOMM INCORPORATED&lt;br /&gt;
|Hardware info&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.model&lt;br /&gt;
|Modem model&lt;br /&gt;
|SIM7600G-H&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.revision&lt;br /&gt;
|Firmware version&lt;br /&gt;
|LE20B04SIM7600G22&lt;br /&gt;
|Useful for debugging&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.device&lt;br /&gt;
|Linux device path&lt;br /&gt;
|/sys/devices/...&lt;br /&gt;
|USB device&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.drivers&lt;br /&gt;
|Kernel drivers&lt;br /&gt;
|option, qmi_wwan&lt;br /&gt;
|Must be present&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.primary-port&lt;br /&gt;
|Control interface&lt;br /&gt;
|cdc-wdm0&lt;br /&gt;
|Critical (QMI control)&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.ports&lt;br /&gt;
|Available interfaces&lt;br /&gt;
|ttyUSB*, wwan0&lt;br /&gt;
|Data + AT + GPS&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.power-state&lt;br /&gt;
|Power status&lt;br /&gt;
|on&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.state&lt;br /&gt;
|Modem state&lt;br /&gt;
|failed&lt;br /&gt;
|Main status field&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.state-failed-reason&lt;br /&gt;
|Failure reason&lt;br /&gt;
|sim-missing&lt;br /&gt;
|Root cause of failure&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.signal-quality.value&lt;br /&gt;
|Signal strength (%)&lt;br /&gt;
|0&lt;br /&gt;
|0 = no signal&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-capabilities&lt;br /&gt;
|Active radio tech&lt;br /&gt;
|gsm-umts, lte&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-modes&lt;br /&gt;
|Active mode&lt;br /&gt;
|allowed: 4g&lt;br /&gt;
|Controlled via API&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.current-bands&lt;br /&gt;
|Active frequency bands&lt;br /&gt;
|[eutran-1, ...]&lt;br /&gt;
|Coverage related&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.supported-bands&lt;br /&gt;
|Supported bands&lt;br /&gt;
|[eutran-*, utran-*]&lt;br /&gt;
|Hardware capability&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.supported-ip-families&lt;br /&gt;
|IP support&lt;br /&gt;
|ipv4, ipv6, ipv4v6&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.sim&lt;br /&gt;
|SIM path&lt;br /&gt;
|/org/.../SIM/0&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.sim-slots&lt;br /&gt;
|SIM slots&lt;br /&gt;
|[slot1, slot2]&lt;br /&gt;
|Slot 2 empty here&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.primary-sim-slot&lt;br /&gt;
|Active SIM slot&lt;br /&gt;
|1&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|modem.generic.bearers&lt;br /&gt;
|Active data sessions&lt;br /&gt;
|[ ]&lt;br /&gt;
|Empty = no connection&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.imei&lt;br /&gt;
|Device IMEI&lt;br /&gt;
|862636056280785&lt;br /&gt;
|Unique identifier&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.operator-name&lt;br /&gt;
|Network name&lt;br /&gt;
| --&lt;br /&gt;
|Not available (no SIM)&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.operator-code&lt;br /&gt;
|MCC/MNC&lt;br /&gt;
| --&lt;br /&gt;
|Not available&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.registration-state&lt;br /&gt;
|Network state&lt;br /&gt;
| --&lt;br /&gt;
|Not registered&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.packet-service-state&lt;br /&gt;
|Data service state&lt;br /&gt;
| --&lt;br /&gt;
|No data session&lt;br /&gt;
|-&lt;br /&gt;
|modem.3gpp.eps.initial-bearer.settings.apn&lt;br /&gt;
|APN&lt;br /&gt;
| --&lt;br /&gt;
|Not set / no connection&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.13.16 Notes: =====&lt;br /&gt;
&lt;br /&gt;
* If no modem is detected: &#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;present&amp;quot;: false&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* If SIM is locked or missing: &#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: modem/runtime/out&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;modem&amp;quot;: {&lt;br /&gt;
        &amp;quot;sim&amp;quot;: &amp;quot;locked&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Operator scan may take several seconds and should be handled asynchronously.&lt;br /&gt;
* Some actions require:&lt;br /&gt;
&lt;br /&gt;
- SIM card inserted&lt;br /&gt;
&lt;br /&gt;
- Modem enabled&lt;br /&gt;
&lt;br /&gt;
- &#039;&#039;&#039;cdc-wdm0&#039;&#039;&#039; interface available&lt;br /&gt;
&lt;br /&gt;
* Signal strength is reported as percentage and may be cached by ModemActor.&lt;br /&gt;
&lt;br /&gt;
==== &amp;lt;big&amp;gt;24.14 CANopen Actor&amp;lt;/big&amp;gt; ====&lt;br /&gt;
&lt;br /&gt;
===== 24.14.1 App Interfacing =====&lt;br /&gt;
User App interface and functionalities exposed to the open part of the MQTT broker.&lt;br /&gt;
&lt;br /&gt;
The CANopen Actor provides a generic protocol interface to CANopen devices.&lt;br /&gt;
&lt;br /&gt;
The actor does NOT interpret device-specific meaning (Object Dictionary semantics).&lt;br /&gt;
&lt;br /&gt;
It only handles communication (HOW to talk).&lt;br /&gt;
&lt;br /&gt;
===== 24.14.2 Configuration =====&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Configure CANopen Nodes&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/config/in&lt;br /&gt;
&lt;br /&gt;
Stores CANopen defaults and logical node configuration inside the actor.&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;sdo_timeout&amp;quot;: &amp;quot;&amp;lt;SDO_TIMEOUT&amp;gt;&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;nodes&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;NODE_NAME&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;node_id&amp;quot;: &amp;quot;&amp;lt;NODE_ID&amp;gt;&amp;quot;,&lt;br /&gt;
          &amp;quot;steps_per_rev&amp;quot;: &amp;quot;&amp;lt;STEPS_PER_REV&amp;gt;&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;motor_1&amp;quot;: {&lt;br /&gt;
        &amp;quot;success&amp;quot;: true&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;1777041089180&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value isreturned in the response, allowing the applicationto match requests and responses.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies who sent the request. Common values canbe&lt;br /&gt;
&#039;&#039;&#039;APP&#039;&#039;&#039;, &#039;&#039;&#039;NodeRED&#039;&#039;&#039;, &#039;&#039;&#039;CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the CANopencommand alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;CONFIG_CANOPEN&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this section,the alias must be&lt;br /&gt;
&#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the configuration data to store inside theCANopen actor.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.defaults&lt;br /&gt;
|object&lt;br /&gt;
|No&lt;br /&gt;
|{ &amp;quot;sdo_timeout&amp;quot;:2.0 }&lt;br /&gt;
|Defines default CANopen settings used by the actorwhen no command-specific value is provided.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.defaults.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Default timeout, in seconds, used for SDOoperations. For example, &#039;&#039;&#039;2.0&#039;&#039;&#039;&lt;br /&gt;
means the actor waitsup to 2 seconds for an SDO response.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;lt;nowiki&amp;gt;{ &amp;quot;motor_1&amp;quot;: {...}}&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
|List of logical CANopen nodes known by the actor.Each key is a user-defined node name.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical name used to reference a node later withoutrepeatedly sending its&lt;br /&gt;
&#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID on the CAN bus. Valid CANopennode IDs are normally in the range&lt;br /&gt;
&#039;&#039;&#039;1..127&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodes.&amp;lt;NODE_NAME&amp;gt;.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Recommended&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw position counts corresponding toone full mechanical revolution, 360°. The actor usesthis later to convert raw position into revolutions and angle_deg.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;1777041089180&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate the&lt;br /&gt;
response with the original command.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response. For successful&lt;br /&gt;
handler replies, this is canopen-actor.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object containing the executed alias and the command&lt;br /&gt;
result.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;CONFIG_CANOPEN&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the configuration outcome.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.defaults.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the &#039;&#039;&#039;defaults&#039;&#039;&#039; configuration was successfully stored. This&lt;br /&gt;
field is present only if &#039;&#039;&#039;defaults&#039;&#039;&#039; was included in the request.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.&amp;lt;NODE_NAME&amp;gt;.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the logical node configuration was successfully stored.&lt;br /&gt;
Example: &#039;&#039;&#039;taskResult.motor_1.success = true&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Generic success field. This appears when no specific &#039;&#039;&#039;defaults&#039;&#039;&#039; or &#039;&#039;&#039;nodes&#039;&#039;&#039;&lt;br /&gt;
result is generated.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;unknown alias&lt;br /&gt;
CONFIG_X&amp;quot;&lt;br /&gt;
|Error description. This field is present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039; does not communicate with the CANopen device directly. It stores logical node configuration inside the actor so that later runtime&lt;br /&gt;
&lt;br /&gt;
commands can refer to nodes by name instead of always sending the numeric &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
====== Configure one CANopen Transmit PDO ======&lt;br /&gt;
Configures a TPDO to transmit position data.&lt;br /&gt;
&lt;br /&gt;
The handler validates &#039;&#039;&#039;pdo_num&#039;&#039;&#039; as &#039;&#039;&#039;1..4&#039;&#039;&#039;, defaults &#039;&#039;&#039;map_index&#039;&#039;&#039; to &#039;&#039;&#039;0x6004&#039;&#039;&#039;, &#039;&#039;&#039;map_subindex&#039;&#039;&#039; to &#039;&#039;&#039;0x00&#039;&#039;&#039;, &#039;&#039;&#039;map_bits&#039;&#039;&#039; to &#039;&#039;&#039;32&#039;&#039;&#039;, &#039;&#039;&#039;transmission_type&#039;&#039;&#039; to &#039;&#039;&#039;255&#039;&#039;&#039; , &#039;&#039;&#039;event_timer_ms&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
to &#039;&#039;&#039;20&#039;&#039;&#039;, and &#039;&#039;&#039;inhibit_time_100us&#039;&#039;&#039; to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/config/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_POSITION_TPDO&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;map_index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;map_subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;map_bits&amp;quot;: 32,&lt;br /&gt;
      &amp;quot;transmission_type&amp;quot;: 255,&lt;br /&gt;
      &amp;quot;event_timer_ms&amp;quot;: 2,&lt;br /&gt;
      &amp;quot;inhibit_time_100us&amp;quot;: 20,&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/config/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_POSITION_TPDO&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;comm_index&amp;quot;: 6144,&lt;br /&gt;
      &amp;quot;map_index&amp;quot;: 6656,&lt;br /&gt;
      &amp;quot;mapped_object&amp;quot;: &amp;quot;0x6004:00/32&amp;quot;,&lt;br /&gt;
      &amp;quot;transmission_type&amp;quot;: 255,&lt;br /&gt;
      &amp;quot;event_timer_ms&amp;quot;: 2,&lt;br /&gt;
      &amp;quot;inhibit_time_100us&amp;quot;: 20,&lt;br /&gt;
      &amp;quot;cob_id&amp;quot;: 389&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== Parameter description ======&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Default&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|node_id&lt;br /&gt;
| int&lt;br /&gt;
|Yes*&lt;br /&gt;
|—&lt;br /&gt;
|CANopen node ID.&lt;br /&gt;
|-&lt;br /&gt;
|node&lt;br /&gt;
| string&lt;br /&gt;
|Yes*&lt;br /&gt;
|—&lt;br /&gt;
|Logical node name configured previously with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|pdo_num&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number. Valid range: &#039;&#039;&#039;1..4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|map_index&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0x6004&lt;br /&gt;
|Object dictionary index to map. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6004&#039;&#039;&#039;&amp;quot; are&lt;br /&gt;
supported.&lt;br /&gt;
|-&lt;br /&gt;
|map_subindex&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0x00&lt;br /&gt;
|Object dictionary subindex.&lt;br /&gt;
|-&lt;br /&gt;
|map_bits&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|32&lt;br /&gt;
|Number of mapped bits.&lt;br /&gt;
|-&lt;br /&gt;
|transmission_type&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|255&lt;br /&gt;
|CANopen TPDO transmission type.&lt;br /&gt;
|-&lt;br /&gt;
|event_timer_ms&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|TPDO event timer in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|inhibit_time_100us&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Inhibit time in 100 μs units.&lt;br /&gt;
|-&lt;br /&gt;
|offset&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset used later when decoding PDO position.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes used later when decoding PDO position.&lt;br /&gt;
|-&lt;br /&gt;
|signed&lt;br /&gt;
|bool&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|Whether decoded raw position should be interpreted as signed.&lt;br /&gt;
|-&lt;br /&gt;
|steps_per_rev&lt;br /&gt;
|int&lt;br /&gt;
|Recommended&lt;br /&gt;
|&#039;&#039;&#039;4096&#039;&#039;&#039; if saved into node&lt;br /&gt;
&lt;br /&gt;
config&lt;br /&gt;
|Encoder steps per revolution.&lt;br /&gt;
|-&lt;br /&gt;
|timeout&lt;br /&gt;
|float&lt;br /&gt;
|No&lt;br /&gt;
|actor default&lt;br /&gt;
|SDO/NMT operation timeout.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===== 24.14.3 Runtime Operations =====&lt;br /&gt;
Supported runtime aliases include &amp;lt;small&amp;gt;&#039;&#039;&#039;READ, READ_CONTINUOUS, STOP_READ_CONTINUOUS, READ_PDO_CONTINUOUS, STOP_READ_PDO_CONTINUOUS, PING, NMT_COMMAND, SDO_READ, SDO_WRITE, READ_HEARTBEAT, RECV_PDO, RECV_EMCY&#039;&#039;&#039;&amp;lt;/small&amp;gt;, and &amp;lt;small&amp;gt;&#039;&#039;&#039;QUERY_NODE_INFO&#039;&#039;&#039;&amp;lt;/small&amp;gt;&amp;lt;small&amp;gt;&#039;&#039;&#039;.&#039;&#039;&#039;&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== NMT Control ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;CONFIG_CANOPEN&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;defaults&amp;quot;: {&lt;br /&gt;
        &amp;quot;sdo_timeout&amp;quot;: &amp;quot;&amp;lt;SDO_TIMEOUT&amp;gt;&amp;quot;&lt;br /&gt;
      },&lt;br /&gt;
      &amp;quot;nodes&amp;quot;: {&lt;br /&gt;
        &amp;quot;&amp;lt;NODE_NAME&amp;gt;&amp;quot;: {&lt;br /&gt;
          &amp;quot;node_id&amp;quot;: &amp;quot;&amp;lt;NODE_ID&amp;gt;&amp;quot;,&lt;br /&gt;
          &amp;quot;steps_per_rev&amp;quot;: &amp;quot;&amp;lt;STEPS_PER_REV&amp;gt;&amp;quot;&lt;br /&gt;
        }&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;NMT_COMMAND&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;nmt-start-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;command&amp;quot;: &amp;quot;START&amp;quot;,&lt;br /&gt;
      &amp;quot;confirmed&amp;quot;: true,&lt;br /&gt;
      &amp;quot;state&amp;quot;: null&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Supported NMT Commands&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Command&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Meaning&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Notes&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|START&lt;br /&gt;
| Puts the node into Operational state.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat state &#039;&#039;&#039;OPERATIONAL&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|STOP&lt;br /&gt;
| Puts the node into Stopped state.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat state &#039;&#039;&#039;STOPPED&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|PRE_OP&lt;br /&gt;
|Puts the node into Pre-Operational state.&lt;br /&gt;
|Used before operations such as PDO remapping.&lt;br /&gt;
|-&lt;br /&gt;
|PRE-OP&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|PREOP&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|PRE_OPERATIONAL&lt;br /&gt;
|Same as &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|RESET_NODE&lt;br /&gt;
|Resets the CANopen node application.&lt;br /&gt;
|If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for boot-up heartbeat.&lt;br /&gt;
|-&lt;br /&gt;
|RESET&lt;br /&gt;
|Same as &#039;&#039;&#039;RESET_NODE&#039;&#039;&#039;.&lt;br /&gt;
|Alternative accepted spelling.&lt;br /&gt;
|-&lt;br /&gt;
|RESET_COMM&lt;br /&gt;
|Resets CANopen communication.&lt;br /&gt;
|Sends NMT reset communication command.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;NMT_COMMAND&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&#039;&#039;&#039;NMT_COMMAND&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the NMT command parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID that will receive the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.command&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|NMT command to send. If omitted, the actor defaults to &#039;&#039;&#039;START&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.wait&lt;br /&gt;
|boolean&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|If &#039;&#039;&#039;true&#039;&#039;&#039;, the actor waits for heartbeat/state confirmation when supported. If&lt;br /&gt;
&#039;&#039;&#039;false&#039;&#039;&#039;, the command is sent without waiting for confirmation.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|5.0&lt;br /&gt;
|Timeout, in seconds, used when waiting for NMT confirmation. &lt;br /&gt;
Default is &#039;&#039;&#039;5.0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Internal timeout used when creating/updating the CANopen node wrapper.&lt;br /&gt;
Usually not required for basic NMT usage.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request and&lt;br /&gt;
response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;NMT_COMMAND&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the NMT command result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the actor successfully executed the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;nmt-start-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches the&lt;br /&gt;
original request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that received the NMT command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.command&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|NMT command that was executed. For aliases such as &#039;&#039;&#039;RESET&#039;&#039;&#039; , the response may&lt;br /&gt;
normalize the command to &#039;&#039;&#039;RESET_NODE&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.confirmed&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the command was considered successful. If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;false&#039;&#039;&#039; , this&lt;br /&gt;
usually means the command was sent successfully. If &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039; , this means&lt;br /&gt;
&lt;br /&gt;
the expected heartbeat/state confirmation was received.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.state&lt;br /&gt;
|string/null&lt;br /&gt;
|null&lt;br /&gt;
|Confirmed NMT state when &#039;&#039;&#039;wait&#039;&#039;&#039; = &#039;&#039;&#039;true&#039;&#039;&#039; and state confirmation is available.&lt;br /&gt;
Otherwise it is &#039;&#039;&#039;null&#039;&#039;&#039; . Possible values include &#039;&#039;&#039;OPERATIONAL&#039;&#039;&#039; , &#039;&#039;&#039;STOPPED&#039;&#039;&#039; , and &#039;&#039;&#039;PRE_OP&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;unsupported NMT&lt;br /&gt;
command X&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== SDO Read ======&lt;br /&gt;
Reads an object dictionary value using SDO upload.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;sdo-read-position-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 123456&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;SDO_READ&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be &#039;&#039;&#039;SDO_READ&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the SDO read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index to read. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6004&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
are supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex to read. If omitted, defaults to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the SDO read operation. If omitted, the&lt;br /&gt;
actor default SDO timeout is used.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request and&lt;br /&gt;
response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO_READ&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the SDO read result.&lt;br /&gt;
task&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the SDO read was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sdo-read-positionnode5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches the&lt;br /&gt;
original request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index that was read, returned as decimal. Example: &#039;&#039;&#039;24580&#039;&#039;&#039; =&lt;br /&gt;
&#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.value&lt;br /&gt;
|integer&lt;br /&gt;
|123456&lt;br /&gt;
|Raw value returned by the SDO read operation.&lt;br /&gt;
task.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO timeout&lt;br /&gt;
0x6004:00&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
SDO&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* SDO Write&lt;br /&gt;
&lt;br /&gt;
Writes an object dictionary value using SDO download.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_WRITE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6003&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;SDO_WRITE&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;sdo-write-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24579,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;value&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Parameter descirption&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Default&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|node_id / nodeId / node&lt;br /&gt;
| int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|CANopen node reference.&lt;br /&gt;
|-&lt;br /&gt;
|index&lt;br /&gt;
| int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|Object dictionary index.&lt;br /&gt;
|-&lt;br /&gt;
|subindex&lt;br /&gt;
|int/string&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex.&lt;br /&gt;
|-&lt;br /&gt;
|value&lt;br /&gt;
|int/string&lt;br /&gt;
|Yes&lt;br /&gt;
|—&lt;br /&gt;
|Value to write.&lt;br /&gt;
|-&lt;br /&gt;
|size&lt;br /&gt;
|int&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes: usually &#039;&#039;&#039;1&#039;&#039;&#039; , &#039;&#039;&#039;2&#039;&#039;&#039; , or &#039;&#039;&#039;4.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|timeout&lt;br /&gt;
|float&lt;br /&gt;
|No&lt;br /&gt;
|actor default&lt;br /&gt;
|SDO timeout in seconds.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in the response.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039; , &#039;&#039;&#039;NodeRED&#039;&#039;&#039; , &#039;&#039;&#039;CLI&#039;&#039;&#039; , or&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;SDO_WRITE&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SDO_WRITE&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the SDO write parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to write to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;0x6003&amp;quot;&lt;br /&gt;
|CANopen object dictionary index to write. Hex strings such as &amp;quot;&#039;&#039;&#039;0x6003&#039;&#039;&#039;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
are supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex to write. If omitted, defaults to &#039;&#039;&#039;0&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.value&lt;br /&gt;
|integer/string&lt;br /&gt;
|Yes&lt;br /&gt;
|0&lt;br /&gt;
|Value to write into the selected object dictionary entry. Hex strings are&lt;br /&gt;
&lt;br /&gt;
also supported.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.size&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes to write. Valid values are normally &#039;&#039;&#039;1&#039;&#039;&#039; , &#039;&#039;&#039;2&#039;&#039;&#039; , &#039;&#039;&#039;3&#039;&#039;&#039; , or &#039;&#039;&#039;4&#039;&#039;&#039; . If&lt;br /&gt;
&lt;br /&gt;
omitted, defaults to &#039;&#039;&#039;4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the SDO write operation. If omitted, the&lt;br /&gt;
&lt;br /&gt;
actor default SDO timeout is used.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request andresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO_WRITE&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the SDO write result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the SDO write was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;sdo-write-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call.&lt;br /&gt;
&lt;br /&gt;
Usually matches theoriginal request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was written to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24579&lt;br /&gt;
|Object dictionary index that was written, returned as decimal.&lt;br /&gt;
&lt;br /&gt;
Example: &#039;&#039;&#039;24579 =0x6003&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex that was written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.value&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Value that was written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.size&lt;br /&gt;
|integer&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes written.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO abort 0x6003:00 -&amp;gt;...&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Read Node State ======&lt;br /&gt;
Reads position and returns raw value, revolutions, and angle. Internally, this reads the configured position object, defaulting to&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;0x6004:00&#039;&#039;&#039;. &#039;&#039;&#039;If&#039;&#039;&#039; &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039; is not provided, the owner reads &#039;&#039;&#039;0x6501:00&#039;&#039;&#039; to obtain it.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 2.0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;id&amp;quot;: &amp;quot;read-node5&amp;quot;,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. The same value is returned in theresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP, NodeRED, CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias andparameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be &#039;&#039;&#039;READ&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the position read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index used as the raw positionsource. If omitted, defaults to &#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex used as the raw positionsource. If omitted, defaults to &#039;&#039;&#039;0x00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Recommended&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per mechanical revolution. Used tocalculate&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;revolutions&#039;&#039;&#039; and &#039;&#039;&#039;angle_deg&#039;&#039;&#039;. If omitted, the ownerattempts to read &#039;&#039;&#039;0x6501:00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Timeout, in seconds, used for the internal SDO reads. Ifomitted, the actor default SDO timeout is used.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.sdo_timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|2.0&lt;br /&gt;
|Internal SDO timeout used when creating/updating the nodewrapper. Usually not required.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the request. Used to correlate request andresponse.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing the position read result.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the position read was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-node5&amp;quot;&lt;br /&gt;
|Internal/request ID returned by the CANopen RPC call. Usually matches theoriginal request &#039;&#039;&#039;id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Raw position value read from the selected object dictionary entry.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for the conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions. Example: &#039;&#039;&#039;1024 / 4096 = 0.25&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees. Example: &#039;&#039;&#039;0.25 × 360 = 90°&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index read as the raw position source. Example: &#039;&#039;&#039;24580 =0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex read as the raw position source.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;SDO timeout0x6004:00&amp;quot;&lt;br /&gt;
|Error description. Present only when the command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== READ SDO Continuous ======&lt;br /&gt;
Starts continuous SDO-based position reading.&lt;br /&gt;
&lt;br /&gt;
The initial command returns an acknowledgement. After that, continuous samples are published repeatedly to &#039;&#039;&#039;canopen/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The continuous loop requires a single node reference and requires &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start request&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;index&amp;quot;: &amp;quot;0x6004&amp;quot;,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: &amp;quot;0x00&amp;quot;,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 0.2,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
// Start acknowledgement&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: true,&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;single&amp;quot;,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
// Continuous sample response&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;index&amp;quot;: 24580,&lt;br /&gt;
      &amp;quot;subindex&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;continuous&amp;quot;: true,&lt;br /&gt;
      &amp;quot;request_id&amp;quot;: &amp;quot;read-cont-node5&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. Continuous sample responses include&lt;br /&gt;
&lt;br /&gt;
this value as &#039;&#039;&#039;request_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP&#039;&#039;&#039;, &#039;&#039;&#039;NodeRED&#039;&#039;&#039;,&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CLI&#039;&#039;&#039;, or &#039;&#039;&#039;TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and&lt;br /&gt;
&lt;br /&gt;
parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Defines the command to execute. For this operation, it must be&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the continuous read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read continuously.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Yes**&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per mechanical revolution. Required by&lt;br /&gt;
&lt;br /&gt;
the fast continuous read loop to calculate &#039;&#039;&#039;revolutions&#039;&#039;&#039; and&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;angle_deg&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.index&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x6004&amp;quot;&lt;br /&gt;
|CANopen object dictionary index used as the raw position&lt;br /&gt;
&lt;br /&gt;
source. If omitted, defaults to &#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.subindex&lt;br /&gt;
|integer/string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;0x00&amp;quot;&lt;br /&gt;
|CANopen object dictionary subindex used as the raw position&lt;br /&gt;
&lt;br /&gt;
source. If omitted, defaults to &#039;&#039;&#039;0x00&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|0.2&lt;br /&gt;
|Timeout, in seconds, used for each fast SDO read cycle. If&lt;br /&gt;
&lt;br /&gt;
omitted, defaults to &#039;&#039;&#039;0.2&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|Delay between continuous read cycles, in milliseconds. If &#039;&#039;&#039;0&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
loop runs again immediately after each cycle yields control.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|Optional action. If set to &#039;&#039;&#039;STOP&#039;&#039;&#039; , &#039;&#039;&#039;OFF&#039;&#039;&#039; , &#039;&#039;&#039;CANCEL&#039;&#039;&#039; , or &#039;&#039;&#039;DISABLE&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
actor stops the continuous read loop instead of starting it.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the start request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object confirming that continuous reading was started.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the start command was accepted.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the continuous read loop is running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.mode&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;single&amp;quot;&lt;br /&gt;
|Read mode. In this fast continuous path, a single node is used when &#039;&#039;&#039;node_id&#039;&#039;&#039; ,&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;nodeId&#039;&#039;&#039; , or &#039;&#039;&#039;node&#039;&#039;&#039; is provided.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|20&lt;br /&gt;
|Configured delay between continuous read cycles, in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;no configured nodes&amp;quot;&lt;br /&gt;
|Error description. Present only when the start command fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| integer/string&lt;br /&gt;
|1777041089180&lt;br /&gt;
|Sample response ID generated by the actor for each read cycle.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the sample response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the running continuous command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing one continuous position sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether this specific read cycle was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that was read.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Raw position value read from the node.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.index&lt;br /&gt;
|integer&lt;br /&gt;
|24580&lt;br /&gt;
|Object dictionary index read as the raw position source. Example: &#039;&#039;&#039;24580 =&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;0x6004&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.subindex&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Object dictionary subindex read as the raw position source.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.continuous&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Marks this response as a continuous sample, not just the initial&lt;br /&gt;
&lt;br /&gt;
acknowledgement.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.request_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-cont-node5&amp;quot;&lt;br /&gt;
|Original request &#039;&#039;&#039;id&#039;&#039;&#039; that started the continuous loop. Useful to correlate&lt;br /&gt;
&lt;br /&gt;
samples with the start command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;operation failed&amp;quot;&lt;br /&gt;
|Error description for a failed sample. Present only when a read cycle fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Stop request ======&lt;br /&gt;
You can stop using either &#039;&#039;&#039;STOP_READ_CONTINUOUS&#039;&#039;&#039; :&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;STOP_READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {}&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Or by sending &#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039; with &#039;&#039;&#039;action: &amp;quot;STOP&amp;quot;&#039;&#039;&#039; :&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-read-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-read-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stopped&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Request Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;stop-read-cont&amp;quot;&lt;br /&gt;
|Unique request identifier.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot; or&lt;br /&gt;
&lt;br /&gt;
&amp;quot;STOP_READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Command used to stop the continuous read loop.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;STOP&amp;quot;&lt;br /&gt;
|When using &#039;&#039;&#039;READ_CONTINUOUS&#039;&#039;&#039; , set &#039;&#039;&#039;action&#039;&#039;&#039; to &#039;&#039;&#039;STOP&#039;&#039;&#039; , &#039;&#039;&#039;OFF&#039;&#039;&#039; , &#039;&#039;&#039;CANCEL&#039;&#039;&#039; ,&lt;br /&gt;
&lt;br /&gt;
or &#039;&#039;&#039;DISABLE&#039;&#039;&#039; to stop the loop. Not required when using&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;STOP_READ_CONTINUOUS&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;stop-read-cont&amp;quot;&lt;br /&gt;
|Same request identifier received in the stop request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias returned by the stop handler.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the stop request was processed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates that the continuous read loop is no longer running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.stopped&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether there was an active task that was actually stopped. If no continuous&lt;br /&gt;
&lt;br /&gt;
task was running, this may be &#039;&#039;&#039;false&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Continuous PDO Reading ======&lt;br /&gt;
Starts continuous PDO-based position reading.&lt;br /&gt;
&lt;br /&gt;
This command does not perform repeated SDO reads. Instead, it waits for TPDO frames already being transmitted by the CANopen node.&lt;br /&gt;
&lt;br /&gt;
Normally, the TPDO should be configured first using &#039;&#039;&#039;CONFIG_POSITION_TPDO&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The initial command returns an acknowledgement. After that, continuous sample responses are published repeatedly to: &#039;&#039;&#039;canopenRM8007/runtime/out&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Request&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;timeout&amp;quot;: 1.0,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: true,&lt;br /&gt;
      &amp;quot;mode&amp;quot;: &amp;quot;pdo&amp;quot;,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;interval_ms&amp;quot;: 20&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;node_id&amp;quot;: 5,&lt;br /&gt;
      &amp;quot;pdo_num&amp;quot;: 1,&lt;br /&gt;
      &amp;quot;angle_deg&amp;quot;: 90.0,&lt;br /&gt;
      &amp;quot;steps_per_rev&amp;quot;: 4096,&lt;br /&gt;
      &amp;quot;revolutions&amp;quot;: 0.25,&lt;br /&gt;
      &amp;quot;raw&amp;quot;: 1024,&lt;br /&gt;
      &amp;quot;data&amp;quot;: [0, 4, 0, 0],&lt;br /&gt;
      &amp;quot;offset&amp;quot;: 0,&lt;br /&gt;
      &amp;quot;size&amp;quot;: 4,&lt;br /&gt;
      &amp;quot;signed&amp;quot;: false,&lt;br /&gt;
      &amp;quot;continuous&amp;quot;: true,&lt;br /&gt;
      &amp;quot;request_id&amp;quot;: &amp;quot;read-pdo-cont-node5&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&#039;&#039;&#039;Start Request Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Required&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Unique request identifier. Continuous sample responses include&lt;br /&gt;
&lt;br /&gt;
this value as &#039;&#039;&#039;request_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;APP&amp;quot;&lt;br /&gt;
|Identifies the sender of the request, for example &#039;&#039;&#039;APP , NodeRED ,&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;CLI , or TestClient&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Main command object containing the command alias and&lt;br /&gt;
&lt;br /&gt;
parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|Yes&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Defines the command to execute.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams&lt;br /&gt;
|object&lt;br /&gt;
|Yes&lt;br /&gt;
|{...}&lt;br /&gt;
|Contains the PDO continuous read parameters.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Numeric CANopen node ID to read from.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.nodeId&lt;br /&gt;
|integer&lt;br /&gt;
|Yes*&lt;br /&gt;
|5&lt;br /&gt;
|Alternative spelling for &#039;&#039;&#039;node_id&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.node&lt;br /&gt;
|string&lt;br /&gt;
|Yes*&lt;br /&gt;
|&amp;quot;motor_1&amp;quot;&lt;br /&gt;
|Logical node name previously configured with &#039;&#039;&#039;CONFIG_CANOPEN&#039;&#039;&#039;. If&lt;br /&gt;
&lt;br /&gt;
used, the actor can reuse saved &#039;&#039;&#039;steps_per_rev , pdo_num ,&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;offset , size&#039;&#039;&#039; , and &#039;&#039;&#039;signed&#039;&#039;&#039; values from the node configuration.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number to listen to. If omitted, defaults to &#039;&#039;&#039;1&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|Yes**&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw position counts per mechanical revolution. Used&lt;br /&gt;
&lt;br /&gt;
to convert &#039;&#039;&#039;raw&#039;&#039;&#039; into &#039;&#039;&#039;revolutions&#039;&#039;&#039; and &#039;&#039;&#039;angle_deg&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.offset&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset inside the PDO payload where the position value&lt;br /&gt;
&lt;br /&gt;
starts.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.size&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes to decode from the PDO payload. For a 32-bit&lt;br /&gt;
&lt;br /&gt;
position value, use &#039;&#039;&#039;4&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.signed&lt;br /&gt;
|boolean&lt;br /&gt;
|No&lt;br /&gt;
|false&lt;br /&gt;
|Defines whether the raw value should be decoded as signed or&lt;br /&gt;
&lt;br /&gt;
unsigned.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.timeout&lt;br /&gt;
|number&lt;br /&gt;
|No&lt;br /&gt;
|1.0&lt;br /&gt;
|Timeout, in seconds, while waiting for each TPDO frame. If no&lt;br /&gt;
&lt;br /&gt;
TPDO is received within this time, the cycle fails.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|No&lt;br /&gt;
|20&lt;br /&gt;
|Delay between read cycles, in milliseconds. If &#039;&#039;&#039;0&#039;&#039;&#039; , the loop&lt;br /&gt;
&lt;br /&gt;
immediately starts the next cycle after yielding control.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskParams.action&lt;br /&gt;
|string&lt;br /&gt;
|No&lt;br /&gt;
|&amp;quot;START&amp;quot;&lt;br /&gt;
|Optional action. If set to &#039;&#039;&#039;STOP , OFF , CANCEL , or DISABLE&#039;&#039;&#039; , the&lt;br /&gt;
&lt;br /&gt;
actor stops the continuous loop instead of starting it.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Start Acknowledgement Response Parameters&#039;&#039;&#039;&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;&amp;lt;TIMESTAMP&amp;gt;&amp;quot;&lt;br /&gt;
|Same request identifier received in the start request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the command that was executed.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object confirming whether the continuous PDO read&lt;br /&gt;
&lt;br /&gt;
was started.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the start command was accepted.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates that the continuous PDO read loop is running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.mode&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;pdo&amp;quot;&lt;br /&gt;
|Indicates that the loop is using PDO reception mode.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number being listened to.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.interval_ms&lt;br /&gt;
|integer&lt;br /&gt;
|20&lt;br /&gt;
|Configured delay between read cycles, in milliseconds.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;&#039;&#039;&#039;READ_PDO_CONTINUOUS&#039;&#039;&#039; requires a single&lt;br /&gt;
&lt;br /&gt;
node&amp;quot;&lt;br /&gt;
|Error description. Present only when the start command&lt;br /&gt;
&lt;br /&gt;
fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Continuous Sample Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| integer/string&lt;br /&gt;
|1777041089180&lt;br /&gt;
|Sample response ID generated by the actor for each PDO read cycle.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the sample.&lt;br /&gt;
|-&lt;br /&gt;
|task&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Main response object.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias of the running continuous command.&lt;br /&gt;
&lt;br /&gt;
task.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult&lt;br /&gt;
|object&lt;br /&gt;
|{...}&lt;br /&gt;
|Result object containing one decoded PDO position sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether this specific PDO read cycle was successful.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.node_id&lt;br /&gt;
|integer&lt;br /&gt;
|5&lt;br /&gt;
|CANopen node ID that produced the TPDO.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.pdo_num&lt;br /&gt;
|integer&lt;br /&gt;
|1&lt;br /&gt;
|TPDO number received and decoded.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.angle_deg&lt;br /&gt;
|number&lt;br /&gt;
|90.0&lt;br /&gt;
|Position inside one revolution, in degrees.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.steps_per_rev&lt;br /&gt;
|integer&lt;br /&gt;
|4096&lt;br /&gt;
|Number of raw counts per revolution used for conversion.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.revolutions&lt;br /&gt;
|number&lt;br /&gt;
|0.25&lt;br /&gt;
|Raw position converted into revolutions. Example: &#039;&#039;&#039;1024 / 4096 = 0.25&#039;&#039;&#039; .&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.raw&lt;br /&gt;
|integer&lt;br /&gt;
|1024&lt;br /&gt;
|Decoded raw position value from the PDO payload.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.data&lt;br /&gt;
|array&lt;br /&gt;
|[0, 4, 0, 0]&lt;br /&gt;
|Raw PDO payload bytes received from the CANopen node.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.offset&lt;br /&gt;
|integer&lt;br /&gt;
|0&lt;br /&gt;
|Byte offset used to extract the raw position value from &#039;&#039;&#039;data.&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.size&lt;br /&gt;
|integer&lt;br /&gt;
|4&lt;br /&gt;
|Number of bytes decoded from &#039;&#039;&#039;data&#039;&#039;&#039;.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.signed&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates whether the raw value was decoded as signed or unsigned.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.continuous&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Marks this response as a continuous sample.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.request_id&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;read-pdo-cont-node5&amp;quot;&lt;br /&gt;
|Original request &#039;&#039;&#039;id&#039;&#039;&#039; that started the continuous loop. Useful to&lt;br /&gt;
&lt;br /&gt;
correlate samples with the start command.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.error&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;pdo operation failed&amp;quot;&lt;br /&gt;
|Error description. Present only when a sample fails.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Stop Request ======&lt;br /&gt;
&#039;&#039;&#039;Req-Topic&#039;&#039;&#039;: canopenRM8007/runtime/in&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;STOP_READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {}&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;Alternative stop request using &#039;&#039;&#039;READ_PDO_CONTINUOUS&#039;&#039;&#039;:&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;APP&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskParams&amp;quot;: {&lt;br /&gt;
      &amp;quot;action&amp;quot;: &amp;quot;STOP&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====== &#039;&#039;&#039;Stop Response&#039;&#039;&#039; ======&lt;br /&gt;
&#039;&#039;&#039;Reply-Topic&#039;&#039;&#039;: canopenRM8007/runtime/out&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; line=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;id&amp;quot;: &amp;quot;stop-pdo-cont&amp;quot;,&lt;br /&gt;
  &amp;quot;origin&amp;quot;: &amp;quot;canopen-actor&amp;quot;,&lt;br /&gt;
  &amp;quot;task&amp;quot;: {&lt;br /&gt;
    &amp;quot;alias&amp;quot;: &amp;quot;READ_PDO_CONTINUOUS&amp;quot;,&lt;br /&gt;
    &amp;quot;taskResult&amp;quot;: {&lt;br /&gt;
      &amp;quot;success&amp;quot;: true,&lt;br /&gt;
      &amp;quot;running&amp;quot;: false,&lt;br /&gt;
      &amp;quot;stopped&amp;quot;: true&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Stop Response Parameters&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Parameter&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Type&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Example&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|id&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;stop-pdo-cont&amp;quot;&lt;br /&gt;
|Same request identifier received in the stop request.&lt;br /&gt;
|-&lt;br /&gt;
|origin&lt;br /&gt;
| string&lt;br /&gt;
|&amp;quot;canopen-actor&amp;quot;&lt;br /&gt;
|Identifies the component that generated the response.&lt;br /&gt;
|-&lt;br /&gt;
|task.alias&lt;br /&gt;
|string&lt;br /&gt;
|&amp;quot;READ_PDO_CONTINUOUS&amp;quot;&lt;br /&gt;
|Alias returned by the stop handler.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.success&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether the stop request was processed successfully.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.running&lt;br /&gt;
|boolean&lt;br /&gt;
|false&lt;br /&gt;
|Indicates that the continuous PDO loop is no longer running.&lt;br /&gt;
|-&lt;br /&gt;
|task.taskResult.stopped&lt;br /&gt;
|boolean&lt;br /&gt;
|true&lt;br /&gt;
|Indicates whether there was an active continuous task that was actually stopped. If&lt;br /&gt;
&lt;br /&gt;
no task was running, this may be &#039;&#039;&#039;false&#039;&#039;&#039;.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====== Decode Logic ======&lt;br /&gt;
The received PDO payload is decoded using:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;: first byte to read from the PDO payload;&lt;br /&gt;
* &#039;&#039;&#039;size&#039;&#039;&#039;: number of bytes to read;&lt;br /&gt;
* &#039;&#039;&#039;signed&#039;&#039;&#039;: whether the value is signed or unsigned;&lt;br /&gt;
* &#039;&#039;&#039;steps_per_rev&#039;&#039;&#039;: scaling factor used to calculate revolutions and angle.&lt;br /&gt;
&lt;br /&gt;
The raw value is decoded as little-endian:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;raw = int.from_bytes(data[offset : offset + size], byteorder=&amp;quot;little&amp;quot;, signed=signed)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Then:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;revolutions = raw / steps_per_rev&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;angle_deg = ((raw % steps_per_rev) / steps_per_rev) * 360.0&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
===== 24.14.4 Design Principles =====&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Protocol-Only Actor&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The CANopen Actor is responsible for:&lt;br /&gt;
&lt;br /&gt;
- CAN frame encoding/decoding;&lt;br /&gt;
&lt;br /&gt;
- SDO communication;&lt;br /&gt;
&lt;br /&gt;
- PDO reception (raw);&lt;br /&gt;
&lt;br /&gt;
- NMT control;&lt;br /&gt;
&lt;br /&gt;
- Heartbeat monitoring.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;No Device Semantics&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The actor:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Does NOT know&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
- What 0x6004 represents;&lt;br /&gt;
&lt;br /&gt;
- Units (RPM, mm, °C, etc.);&lt;br /&gt;
&lt;br /&gt;
- Device-specific logic.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Only returns&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
- Raw values;&lt;br /&gt;
&lt;br /&gt;
- Protocol-level responses.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Node Management&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Nodes must be defined via configuration;&lt;br /&gt;
&lt;br /&gt;
- Actor maintains node state internally;&lt;br /&gt;
&lt;br /&gt;
- Supports multiple nodes simultaneously.&lt;br /&gt;
&lt;br /&gt;
===== Summary =====&lt;br /&gt;
The CANopen Actor:&lt;br /&gt;
&lt;br /&gt;
- Implements &#039;&#039;&#039;CANopen protocol communication;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Provides &#039;&#039;&#039;generic MQTT interface;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Supports &#039;&#039;&#039;multi-node networks;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
- Keeps &#039;&#039;&#039;strict separation between transport and semantics.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== 25. Included Software Stack ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:AtlasCode.svg|center|frameless|583x583px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 26. Software Stack and IPC Architecture ===&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
[[File:Hardware Peripherals Library Architecture.svg|center|frameless|1934x1934px]]&lt;br /&gt;
&lt;br /&gt;
=== 27. Related Products ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;PA&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|PA000000074&lt;br /&gt;
|[[SENSBLUE MONARCH|SENSBLUE MONARCH Gateway]]&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
{{SimilarProductsTable}}&lt;br /&gt;
&lt;br /&gt;
=== 28. Accessories ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;PA&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Name&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Requirements&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 29. Document History ===&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|&#039;&#039;&#039;Version&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Description&#039;&#039;&#039;&lt;br /&gt;
|&#039;&#039;&#039;Date&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|SBADATAv0.1&lt;br /&gt;
|First  version of SENSBLUE ATLAS Datasheet&lt;br /&gt;
|11/03/2026&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== 30. SENSBLUE ATLAS in-the-field ===&lt;br /&gt;
[IMAGE PLACEHOLDER]&lt;/div&gt;</summary>
		<author><name>WikiManagement</name></author>
	</entry>
</feed>