Fraunhofer-FIT-DIEN / iec104-python

A Python module to simulate SCADA and RTU communication over protocol 60870-5-104 to research ICT behavior in power grids.
https://iec104-python.readthedocs.io/latest/python/index.html
GNU General Public License v3.0
51 stars 9 forks source link

Feature-Request: Allow to set the c104.type of a point #32

Open georgwerner-lemonbeat opened 1 month ago

georgwerner-lemonbeat commented 1 month ago

Hello,

we have a scenario where we might want to transmit a point in two different variations.

  1. As Type 1 -> M_SP_NA_1 (Single Info without timestamp)
  2. As Type 30 -> M_SP_TB_1 (Single Info with timestamp)

So basically the underlying data-type shall not change. Depending on the scenario (Interrogation, Spontaneous) we would like to send the value either with or without timestamp.

Unfortunately there is no setter for the type of a point.

Is it possible to allow setting the type of an already changes point?

Thanks a lot in advance Georg

m-unkel commented 1 month ago

Hello Georg,

Thank you for your feedback.

Currently, it was a design choice to have different information object addresses (IOAs) for distinct types. This approach helps avoid unexpected payload formats and minimizes repeated type checking, ensuring that each data type has its own distinct identity in the communication flow.

One potential solution would be to implement another abstraction layer in your code that internally manages two separate points (one for each type) but exposes them as a single logical entity externally.

Alternatively, you could consider sending a timestamp with a known "unset" state (such as 0) when you want the client to ignore it. However, this approach would require you to have control over the client as well, to ensure the client-side logic disregards the zero timestamp and retains the previous valid one.

May I ask, what specific challenges are you facing with sending a timestamp too frequently? Is it that the correct timestamp value isn't available at the time of transmission, or is there another reason for preferring to omit it in certain scenarios?

Looking forward to your feedback. Best Martin

georgwerner-lemonbeat commented 1 month ago

Hello Martin,

thanks a lot for your help and solution proposals.

Fortunately we now agreed in our integration-prototype not mix message-types for already defined datapoints, thus following your design decision.

Switching the datatype of an already created entity would also allow that you can witch from value-report to step-command. So I thinks it's good to stick to fixed types.

Answering your question: We don't have any challenges sending the timestamp too frequently. The request to change the message type without having a timestamp for interrogation responses came from our test-partner (the reason for this is unclear). I guess somewhow our partner also came to the conclusion that mixing types is not a good idea.


We also have been working on another topic, setting the daylight-saving-time bit for messages. I created a fork and implemented a prototype only for one message type.

This approach is not very generic and must be adapted for every message type.

Would great to have your feedback on this.

Shall I open another thread for this?

(Hint: We know that using the SU-BIT in iec104 according to the Din-Norm is not recommended).

Thanks in advance Georg

m-unkel commented 3 weeks ago

Hello Georg, Thank you for your PR.

Regarding the timestamps, we can continue the discussion in this thread; next time, please feel free to open a parallel issue. I saw your pull request, but you closed it again. Generally, a contributor license agreement would be necessary for a pull request of this magnitude.

The timestamp in the protocol also comes with an invalid flag, which can be used for the previously mentioned marking of invalid timestamps instead of a defined "unset" state. There is the possibility of creating a wrapper class (i.e., c104.DateTime) that can be converted to native Python datetime.datetime objects and also provides access to the SU bit, IV bit, and SB bit. There are already functions for the bit flags in the lib60870-C, so encoding and decoding do not need to be programmed from scratch.

However, the question remains where the state of DST is stored. In your PR, the state was assigned to the server. But does it really make sense for state to vary per server/client instance of a running process? Otherwise, I would tend to consider a static class property as a global configuration that is valid for all servers and clients in the running Python process (c104.DateTime.summerTime = True).

Best Martin

m-unkel commented 3 weeks ago

In general, this approach could be used to flag all timestamps implicitly added by this module as substituted. For example, if I change the value of a point that has a type with an associated timestamp by using point.value = ... and not by using point.info = .... Since this would be a breaking change, this behavior should also be configurable through an option. And by default, it should behave as it did before.