How to prevent redmine always logging out

In Redmine, by default you are always logged out after a very short period of time.

You can fix this by logging in as an administrator and opening Administration -> Settings -> Authentication and setting Autologin to 365 days. You can also choose a lower value if you want sessions to automatically expire sooner.

Posted by Uli Köhler in Allgemein

How to fix MikroTik RouterOS v7 SSH port forwarding not working: Connection refused

In multiple models of MikroTik routers running RouterOS v7.5 I got Error: Connection refused when running simple SSH port forwarding commands such as

ssh [email protected] -L 8080:192.168.178.1:80

but in the RouterLS log I could see multiple local forwarding forbidden error messages:

Solution

In this case, the solution was simple: Go to IP -> SSH in WebFig or Winbox and set Forwarding Enabled to Both and click Apply.

If you have already set Forwarding Enabled to Both or Localon one of my routers this setting wasn’t properly activated – possibly after a RoutreOS upgrade. In order to fix this, set Forwarding Enabled to no, click Apply, then  set Forwarding Enabled to Both and click Apply again. For me, this fixed the issue of being unable to do SSH port forwarding.

Posted by Uli Köhler in MikroTik, Networking

How to print fingerprints of all SSH host keys

In oder to print new-style (SHA256) fingerprints such as Is7oLjYcKue/zRjPKy9gQma/9F24KGaMPHbGberPGAw, use

for i in /etc/ssh/ssh_host_*_key; do sudo ssh-keygen -l -E sha256 -f "$i"; done

Example output:

1024 SHA256:SAhM78NWwqoYS/nRByGs1oqJxrX8fZL/PR/F5oX3QWs root@myserver (DSA)
256 SHA256:V/+9872Yg1i2Q4i7Nt4ef5R06lAuzT6qKemaQEt8EJQ root@myserver (ECDSA)
256 SHA256:Is7oLjYcKue/zRjPKy9gQma/9F24KGaMPHbGberPGAw root@myserver (ED25519)
2048 SHA256:AORSBitRPpwXrbTQzP0Mb/OBXyK+V6gyWf0S4bIh7Ys root@myserver (RSA)

In order to print old-style (MD5) fingerprints such as 5c:19:8b:94:44:5e:b6:15:e6:32:cc:3c:9b:38:6b:4c, use this command:

for i in /etc/ssh/ssh_host_*_key; do sudo ssh-keygen -l -E md5 -f "$i"; done

Example output:

1024 MD5:6d:f8:17:9b:4a:f5:ec:14:04:68:22:9c:ca:2c:a1:19 root@myserver (DSA)
256 MD5:5c:19:8b:94:44:5e:b6:15:e6:32:cc:3c:9b:38:6b:4c root@myserver (ECDSA)
256 MD5:45:dd:7f:91:89:67:ab:2d:ee:a2:f8:9e:18:68:5b:0d root@myserver (ED25519)
2048 MD5:1b:b2:54:3a:10:51:17:b4:49:af:73:c2:da:d6:fc:df root@myserver (RSA)
Posted by Uli Köhler in Linux

TechOverflow: 2000 posts and counting

Not even two years after the 1000th blogpost, this is TechOverflow’s 2001th blog post – and certainly not the last one.

It took 8 years to reach 1000 posts and 7500 visitors a day – and not even two more years to reach up to 13200 visitors in one day (typical work days have around 12.5k visitors), with an upwards trend:

Posted by Uli Köhler in TechOverflow

How to fix Ubuntu PHP Uncaught Error: Call to undefined function simplexml_load_file()

Problem:

Your wordpress page or other PHP application displays a critical error, with the following message:

2022/09/17 04:11:49 [error] 98082#98082: *1053 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function simplexml_load_file() in /var/sites/mysite.com/wp-content/plugins/otgs-installer-plugin/vendor/otgs/installer/includes/class-wp-installer.php:870

Solution:

Install the php[VERSION]-xml package for the PHP version that is running wordpress.

For example:

sudo apt -y install php8.1-xml
Posted by Uli Köhler in Linux

How to fix Ubuntu PHP error: Your PHP installation appears to be missing the MySQL extension which is required by WordPress.

Problem:

When loading your wordpress page, you see the following message:

Your PHP installation appears to be missing the MySQL extension which is required by WordPress.

Solution:

Install the php[VERSION]-mysql package for the PHP version that is running wordpress.

For example:

sudo apt -y install php8.1-mysql

 

Posted by Uli Köhler in Linux

Density of V4A (AISI 316/316L)

According to theworldmaterial.com the density of V4A stainless steel is approximately 8000 kg/m³ or 8.0 g/cm³

Posted by Uli Köhler in Physics

How to install ZeroTier client on Raspberry Pi (Raspbian) in just 20 seconds

Run this command to install the ZeroTier client on Rasbian. You can use the same command to install ZeroTier on virtually any Linux platform.

curl -s https://install.zerotier.com | sudo bash

Source: ZeroTier installation website

Posted by Uli Köhler in Networking, ZeroTier

How to Serial.println() a std::string

In Arduino, if you have a std::string:

std::string str = "test";

you can’t directly print it – trying to do so leads to the following error messages:

