The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

Archive for December, 2021

Some ESXi 7.x notes

Posted by jpluimers on 2021/12/16

Yes, I know this is late in the game, but I’m still catching up with some of the things after from autumn 2019 to spring 2021 spending most of my time on rectum cancer treatment and other core things.

So here are some links on ESXi 7.x so I know what to expect to upgrade existing ESXi 6.x installations and get some new ones up. This will hopefully make some software development easier too, as I plan to have a build-rig some day.

But first of all a surprise for me:

ESXi 7 on ARM

I had not expected ESXi 7 to be available on ARM in 2020 yet, but it’s there and certified to run on Raspberry Pi 4. So here are some links:

ESXi 7 on x64

The bulk of the links:

–jeroen

Read the rest of this entry »

Posted in ESXi6, ESXi6.5, ESXi6.7, Power User, Virtualization, VMware, VMware ESXi | Leave a Comment »

Always develop and test your application on multi-core machines

Posted by jpluimers on 2021/12/15

It’s an advice from a very long time ago, but wort to repeat every 20 years or so.

Develop and test your code on multi-threaded machines, not in single threaded VMs.

[Archive.is] Jeroen Wiert Pluimers on Twitter: “This sounds like @danny_thorpe on a BorCon some 20 years ago in the Windows XP era. Thread slices going down from ~10 millisecond to CPU instruction execution magnitude highly increases the chance of race conditions.… “

–jeroen

Read the rest of this entry »

Posted in Development, Software Development | Leave a Comment »

Easiest way to move the C:\MSOCache directory to another drive is to create symbolic link to the new location

Posted by jpluimers on 2021/12/15

I always forget that, when moving a folder, instead of finding all references to that folder and fixing them, you can create an NTFS symlink from the old location to the new one.

[Wayback] how to move MSOCACHE folder from C-drive to D-drive ?? – Microsoft Community (thanks [Wayback] tgunda numbering and casing updates mine):

There are too much entries in the registry to correct them manually one by one.

An easier and quicker solution is to copy the full MSOCache folder to a new place and to make a soft link to it:
  1. Create a new folder, e.g. F:\MSOCache
  2. Copy everything from C:\MSOCache to the new one.
  3. Rename the old folder  C:\xMSOCache  (Don’t delete it, just in case).
  4. Open a command prompt window in administrator mode.
  5. Write:  mklink /d c:\MSOCache f:\MSOCache
Now there is an MSOCache link at C, pointing to the new place.
If everything is OK, you can delete  C:\xMSOCache

This can be very handy when moving around large software development installations, circumventing a full uninstall/install sequence loosing lots of configuration settings.

–jeroen

Posted in Development, LifeHacker, Office, Power User, Software Development, Windows, Windows Development | Leave a Comment »

Operame: Dutch open source CO2 sensor device for indoor usage: shows green/yellow/red for good/okay/bad CO2 ppm levels

Posted by jpluimers on 2021/12/15

Since all information is in Dutch, I keep only the title and this short explanation in English.

[Archive.is] Sebastian Oort on Twitter: “Gaat jouw school binnenkort weer open? Wil je jouw klas veiliger maken? Hang een CO2 sensor op. Ze zijn weer op voorraad bij OperameNL ! We hebben nog ruim 100 stuks op voorraad en maandag komen de volgende 250 binnen! @OperameNL van @revspacenl… “

 

Read the rest of this entry »

Posted in Development, ESP32, Hardware Development, Hardware Interfacing, IKEA hacks, LifeHacker, Power User, Software Development | Leave a Comment »

Delphi: workaround doing math with generic types preventing “E2015 Operator not applicable to this operand type” with TValue (as there is no way to constraint the generic type to be floating point or ordinal)

Posted by jpluimers on 2021/12/14

A while ago on Facebook (it’s a private group, so you cannot see the posts unless you both have a Facebook account and are member of the group), [Archive.is] Niels Tjørnhøj-Thomsen (coming from a C++ templates background) asked why the below method would throw a E2015 Operator not applicable to this operand type in the complex expression:

function TAxis<t>.Calc(const AScalar: T): single;
begin
  Result := fStart + ( ( ( AScalar - fMin ) / fRange ) * fExtent );
end;

The type itself was very simple:

TAxis<T> = record
  fMin, fMax, fRange: T;
  fStart, fEnd, fExtent: single;
  function Calc( const AScalar: T ): single;
end;

He used these small example specialisations that put me on the wrong foot, as the order was TDateTime followed by single:

var
  rXAxis: TAxis<TDateTime>;
  rYAxis: TAxis<single>;

So at first I thought this might be caused by TDateTime to be defined in the System unit as a typed type:

