@@ -10,6 +10,7 @@ use crate::Tick;
1010use async_trait:: async_trait;
1111use camino:: Utf8PathBuf ;
1212use futures:: FutureExt ;
13+ use serde_json:: json;
1314use std:: cmp:: min;
1415use std:: collections:: HashSet ;
1516use std:: time:: Duration ;
@@ -21,10 +22,13 @@ use tedge_actors::Sender;
2122use tedge_actors:: SimpleMessageBox ;
2223use tedge_file_system_ext:: FsWatchEvent ;
2324use tedge_mqtt_ext:: MqttMessage ;
25+ use tedge_mqtt_ext:: QoS ;
2426use tedge_mqtt_ext:: SubscriptionDiff ;
27+ use tedge_mqtt_ext:: Topic ;
2528use tedge_mqtt_ext:: TopicFilter ;
2629use tedge_watch_ext:: WatchEvent ;
2730use tedge_watch_ext:: WatchRequest ;
31+ use time:: OffsetDateTime ;
2832use tokio:: io:: AsyncWriteExt ;
2933use tokio:: time:: sleep_until;
3034use tokio:: time:: Instant ;
@@ -52,6 +56,7 @@ impl Actor for FlowsMapper {
5256
5357 async fn run ( mut self ) -> Result < ( ) , RuntimeError > {
5458 self . send_updated_subscriptions ( ) . await ?;
59+ self . notify_flows_status ( ) . await ?;
5560
5661 while let Some ( message) = self . next_message ( ) . await {
5762 match message {
@@ -73,17 +78,19 @@ impl Actor for FlowsMapper {
7378 if matches ! ( path. extension( ) , Some ( "js" | "ts" | "mjs" ) ) {
7479 self . processor . reload_script ( path) . await ;
7580 } else if path. extension ( ) == Some ( "toml" ) {
76- self . processor . add_flow ( path) . await ;
81+ self . processor . add_flow ( path. clone ( ) ) . await ;
7782 self . send_updated_subscriptions ( ) . await ?;
83+ self . update_flow_status ( path. as_str ( ) ) . await ?;
7884 }
7985 }
8086 InputMessage :: FsWatchEvent ( FsWatchEvent :: FileCreated ( path) ) => {
8187 let Ok ( path) = Utf8PathBuf :: try_from ( path) else {
8288 continue ;
8389 } ;
8490 if matches ! ( path. extension( ) , Some ( "toml" ) ) {
85- self . processor . add_flow ( path) . await ;
91+ self . processor . add_flow ( path. clone ( ) ) . await ;
8692 self . send_updated_subscriptions ( ) . await ?;
93+ self . update_flow_status ( path. as_str ( ) ) . await ?;
8794 }
8895 }
8996 InputMessage :: FsWatchEvent ( FsWatchEvent :: FileDeleted ( path) ) => {
@@ -93,8 +100,9 @@ impl Actor for FlowsMapper {
93100 if matches ! ( path. extension( ) , Some ( "js" | "ts" | "mjs" ) ) {
94101 self . processor . remove_script ( path) . await ;
95102 } else if path. extension ( ) == Some ( "toml" ) {
96- self . processor . remove_flow ( path) . await ;
103+ self . processor . remove_flow ( path. clone ( ) ) . await ;
97104 self . send_updated_subscriptions ( ) . await ?;
105+ self . update_flow_status ( path. as_str ( ) ) . await ?;
98106 }
99107 }
100108 _ => continue ,
@@ -163,6 +171,38 @@ impl FlowsMapper {
163171 watch_requests
164172 }
165173
174+ async fn notify_flows_status ( & mut self ) -> Result < ( ) , RuntimeError > {
175+ let status = "enabled" ;
176+ let now = OffsetDateTime :: now_utc ( ) ;
177+ for flow in self . processor . flows . keys ( ) {
178+ let status = Self :: flow_status ( flow, status, & now) ;
179+ self . mqtt_sender . send ( status) . await ?;
180+ }
181+ Ok ( ( ) )
182+ }
183+
184+ async fn update_flow_status ( & mut self , flow : & str ) -> Result < ( ) , RuntimeError > {
185+ let now = OffsetDateTime :: now_utc ( ) ;
186+ let status = if self . processor . flows . contains_key ( flow) {
187+ "updated"
188+ } else {
189+ "removed"
190+ } ;
191+ let status = Self :: flow_status ( flow, status, & now) ;
192+ self . mqtt_sender . send ( status) . await ?;
193+ Ok ( ( ) )
194+ }
195+
196+ fn flow_status ( flow : & str , status : & str , time : & OffsetDateTime ) -> MqttMessage {
197+ let topic = Topic :: new_unchecked ( "te/device/main/service/tedge-flows/status/flows" ) ;
198+ let payload = json ! ( {
199+ "flow" : flow,
200+ "status" : status,
201+ "time" : time. unix_timestamp( ) ,
202+ } ) ;
203+ MqttMessage :: new ( & topic, payload. to_string ( ) ) . with_qos ( QoS :: AtLeastOnce )
204+ }
205+
166206 async fn on_source_poll ( & mut self ) -> Result < ( ) , RuntimeError > {
167207 let now = Instant :: now ( ) ;
168208 let timestamp = DateTime :: now ( ) ;
0 commit comments