src/main.cpp: In function 'void setup()':
src/main.cpp:122:22: error: no matching function for call to 'HardwareSerial::println(std::__cxx11::string&)'
   Serial.println(cert);
                      ^
In file included from /home/uli/.platformio/packages/framework-arduinoespressif32@src-76bf6cf11a70195daa934985b7bd68e2/cores/esp32/Stream.h:26,
                 from /home/uli/.platformio/packages/framework-arduinoespressif32@src-76bf6cf11a70195daa934985b7bd68e2/cores/esp32/Arduino.h:166,
                 from src/main.cpp:1:
/home/uli/.platformio/packages/framework-arduinoespressif32@src-76bf6cf11a70195daa934985b7bd68e2/cores/esp32/Print.h:96:12: note: candidate: 'size_t Print::println(const __FlashStringHelper*)'
     size_t println(const __FlashStringHelper *);
            ^~~~~~~
/home/uli/.platformio/packages/framework-arduinoespressif32@src-76bf6cf11a70195daa934985b7bd68e2/cores/esp32/Print.h:96:12: note:   no known conversion for argument 1 from 'std::__cxx11::string' {aka 'std::__cxx11::basic_string<char>'} to 'const __FlashStringHelper*'
/home/uli/.platformio/packages/framework-arduinoespressif32@src-76bf6cf11a70195daa934985b7bd68e2/cores/esp32/Print.h:97:12: note: candidate: 'size_t Print::println(const String&)'
     size_t println(const String &s);

 

Solution:

You can use .c_str() to convert it to a NUL-terminated char* which can be printed directly:

Serial.println(str.c_str());

 

Posted by Uli Köhler in Arduino, C/C++, Embedded

How to convert Arduino String to std::string

If you have an Arduino String:

String arduinoStr = "test123";

you can easily convert it to a std::string by using:

std::string stdStr(arduinoStr.c_str(), arduinoStr.length());

The std::string constructor will copy the data, therefore you can de-allocate the Arduino String instance safely.

Posted by Uli Köhler in Arduino, C/C++

Should you use SPIFFS oder LittleFS?

For new projects, you should exclusively use LittleFS, period.

The only reason why you would you SPIFFS at all if you have data stored on SPIFFS and can’t easily migrate to LittleFS.

LittleFS is just better than SPIFFS in every regard and SPIFFS will at some point in time be deprecated anyways.

Posted by Uli Köhler in Embedded, ESP8266/ESP32, PlatformIO

How to get filesize in LittleFS (ESP32/PlatformIO)

After you have initialized LittleFS (see ESP32 Filesystem initialization code example (LittleFS)) you can get the filesize by first opening the file, and then calling .size() on the opened file. Don’t forget to close the file afterwards.

auto file = LittleFS.open(filename, "r");
size_t filesize = file.size();
// Don't forget to clean up!
file.close();

Utility function to get the size of a file stored on LittleFS:

size_t LittleFSFilesize(const char* filename) {
  auto file = LittleFS.open(filename, "r");
  size_t filesize = file.size();
  // Don't forget to clean up!
  file.close();
  return filesize;
}

Example usage:

Serial.println(LittleFSFilesize("/cert.pem"));

 

Posted by Uli Köhler in C/C++, ESP8266/ESP32, PlatformIO

How to fix ESP32 PlatformIO esp_https_server.h: No such file or directory

Problem:

When compiling your PlatformIO project, you see a compiler error like

src/main.cpp:6:10: fatal error: esp_https_server.h: No such file or directory

at the following line:

#include <esp_https_server.h>

Solution:

The ESP32 HTTPS server library is not included with the older versions of arduino-espressif32. The solution therefore is to use a more recent version of the platform library such as version 2.0.4. In order to do that, add the following line to your platformio.ini:

platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.4

Complete platformio.ini example:

[env:esp32dev]
platform = espressif32
platform_packages = framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.4
board = esp32dev
framework = arduino
monitor_speed = 115200

 

Posted by Uli Köhler in Embedded, ESP8266/ESP32, PlatformIO

How to import certificate and private key (.pem) in MikroTik RouterOS

In RouterOS, you can simply import .pem files using /certificate import no matter if the file contains a certificate and/or a private key.

First, upload them either via WebFig (Files) or via SCP to the filesystem of the Router.

We will assume the certificate is called cert.pem while the private key is called privkey.pem

After that, import the certificate and the private key, one after another:

/certificate/import file-name="cert.pem" passphrase="" name="mikrotik.mydomain.net"
/certificate/import file-name="privkey.pem" passphrase="" name="mikrotik.mydomain.net"

This will tell you that first the certificate and then the private key have been successfully imported:

[admin@MyRouter] > /certificate/import file-name=cert.pem passphrase="" name="mikrotik.mydomain.com"
     certificates-imported: 1
     private-keys-imported: 0
            files-imported: 1
       decryption-failures: 0
  keys-with-no-certificate: 0

[admin@MyRouter] > /certificate/import file-name=privkey.pem passphrase="" name="mikrotik.mydomain.com"
     certificates-imported: 0
     private-keys-imported: 1
            files-imported: 1
       decryption-failures: 0
  keys-with-no-certificate: 0

 