type
  TDateTime = type Double;

It wasn’t.

Splitting the code in 4 lines with assignments of single expression operations would make the error appear in all expressions.

Casting parts of the expression to simple would not help either.

A small test program [Archive.is] might put you, like me, on the wrong foot because the specialisation is in the same source file as the generic type:

program DelphiMathAndGenerics;

type
  TAxis<T> = record
    fMin, fMax, fRange: T;
    fStart, fEnd, fExtent: single;
    function CalcCasted( const AScalar: T ): single;
    function CalcPlain( const AScalar: T ): single;
  end;

function TAxis<T>.CalcCasted(const AScalar: T): single;
var
  Offset: single;
  NormalisedOffset: single;
  ScaledOffset: single;
begin
  // First 2 lines give the same error: E2089 Invalid typecast
  Offset := single(AScalar) - fMin;
  NormalisedOffset := Offset / single(fRange);
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

function TAxis<T>.CalcPlain(const AScalar: T): single;
var
  Offset: T;
  NormalisedOffset: T;
  ScaledOffset: T;
begin
  // All 4 lines give the same error: E2015 Operator not applicable to this operand type
  Offset := AScalar - fMin;
  NormalisedOffset := Offset / fRange;
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

var
  rXAxis: TAxis<TDateTime>;
  rYAxis: TAxis<single>;

begin
end.

Splitting this in two files [Archive.is], a AxisUnit unit having only the TAxis<T> type, and a main program (even without having the specialisations) shows that even the unit itself would not compile.

