Modelosensorvirtual: Difference between revisions

From QuatenusWiki
No edit summary
Tag: Reverted
No edit summary
 
(6 intermediate revisions by the same user not shown)
Line 16: Line 16:
==== Activação do sensor e da respectiva coluna no sistema ====
==== Activação do sensor e da respectiva coluna no sistema ====


<pre>
<syntaxhighlight lang="csharp">
// VOLTAGEM 3 - DataValue3
// VOLTAGEM 3 - DataValue3
bool enable3 = true;
bool enable3 = true;
</pre>
</syntaxhighlight>


Se alterarem o <code>true</code> para <code>false</code> este sensor deixará de ser contabilizado para as contas dos litros.
Se alterarem o <code>true</code> para <code>false</code> este sensor deixará de ser contabilizado para as contas dos litros.
Line 46: Line 46:
Exemplo de código em C# para ser copiado e colado, ou num novo sensor diretamente ou para usar num novo modelo de sensor virtual.
Exemplo de código em C# para ser copiado e colado, ou num novo sensor diretamente ou para usar num novo modelo de sensor virtual.


<pre>
<syntaxhighlight lang="csharp">
// VOLTAGEM 1 - DataValue1
// VOLTAGEM 1 - DataValue1
bool enable1 = false;
bool enable1 = false;
decimal inputMin1 = 1m; //Volts - Valor mínimo que a sonda irá enviar
decimal inputMin1 = 1m; //Volts - Valor mínimo que a sonda irá enviar
decimal inputMax1 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar
decimal inputMax1 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar
decimal outputMin1 = 0.0m; //Litros - Nivel do tanque com voltagem no minimo
decimal outputMin1 = 0.0m; //Litros - Nivel do tanque com voltagem no minimo
decimal outputMax1 = 100.0m; //Litros - Nivel do tanque com voltagem no máximo
decimal outputMax1 = 100.0m; //Litros - Nivel do tanque com voltagem no máximo
// VOLTAGEM 2 - DataValue2
// VOLTAGEM 2 - DataValue2
bool enable2 = false;
bool enable2 = false;
decimal inputMin2 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMin2 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax2 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal inputMax2 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal outputMin2 = 0.0m; //Litros - Capacidade minima tanque
decimal outputMin2 = 0.0m; //Litros - Capacidade minima tanque
decimal outputMax2 = 100.0m; //Litros - Preencher com capacidade do tanque
decimal outputMax2 = 100.0m; //Litros - Preencher com capacidade do tanque
// VOLTAGEM 3 - DataValue3
// VOLTAGEM 3 - DataValue3
bool enable3 = true;
bool enable3 = true;
decimal inputMin3 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMin3 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax3 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal inputMax3 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal outputMin3 = 0.0m; //Litros - Capacidade minima tanque
 
decimal outputMax3 = 505.0m; //Litros - Preencher com capacidade do tanque
decimal outputMin3 = 2.0m; //Litros - Capacidade minima tanque
decimal outputMax3 = 100.0m; //Litros - Preencher com capacidade do tanque
 
 
 
// VOLTAGEM 4 - DataValue4
// VOLTAGEM 4 - DataValue4
bool enable4 = true;
bool enable4 = true;
decimal inputMin4 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMin4 = 1.0m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax4 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal inputMax4 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio
decimal outputMin4 = 0.0m; //Litros - Capacidade minima tanque
 
