SVGHMI: ensures that PLC sends only fresh data to HMI, even right after variable being subscribed.
authorEdouard Tisserant
Wed, 14 Sep 2022 12:41:44 +0200
changeset 3613 7af7a23e4adb
parent 3604 be87303d5b2d
child 3614 0e0252339e83
child 3621 da020d88db0c
SVGHMI: ensures that PLC sends only fresh data to HMI, even right after variable being subscribed.
svghmi/svghmi.c
--- a/svghmi/svghmi.c	Tue Sep 13 16:31:52 2022 +0200
+++ b/svghmi/svghmi.c	Wed Sep 14 12:41:44 2022 +0200
@@ -103,12 +103,14 @@
     void *dest_p = NULL;
     void *value_p = NULL;
     size_t sz = 0;
+    int do_sample = 0;
     while(session_index < MAX_CONNECTIONS) {
         if(dsc->wstate[session_index] == buf_set){
             /* if being subscribed */
             if(dsc->refresh_period_ms[session_index]){
-                if(dsc->age_ms[session_index] + ticktime_ms < dsc->refresh_period_ms[session_index]){
-                    dsc->age_ms[session_index] += ticktime_ms;
+                uint16_t new_age_ms = dsc->age_ms[session_index] + ticktime_ms;
+                if(new_age_ms < dsc->refresh_period_ms[session_index]){
+                    dsc->age_ms[session_index] = new_age_ms;
                 }else{
                     dsc->wstate[session_index] = buf_tosend;
                     global_write_dirty = 1;
@@ -116,33 +118,30 @@
             }
         }
 
-        /* variable is sample only if just subscribed
+        /* variable is sampled if just subscribed (initial value)
            or already subscribed and having value change */
-        int do_sample = 0;
+        int sample_session = 0;
         int just_subscribed = dsc->wstate[session_index] == buf_new;
-        if(!just_subscribed){
+        if(just_subscribed){
+            sample_session = 1;
+        } else {
             int already_subscribed = dsc->refresh_period_ms[session_index] > 0;
             if(already_subscribed){
-                if(!value_changed){
-                    if(!value_p){
-                        UnpackVar(dsc, &value_p, NULL, &sz);
-                        if(__Is_a_string(dsc)){
-                            sz = ((STRING*)value_p)->len + 1;
-                        }
-                        dest_p = &wbuf[dsc->buf_index];
-                    }
+                /* compute value_changed once only */
+                if(!value_p){
+                    UnpackVar(dsc, &value_p, NULL, &sz);
+                    if(__Is_a_string(dsc)){
+                        sz = ((STRING*)value_p)->len + 1;
+                    }
+                    dest_p = &wbuf[dsc->buf_index];
                     value_changed = memcmp(dest_p, value_p, sz) != 0;
-                    do_sample = value_changed;
-                }else{
-                    do_sample = 1;
-                }
-            }
-        } else {
-            do_sample = 1;
-        }
-
-
-        if(do_sample){
+                }
+                sample_session = value_changed;
+            }
+        }
+
+
+        if(sample_session){
             if(dsc->wstate[session_index] != buf_set && dsc->wstate[session_index] != buf_tosend) {
                 if(dsc->wstate[session_index] == buf_new \
                    || ticktime_ms > dsc->refresh_period_ms[session_index]){
@@ -153,13 +152,23 @@
                 }
                 dsc->age_ms[session_index] = 0;
             }
+            do_sample = 1;
         }
 
         session_index++;
     }
-    /* copy value if changed (and subscribed) */
-    if(value_changed)
+
+    /* copy value if one at least one session did sample */
+    if(do_sample){
+        if(!value_p){
+            UnpackVar(dsc, &value_p, NULL, &sz);
+            if(__Is_a_string(dsc)){
+                sz = ((STRING*)value_p)->len + 1;
+            }
+            dest_p = &wbuf[dsc->buf_index];
+        }
         memcpy(dest_p, value_p, sz);
+    }
     return 0;
 }