Added clock
This commit is contained in:
@@ -13,36 +13,27 @@ public class MatrixRenderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
public async Task DrawAndSendFrameAsync(float currentTemp, int currentWater)
|
public async Task DrawAndSendFrameAsync(float currentTemp, int currentWater, DateTime currentTime)
|
||||||
//public async Task DrawAndSendFrameAsync(string currentTemp)
|
//public async Task DrawAndSendFrameAsync(string currentTemp)
|
||||||
{
|
{
|
||||||
// 1. Create a 64x64 canvas
|
|
||||||
using SKBitmap bitmap = new SKBitmap(_width, _height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
using SKBitmap bitmap = new SKBitmap(_width, _height, SKColorType.Rgba8888, SKAlphaType.Premul);
|
||||||
using SKCanvas canvas = new SKCanvas(bitmap);
|
using SKCanvas canvas = new SKCanvas(bitmap);
|
||||||
|
|
||||||
// 2. Clear background to black
|
|
||||||
canvas.Clear(SKColors.Black);
|
canvas.Clear(SKColors.Black);
|
||||||
|
|
||||||
// 3. Draw something (e.g., Temperature Text)
|
// --- DRAW CLOCK ---
|
||||||
|
using SKPaint clockPaint = new SKPaint { Color = SKColors.Cyan, IsAntialias = false };
|
||||||
|
using SKTypeface typeface = SKTypeface.FromFamilyName("monospace");
|
||||||
|
using SKFont clockFont = new SKFont(typeface, 16);
|
||||||
|
string timeFormat = (currentTime.Second % 2 == 0) ? "HH:mm" : "HH mm";
|
||||||
|
string timeString = currentTime.ToString(timeFormat);
|
||||||
|
canvas.DrawText(timeString, 4, 16, SKTextAlign.Left, clockFont, clockPaint);
|
||||||
|
|
||||||
// Paint now only handles the color and rendering style
|
// --- DRAW TEMPERATURE ---
|
||||||
using SKPaint textPaint = new SKPaint
|
using SKPaint textPaint = new SKPaint { Color = SKColors.Orange, IsAntialias = false };
|
||||||
{
|
using SKFont textFont = new SKFont { Size = 16 };
|
||||||
Color = SKColors.Orange,
|
canvas.DrawText($"{currentTemp:F1}c", 4, 30, SKTextAlign.Left, textFont, textPaint);
|
||||||
IsAntialias = false // Keep crisp pixels for LED matrices
|
canvas.DrawText($"{currentWater:F1}%", 4, 50, SKTextAlign.Left, textFont, textPaint);
|
||||||
};
|
|
||||||
|
|
||||||
// Font handles the typography
|
|
||||||
using SKFont textFont = new SKFont
|
|
||||||
{
|
|
||||||
Size = 16
|
|
||||||
};
|
|
||||||
|
|
||||||
// DrawText now takes the string, X, Y, the font, and the paint
|
|
||||||
//canvas.DrawText($"{currentTemp:F1}c", 4, 32, textFont, textPaint);
|
|
||||||
// DrawText now takes the string, X, Y, alignment, the font, and the paint
|
|
||||||
canvas.DrawText($"{currentTemp:F1}c", 4, 12, SKTextAlign.Left, textFont, textPaint);
|
|
||||||
canvas.DrawText($"{currentWater:F1}%", 4, 32, SKTextAlign.Left, textFont, textPaint);
|
|
||||||
|
|
||||||
// 4. Convert 32-bit RGBA to 24-bit RGB for WLED
|
// 4. Convert 32-bit RGBA to 24-bit RGB for WLED
|
||||||
byte[] rgbaBytes = bitmap.Bytes;
|
byte[] rgbaBytes = bitmap.Bytes;
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ using System.Diagnostics;
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
var renderer = new MatrixRenderer("192.168.0.150"); // Your WLED IP
|
var renderer = new MatrixRenderer("192.168.0.150"); // Your WLED IP
|
||||||
|
var ntp = new NtpService("ntp.parsons.cc");
|
||||||
|
|
||||||
// Replace these with your actual InfluxDB v2 credentials
|
// Replace these with your actual InfluxDB v2 credentials
|
||||||
// If Influx is on the same Pi, you can use the Pi's local IP and port 8086
|
// If Influx is on the same Pi, you can use the Pi's local IP and port 8086
|
||||||
@@ -31,8 +32,10 @@ while (true)
|
|||||||
dbTimer.Restart();
|
dbTimer.Restart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DateTime now = ntp.GetCurrentTime();
|
||||||
|
|
||||||
// Keep pushing frames to WLED at 30 FPS
|
// Keep pushing frames to WLED at 30 FPS
|
||||||
await renderer.DrawAndSendFrameAsync(currentTemp, currentWaterLevel);
|
await renderer.DrawAndSendFrameAsync(currentTemp, currentWaterLevel, now);
|
||||||
|
|
||||||
|
|
||||||
await Task.Delay(1000 / 30);
|
await Task.Delay(1000 / 30);
|
||||||
|
|||||||
64
ntpService.cs
Normal file
64
ntpService.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using System;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
public class NtpService
|
||||||
|
{
|
||||||
|
private readonly string _ntpServer;
|
||||||
|
private TimeSpan _timeOffset = TimeSpan.Zero;
|
||||||
|
private DateTime _lastSync = DateTime.MinValue;
|
||||||
|
|
||||||
|
public NtpService(string ntpServer)
|
||||||
|
{
|
||||||
|
_ntpServer = ntpServer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DateTime GetCurrentTime()
|
||||||
|
{
|
||||||
|
// Sync with your NTP server every 1 hour
|
||||||
|
if ((DateTime.UtcNow - _lastSync).TotalHours > 1)
|
||||||
|
{
|
||||||
|
SyncWithNtp();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the offset so the clock advances smoothly between syncs
|
||||||
|
return DateTime.Now.Add(_timeOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SyncWithNtp()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var ntpData = new byte[48];
|
||||||
|
ntpData[0] = 0x1B; // NTP request header (Client mode, Version 3)
|
||||||
|
|
||||||
|
var addresses = Dns.GetHostEntry(_ntpServer).AddressList;
|
||||||
|
var ipEndPoint = new IPEndPoint(addresses[0], 123);
|
||||||
|
|
||||||
|
using (var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
|
||||||
|
{
|
||||||
|
socket.ReceiveTimeout = 3000;
|
||||||
|
socket.Connect(ipEndPoint);
|
||||||
|
socket.Send(ntpData);
|
||||||
|
socket.Receive(ntpData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the 64-bit timestamp from the NTP response
|
||||||
|
ulong intPart = (ulong)ntpData[40] << 24 | (ulong)ntpData[41] << 16 | (ulong)ntpData[42] << 8 | (ulong)ntpData[43];
|
||||||
|
ulong fractPart = (ulong)ntpData[44] << 24 | (ulong)ntpData[45] << 16 | (ulong)ntpData[46] << 8 | (ulong)ntpData[47];
|
||||||
|
|
||||||
|
var milliseconds = (intPart * 1000) + ((fractPart * 1000) / 0x100000000L);
|
||||||
|
var networkTime = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddMilliseconds((long)milliseconds);
|
||||||
|
|
||||||
|
// Calculate the difference between Pi's local UTC and NTP UTC
|
||||||
|
_timeOffset = networkTime - DateTime.UtcNow;
|
||||||
|
_lastSync = DateTime.UtcNow;
|
||||||
|
|
||||||
|
Console.WriteLine($"NTP Sync to {_ntpServer} successful. Offset: {_timeOffset.TotalMilliseconds:F1}ms");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"NTP Sync failed: {ex.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user