Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pull Back Issue while getting the live data from websocket #2318

Open
BARSHA-ABHILASHA opened this issue Mar 25, 2025 · 0 comments
Open

Pull Back Issue while getting the live data from websocket #2318

BARSHA-ABHILASHA opened this issue Mar 25, 2025 · 0 comments
Labels
charts Charts component open Open

Comments

@BARSHA-ABHILASHA
Copy link

I am fetching real-time data via WebSockets from ThingsBoard and have fixed time window (10s), the timewindow is not depended to data points due to live it scrolling from right to left continuously without any interruption , if any data comes it should show in time window if not it will not affect the time window and time window will runs as usual without data.

ISSUE I AM FACING

The background time window is working correctly but while having the data ( as I am geeting the 200 of data in 1 chunk and it is also the time between the 2 chunks is not fixed so may be in 10sec i am getting 2 chunks * 200 data = 400 data or sometime i am getting 1 chunk * 200 data = 200 data ), So while the first chunk of data is coming looks good but while next chunk is coming and the 1st chunk is moving towards Y -axis while touching the Y-axis it looks like the 1st chunk is throwing the lines of graph to the 2nd chunk of graph to feed it (Looks like 2nd chunk is Pulling back the graphs from the 1st chunk which is actually not in window, I don't know may be the issue is in UI or backend)
Below is the actual flutter code implementation where i am getting the values and the issue i have explained above i captured a video of that, Please see the video and my code and review it where is the actuall issue Please suggest me I am waiting for the reply from you guys.

screen-20250325-201100.mp4

CODE

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:smarty/features/login/thingsboard_service.dart';
import 'package:syncfusion_flutter_charts/charts.dart';
import 'package:intl/intl.dart';
import 'package:web_socket_channel/io.dart';

class StatsHomeScreen extends StatefulWidget {
@OverRide
_StatsHomeScreenState createState() => _StatsHomeScreenState();
}

class _StatsHomeScreenState extends State {
List dataPoints = [];
late Timer timer;
int visibleDuration = 10; // Keep last 10 seconds visible
DateTime startTime = DateTime.now(); // Base time to move timeline
final ThingsBoardAuthService authService = ThingsBoardAuthService();

late IOWebSocketChannel channel; // WebSocket connection

@OverRide
void initState() {
super.initState();

// Initialize WebSocket connection
connectWebSocket();

// Timer for moving timeline every 500ms
timer = Timer.periodic(const Duration(milliseconds: 500), (timer) {
  setState(() {
    // Shift the start time forward to create a scrolling effect
    startTime = startTime.add(const Duration(milliseconds: 500));

    // Remove old data beyond visible range
//     dataPoints.removeWhere((point) =>
//   point.time.isBefore(startTime.subtract(Duration(seconds: visibleDuration)))
// );
    dataPoints.removeWhere((point) =>
        DateTime.now().difference(point.time).inSeconds > visibleDuration);
  });


});

}

Future connectWebSocket() async {
print("🔌 Connecting to WebSocket...");
String? accesstoken = await authService.getValidToken();
channel = IOWebSocketChannel.connect(
"ws://localhost/api/ws/plugins/telemetry?token=$accesstoken",
);

// Send subscription request to ThingsBoard
channel.sink.add(jsonEncode({
  "tsSubCmds": [
    {
      "entityType": "DEVICE",
      "entityId": "707970f0-ef6f-11ef-b7bb-93f364633065",
      "scope": "LATEST_TELEMETRY",
      "cmdId": 1
    }
  ],
  "historyCmds": [],
  "attrSubCmds": []
}));

// Listen for new telemetry data
channel.stream.listen(
  (message) {
    // print("📩 Received WebSocket Message: $message");

    try {
      var data = jsonDecode(message);
      var adcData = data["data"]["ADC Values CH_0"];
      if (adcData != null && adcData is List && adcData.isNotEmpty) {
        var timestamp = int.parse(
            adcData[0][0].toString()); // First item in list is timestamp
        var value = double.parse(
            adcData[0][1].toString()); // Second item is the value (string)
        setState(() {
          dataPoints.add(LiveData(
              DateTime.fromMillisecondsSinceEpoch(timestamp), value));
        });
      } else {
        print("⚠️ No valid ADC Values CH_0 data found.");
      }
    } catch (e) {
      print("❌ Error parsing WebSocket data: $e");
    }
  },
  onDone: () {
    print("❌ WebSocket Connection Closed.");
  },
  onError: (error) {
    print("🚨 WebSocket Error: $error");
  },
);

}

@OverRide
void dispose() {
timer.cancel();
channel.sink.close(); // Close WebSocket connection
print("🔌 WebSocket Disconnected.");
super.dispose();
}

@OverRide
Widget build(BuildContext context) {
DateTime minTime = startTime.subtract(Duration(seconds: visibleDuration));
DateTime maxTime = startTime;

return Scaffold(
  appBar: AppBar(title: const Text("Live Timeline Chart")),
  body: Padding(
    padding: const EdgeInsets.all(16.0),
    child: SfCartesianChart(

      zoomPanBehavior: ZoomPanBehavior(
                enablePinching: true,
                zoomMode: ZoomMode.xy,
                enablePanning: true,
              ),
              trackballBehavior: TrackballBehavior(
                enable: true,
                activationMode: ActivationMode.singleTap,
              ),
      primaryXAxis: DateTimeAxis(
        minimum: minTime,
        maximum: maxTime,
        intervalType: DateTimeIntervalType.seconds,
        interval: 1, // Keep 1-second grid lines
        dateFormat: DateFormat.Hms(),
        // majorGridLines: const MajorGridLines(width: 1, color: Colors.grey),
      ),
      primaryYAxis: NumericAxis(
        isVisible: dataPoints.isNotEmpty, // Hide Y-axis if no data
      ),
      series: <LineSeries<LiveData, DateTime>>[
        LineSeries<LiveData, DateTime>(
          dataSource: dataPoints,
          xValueMapper: (LiveData data, _) => data.time,
          yValueMapper: (LiveData data, _) => data.value,
          color: Colors.blue,
          width: 3,
        ),
      ],
    ),
  ),
);

}
}

// Data model for time-series points
class LiveData {
final DateTime time;
final double? value;
LiveData(this.time, this.value);
}

@LavanyaGowtham2021 LavanyaGowtham2021 added charts Charts component open Open labels Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
charts Charts component open Open
Projects
None yet
Development

No branches or pull requests

2 participants