This shows a major difference between Delphi (and similar C#) generics and C++ templates:

  • generics are compiled and fully verified at the generic stage
  • templates are pre-processed, then finally verified at specialisation stage

A solution would be that Delphi could constraint the generic type T into something like float or ordinal so the compiler would know that more operators are allowed in the code. But alas, Delphi – like C# – has a very limited number of constraints (C# only would allow a constraint for enumerations in version 7.3): Delphi Constraints in Generics – RAD Studio XE documentation wiki.

This StackOverflow question is very similar, and has the same answer (generics in Delphi work differently than templates in C++): [Source] templates – Arithmetic operations with generic types in Delphi – Stack Overflow

I’m new in Delphi. For a project required by my company, I need to translate some code from our existing C++ classes to Delphi. Some of these classes are templates, such …

Workaround: use the TValue.From<T>() function

There is a workaround though, but it is slow, as you need to convert from the generic T type to the actual (in this case floating point) type you can apply the operators on.

This is possible with the (Delphi 2010 introduced) TValue.From<T>() method which returns a TValue record. That TValue record has instance methods like AsExtended to extract or convert the embedded value as a specific type.

Initially, [Wayback] Delphi 2010 Rtti.TValue documentation had the From method signature wrong, maybe because of many wiki and blog HTML editors kill angle bracket pairs < and > in code blocks:

function From(const Value: T): TValue; static;

Since the [Wayback] Delphi XE System.Rtti.TValue documentation, the From method signature is fixed (see the bold parts):

class function From<T>(const Value: T): TValue; static;

With the [Wayback] Delphi XE2 Rtti.TValue documentation, the unit got renamed from Rtti into System.Rtti and has not changed further.

When using TValue.From<T>(), the AxisUnit becomes this:

unit AxisUnit;

interface

type
  TAxis<T> = record
    fMin, fMax, fRange: T;
    fStart, fEnd, fExtent: single;
    function Calc( const AScalar: T ): single;
  strict private
    function AsSingle(const Value: T): single;
  end;

implementation

uses
  System.Rtti;

function TAxis<T>.AsSingle(const Value: T): single;
begin
  Result := TValue.From<T>(Value).AsExtended
end;

function TAxis<T>.Calc(const AScalar: T): single;
var
  Offset: single;
  NormalisedOffset: single;
  ScaledOffset: single;
begin
  Offset := AsSingle(AScalar) - AsSingle(fMin);
  NormalisedOffset := Offset / AsSingle(fRange);
  ScaledOffset := NormalisedOffset * fExtent;
  Result := fStart + ScaledOffset;
end;

end.

–jeroen

Read the rest of this entry »

Posted in .NET, C#, Conference Topics, Conferences, Delphi, Development, Event, Software Development | Leave a Comment »

Locations and IPs for whitelisting | UptimeRobot

Posted by jpluimers on 2021/12/14

A page with IPv4 and IPv6 network blocks and addresses [Wayback] Locations and IPs for whitelisting | UptimeRobot:

If you need to whitelist these IPs so that any requests that Uptime Robot send are not blocked.

Or in [Wayback] text form (with Wayback history):

216.144.250.150
69.162.124.226
69.162.124.227
69.162.124.228
69.162.124.229
69.162.124.230
69.162.124.231
69.162.124.232
69.162.124.233
69.162.124.234
69.162.124.235
69.162.124.236
69.162.124.237
63.143.42.242
63.143.42.243
63.143.42.244
63.143.42.245
63.143.42.246
63.143.42.247
63.143.42.248
63.143.42.249
63.143.42.250
63.143.42.251
63.143.42.252
63.143.42.253
216.245.221.82
216.245.221.83
216.245.221.84
216.245.221.85
216.245.221.86
216.245.221.87
216.245.221.88
216.245.221.89
216.245.221.90
216.245.221.91
216.245.221.92
216.245.221.93
208.115.199.18
208.115.199.19
208.115.199.20
208.115.199.21
208.115.199.22
208.115.199.23
208.115.199.24
208.115.199.25
208.115.199.26
208.115.199.27
208.115.199.28
208.115.199.29
208.115.199.30
208.115.199.30
46.137.190.132
122.248.234.23
188.226.183.141
178.62.52.237
54.79.28.129
54.94.142.218
104.131.107.63
54.67.10.127
54.64.67.106
159.203.30.41
46.101.250.135
18.221.56.27
52.60.129.180
159.89.8.111
146.185.143.14
139.59.173.249
165.227.83.148
128.199.195.156
138.197.150.151
34.233.66.117
2607:ff68:107::3
2607:ff68:107::4
2607:ff68:107::5
2607:ff68:107::6
2607:ff68:107::7
2607:ff68:107::8
2607:ff68:107::9
2607:ff68:107::10
2607:ff68:107::11
2607:ff68:107::12
2607:ff68:107::13
2607:ff68:107::14
2607:ff68:107::15
2607:ff68:107::16
2607:ff68:107::17
2607:ff68:107::18
2607:ff68:107::19
2607:ff68:107::20
2607:ff68:107::21
2607:ff68:107::22
2607:ff68:107::23
2607:ff68:107::24
2607:ff68:107::25
2607:ff68:107::26
2607:ff68:107::27
2607:ff68:107::28
2607:ff68:107::29
2607:ff68:107::30
2607:ff68:107::31
2607:ff68:107::32
2607:ff68:107::33
2607:ff68:107::34
2607:ff68:107::35
2607:ff68:107::36
2607:ff68:107::37
2607:ff68:107::38
2607:ff68:107::39
2607:ff68:107::40
2607:ff68:107::41
2607:ff68:107::42
2607:ff68:107::43
2607:ff68:107::44
2607:ff68:107::45
2607:ff68:107::46
2607:ff68:107::47
2607:ff68:107::48
2607:ff68:107::49
2607:ff68:107::50
2607:ff68:107::51
2607:ff68:107::52
2607:ff68:107::53
2607:ff68:107::54
2607:ff68:107::55
2a03:b0c0:0:1010::832:1
2a03:b0c0:1:d0::e54:a001
2604:a880:800:10::4e6:f001
2604:a880:cad:d0::122:7001
2a03:b0c0:3:d0::33e:4001
2600:1f16:775:3a01:70d6:601a:1eb5:dbb9
2600:1f11:56a:9000:23:651b:dac0:9be4
2a03:b0c0:3:d0::44:f001
2a03:b0c0:0:1010::2b:b001
2a03:b0c0:1:d0::22:5001
2604:a880:400:d0::4f:3001
2400:6180:0:d0::16:d001
2604:a880:cad:d0::18:f001
2600:1f18:179:f900:88b2:b3d:e487:e2f4

–jeroen

Posted in Development, LifeHacker, Power User, Web Development | Leave a Comment »

SVB PGB and DigiD security suddenly logged you out every 15 minutes despite the count down counter indicating otherwise.

Posted by jpluimers on 2021/12/14

From a while back, so I hope it has been fixed by now on the SVB PGB site.

The Dutch SVB (sociale verzekeringsbank, the [WayBack] organisation that implements social security schemes in The Netherlands) has a web-site to submit declarations for PGB ([Wayback] individualised subsidy for care, or personal care budget).

Authentication for the site goes through DigiD, the identity provider through which government related web-sites can verify the identity of Dutch residents on the internet.

In from somewhere in the mid 2010s until somewhere in 2020, the SVB PGB site would log you out when the 15-minute inactivity count-down in the lower right of the screen would reach zero.

After that, the behaviour changed: you would be logged out 15 minutes after logon, forcing one to login way more often. Each logoff/logon cycle had these effets:

  1. loosing the data you entered on the current page
  2. a cost to SVB of about EUR 0.15 excluding VAT for the logon
  3. loss of time and convenience for the end-user

Note that due to site stability reasons in the years before, I already printed each web-page to PDF before submitting, as there was no way to use the “back” button to see what information you had entered.

That way at least I had the information at hand when re-entering the same information. It also provided me of a “paper” trail of site navigation and entered data.

That’s why I reported it early March 2021:

Read the rest of this entry »

Posted in Authentication, Development, DigiD, Power User, Security, Software Development, Web Development | Leave a Comment »

Getting the primary IP address (plain and CIDR) on Linux and OS X, then nmap scan on the associated subnet

Posted by jpluimers on 2021/12/13

The below answer works on my Linux and OS X systems (each having multiple network adapters configured):

[WayBack] bash – How to get the primary IP address of the local machine on Linux and OS X? – Stack Overflow

ip route get 1 | awk '{print $NF;exit}'

For Linux, I have this bash function:

# note the ";exit" lists the first default route interface, as there can be multiple
function nmap-fingerprint_network_of_default_interface() {
        default_if=$(ip route list | awk '/^default/ {print $5;exit}')
        default_if_cidr=$(ip -o -f inet addr show $default_if | awk '{print $4}')
        nmap -sP $default_if_cidr
}

And for OS X this one:

# requires ipcalc
function nmap-fingerprint_network_of_default_interface() {
        default_if=$(route -q -n get default | awk '/interface:/ {print $2;exit}')
        default_if_address=$(ifconfig $default_if | awk '/inet / {print $2;exit}')
        default_if_netmask_hex=$(ifconfig $default_if | awk '/inet / {print $4;exit}')
        default_if_network_bit_count=$(ipcalc --nocolor --class $default_if_address $default_if_netmask_hex)
        default_if_cidr=$(echo "$default_if_address/$default_if_network_bit_count")
        nmap -sP $default_if_cidr
}

These are the variables used:

  • default_if: network interface of the default route
  • default_if_cidr: IPv4 CIDR of the network interface of the default route (see Classless Inter-Domain Routing: CIDR notation – Wikipedia)
  • default_if_address: IPv4 address of network interface of the default route
  • default_if_netmask_hex: hexadecimal IPv4 network mask of network interface of the default route
  • default_if_network_bit_count: number of set bits in the IPv4 network mask of the network interface of the default route

Links used to get the above functions:

I might have gotten away with a pure bash solution (see [WayBack] Bash script for calculating network and broadcast addresses from ip and netmask or CIDR Notation · GitHub or my post Getting your local IPv4 addresses, netmasks and CIDRs), but the above works and is way shorter, and easier to maintain.

In stead of ipcalc, subnetcalc can do the same calculations and also supports IPv6, so that is something for a future try:

–jeroen

Posted in *nix, *nix-tools, Apple, bash, Color (software development), Development, Mac, Mac OS X / OS X / MacOS, Power User, Scripting, Software Development | Leave a Comment »

Reset MikroTik through LCD TouchScreen when reset button procedure fails

Posted by jpluimers on 2021/12/13

I wanted access to a supposedly reset a MikroTik [WayBack] MikroTik CRS109-8G-1S-2HnD-IN, but the default credentials did not work. Somehow, keeping the reset button pushed for almost 20 seconds also did not reset+reboot it.

Luckily, the default PIN code was still 1234 ([WayBack] Manual:LCD TouchScreen: PIN code – MikroTik Wiki) so I could reset it ([WayBack] Manual:LCD TouchScreen: Reboot and Reset Configuration – MikroTik Wiki).

After this, I changed credentials and PIN, documented configuration and credentials, and ensured there is a back-up of that documentation available.

Note: fiddling with power and reset button might have worked, though it is odd the CRS109 documentation does not mention this. PIN code worked faster, so that’s what solved my issue first.

Related:

–jeroen

Posted in Hardware, Internet, MikroTik, Network-and-equipment, Power User, routers | Leave a Comment »

Rabobank webcare phone contact: +31887226767

Posted by jpluimers on 2021/12/13

In case something you want to arrange in the on-line Rabobank portal fails, you can call their web-care team:

[Archive.is] Rabobank on Twitter: “Hi Jeroen, jammer dat het online niet lukt. Ik adviseer om te bellen met mijn collega’s op 088 722 67 67. Fijne dag 🍀 ^Liesbeth… “

In my case as custodian, it was impossible to on-line change the bank statements from paper to digital, even after following [WayBack] Wijzigen of stoppen ontvangst rekeningafschriften – Rabobank.

The on-line team changed it for me in a matter of minutes.

–jeroen

Read the rest of this entry »

Posted in LifeHacker, Power User | Leave a Comment »