InfluxDB C# WritePoint write integer values shows as double - c#

I'm trying to write a point into a influxdb bucket, using the code below C# inluxdb client, but when i look into influxdb the values have decimal places.
I saw examples with .Field("example", 10D), but how i do it with a variable?
point = PointData.Measurement(measurement)
.Field(name, Int32.Parse(value, CultureInfo.InvariantCulture))
.Timestamp(DateTime.UtcNow, WritePrecision.Ns);
writeApi.WritePoint(point, bucket, orgID);

Related

JArrary find value from key

I have a long json string that I get from reddit which looks like: this. Once I download and parse the string, I am looking for two parts, "fallback_url" and "thumbnail". The thing is that depending on the time that the reddit post was uploaded the format of the json string can vary so those parts can be in different spots. What I want to do is look through the objects and arrays in the JArray to find the value of "fallback_url" and "thumbnail".
I am trying to use Newtonsoft, but I am not very familiar with it, and when I try the following I get an error:
var data = JArray.Parse(json);
string path = data.Value<string>("fallback_url")?? data.Value<string>("url_overridden_by_dest");
System.ArgumentException: Accessed JArray values with invalid key value: "fallback_url". Int32 array index expected.
Clearly, I'm either using the function wrong or it's not the right function to use. I've tried looking online for answers, but all the examples I found directly referenced the structure of the json to find a value from a key, which I can't do.

Converting real data type from Siemens PLC (S7-1200) to be displayed in Visual C# Windows Form

I am trying to read a real value from a Siemens PLC (S7-1200) and display it in Windows Form. I am using the S7.NET library to communicate with the PLC and a TIA Portal V15 to program/Monitor the PLC.
I am able to read the particular data block (DB3.DBD0) in the Windows Form from the PLC, it does return a value, but the value is displayed in some other format. For example, if I modify the value in DB3.DBD0 to "2.22", it gives me "1.074665+09". I would like it to return the same value as in the TIA Portal which is "2.22".
Below is the code I am using to convert the values.
object real0 = Convert.ToSingle(plc.Read("DB3.DBD0"));
label43.Text = real0.ToString();
If my question is not clear, please let me know, I can try to explain in more detail.
Thank you in advance!
The PLC data type appears to be a REAL (Floating-point number) 'IEEE Floating-point number' as per http://www.plcdev.com/step_7_elementary_data_types
These numbers are represented as fractions, whereby 2.2 cannot be accurately defined.
Great detailed explanation:
Why are floating point numbers inaccurate?
Good simple explanation:
https://floating-point-gui.de/basic
Try converting to decimal data types, then rounding to remove trailing 0's
Siemens and other PLC systems store those numbers as WORDs.
For example 2.22 floating point/real value is stored as 0x400E147B in PLC. in ABCD byte order. A=40, B=0E, C=14, D=7B.
But as I can see you are reading correct hexadecimal value from PLC but converting it as 32bit INTEGER.
You can check from:
https://www.scadacore.com/tools/programming-calculators/online-hex-converter/
You have to cast it as an uint and convert it to a double.
for example: var real0 = Convert.ToDouble((uint)plc.Read("DB3.DBD0"));
or this: var real0 = ((uint)plc.Read("DB3.DBD0")).ConvertToDouble();
I hope this helped :)
for more examples you can try this video, it is a bit outdated so you might need to do some small things different: https://www.mesta-automation.com/siemens-s7-plc-c-s7-net-plc-driver/

Dynamic type loading in C#

