Install .NET SDK 9.0 on Ubuntu 22.04
sudo add-apt-repository ppa:dotnet/backports
sudo apt-get update && \ sudo apt-get install -y dotnet-sdk-9.0
sudo add-apt-repository ppa:dotnet/backports
sudo apt-get update && \ sudo apt-get install -y dotnet-sdk-9.0
4-20 mA
5529 to 27648 for a 4-20 mA range.
0-20 mA
0 to 27648 for a 0-20 mA range.
0-10V
0 to 27648 for a 0-10V range.
In Ubuntu Server, the systemd-networkd-wait-online.service
is responsible for waiting until the network is fully online before allowing the boot process to continue. This service can sometimes cause delays during the boot process if the network configuration takes a long time to initialize.
To completely disable the systemd-networkd-wait-online.service
, run the following command:
sudo systemctl disable systemd-networkd-wait-online.service
This will prevent the service from starting at boot time.
If you want to ensure that the service cannot be started manually or automatically by any other service, you can mask it:
sudo systemctl mask systemd-networkd-wait-online.service
Masking creates a symbolic link to /dev/null
, making it impossible for the service to start unless explicitly unmasked.
In your Blazor application, modify the Program.cs
file to configure data protection with certificate-based encryption.
using Microsoft.AspNetCore.DataProtection; using System.Security.Cryptography.X509Certificates; var builder = WebApplication.CreateBuilder(args); // Add services to the container. builder.Services.AddRazorPages(); builder.Services.AddServerSideBlazor(); // Configure Data Protection to use a certificate for key encryption var certificate = X509CertificateLoader.LoadPkcs12FromFile("path_to_certificate.pfx", "password"); builder.Services.AddDataProtection() .ProtectKeysWithCertificate(certificate) .PersistKeysToFileSystem(new DirectoryInfo(keyFolderPath)) .SetApplicationName("ERP"); var app = builder.Build(); // Configure the HTTP request pipeline. if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.MapBlazorHub(); app.MapFallbackToPage("/_Host"); app.Run();
# Add the release PGP keys: sudo mkdir -p /etc/apt/keyrings sudo curl -L -o /etc/apt/keyrings/syncthing-archive-keyring.gpg https://syncthing.net/release-key.gpg
# Add the "stable" channel to your APT sources: echo "deb [signed-by=/etc/apt/keyrings/syncthing-archive-keyring.gpg] https://apt.syncthing.net/ syncthing stable" | sudo tee /etc/apt/sources.list.d/syncthing.list
# Update and install syncthing: sudo apt-get update sudo apt-get install syncthing
Syncthing can be run as a service so that it starts automatically on boot.
syncthing
. You can enable it to start on boot.
sudo systemctl enable syncthing@<username>.service
Replace <username>
with the username of the user who will run Syncthing. For example, if your username is ubuntu
, the command would be:
sudo systemctl enable [email protected]
sudo systemctl start syncthing@<username>.service
By default, Syncthing runs on localhost
and listens on port 8384
.
References
https://apt.syncthing.net/
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY your-gui-app
pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY /opt/v2rayN/v2rayN
Tuning the Kp (proportional gain), Ki (integral gain), and Kd (derivative gain) parameters is critical for a PID controller to achieve stable and responsive control. Here’s a structured approach to tuning:
Term | Effect on System | Impact of Increasing Gain |
---|---|---|
Kp | Responds to current error (e.g., how far you are from the setpoint). | Reduces steady-state error but can overshoot. |
Ki | Eliminates steady-state error by integrating past errors over time. | Eliminates residual error but risks integral windup. |
Kd | Predicts future error based on the rate of change (slows rapid corrections). | Reduces overshoot and oscillations but amplifies noise. |
A systematic way to find PID parameters using experiments:
Controller | Kp | Ki | Kd |
---|---|---|---|
P-only | 0.5 * Ku | 0 | 0 |
PI | 0.45 * Ku | 1.2 * Kp / Pu | 0 |
PID | 0.6 * Ku | 2 * Kp / Pu | Kp * Pu / 8 |
Controller | Kp | Ki | Kd |
---|---|---|---|
PI | 0.9*T/L | 0.3*Kp/L | 0 |
PID | 1.2*T/L | 0.5*Kp/L | 0.5KpL |
OutputMin
/OutputMax
to clamp the controller’s output during tuning.scipy
) to simulate the system before real-world testing.control
library can optimize gains mathematically.Tuning is highly system-dependent. Always prioritize stability over speed, and validate gains in real-world conditions.
AsAsyncEnumerable()
for StreamingEF Core 3.0+ supports AsAsyncEnumerable()
, which streams results incrementally (similar to a cursor):
using Microsoft.EntityFrameworkCore; using System.Linq; var dbContext = new YourDbContext(); // Replace with your DbContext var query = dbContext.YourEntities.AsNoTracking().AsAsyncEnumerable(); await foreach (var entity in query) { // Process one entity at a time DateTime utcTime = entity.Time.ToUniversalTime(); long epochSeconds = (long)(utcTime - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; // ... }
For complex queries, execute raw SQL and stream results:
var sql = "SELECT * FROM your_table"; var query = dbContext.YourEntities .FromSqlRaw(sql) .AsAsyncEnumerable(); await foreach (var entity in query) { // Process entity }
ToCursor
and Process Documents IncrementallyThe MongoDB C# driver supports iterating over results with a cursor, which retrieves documents in batches from the server (default batch size is 101 documents). This avoids loading all data into memory.
using MongoDB.Driver; using MongoDB.Bson; var client = new MongoClient("mongodb://localhost:27017"); var database = client.GetDatabase("YourDatabaseName"); var collection = database.GetCollection<BsonDocument>("YourCollectionName"); // Get a cursor to iterate over the collection using (var cursor = await collection.Find(new BsonDocument()).ToCursorAsync()) { while (await cursor.MoveNextAsync()) { foreach (var document in cursor.Current) { // Process one document at a time Console.WriteLine(document); } } }
BatchSize
Explicitly control the batch size to optimize memory usage:
var filter = Builders<BsonDocument>.Filter.Empty; var options = new FindOptions<BsonDocument> { BatchSize = 1000 // Adjust batch size based on your needs }; using (var cursor = await collection.FindAsync(filter, options)) { while (await cursor.MoveNextAsync()) { var batch = cursor.Current; // Process a batch of documents foreach (var document in batch) { Console.WriteLine(document); } } }
IAsyncEnumerable
)If using C# 8 or later, you can leverage IAsyncEnumerable
for cleaner iteration:
await foreach (var document in collection.Find(new BsonDocument()).ToAsyncEnumerable()) { // Process one document at a time Console.WriteLine(document); }
DbContextTransaction
Entity Framework allows you to manage transactions using the BeginTransaction
method of the DbContext
.
using (var context = new YourDbContext()) { using (var transaction = context.Database.BeginTransaction()) { try { // Perform multiple operations var newEntity = new YourEntity { Name = "Example" }; context.YourEntities.Add(newEntity); context.SaveChanges(); var anotherEntity = new AnotherEntity { Value = "Test" }; context.AnotherEntities.Add(anotherEntity); context.SaveChanges(); // Commit transaction transaction.Commit(); } catch (Exception ex) { // Rollback transaction if there is any error transaction.Rollback(); Console.WriteLine(ex.Message); } } }
TransactionScope
You can use the TransactionScope
class for more advanced scenarios, which allows transactions across multiple DbContext
instances.
using System.Transactions; using (var scope = new TransactionScope()) { try { using (var context1 = new YourDbContext()) { // Perform operations on first DbContext var entity1 = new YourEntity { Name = "Entity1" }; context1.YourEntities.Add(entity1); context1.SaveChanges(); } using (var context2 = new AnotherDbContext()) { // Perform operations on second DbContext var entity2 = new AnotherEntity { Value = "Entity2" }; context2.AnotherEntities.Add(entity2); context2.SaveChanges(); } // Commit the transaction scope.Complete(); } catch (Exception ex) { // Transaction will be rolled back automatically if not completed Console.WriteLine(ex.Message); } }
IDbContextTransaction
In Entity Framework Core, transactions are handled using the IDbContextTransaction
interface.
using (var context = new YourDbContext()) { using (var transaction = await context.Database.BeginTransactionAsync()) { try { // Perform database operations context.YourEntities.Add(new YourEntity { Name = "Entity1" }); await context.SaveChangesAsync(); context.AnotherEntities.Add(new AnotherEntity { Value = "Entity2" }); await context.SaveChangesAsync(); // Commit transaction await transaction.CommitAsync(); } catch (Exception ex) { // Rollback transaction await transaction.RollbackAsync(); Console.WriteLine(ex.Message); } } }