Template Matching on Images using OpenCvSharp

//read image
// var refMat = new Mat("001f.png", ImreadModes.Unchanged);
// var tplMat = new Mat("001.png", ImreadModes.Unchanged);
using (Mat refMat = new Mat("001f.png", ImreadModes.Unchanged))
using (Mat tplMat = new Mat("001.png", ImreadModes.Unchanged))
using (Mat res = new Mat(refMat.Rows - tplMat.Rows + 1, refMat.Cols - tplMat.Cols + 1, MatType.CV_32FC1))
{
    //Convert input images to gray
    Mat gref = refMat.CvtColor(ColorConversionCodes.BGR2GRAY);
    Mat gtpl = tplMat.CvtColor(ColorConversionCodes.BGR2GRAY);

    Cv2.MatchTemplate(gref, gtpl, res, TemplateMatchModes.CCoeffNormed);
    Cv2.Threshold(res, res, 0.8, 1.0, ThresholdTypes.Tozero);

    while (true)
    {
        double minval, maxval, threshold = 0.8;
        Point minloc, maxloc;
        Cv2.MinMaxLoc(res, out minval, out maxval, out minloc, out maxloc);

        if (maxval >= threshold)
        {
            //draw a rectangle of the matching area
            Rect r = new Rect(new Point(maxloc.X, maxloc.Y), new Size(tplMat.Width, tplMat.Height));
            Cv2.Rectangle(refMat, r, Scalar.Red, 2);

            //debug
            String msg =
                $"MinVal={minval.ToString()} MaxVal={maxval.ToString()} MinLoc={minloc.ToString()} MaxLoc={maxloc.ToString()} Rect={r.ToString()}";
            Console.WriteLine(msg);

            //fill in the res mat so you don't find the same area again in the minmaxloc
            //Rect outRect;
            //Cv2.FloodFill(res, maxloc, new Scalar(0), out outRect, new Scalar(0.1), new Scalar(1.0), FloodFillFlags.Link4);
            Cv2.FloodFill(res, maxloc, new Scalar(0));
        }
        else
        {
            break;
        }
    }
}

 

Reset the RabbitMQ broker

In some cases, you just need to wipe everything off from your RabbitMQ server and start over. Despite being extremely stable, in some rare circumstances, you will need to completely reset RabbitMQ after encountering errors such as corrupt data, nodes permanently separated from the cluster, or an unmanageably large broker.

Recreate the virtual host from the command line

rabbitmqctl delete_vhost /
rabbitmqctl add_vhost /
rabbitmqctl set_permissions -p / monitoring ".*" ".*" ".*"

 

References
https://www.cloudamqp.com/blog/how-to-reset-the-rabbitmq-broker.html

Read Data Block of S7 300 PLC using C#

            S7Client client = new S7Client();
            int result = client.ConnectTo("192.168.0.3", 0, 2);

            if (result != 0)
            {
                Console.WriteLine(client.ErrorText(result));
            }
            else
            {
                byte[] dbBuffer = new byte[12];
                result = client.DBRead(1, 0, 12, dbBuffer);
                var var1 = S7.GetIntAt(dbBuffer, 0);
                var var2 = S7.GetRealAt(dbBuffer, 2);
                var var4 = S7.GetDWordAt(dbBuffer, 8);
                Console.WriteLine(var1);
                Console.WriteLine(var2);
                Console.WriteLine(var4);
            }

 

References
https://github.com/fbarresi/Sharp7/wiki
https://github.com/S7NetPlus/s7netplus/wiki
http://gmiru.com/article/s7comm/
https://wiki.wireshark.org/S7comm
https://plc4x.incubator.apache.org/protocols/s7/index.html

Connect Step 7 PLC-Sim to Scadas using NetToPLCsim

You should use Nettoplcsim in this way

  • restart computer
  • before starting any Siemens software, start Nettoplcsim with Admin rights, and let Nettoplcsim stop/start the Siemens service to capture the TCP port 102. Let Nettoplcsim in this state (open with no configuration)
  • start Step 7 (or TIA Portal if you want to use this), then start Plcsim and download your project
  • configure Plcsim station in Nettoplcsim, and start Nettoplcsim server

References
https://www.mesta-automation.com/nettoplcsim-how-to-connect-step-7-plc-sim-to-scadas/
http://nettoplcsim.sourceforge.net/
https://sourceforge.net/p/nettoplcsim/discussion/912717/thread/777cf7c4/?limit=25

Dependency Injection in WPF Application using Generic HostBuilder

Creating Generic HostBuilder

Nuget :

PM> Install-Package Microsoft.Extensions.Hosting -Version 3.1.2

The HostBuilder class is available from the following namespace,

using Microsoft.Extensions.Hosting;

Initialize the Host

Within Constructor of App class(file: App.xaml.cs) please add below code to build Host,

host = new HostBuilder()
           .ConfigureServices((hostContext, services) =>
           {
 
           }).Build();

DI Container

host = new HostBuilder()
          .ConfigureServices((hostContext, services) =>
          {
              //Add business services as needed
              services.AddScoped<IEmployeeViewModel, EmployeeViewModel>();
 
              //Lets Create single tone instance of Master windows
              services.AddSingleton<EmployeeWindow>();
 
          }).Build();

Setting up OnStartup and OnExit Application events

private void OnStartup(object sender, StartupEventArgs e)
        {
            var mainWindow = host.Services.GetService<EmployeeWindow>();
            mainWindow.Show();
        }
protected override async void OnExit(ExitEventArgs e)
       {
           using (host)
           {
               await host.StopAsync();
           }
 
           base.OnExit(e);
       }

App.XAML file used as below,

<Application x:Class="WPFDesktopApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Startup="OnStartup">
    <Application.Resources>
         
    </Application.Resources>
</Application>

References
https://www.thecodebuzz.com/dependency-injection-wpf-generic-hostbuilder-net-core/
https://laurentkempe.com/2019/09/03/WPF-and-dotnet-Generic-Host-with-dotnet-Core-3-0/