I'm using a protocol named Ethernet Industrial Protocol (EIP) and I use it to send and receive data from a Programmable Logic Controller (PLC).
The data is sent as hex values and in 2 byte sizes as the smallest. So when I ask for what is stored in a memory area in the PLC I get a 2 byte hex value back.
Currently I'm using hardcoded approach for parsing the data that comes back.
What I'm looking at is the ability to use a config file or something instead to tell what the string of bytes should look like.
Let's say I have 3 temperature readings and product type, the 3 temperatures are floating point and use 4 bytes per and the product type is an integer.
If I want to change it I need to change the program..
What should I read up on to be able to change this in for instance a config file instead of rewriting the application?
I want to be able to say that I have x number of instances of this type and the program should then parse it as that.
The program saves all the data it reads into a MySql database.
This is a snipet of the code that parses the values as the come in from the PLC.
Krakk = (BitConverter.ToUInt16(data, bIndex)); bIndex += 2;
Small = (BitConverter.ToUInt16(data, bIndex)); bIndex += 2;
Medium = (BitConverter.ToUInt16(data, bIndex)); bIndex += 2;
Large = (BitConverter.ToUInt16(data, bIndex)); bIndex += 2;
If I use a config file I would like to say something in the lines of:
name, uint, size and the program should then read that.
So for instance -> Krakk, uint16, 2 and then the program would know that it should change that out for this: Krakk = (BitConverter.ToUInt16(data, bIndex)); bIndex += 2;
Even though I think you are already answering yourself, but here is my answer with some details:
You may need to create a new custom configuration section (How to Create and Access a Custom Configuration) with four properties as follows:
ReadingName (accepts string value and represents the name of the
instance you want to read).
StartIndex (accepts integer value and represents the starting index from which you start reading the data bytes of the instance.)
Length (accepts integer value and represents the number of data bytes of the instance.)
Data Type.
In the app.config file you should add a section for each instance you want to read, then in your program you should read these values and act accordingly.

Handling of exponential number through JavaScript VS C#

I have a exponential number : 4.65661287307739E-10
When I round it off using JavaScript, it gets converted as 5. I use following code
var roundFormattedNumber = function (n) {
var val = parseFloat(n.replace(/[^0-9.]/g, '')).toFixed(0);
Ext.util.Format.thousandSeparator = ',';
Ext.util.Format.decimalSeparator = '.';
return Ext.util.Format.number(val, '0,000');
};
When I try to first parse this number into decimal using C# I get : 0.000000000465661287307739M
decimal amount;
decimal.TryParse("4.65661287307739E-10", NumberStyles.Any, CultureInfo.InvariantCulture, out amount);
If I round off this value using C# result would be different as compared to JavaScript result.
Why there is a difference? Which result it correct?
Please suggest.
Thank you
When I round it off using JavaScript, it gets converted as 5.
That's not JavaScript, that's your code. You're removing everything from the string that isn't a digit or a .:
var val = parseFloat(n.replace(/[^0-9.]/g, '')).toFixed(0);
// -------------------^^^^^^^^^^^^^^^^^^^^^^^^
...so you're turning
4.65661287307739E-10
into
4.6566128730773910
and then parsing that, which naturally gives you a completely different number from 4.65661287307739E-10. There's no need to do that, JavaScript's parseFloat can interpret E-notation.
Whereas in your C# code, you're actually providing the E-notation number to the TryParse function.
Why there is a difference?
Because in the one case you're removing really important information from the string before asking JavaScript to parse it.
Which result it correct?
The C# one (although I have no idea why there's an M at the end of it).

Parse Number Data from Letters C#

I am trying to parse data I am getting from an arduino robot I created. I currently have my serial program up and running and I am able to monitor the data being sent and received by my computer.
The data I am trying to get from the robot includes: speed, range, and heading. The data being sent from the arduino are floats.
I use a single character to denote what the data being received is by either a S,R, or H. For example:
R150.6
This would denote that this is range data and 150.6 would be the new range to update the program with.
I'm a little stuck trying to figure out the best way to parse this using c# as this is my first c# program.
I have tried with a similar code to:
if (RxString[0] == 'R')
Range = double.Parse(RxString);
I read on the site to use regular expressions, however I am having a hard time figuring out how to incorporate it into my code.
This is the link I was using for guidance:
String parsing, extracting numbers and letters
You're almost there. If you're always starting with a single letter, try Range = double.Parse(RxString.Substring(1)). It will read from the second character on.
i can use regex for find double:
\d+([,\.]\d+)?
using:
Regex re = Regex.Match("R1.23", "\d+([,\.]\d+)?");
if (re.Success)
{
double #double = Convert.ToDouble(re.Value, System.Globalization.CultureInfo.InvariantCulture);
}
it garanties to get first decimal from string if your letter migrate in string or adding other symbols
Since you know the format of the returned data, you can try something like this
data = RxString.SubString(0,1);
value = RxString.SubString(1, RxString.Length-1);
if(data == "R")
range = double.Parse(value);

Categories

Resources