<?xml version="1.0" encoding="utf-8"?>
<Templates format="2" protocolVersion="83">
  <Template id="e9452b3c-b2b0-4b41-b7d8-f4f5fa828e88" revision="1.0">
    <SuggestedCCUParameters/>
    <RevisionHistory>
      <Revision id="1.0">Initial version</Revision>
    </RevisionHistory>
    <Name>LinkedGo ST802-B</Name>
    <CcuModel>PacketParserCCU</CcuModel>
    <Producer>LinkedGo Technology</Producer>
    <Model>ST802-B</Model>
    <Description>Fan coil thermostat LinkedGo ST802-B (Powered by Shelly) over the local Shelly RPC API</Description>
    <Category>1</Category>
    <ImportParameters>
      <Parameter>
        <Id>IpAddress</Id>
        <Name>${ipAddress}</Name>
        <Value>192.168.1.100</Value>
      </Parameter>
    </ImportParameters>
    <Module>
      <Name>LinkedGo ST802-B</Name>
      <Id>-1</Id>
      <Model>PacketParserModuleHttp</Model>
      <DeviceProperties>
        <IpAddress>$[IpAddress]</IpAddress>
        <Port>80</Port>
        <UseHttps>False</UseHttps>
        <HttpAuthentification>0</HttpAuthentification>
        <InternalPollInterval>15000</InternalPollInterval>
        <CustomVariables>[{&quot;Name&quot;:&quot;SysStatus&quot;,&quot;ValueTypeId&quot;:2,&quot;NumericValue&quot;:0,&quot;StringValue&quot;:&quot;&quot;},{&quot;Name&quot;:&quot;WiFiStatus&quot;,&quot;ValueTypeId&quot;:2,&quot;NumericValue&quot;:0,&quot;StringValue&quot;:&quot;&quot;},{&quot;Name&quot;:&quot;ServiceConfig&quot;,&quot;ValueTypeId&quot;:2,&quot;NumericValue&quot;:0,&quot;StringValue&quot;:&quot;&quot;},{&quot;Name&quot;:&quot;ServiceStatus&quot;,&quot;ValueTypeId&quot;:2,&quot;NumericValue&quot;:0,&quot;StringValue&quot;:&quot;&quot;}]</CustomVariables>
        <ReadScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Sys.GetStatus&quot;);
IF r.IsSuccess
    SysStatus := r.Content;
ELSE
    IF r.StatusCode = 401
        ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
    ELSE
        ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
    END
    RETURN(0);
END
r := SENDHTTPREQUEST(&quot;/rpc/WiFi.GetStatus&quot;);
IF r.IsSuccess
    WiFiStatus := r.Content;
END
r := SENDHTTPREQUEST(&quot;/rpc/Service.GetConfig?id=0&quot;);
IF r.IsSuccess
    ServiceConfig := r.Content;
END
r := SENDHTTPREQUEST(&quot;/rpc/Service.GetStatus?id=0&quot;);
IF r.IsSuccess
    ServiceStatus := r.Content;
END
IF PARSEJSON(ServiceConfig, &quot;$.temp_unit&quot;, true) = &quot;F&quot;
    ADDWARNING(4, &quot;Thermostat uses degrees Fahrenheit. Set the temperature unit to Celsius in the Shelly app, TapHome reads the values as degrees Celsius.&quot;);
END
VAR errors := PARSEJSON(ServiceStatus, &quot;$.errors&quot;, true);
IF ! ISNULL(errors)
    ADDWARNING(5, &quot;Thermostat reports: &quot; + TOSTRING(errors));
END
IF ! ISNULL(PARSEJSON(SysStatus, &quot;available_updates.stable&quot;, true))
    ADDWARNING(2, &quot;New firmware update is available&quot;);
END
IF PARSEJSON(SysStatus, &quot;restart_required&quot;, true)
    ADDWARNING(3, &quot;Restart required&quot;);