decimal outputMax4 = 350.0m; //Litros - Preencher com capacidade do tanque
decimal outputMin4 = 2.0m; //Litros - Capacidade minima tanque
decimal outputMax4 = 100.0m; //Litros - Preencher com capacidade do tanque
 
 
 
 
 
 
///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 
//  ███╗  ██╗ █████╗  ██████╗    ███╗  ███╗███████╗██╗  ██╗███████╗██████╗       
//  ████╗  ██║██╔══██╗██╔═══██╗    ████╗ ████║██╔════╝╚██╗██╔╝██╔════╝██╔══██╗     
//  ██╔██╗ ██║███████║██║  ██║    ██╔████╔██║█████╗  ╚███╔╝ █████╗  ██████╔╝     
//  ██║╚██╗██║██╔══██║██║  ██║    ██║╚██╔╝██║██╔══╝  ██╔██╗ ██╔══╝  ██╔══██╗     
//  ██║ ╚████║██║  ██║╚██████╔╝    ██║ ╚═╝ ██║███████╗██╔╝ ██╗███████╗██║  ██║     
//  ╚═╝  ╚═══╝╚═╝  ╚═╝ ╚═════╝    ╚═╝    ╚═╝╚══════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝     
//                                                                           
//  ██████╗  █████╗  ██████╗ ██╗  ██╗██╗    ██████╗  █████╗ ██████╗  █████╗
//  ██╔══██╗██╔══██╗██╔═══██╗██║  ██║██║    ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
//  ██║  ██║███████║██║  ██║██║  ██║██║    ██████╔╝███████║██████╔╝███████║
//  ██║  ██║██╔══██║██║▄▄ ██║██║  ██║██║    ██╔═══╝ ██╔══██║██╔══██╗██╔══██║
//  ██████╔╝██║  ██║╚██████╔╝╚██████╔╝██║    ██║    ██║  ██║██║  ██║██║  ██║
//  ╚═════╝ ╚═╝  ╚═╝ ╚══▀▀═╝  ╚═════╝ ╚═╝    ╚═╝    ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝
//                                                                           
//  ██████╗  █████╗ ██╗██╗  ██╗ ██████╗                                     
//  ██╔══██╗██╔══██╗██║╚██╗██╔╝██╔═══██╗                                   
//  ██████╔╝███████║██║ ╚███╔╝ ██║  ██║                                   
//  ██╔══██╗██╔══██║██║ ██╔██╗ ██║  ██║                                   
//  ██████╔╝██║  ██║██║██╔╝ ██╗╚██████╔╝                                   
//  ╚═════╝ ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝ ╚═════╝                                     
// 
 
 
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
decimal? outputLevel = null;
decimal? outputLevel = null;
decimal? maxOutputLevel = null;
decimal? maxOutputLevel = null;
//
if(enable1)
if(enable1)
{
{
Line 81: Line 128:
     {
     {
         decimal tempOutputValue;
         decimal tempOutputValue;
         if(InputRecord.DataValue1 <= inputMin1)
 
         if(InputRecord.DataValue1 <= inputMin1) // abaixo do valor de vazio
         {
         {
             tempOutputValue = outputMin1;
             tempOutputValue = outputMin1;
         }
         }
         else if(InputRecord.DataValue1 >= inputMax1)
         else if(InputRecord.DataValue1 >= inputMax1) // acima do valor de cheio
         {
         {
             tempOutputValue = outputMax1;
             tempOutputValue = outputMax1;
Line 91: Line 139:
         else
         else
         {
         {
            // regra de 3 linear entre inputMin e inputMax
             tempOutputValue = outputMin1
             tempOutputValue = outputMin1
                                 + (InputRecord.DataValue1.Value - inputMin1)
                                 + (InputRecord.DataValue1.Value - inputMin1)
                                 * (outputMax1 - outputMin1)
                                 * (outputMax1 - outputMin1)
                                 / (inputMax1 - inputMin1);
                                 / (inputMax1 - inputMin1);
             tempOutputValue = System.Math.Abs(tempOutputValue);
             tempOutputValue = System.Math.Abs(tempOutputValue);
         }
         }
         if(outputLevel == null)
         if(outputLevel == null)
         {
         {
Line 106: Line 157:
         }
         }
     }
     }
     decimal max = System.Math.Max(outputMin1, outputMax1);
     decimal max = System.Math.Max(outputMin1, outputMax1);
     if(maxOutputLevel == null)
     if(maxOutputLevel == null)
     {
     {
Line 116: Line 169:
     }
     }
}
}
//
if(enable2)
if(enable2)
{
{
Line 121: Line 176:
     {
     {
         decimal tempOutputValue;
         decimal tempOutputValue;
         if(InputRecord.DataValue2 <= inputMin2)
 
         if(InputRecord.DataValue2 <= inputMin2) // abaixo do valor de vazio
         {
         {
             tempOutputValue = outputMin2;
             tempOutputValue = outputMin2;
         }
         }
         else if(InputRecord.DataValue2 >= inputMax2)
         else if(InputRecord.DataValue2 >= inputMax2) // acima do valor de cheio
         {
         {
             tempOutputValue = outputMax2;
             tempOutputValue = outputMax2;
Line 131: Line 187:
         else
         else
         {
         {
            // regra de 3 linear entre inputMin e inputMax
             tempOutputValue = outputMin2
             tempOutputValue = outputMin2
                                 + (InputRecord.DataValue2.Value - inputMin2)
                                 + (InputRecord.DataValue2.Value - inputMin2)
                                 * (outputMax2 - outputMin2)
                                 * (outputMax2 - outputMin2)
                                 / (inputMax2 - inputMin2);
                                 / (inputMax2 - inputMin2);
             tempOutputValue = System.Math.Abs(tempOutputValue);
             tempOutputValue = System.Math.Abs(tempOutputValue);
         }
         }
         if(outputLevel == null)
         if(outputLevel == null)
         {
         {
Line 146: Line 205:
         }
         }
     }
     }
     decimal max = System.Math.Max(outputMin2, outputMax2);
     decimal max = System.Math.Max(outputMin2, outputMax2);
     if(maxOutputLevel == null)
     if(maxOutputLevel == null)
     {
     {
Line 156: Line 217:
     }
     }
}
}
if(enable3)
if(enable3)
{
{
Line 161: Line 224:
     {
     {
         decimal tempOutputValue;
         decimal tempOutputValue;
         if(InputRecord.DataValue3 <= inputMin3)
 
         if(InputRecord.DataValue3 <= inputMin3) // abaixo do valor de vazio
         {
         {
             tempOutputValue = outputMin3;
             tempOutputValue = outputMin3;
         }
         }
         else if(InputRecord.DataValue3 >= inputMax3)
         else if(InputRecord.DataValue3 >= inputMax3) // acima do valor de cheio
         {
         {
             tempOutputValue = outputMax3;
             tempOutputValue = outputMax3;
Line 171: Line 235:
         else
         else
         {
         {
            // regra de 3 linear entre inputMin e inputMax
             tempOutputValue = outputMin3
             tempOutputValue = outputMin3
                                 + (InputRecord.DataValue3.Value - inputMin3)
                                 + (InputRecord.DataValue3.Value - inputMin3)
                                 * (outputMax3 - outputMin3)
                                 * (outputMax3 - outputMin3)
                                 / (inputMax3 - inputMin3);
                                 / (inputMax3 - inputMin3);
             tempOutputValue = System.Math.Abs(tempOutputValue);
             tempOutputValue = System.Math.Abs(tempOutputValue);
         }
         }
         if(outputLevel == null)
         if(outputLevel == null)
         {
         {
Line 186: Line 253:
         }
         }
     }
     }
     decimal max = System.Math.Max(outputMin3, outputMax3);
     decimal max = System.Math.Max(outputMin3, outputMax3);
     if(maxOutputLevel == null)
     if(maxOutputLevel == null)
     {
     {
Line 196: Line 265:
     }
     }
}
}
if(enable4)
if(enable4)
{
{
Line 201: Line 271:
     {
     {
         decimal tempOutputValue;
         decimal tempOutputValue;
         if(InputRecord.DataValue4 <= inputMin4)
 
         if(InputRecord.DataValue4 <= inputMin4) // abaixo do valor de vazio
         {
         {
             tempOutputValue = outputMin4;
             tempOutputValue = outputMin4;
         }
         }
         else if(InputRecord.DataValue4 >= inputMax4)
         else if(InputRecord.DataValue4 >= inputMax4) // acima do valor de cheio
         {
         {
             tempOutputValue = outputMax4;
             tempOutputValue = outputMax4;
Line 211: Line 282:
         else
         else
         {
         {
            // regra de 3 linear entre inputMin e inputMax
             tempOutputValue = outputMin4
             tempOutputValue = outputMin4
                                 + (InputRecord.DataValue4.Value - inputMin4)
                                 + (InputRecord.DataValue4.Value - inputMin4)
                                 * (outputMax4 - outputMin4)
                                 * (outputMax4 - outputMin4)
                                 / (inputMax4 - inputMin4);
                                 / (inputMax4 - inputMin4);
             tempOutputValue = System.Math.Abs(tempOutputValue);
             tempOutputValue = System.Math.Abs(tempOutputValue);
         }
         }
         if(outputLevel == null)
         if(outputLevel == null)
         {
         {
Line 226: Line 300:
         }
         }
     }
     }
     decimal max = System.Math.Max(outputMin4, outputMax4);
     decimal max = System.Math.Max(outputMin4, outputMax4);
     if(maxOutputLevel == null)
     if(maxOutputLevel == null)
     {
     {
Line 236: Line 312:
     }
     }
}
}
if(outputLevel != null)
if(outputLevel != null)
{
{
     OutputRecord.FMSFuelLevel = outputLevel;
     //OutputRecord.FMSFuelLevel = outputLevel;
     OutputRecord.FMSFuelLevelPercentage = (outputLevel / maxOutputLevel) * 100m;
     OutputRecord.FMSFuelLevelPercentage = (outputLevel / maxOutputLevel) * 100m;
     OutputValue = OutputRecord.FMSFuelLevel;
 
     // OutputValue = OutputRecord.FMSFuelLevelPercentage;
     //OutputValue = OutputRecord.FMSFuelLevel;
     OutputValue = OutputRecord.FMSFuelLevelPercentage;
}
}
</pre>
</syntaxhighlight>
 
 
 
 
'''Modelo Sensor Virtual para depósitos com leituras não lineares'''
 
 
<syntaxhighlight lang="csharp">
 
/*****************************************************
Sensor Virtual para tanque de 15.600 Litros e tensão tanque cheio 8.35 VOLTS
*****************************************************/
 
if(InputValue.HasValue)
{
    decimal[,] table2 = new decimal[,] {
        { 1m, 0m },
        { 1.05m, 200m },
        { 1.1m, 400m },
        { 1.27m, 600m },
        { 1.4m, 800m },
        { 1.54m, 1000m },
        { 1.64m, 1200m },
        { 1.77m, 1400m },
        { 1.88m, 1600m },
        { 2m, 1800m },
        { 2.09m, 2000m },
        { 2.19m, 2200m },
        { 2.29m, 2400m },
        { 2.39m, 2600m },
        { 2.47m, 2800m },
        { 2.59m, 3000m },
        { 2.65m, 3200m },
        { 2.75m, 3400m },
        { 2.83m, 3600m },
        { 2.92m, 3800m },
        { 3.01m, 4000m },
        { 3.09m, 4200m },
        { 3.19m, 4400m },
        { 3.28m, 4600m },
        { 3.37m, 4800m },
        { 3.44m, 5000m },
        { 3.53m, 5200m },
        { 3.63m, 5400m },
        { 3.71m, 5600m },
        { 3.79m, 5800m },
        { 3.87m, 6000m },
        { 3.96m, 6200m },
        { 4.06m, 6400m },
        { 4.13m, 6600m },
        { 4.22m, 6800m },
        { 4.3m, 7000m },
        { 4.37m, 7200m },
        { 4.45m, 7400m },
        { 4.53m, 7600m },
        { 4.62m, 7800m },
        { 4.71m, 8000m },
        { 4.77m, 8200m },
        { 4.88m, 8400m },
        { 4.96m, 8600m },
        { 5.04m, 8800m },
        { 5.14m, 9000m },
        { 5.19m, 9200m },
        { 5.26m, 9400m },
        { 5.35m, 9600m },
        { 5.45m, 9800m },
        { 5.53m, 10000m },
        { 5.62m, 10200m },
        { 5.69m, 10400m },
        { 5.8m, 10600m },
        { 5.87m, 10800m },
        { 5.96m, 11000m },
        { 6.04m, 11200m },
        { 6.12m, 11400m },
        { 6.22m, 11600m },
        { 6.32m, 11800m },
        { 6.4m, 12000m },
        { 6.5m, 12200m },
        { 6.59m, 12400m },
        { 6.68m, 12600m },
        { 6.76m, 12800m },
        { 6.87m, 13000m },
        { 6.97m, 13200m },
        { 7.07m, 13400m },
        { 7.16m, 13600m },
        { 7.25m, 13800m },
        { 7.35m, 14000m },
        { 7.46m, 14200m },
        { 7.56m, 14400m },
        { 7.66m, 14600m },
        { 7.8m, 14800m },
        { 7.93m, 15000m },
        { 8.08m, 15200m },
        { 8.23m, 15400m },
        { 8.35m, 15600 }
    };
 
    int tableLen = table2.GetLength(0);
 
    if(InputValue <= table2[0, 0])
    {
        OutputValue = table2[0, 1];
    }
    else if(InputValue >= table2[tableLen - 1, 0])
    {
        OutputValue = table2[tableLen - 1, 1];
    }
    else
    {
        int lowerIndex = 0;
        int upperIndex = tableLen;
        int index = tableLen / 2;
        int range = upperIndex - lowerIndex;
 
        int j = 0;
 
        do
        {
            j++;
 
            var currentValues = table2[index, 0];
 
            if(InputValue.Value < currentValues)
            {
                upperIndex = index;
            }
            else
            {
                lowerIndex = index;
            }
 
            range = upperIndex - lowerIndex;
 
            index = range / 2 + lowerIndex;
 
 
        } while(range > 1);
 
        OutputValue = table2[index, 1];
    }
}
</syntaxhighlight>
 
 
 
 
 


{{QuatenusFooter}}
{{QuatenusFooter}}

Latest revision as of 07:50, 31 August 2026

MODELO SENSORES VIRTUAIS EXEMPLO

Sensores Virtuais são uma forma de poder converter uma leitura analógica de uma sonda combustivel em que o valor é em Volts e é convertido em Litros e em percentagem de depósito.

Modelo de sensor virtual: SENSORESVIREXEMPLOS

Permite até de um a quatro sensores em simultâneo.

Exemplos

Sendo que é um GV300 com 2 sondas devem trabalhar sobre os DATAVALUE3 e DATAVALUE4.

Devem ajustar os valores nas seguintes variáveis.

Activação do sensor e da respectiva coluna no sistema

// VOLTAGEM 3 - DataValue3
bool enable3 = true;

Se alterarem o true para false este sensor deixará de ser contabilizado para as contas dos litros. E se estiver a false e for colocado true passa a ser contabilizado para as contas dos litros.

Variáveis a configurar

Variável Descrição
outputMax3 Litros - Preencher com capacidade do tanque 1
outputMax4 Litros - Preencher com capacidade do tanque 2
inputMin3 Volts - Valor mínimo que a sonda irá enviar para o tanque 1 vazio
inputMin4 Volts - Valor mínimo que a sonda irá enviar para o tanque 2 vazio
inputMax3 Volts - Valor máximo em volts que a sonda irá enviar para o tanque 1 cheio
inputMax4 Volts - Valor máximo em volts que a sonda irá enviar para o tanque 2 cheio

Código

Exemplo de código em C# para ser copiado e colado, ou num novo sensor diretamente ou para usar num novo modelo de sensor virtual.

// VOLTAGEM 1 - DataValue1
bool enable1 = false;
decimal inputMin1 = 1m; //Volts - Valor mínimo que a sonda irá enviar
decimal inputMax1 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar

decimal outputMin1 = 0.0m; //Litros - Nivel do tanque com voltagem no minimo
decimal outputMax1 = 100.0m; //Litros - Nivel do tanque com voltagem no máximo



// VOLTAGEM 2 - DataValue2
bool enable2 = false;
decimal inputMin2 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax2 = 100.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio

decimal outputMin2 = 0.0m; //Litros - Capacidade minima tanque
decimal outputMax2 = 100.0m; //Litros - Preencher com capacidade do tanque



// VOLTAGEM 3 - DataValue3
bool enable3 = true;
decimal inputMin3 = 1m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax3 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio

decimal outputMin3 = 2.0m; //Litros - Capacidade minima tanque
decimal outputMax3 = 100.0m; //Litros - Preencher com capacidade do tanque



// VOLTAGEM 4 - DataValue4
bool enable4 = true;
decimal inputMin4 = 1.0m; //Volts - Valor mínimo que a sonda irá enviar para o tanque vazio
decimal inputMax4 = 9.0m; //Volts - Valor máximo em volts que a sonda irá enviar para o tanque cheio

decimal outputMin4 = 2.0m; //Litros - Capacidade minima tanque
decimal outputMax4 = 100.0m; //Litros - Preencher com capacidade do tanque






///////////////////////////////////////////////////////////////////////////////////////////////////////////////
//   
//   ███╗   ██╗ █████╗  ██████╗     ███╗   ███╗███████╗██╗  ██╗███████╗██████╗        
//   ████╗  ██║██╔══██╗██╔═══██╗    ████╗ ████║██╔════╝╚██╗██╔╝██╔════╝██╔══██╗       
//   ██╔██╗ ██║███████║██║   ██║    ██╔████╔██║█████╗   ╚███╔╝ █████╗  ██████╔╝       
//   ██║╚██╗██║██╔══██║██║   ██║    ██║╚██╔╝██║██╔══╝   ██╔██╗ ██╔══╝  ██╔══██╗       
//   ██║ ╚████║██║  ██║╚██████╔╝    ██║ ╚═╝ ██║███████╗██╔╝ ██╗███████╗██║  ██║       
//   ╚═╝  ╚═══╝╚═╝  ╚═╝ ╚═════╝     ╚═╝     ╚═╝╚══════╝╚═╝  ╚═╝╚══════╝╚═╝  ╚═╝       
//                                                                            
//   ██████╗  █████╗  ██████╗ ██╗   ██╗██╗    ██████╗  █████╗ ██████╗  █████╗ 
//   ██╔══██╗██╔══██╗██╔═══██╗██║   ██║██║    ██╔══██╗██╔══██╗██╔══██╗██╔══██╗
//   ██║  ██║███████║██║   ██║██║   ██║██║    ██████╔╝███████║██████╔╝███████║
//   ██║  ██║██╔══██║██║▄▄ ██║██║   ██║██║    ██╔═══╝ ██╔══██║██╔══██╗██╔══██║
//   ██████╔╝██║  ██║╚██████╔╝╚██████╔╝██║    ██║     ██║  ██║██║  ██║██║  ██║
//   ╚═════╝ ╚═╝  ╚═╝ ╚══▀▀═╝  ╚═════╝ ╚═╝    ╚═╝     ╚═╝  ╚═╝╚═╝  ╚═╝╚═╝  ╚═╝
//                                                                            
//   ██████╗  █████╗ ██╗██╗  ██╗ ██████╗                                      
//   ██╔══██╗██╔══██╗██║╚██╗██╔╝██╔═══██╗                                     
//   ██████╔╝███████║██║ ╚███╔╝ ██║   ██║                                     
//   ██╔══██╗██╔══██║██║ ██╔██╗ ██║   ██║                                     
//   ██████╔╝██║  ██║██║██╔╝ ██╗╚██████╔╝                                     
//   ╚═════╝ ╚═╝  ╚═╝╚═╝╚═╝  ╚═╝ ╚═════╝                                      
//   


//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO
//NÃO MEXER DAQUI PARA BAIXO

decimal? outputLevel = null;
decimal? maxOutputLevel = null;

//
if(enable1)
{
    if(InputRecord.DataValue1 != null)
    {
        decimal tempOutputValue;

        if(InputRecord.DataValue1 <= inputMin1) // abaixo do valor de vazio
        {
            tempOutputValue = outputMin1;
        }
        else if(InputRecord.DataValue1 >= inputMax1) // acima do valor de cheio
        {
            tempOutputValue = outputMax1;
        }
        else
        {
            // regra de 3 linear entre inputMin e inputMax
            tempOutputValue = outputMin1
                                + (InputRecord.DataValue1.Value - inputMin1)
                                * (outputMax1 - outputMin1)
                                / (inputMax1 - inputMin1);

            tempOutputValue = System.Math.Abs(tempOutputValue);
        }

        if(outputLevel == null)
        {
            outputLevel = tempOutputValue;
        }
        else
        {
            outputLevel += tempOutputValue;
        }
    }

    decimal max = System.Math.Max(outputMin1, outputMax1);

    if(maxOutputLevel == null)
    {
        maxOutputLevel = max;
    }
    else
    {
        maxOutputLevel += max;
    }
}

//
if(enable2)
{
    if(InputRecord.DataValue2 != null)
    {
        decimal tempOutputValue;

        if(InputRecord.DataValue2 <= inputMin2) // abaixo do valor de vazio
        {
            tempOutputValue = outputMin2;
        }
        else if(InputRecord.DataValue2 >= inputMax2) // acima do valor de cheio
        {
            tempOutputValue = outputMax2;
        }
        else
        {
            // regra de 3 linear entre inputMin e inputMax
            tempOutputValue = outputMin2
                                + (InputRecord.DataValue2.Value - inputMin2)
                                * (outputMax2 - outputMin2)
                                / (inputMax2 - inputMin2);

            tempOutputValue = System.Math.Abs(tempOutputValue);
        }

        if(outputLevel == null)
        {
            outputLevel = tempOutputValue;
        }
        else
        {
            outputLevel += tempOutputValue;
        }
    }

    decimal max = System.Math.Max(outputMin2, outputMax2);

    if(maxOutputLevel == null)
    {
        maxOutputLevel = max;
    }
    else
    {
        maxOutputLevel += max;
    }
}


if(enable3)
{
    if(InputRecord.DataValue3 != null)
    {
        decimal tempOutputValue;

        if(InputRecord.DataValue3 <= inputMin3) // abaixo do valor de vazio
        {
            tempOutputValue = outputMin3;
        }
        else if(InputRecord.DataValue3 >= inputMax3) // acima do valor de cheio
        {
            tempOutputValue = outputMax3;
        }
        else
        {
            // regra de 3 linear entre inputMin e inputMax
            tempOutputValue = outputMin3
                                + (InputRecord.DataValue3.Value - inputMin3)
                                * (outputMax3 - outputMin3)
                                / (inputMax3 - inputMin3);

            tempOutputValue = System.Math.Abs(tempOutputValue);
        }

        if(outputLevel == null)
        {
            outputLevel = tempOutputValue;
        }
        else
        {
            outputLevel += tempOutputValue;
        }
    }

    decimal max = System.Math.Max(outputMin3, outputMax3);

    if(maxOutputLevel == null)
    {
        maxOutputLevel = max;
    }
    else
    {
        maxOutputLevel += max;
    }
}

if(enable4)
{
    if(InputRecord.DataValue4 != null)
    {
        decimal tempOutputValue;

        if(InputRecord.DataValue4 <= inputMin4) // abaixo do valor de vazio
        {
            tempOutputValue = outputMin4;
        }
        else if(InputRecord.DataValue4 >= inputMax4) // acima do valor de cheio
        {
            tempOutputValue = outputMax4;
        }
        else
        {
            // regra de 3 linear entre inputMin e inputMax
            tempOutputValue = outputMin4
                                + (InputRecord.DataValue4.Value - inputMin4)
                                * (outputMax4 - outputMin4)
                                / (inputMax4 - inputMin4);

            tempOutputValue = System.Math.Abs(tempOutputValue);
        }

        if(outputLevel == null)
        {
            outputLevel = tempOutputValue;
        }
        else
        {
            outputLevel += tempOutputValue;
        }
    }

    decimal max = System.Math.Max(outputMin4, outputMax4);

    if(maxOutputLevel == null)
    {
        maxOutputLevel = max;
    }
    else
    {
        maxOutputLevel += max;
    }
}




if(outputLevel != null)
{
    //OutputRecord.FMSFuelLevel = outputLevel;
    OutputRecord.FMSFuelLevelPercentage = (outputLevel / maxOutputLevel) * 100m;

    //OutputValue = OutputRecord.FMSFuelLevel;
    OutputValue = OutputRecord.FMSFuelLevelPercentage;
}



Modelo Sensor Virtual para depósitos com leituras não lineares


/*****************************************************
Sensor Virtual para tanque de 15.600 Litros e tensão tanque cheio 8.35 VOLTS
*****************************************************/

if(InputValue.HasValue)
{
    decimal[,] table2 = new decimal[,] {
        { 1m, 0m },
        { 1.05m, 200m },
        { 1.1m, 400m },
        { 1.27m, 600m },
        { 1.4m, 800m },
        { 1.54m, 1000m },
        { 1.64m, 1200m },
        { 1.77m, 1400m },
        { 1.88m, 1600m },
        { 2m, 1800m },
        { 2.09m, 2000m },
        { 2.19m, 2200m },
        { 2.29m, 2400m },
        { 2.39m, 2600m },
        { 2.47m, 2800m },
        { 2.59m, 3000m },
        { 2.65m, 3200m },
        { 2.75m, 3400m },
        { 2.83m, 3600m },
        { 2.92m, 3800m },
        { 3.01m, 4000m },
        { 3.09m, 4200m },
        { 3.19m, 4400m },
        { 3.28m, 4600m },
        { 3.37m, 4800m },
        { 3.44m, 5000m },
        { 3.53m, 5200m },
        { 3.63m, 5400m },
        { 3.71m, 5600m },
        { 3.79m, 5800m },
        { 3.87m, 6000m },
        { 3.96m, 6200m },
        { 4.06m, 6400m },
        { 4.13m, 6600m },
        { 4.22m, 6800m },
        { 4.3m, 7000m },
        { 4.37m, 7200m },
        { 4.45m, 7400m },
        { 4.53m, 7600m },
        { 4.62m, 7800m },
        { 4.71m, 8000m },
        { 4.77m, 8200m },
        { 4.88m, 8400m },
        { 4.96m, 8600m },
        { 5.04m, 8800m },
        { 5.14m, 9000m },
        { 5.19m, 9200m },
        { 5.26m, 9400m },
        { 5.35m, 9600m },
        { 5.45m, 9800m },
        { 5.53m, 10000m },
        { 5.62m, 10200m },
        { 5.69m, 10400m },
        { 5.8m, 10600m },
        { 5.87m, 10800m },
        { 5.96m, 11000m },
        { 6.04m, 11200m },
        { 6.12m, 11400m },
        { 6.22m, 11600m },
        { 6.32m, 11800m },
        { 6.4m, 12000m },
        { 6.5m, 12200m },
        { 6.59m, 12400m },
        { 6.68m, 12600m },
        { 6.76m, 12800m },
        { 6.87m, 13000m },
        { 6.97m, 13200m },
        { 7.07m, 13400m },
        { 7.16m, 13600m },
        { 7.25m, 13800m },
        { 7.35m, 14000m },
        { 7.46m, 14200m },
        { 7.56m, 14400m },
        { 7.66m, 14600m },
        { 7.8m, 14800m },
        { 7.93m, 15000m },
        { 8.08m, 15200m },
        { 8.23m, 15400m },
        { 8.35m, 15600 }
    };

    int tableLen = table2.GetLength(0);

    if(InputValue <= table2[0, 0])
    {
        OutputValue = table2[0, 1];
    }
    else if(InputValue >= table2[tableLen - 1, 0])
    {
        OutputValue = table2[tableLen - 1, 1];
    }
    else
    {
        int lowerIndex = 0;
        int upperIndex = tableLen;
        int index = tableLen / 2;
        int range = upperIndex - lowerIndex;

        int j = 0;

        do
        {
            j++;

            var currentValues = table2[index, 0];

            if(InputValue.Value < currentValues)
            {
                upperIndex = index;
            }
            else
            {
                lowerIndex = index;
            }

            range = upperIndex - lowerIndex;

            index = range / 2 + lowerIndex;


        } while(range > 1);

        OutputValue = table2[index, 1];
    }
}