Posted by Uli Köhler in MikroTik, Networking

bash cat EOF to file minimal example

This is an example of using a Here document (Heredoc) in bash to write an inline string to a file.

cat <<EOF >/etc/dhcp/dhcpd.conf
authoritative;
default-lease-time 86400;
max-lease-time 86400;

subnet 192.168.99.0 netmask 255.255.255.0 {
  range 192.168.99.100 192.168.99.150;
  option routers 192.168.99.1;
  option domain-name-servers 192.168.99.1;
  option domain-name "local";
}
EOF

 

Posted by Uli Köhler in Linux

How to set static IP address on ESP32

TL;DR

Before you call WiFi.begin(...), call this:

if (!WiFi.config(
      IPAddress(192, 168, 19, 5), // ESP's IP address
      IPAddress(192, 168, 19, 1), // Gateway
      IPAddress(255, 255, 255, 0), // IP Address
      IPAddress(192, 168, 19, 1) // DNS server
    )) {
  Serial.println("Failed to set static IP");
}

and replace the IP address etc with the static

Full example

This is based on our previous post on How to fix ESP32 not connecting to the Wifi network:

#include <Arduino.h>
#include <WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.begin("MyWifiSSID", "MyWifiPassword");

  // Set static IP
  if (!WiFi.config(
        IPAddress(192, 168, 19, 5), // ESP's IP address
        IPAddress(192, 168, 19, 2), // Gateway
        IPAddress(255, 255, 255, 0), // IP Address
        IPAddress(192, 168, 19, 1) // DNS server
      )) {
    Serial.println("Failed to set static IP");
  }

  // Wait for wifi to be connected
  uint32_t notConnectedCounter = 0;
  while (WiFi.status() != WL_CONNECTED) {
      delay(100);
      Serial.println("Wifi connecting...");
      notConnectedCounter++;
      if(notConnectedCounter > 150) { // Reset board if not connected after 5s
          Serial.println("Resetting due to Wifi not connecting...");
          ESP.restart();
      }
  }
  Serial.print("Wifi connected, IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
  // put your main code here, to run repeatedly:
}

 

Posted by Uli Köhler in Embedded, ESP8266/ESP32, Networking

How to get current task handle in FreeRTOS

Simply use xTaskGetCurrentTaskHandle()

#include <freertos/FreeRTOS.h>
#include <freertos/task.h>

TaskHandle_t myTaskHandle = xTaskGetCurrentTaskHandle();

 

Posted by Uli Köhler in Embedded, FreeRTOS

How to fix GCC elaborated-type-specifier for a scoped enum must not use the ‘class’ keyword

Problem:

In C++, you are declaring an enum class like this:

enum class Shape : uint8_t {
    Circle = 0,
    Square = 1
};

but when you try to compile the project, you see an error message like

include/Shape.hpp:4:6: warning: elaborated-type-specifier for a scoped enum must not use the 'class' keyword
 enum class Shape : uint8_t {
 ~~~~ ^~~~~
      -----

Solution:

The issue here is that you are deriving the enum class from another type –  uint8_t in this example –  but that type has not been declared.

So the solution is to #include the header where the type from which the enum class is inherited.

In our example – for the type uint8_t and for many other integral types such as int32_t , you can do that by adding

#include <cstdint>

before the enum class declaration.

Posted by Uli Köhler in C/C++, GCC errors

Python Lock / Mutex minimal example (threading.Lock)

This minimal example creates a threading.Lock and locks it using a with statement. This is the simplest way of using a Lock.

from threading import Lock

lock = Lock()

with lock:
    print("Holding the lock!")

 

Posted by Uli Köhler in Python

How to generate filename with date & time in Python

When storing real-time data from a Python script, it is often helpful to have a timestamp consisting of both date & time in your filename, such as

mydata-2022-09-02_00-31-50-613015.csv

With this specific syntax we avoid special characters which are an issue on Windows operating systems, and we provide a lexically sortable filename

In Python you can do that using UliEngineering.Utils.generate_datetime_filename() from the UliEngineering library.

First, install the UliEngineering library using

pip install UliEngineering

Now you can generate your filename using

from UliEngineering.Utils.Date import *

filename = generate_datetime_filename()
# example: filename == 'data-2022-09-02_03-02-00-045587.csv'

or you can just open the file using with open():

with open(generate_datetime_filename(), "w") as outfile:
    # Example of what you can do with outfile
    outfile.write("test")

Without using UliEngineering

You can use this simplified version which does not support fractional seconds and will generate filenames like

data-2022-09-02_00-31-50.csv

Source code (simple version – the UliEngineering version is more robust and supports more features):

from datetime import datetime

def generate_datetime_filename(label="data", extension="csv", dt=None):
    if dt is None:
        dt = datetime.now()
    return f"{label}-{dt.year}-{dt.month:02d}-{dt.day:02d}_{dt.hour:02d}-{dt.minute:02d}-{dt.second:02d}.{extension}"
Posted by Uli Köhler in Python
This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Cookie settingsACCEPTPrivacy &amp; Cookies Policy