END</ReadScriptPacketParser>
        <ServiceAttributesScriptsPacketParser>[{&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Wi-Fi&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(WiFiStatus, \&quot;ssid\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;${ipAddress}&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(WiFiStatus, \&quot;sta_ip\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;${xml_signal_strength} [dB]&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(WiFiStatus, \&quot;rssi\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;MAC&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(SysStatus, \&quot;mac\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Service state&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(ServiceStatus, \&quot;state\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Thermostat mode&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(ServiceConfig, \&quot;thermostat_mode\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Temperature unit&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(ServiceConfig, \&quot;temp_unit\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Temperature offset&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(ServiceConfig, \&quot;temp_offset\&quot;, true)&quot;}, {&quot;AttributeDefinition&quot;: {&quot;Name&quot;: &quot;Humidity offset [%]&quot;}, &quot;ReadFormula&quot;: &quot;PARSEJSON(ServiceConfig, \&quot;humidity_offset\&quot;, true)&quot;}]</ServiceAttributesScriptsPacketParser>
        <ServiceActionsScriptsPacketParser>[{&quot;ActionDefinition&quot;: {&quot;Name&quot;: &quot;${xml_update_fw}&quot;, &quot;NumericParameters&quot;: [], &quot;BoolParameters&quot;: [], &quot;EnumParameters&quot;: []}, &quot;Script&quot;: &quot;VAR r := SENDHTTPREQUEST(\&quot;/rpc/Shelly.Update?stage=\\\&quot;stable\\\&quot;\&quot;);\nIF r.IsSuccess\n    RETURN(\&quot;OK\&quot;);\nELSE\n    RETURN(\&quot;Error \&quot; + TOSTRING(r.StatusCode));\nEND&quot;}, {&quot;ActionDefinition&quot;: {&quot;Name&quot;: &quot;Reboot&quot;, &quot;NumericParameters&quot;: [], &quot;BoolParameters&quot;: [], &quot;EnumParameters&quot;: []}, &quot;Script&quot;: &quot;VAR r := SENDHTTPREQUEST(\&quot;/rpc/Shelly.Reboot\&quot;);\nIF r.IsSuccess\n    RETURN(\&quot;OK\&quot;);\nELSE\n    RETURN(\&quot;Error \&quot; + TOSTRING(r.StatusCode));\nEND&quot;}]</ServiceActionsScriptsPacketParser>
      </DeviceProperties>
      <Devices>
        <Device>
          <Name>Thermostat</Name>
          <Id>-2</Id>
          <Model>PacketParserThermostat</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>10000</InternalPollInterval>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <MinTemperature>5</MinTemperature>
            <MaxTemperature>35</MaxTemperature>
            <ReadCurrentTemperatureScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Number.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;current_temperature\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadCurrentTemperatureScriptPacketParser>
            <ReadTemperatureSetPointScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Number.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;target_temperature\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadTemperatureSetPointScriptPacketParser>
            <WriteTemperatureSetPointScriptPacketParser>SENDHTTPREQUEST(&quot;/rpc/Number.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;target_temperature\&quot;&amp;value=&quot; + TOSTRING(Se, &quot;F1&quot;));</WriteTemperatureSetPointScriptPacketParser>
            <ReadHumidityScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Number.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;current_humidity\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadHumidityScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Fan speed</Name>
          <Id>-3</Id>
          <Model>PacketParserMultiValueSwitch</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>5000</InternalPollInterval>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <ReadSwitchStateScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Enum.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;fan_speed\&quot;&quot;);
IF r.IsSuccess = false
    IF r.StatusCode = 401
        ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
    ELSE
        ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
    END
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, &quot;$.value&quot;, true);
IF v = &quot;auto&quot;
    RETURN(0);
ELSEIF v = &quot;low&quot;
    RETURN(1);
ELSEIF v = &quot;medium&quot;
    RETURN(2);
ELSEIF v = &quot;high&quot;
    RETURN(3);
END
ADDERROR(2, &quot;Unknown fan speed: &quot; + TOSTRING(v));
RETURN(NaN);</ReadSwitchStateScriptPacketParser>
            <WriteSwitchStateScriptPacketParser>VAR val := &quot;high&quot;;
IF Mu = 0
    val := &quot;auto&quot;;
ELSEIF Mu = 1
    val := &quot;low&quot;;
ELSEIF Mu = 2
    val := &quot;medium&quot;;
END
SENDHTTPREQUEST(&quot;/rpc/Enum.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;fan_speed\&quot;&amp;value=\&quot;&quot; + val + &quot;\&quot;&quot;);</WriteSwitchStateScriptPacketParser>
            <Value0>0</Value0>
            <Value0Index>0</Value0Index>
            <Value0Name>Auto</Value0Name>
            <Value0IconId>113</Value0IconId>
            <Value1>1</Value1>
            <Value1Index>1</Value1Index>
            <Value1Name>Low</Value1Name>
            <Value1IconId>25</Value1IconId>
            <Value2>2</Value2>
            <Value2Index>2</Value2Index>
            <Value2Name>Medium</Value2Name>
            <Value2IconId>26</Value2IconId>
            <Value3>3</Value3>
            <Value3Index>3</Value3Index>
            <Value3Name>High</Value3Name>
            <Value3IconId>28</Value3IconId>
            <Value4Index>68</Value4Index>
            <Value5Index>69</Value5Index>
            <Value6Index>70</Value6Index>
            <Value7Index>71</Value7Index>
            <Value8Index>72</Value8Index>
            <Value9Index>73</Value9Index>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Working mode</Name>
          <Id>-4</Id>
          <Model>PacketParserMultiValueSwitch</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>5000</InternalPollInterval>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <ReadSwitchStateScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Enum.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;working_mode\&quot;&quot;);
IF r.IsSuccess = false
    IF r.StatusCode = 401
        ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
    ELSE
        ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
    END
    RETURN(NaN);
END
VAR v := PARSEJSON(r.Content, &quot;$.value&quot;, true);
IF v = &quot;cool&quot;
    RETURN(0);
ELSEIF v = &quot;heat&quot;
    RETURN(1);
ELSEIF v = &quot;dry&quot;
    RETURN(2);
ELSEIF v = &quot;ventilation&quot;
    RETURN(3);
ELSEIF v = &quot;floor_heating&quot;
    RETURN(4);
END
ADDERROR(2, &quot;Unknown working mode: &quot; + TOSTRING(v));
RETURN(NaN);</ReadSwitchStateScriptPacketParser>
            <WriteSwitchStateScriptPacketParser>VAR val := &quot;floor_heating&quot;;
IF Mu = 0
    val := &quot;cool&quot;;
ELSEIF Mu = 1
    val := &quot;heat&quot;;
ELSEIF Mu = 2
    val := &quot;dry&quot;;
ELSEIF Mu = 3
    val := &quot;ventilation&quot;;
END
SENDHTTPREQUEST(&quot;/rpc/Enum.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;working_mode\&quot;&amp;value=\&quot;&quot; + val + &quot;\&quot;&quot;);</WriteSwitchStateScriptPacketParser>
            <Value0>0</Value0>
            <Value0Index>0</Value0Index>
            <Value0Name>Cool</Value0Name>
            <Value0IconId>2</Value0IconId>
            <Value1>1</Value1>
            <Value1Index>1</Value1Index>
            <Value1Name>Heat</Value1Name>
            <Value1IconId>1</Value1IconId>
            <Value2>2</Value2>
            <Value2Index>2</Value2Index>
            <Value2Name>Dry</Value2Name>
            <Value2IconId>2014</Value2IconId>
            <Value3>3</Value3>
            <Value3Index>3</Value3Index>
            <Value3Name>Ventilation</Value3Name>
            <Value3IconId>115</Value3IconId>
            <Value4>4</Value4>
            <Value4Index>4</Value4Index>
            <Value4Name>Floor Heating</Value4Name>
            <Value4IconId>78</Value4IconId>
            <Value5Index>69</Value5Index>
            <Value6Index>70</Value6Index>
            <Value7Index>71</Value7Index>
            <Value8Index>72</Value8Index>
            <Value9Index>73</Value9Index>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Thermostat on/off</Name>
          <Id>-5</Id>
          <Model>PacketParserSwitch</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>5000</InternalPollInterval>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <OnStateIconId>60</OnStateIconId>
            <OffStateIconId>61</OffStateIconId>
            <OnStateName>${general_on}</OnStateName>
            <OffStateName>${general_off}</OffStateName>
            <ReadSwitchStateScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Boolean.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;enable\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadSwitchStateScriptPacketParser>
            <WriteSwitchStateScriptPacketParser>SENDHTTPREQUEST(&quot;/rpc/Boolean.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;enable\&quot;&amp;value=&quot; + IF(St, &quot;true&quot;, &quot;false&quot;));</WriteSwitchStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Anti-freeze</Name>
          <Id>-6</Id>
          <Model>PacketParserSwitch</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>10000</InternalPollInterval>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <OnStateIconId>60</OnStateIconId>
            <OffStateIconId>61</OffStateIconId>
            <OnStateName>${general_on}</OnStateName>
            <OffStateName>${general_off}</OffStateName>
            <ReadSwitchStateScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Boolean.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;anti_freeze\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadSwitchStateScriptPacketParser>
            <WriteSwitchStateScriptPacketParser>SENDHTTPREQUEST(&quot;/rpc/Boolean.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;anti_freeze\&quot;&amp;value=&quot; + IF(St, &quot;true&quot;, &quot;false&quot;));</WriteSwitchStateScriptPacketParser>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Target humidity</Name>
          <Id>-7</Id>
          <Model>PacketParserVariable</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>10000</InternalPollInterval>
            <IsReadOnly>False</IsReadOnly>
            <ShouldDoPeriodicWrite>False</ShouldDoPeriodicWrite>
            <StartupValueSource>ReadFromDevice</StartupValueSource>
            <ReadStateScriptPacketParser>VAR r := SENDHTTPREQUEST(&quot;/rpc/Number.GetStatus?owner=\&quot;service:0\&quot;&amp;role=\&quot;target_humidity\&quot;&quot;);
IF r.IsSuccess
    RETURN(PARSEJSON(r.Content, &quot;$.value&quot;));
END
IF r.StatusCode = 401
    ADDERROR(401, &quot;Thermostat asks for a password (HTTP 401). Turn off password protection in the Shelly app, TapHome does not support HTTP Digest.&quot;);
ELSE
    ADDERROR(1, &quot;Thermostat answered HTTP &quot; + TOSTRING(r.StatusCode));
END
RETURN(NaN);</ReadStateScriptPacketParser>
            <WriteStateScriptPacketParser>SENDHTTPREQUEST(&quot;/rpc/Number.Set?owner=\&quot;service:0\&quot;&amp;role=\&quot;target_humidity\&quot;&amp;value=&quot; + TOSTRING(Va, &quot;F0&quot;));</WriteStateScriptPacketParser>
          </DeviceProperties>
        </Device>
      </Devices>
    </Module>
  </Template>
</Templates>
