Hexa's Blog

Creality K1 Max - User Configuration for Filament

13/09/2024 @ Saigon 3D Print

NOTE: Due to Creality Print bug, filament configuration gonna be missed after software restarts.

a. Filament

  • Filament > Pressure Advance: 0.2
  • Filament > Flow Ratio: 1
  • Filament > Print Temperature > Nozzle > First Layer: 230
  • Filament > Print Temperature > Nozzle > Other Layer: 230
  • Filament > Max volumetric speed: 27

b. Setting Override

  • Setting Override > Retraction > Length: 0.5
  • Setting Override > Retraction > Z hop type: Spiral
  • Setting Override > Retraction > Retraction Speed: 18

There are more settings gonna be reset but not important that much!

I. Filament

[1] Filament #1
[1] Filament #1
[2] Filament #2
[2] Filament #2
[3] Filament #3
[3] Filament #3
[4] Filament #4
[4] Filament #4
[5] Filament #5
[5] Filament #5

II. Cools

[6] Cool #1
[6] Cool #1
[7] Cool #2
[7] Cool #2
[8] Cool #3
[8] Cool #3

III. Setting Overrides

[9]  Setting Overrides #1
[9] Setting Overrides #1
[10] Setting Overrides #2
[10] Setting Overrides #2

IV. Advanced

[11] Advanced settings
[11] Advanced settings

V. Multimaterial

[12] Multimaterial #1
[12] Multimaterial #1
[13] Multimaterial #2
[13] Multimaterial #2

Doanh thu đầu tiên với máy in 3D

15/08/2024 @ Saigon Projects

Xin chào, bây giờ là tháng 8, vậy là đã 6 tháng từ khi tôi nghỉ khỏi công ty cũ TTEK (29/2/2024). Áp lực công việc là quá lớn, sức khỏe và cụ thể là cột sống của tôi không thể chịu đựng nổi, tôi hoàn toàn không có giải pháp nào ngoài trừ phải nghỉ việc.

Trong khoảng thời gian nghỉ việc, tôi hoàn toàn không có xin được trợ cấp thất nghiệp do giấy tờ gặp trục trặc. 3 tháng để làm giấy tờ có vẻ là quá ít với tôi.

  • Có 2 sổ bảo hiểm xã hội thay vì một sổ.
  • Thiếu tờ rời trong cuốn bảo hiểm xã hội.

Trong quá trình làm việc tại TTEK, tôi có tìm hiểu và tự học về thiết kế, cũng như là in 3D. Cảm ơn anh Tiến Minh RMIT đã bán cho em Creality Ender 3 Pro.

Ở thời điểm thất nghiệp hiện tại, may mắn làm sao, lại có người cần tôi đúng mảng này. Rất cảm ơn anh Dũng đã ủng hộ và hỗ trợ khoảng thời gian qua.

Mặt hàng tôi thiết kế là ống dẫn khí cho ASIC dòng KS0/KS0 Ultra. Với sản phẩm này, ASIC sẽ chạy mát hơn, bên cạnh đó cho phép việc mod firmware để chạy nhanh hơn. Một cái ống dẫn khí tôi bán với mức giá là 150,000 VND, ngay sau khi ra thiết kế, và tinh chỉnh. Khách hàng đã đặt ngay 10 chiếc và hứa hẹn có những đơn hàng sau.

Tôi thực sự rất vui khi mình đã có thể tự kiếm tiền mà không cần nhờ đến công ty, hay một đơn vị chủ quản. Tất nhiên là không thể nào nhiều bằng làm cho công ty TTEK được.

Dưới đây là mẫu tôi đã làm.

[1] Sản phẩm ống thoát khí
[1] Sản phẩm ống thoát khí

Còn đây là hình ảnh khách hàng đầu tiên, anh Dũng.

[2] Khách hàng đầu tiên
[2] Khách hàng đầu tiên

Cuối cùng, đây là hóa đơn VAT cho khách hàng.

[3] Hóa đơn VAT
[3] Hóa đơn VAT

Nếu mà bạn thắc mắc tên công ty tại sao lại là Nguyễn Hoàng, thì đó là hai chữ đầu tiên của tên ông ngoại tôi - Nguyễn Hoàng Nhu.

Google Search Console - Sitemap Indexing Error!

15/08/2024 @ Saigon etc

Today, I have seen a very weird error while using Google Search Console to index my sitemap. After I submit my sitemap https://hexalink.xyz/sitemap.xml. it always shows error: Couldn't fetch. I think you can try it yourself with my sitemap.

This error is super tricky and it took me a whole night to debug. At first, let look at our usecase.

There are two identical file named: sitemap.xml and sitemap1.xml.

Check 1: Sitemap file are all the same with extract contents.

[1][nginx directory]: file ownership & md5sum
[1][nginx directory]: file ownership & md5sum
  • Same ownership (jenkins:jenkins)
  • Same content (md5sum: 859ffa73b9eaf8dcaef920ffafbc1a45)

Check 2: wget & md5sum

[2]wget & md5sum
[2]wget & md5sum
  • Same content (md5sum: 859ffa73b9eaf8dcaef920ffafbc1a45)

Check 3: Testing with Google Search Console to read my sitemap

It’s getting interesting here!
When google try to fetch my sitemap.xml , it shows an error Couldn't fetch. However, it works for sitemap1.xml.
I believe it’s because of caching issue. Old data exists somewhere on the google data center. I would wait hours for this but to debug a sitemap generator, it’s crazy. I better create a new file sitemap-n.xml to debug.

Right now, there is no solution for me but a work-around using sitemap1.xml, or any sitemap-n.xml.

[3]Google Search Console | Indexing Sitemap | 2024-08-14 22:26:39 GMT+7
[3]Google Search Console | Indexing Sitemap | 2024-08-14 22:26:39 GMT+7

By the way, this is my jekyll sitemap.xml. You can found it https://github.com/nguyenvinhlinh/nguyenvinhlinh.github.io/blob/master/sitemap.xml.

---
layout: null
---
<?xml version="1.0" encoding="UTF-8"?>
<urlset
    xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
{% for post in site.posts %}
{%   if post.update == nil or post.update == ""  %}
{%     assign mod_date = post.date %}
{%   else %}
{%     assign mod_date = post.update %}
{%   endif %}
<url>
  <loc>{{ site.url }}{{ post.url }}</loc>
  <lastmod>{{ mod_date | date_to_xmlschema }}</lastmod>
</url>
{% endfor %}
</urlset>

Personal Node: Installing a Spectre fullnode

08/08/2024 @ Saigon Cryptocurrency Node

I. Systemctl service - /etc/systemd/system/spectre.service

[Unit]
Description=Spectre Network - Full Node
After=network.target mnt-disk_2.mount

[Service]
WorkingDirectory=/opt/rusty-spectre-v0.3.14-linux-gnu-amd64
ExecStart=/opt/rusty-spectre-v0.3.14-linux-gnu-amd64/bin/spectred  --appdir=/mnt/disk_2/CryptoCurrency/Spectre  --rpclisten=0.0.0.0:18110 --rpclisten-borsh=0.0.0.0:19110 --rpclisten-json=0.0.0.0:20110 --listen=0.0.0.0:18111 --outpeers=64>
User=nguyenvinhlinh
RemainAfterExit=yes
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

II. Firewall-cmd service - /etc/firewalld/services/spectre.xml

Port Description Firewall
18110 gRPC, miner/stratum bridge/golang wallet need it Closed
18111 P2P Open
19110 WebSocket-framed wRPC/Borsh protocol. It’s used for (rust) spectre wallet Closed
20110 WebSocket-framed wRPC/JSON-RPC protocol Closed
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Spectre node</short>
  <description>
    This option allows Spectre node to use tcp port 18110
    - RPC: 18110
    - P2P: 18111
  </description>
  <port protocol="tcp" port="18110"/>
  <port protocol="udp" port="18110"/>
  <port protocol="tcp" port="18111"/>
  <port protocol="udp" port="18111"/>
</service>

References

Setup kaspa stratum bridge for solo mining

16/07/2024 @ Saigon Cryptocurrency Node

I. Clone repo https://github.com/rdugan/kaspa-stratum-bridge

Or copy relase to /opt/kaspa-ks-bridge

$  kaspa_ks_bridge pwd
/opt/kaspa_ks_bridge

$  kaspa_ks_bridge tree
.
├── bridge.log
├── config.yaml
└── ks_bridge

1 directory, 3 files

II. Modify config.yaml

stratum_port: :5555
kaspad_address: localhost:16110
min_share_diff: 8192
pow2_clamp: true
var_diff: true
shares_per_min: 20
var_diff_stats: true
block_wait_time: 500ms
extranonce_size: 2
print_stats: true
log_to_file: true
prom_port: :2114

III. Systemctl service - /etc/systemd/system/kaspa_ks_bridge.service

[Unit]
Description=Kaspa - KS Bridge
Requires=network.target

[Service]
WorkingDirectory=/opt/kaspa_ks_bridge
ExecStart=/opt/kaspa_ks_bridge/ks_bridge
User=nguyenvinhlinh
RemainAfterExit=yes
Restart=on-failure
RestartSec=10
TimeoutStopSec=180

[Install]
WantedBy=multi-user.target

To check log, journalctl -f -u kaspa_ks_bridge

[1] KS bridge - Console log
[1] KS bridge - Console log

IV. Config ASIC’s Mining Settings

The pool address should be stratum+tcp://192.168.1.XXX:5555 (your local stratum node ip)

[2] ASIC's Mining setting
[2] ASIC's Mining setting

Kaspa Asic - KS5L - API sample to get operational stage

15/07/2024 @ Saigon Mining Rig

Ice River - KS5L
Ice River - KS5L

This post is all about HTTP API to get ASIC operational stage, in particular KS5L. I believe that this API is also for KS0 and other future Ice River’s ASICs This finding is a part of my open source project named Mining Rig Monitor.

This is the HTTP POST example with curl.

$ curl 'http://192.168.1.XXX/user/userpanel' \
  -H 'Accept: application/json, text/javascript, */*; q=0.01' \
  -H 'Accept-Language: en-US,en;q=0.9,vi-VN;q=0.8,vi;q=0.7' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: application/x-www-form-urlencoded; charset=UTF-8' \
  -H 'Cookie: language=en; ctime=1' \
  -H 'DNT: 1' \
  -H 'Origin: http://192.168.1.XXX' \
  -H 'Referer: http://192.168.1.XXX/' \
  -H 'User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' \
  -H 'X-Requested-With: XMLHttpRequest' \
  --data-raw 'post=4' \
  --insecure

HTTP 200 - Response

{
  "error": 0,
  "data": {
    "model": "none",
    "algo": "none",
    "online": true,
    "firmver1": "BOOT_3_1",
    "firmver2": "image_1.0",
    "softver1": "ICM168_3_2_10_ks5L_miner",
    "softver2": "ICM168_3_2_10_ks5L_bg",
    "firmtype": "Factory",
    "nic": "eth0",
    "mac": "****:****:****:****:****:**",
    "ip": "192.168.1.XX",
    "netmask": "255.255.255.0",
    "host": "XJGXG_SSYYGB",
    "dhcp": false,
    "gateway": "192.168.1.xxfe80::1",
    "dns": "xx.xx.xx.xx",
    "locate": false,
    "rtpow": "15011G",
    "avgpow": "10789G",
    "reject": 0.0,
    "runtime": "01:04:29:02",
    "unit": "G",
    "pows": {
      "board1": [
        10789,
        9851,
        11728,
        11728,
        9851,
        8913,
        7505,
        7505,
        8913,
        8913,
        13135,
        8444,
        10320,
        7036,
        5629,
        12197,
        9382,
        12666,
        11258,
        9382,
        7505,
        8913,
        15011
      ]
    },
    "pows_x": [
      "0 mins",
      "5 mins",
      "10 mins",
      "15 mins",
      "20 mins",
      "25 mins",
      "30 mins",
      "35 mins",
      "40 mins",
      "45 mins",
      "50 mins",
      "55 mins",
      "60 mins",
      "65 mins",
      "70 mins",
      "75 mins",
      "80 mins",
      "85 mins",
      "90 mins",
      "95 mins",
      "100 mins",
      "105 mins",
      "110 mins"
    ],
    "powstate": true,
    "netstate": true,
    "fanstate": true,
    "tempstate": false,
    "fans": [
      5900,
      5900,
      5900,
      5855
    ],
    "pools": [
      {
        "no": 1.0,
        "addr": "stratum+tcp://asia1.kaspa-pool.org:4441",
        "user": "kaspa:qr3d34p6gzewwjs93fvheruwjyvfn35kn5uu00e6ffsgt6k087c4qsgp8l0mk.worker_1",
        "pass": "x",
        "connect": 1.0,
        "diff": "140737.49 G",
        "priority": 1.0,
        "accepted": 7225.0,
        "rejected": 0.0,
        "diffa": 0.0,
        "diffr": 0.0,
        "state": 1.0,
        "lsdiff": 0.0,
        "lstime": "00:00:00"
      },
      {
        "no": 2.0,
        "addr": "stratum+tcp://eu1.kaspa-pool.org:4441",
        "user": "kaspa:**********.worker_1",
        "pass": "x",
        "connect": -1.0,
        "diff": "0.00 G",
        "priority": 2.0,
        "accepted": 0.0,
        "rejected": 0.0,
        "diffa": 0.0,
        "diffr": 0.0,
        "state": 0.0,
        "lsdiff": 0.0,
        "lstime": "00:00:00"
      },
      {
        "no": 3.0,
        "addr": "stratum+tcp://us1.kaspa-pool.org:4441",
        "user": "kaspa:**********.worker_1",
        "pass": "x",
        "connect": -1.0,
        "diff": "0.00 G",
        "priority": 3.0,
        "accepted": 0.0,
        "rejected": 0.0,
        "diffa": 0.0,
        "diffr": 0.0,
        "state": 0.0,
        "lsdiff": 0.0,
        "lstime": "00:00:00"
      }
    ],
    "boards": [
      {
        "no": 1.0,
        "chipnum": 18.0,
        "chipsuc": 0.0,
        "error": 0.0,
        "freq": 875.0,
        "rtpow": "5160.37G",
        "avgpow": "3831.19G",
        "idealpow": "0.00G",
        "tempnum": "(null)",
        "pcbtemp": "0.00-0.00-0.00-0.00",
        "intmp": 61.0,
        "outtmp": 63.0,
        "state": true,
        "false": [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18
        ]
      },
      {
        "no": 2.0,
        "chipnum": 18.0,
        "chipsuc": 0.0,
        "error": 0.0,
        "freq": 875.0,
        "rtpow": "5629.50G",
        "avgpow": "3440.25G",
        "idealpow": "0.00G",
        "tempnum": "(null)",
        "pcbtemp": "0.00-0.00-0.00-0.00",
        "intmp": 57.0,
        "outtmp": 61.0,
        "state": true,
        "false": [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18
        ]
      },
      {
        "no": 3.0,
        "chipnum": 18.0,
        "chipsuc": 0.0,
        "error": 0.0,
        "freq": 875.0,
        "rtpow": "4222.12G",
        "avgpow": "3518.44G",
        "idealpow": "0.00G",
        "tempnum": "(null)",
        "pcbtemp": "0.00-0.00-0.00-0.00",
        "intmp": 62.0,
        "outtmp": 67.0,
        "state": true,
        "false": [
          1,
          2,
          3,
          4,
          5,
          6,
          7,
          8,
          9,
          10,
          11,
          12,
          13,
          14,
          15,
          16,
          17,
          18
        ]
      }
    ],
    "refTime": "2024-03-08 01:58:25 UTC"
  },
  "message": ""
}

I hope that you guys could find it useful, good luck!

Cách làm Certificate Authority cấp SSL nội bộ

15/07/2024 @ Saigon SSL

[1] Mô hình chứng chỉ
[1] Mô hình chứng chỉ

I. Tạo Certificate Authority

a. Tạo private key

$ openssl genrsa -des3 -out my-ca.key 4096

b. Tạo certificate

$ openssl req -x509 -new -nodes -key my-ca.key -sha256 -days 365000 -out my-ca.pem

Kết quả của quá trình này là file my-ca.pem đây là certificate của Certificate Authority. Nói một cách khác, một Certificate Authority đã được tạo.

II. Tạo web1.local certificate

a. Tạo private key

$ openssl genrsa -out web1.local.key 4096

b. Tạo yêu cầu chứng nhận, (Certificate signing request)

$ openssl req -new -key web1.local.key -out web1.local.csr

c. Tạo thêm X509 V3 certificate extension config file

Tạo file có tên là web1.local.ext

authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

[alt_names]
DNS.1 = web1.local

d. Tạo certificate cho web1.local

Yêu cầu:

  • my-ca.key - private key của Certificate Authority(CA)
  • my-ca.pem - certificate của Certificate Authority(CA)
  • web1.local.csr - yêu cầu tạo chứng chỉ(Certificate signing request - CSR) của trang web, ví dụ web1.local
  • web1.local.ext - extension của yêu cầu tạo chứng chỉ.
$ openssl x509 -req -in ./web1.local-cert/web1.local.csr  -CA ./ca-cert/my-ca.pem  -CAkey ./ca-cert/my-ca.key \
    -CAcreateserial -out ./web1.local-cert/web1.local.crt -days 365 -sha256 -extfile  ./web1.local-cert/web1.local.ext

Installing a Kaspa fullnode

I. Systemctl service - /etc/systemd/system/kaspa.service

[Unit]
Description=Kaspa Full Node
After=network.target mnt-disk_2.mount

[Service]
WorkingDirectory=/opt/rusty-kaspa-v0.14.1-linux-gnu-amd64
ExecStart=ExecStart=/opt/rusty-kaspa-v0.14.1-linux-gnu-amd64/bin/kaspad --configfile /opt/rusty-kaspa-v0.14.1-linux-gnu-amd64/bin/kaspad.conf
User=nguyenvinhlinh
RemainAfterExit=yes
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

II. Kaspa config file - /opt/rusty-kaspa-v0.14.1-linux-gnu-amd64/bin/kaspad.conf

appdir="/opt/rusty-kaspa-v0.14.1-linux-gnu-amd64/data"
utxoindex=true
outpeers=128
maxinpeers=128
rpclisten="0.0.0.0:16110"
rpclisten-borsh="0.0.0.0:17110"
listen="0.0.0.0:16111"

II. Firewall-cmd - /etc/firewalld/services/kaspa.xml

<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>Kaspa node</short>
  <description>
    This option allows Kaspa node to use tcp port
    - 16110: gRPC for mining + go wallet
    - 16111: P2P
    - 17110: wRPC Borsh for rusty wallet
  </description>
  <port protocol="tcp" port="16110"/>
  <port protocol="tcp" port="16111"/>
  <port protocol="tcp" port="17110"/>
</service>

III. How to use kaspa-wallet?

$ ./kaspa-wallet
####### You are in kaspa-wallet interactive console
$ server 127.0.0.1:17110
Setting RPC server to: 127.0.0.1:17110
$ connect
Connected to Kaspa node version 0.14.1 at ws://127.0.0.1:17110
$ wallet create test_wallet

$ wallet help
unknown command: 'help'

    close             Close an opened wallet (shorthand: 'close')
    create [<name>]   Create a new bip32 wallet
    hint              Change the wallet phishing hint
    import [<name>]   Create a wallet from an existing mnemonic (bip32 only).

                      To import legacy wallets (KDX or kaspanet) please create
                      a new bip32 wallet and use the 'account import' command.
                      Legacy wallets can only be imported as accounts.

    list              List available local wallet files
    open [<name>]     Open an existing wallet (shorthand: 'open [<name>]')

How does this website is built & delploy?

05/07/2024 @ Saigon Projects

1. Introduction

This website is built with Jekyll, build with Docker and deploy with Nginx on bare metal. At the deploy step, it’s all about copy file html files from docker to nginx’s www directory.

A process of auto-build & auto-deploy is done with Jenkins.

2. Jenkins

a. Build Trigger

I use GitHub hook trigger for GITScm polling.

[1] Jenkins - Build Trigger
[1] Jenkins - Build Trigger

In addition, on the github, I configure github’s webhook.

[2] Jenkins - Github's webhook
[2] Jenkins - Github's webhook

b. Pipeline

pipeline {
    agent any

    stages {
        stage('Clone Repo') {
            steps {
                git 'https://github.com/nguyenvinhlinh/nguyenvinhlinh.github.io'
            }
        }

        stage('Build') {
            steps {
                sh 'DOCKER_BUILDKIT=1 docker build -f  Dockerfile --target=release --output nginx-dist .'
            }
        }

        stage('Remove old html') {
            steps {
                sh 'rm -rvf /usr/share/nginx/hexalink.xyz.html/*'
            }
        }

        stage('Copy to /usr/share/nginx/hexalink.xyz.html/') {
            steps {
                sh 'cp -r ./nginx-dist/* /usr/share/nginx/hexalink.xyz.html/'
            }
        }
    }
}

There is a trick here to copy to nginx’s www directory. user named jenkins does copy file htmls into the nginx’s html directory. As a consequence, prior to run pipeline,

  • First, I create nginx’s html directory (/usr/share/nginx/hexalink.xyz.html/)
  • Then, I change user ownership to jenkins.

3. Nginx

a. Nginx config for hexalink.xyz / www.hexalink.xyz

server {
    listen       443 ssl;
    listen       [::]:443 ssl;
    http2        on;
    server_name  hexalink.xyz www.hexalink.xyz;
    root         /usr/share/nginx/abc.xyz.html;

    ssl_certificate "/etc/pki/abc.xyz/www_abc_xyz.bundle.crt";
    ssl_certificate_key "/etc/pki/abc.xyz/www_abc_xyz.pem";
    ssl_session_cache shared:SSL:1m;
    ssl_session_timeout  10m;
    ssl_ciphers PROFILE=SYSTEM;
    ssl_prefer_server_ciphers on;
    charset UTF-8;

    # Load configuration files for the default server block.
    include /etc/nginx/default.d/*.conf;
}

b. Nginx config for jenkins

I follow this tutorial Reverse proxy - Nginx.

Crypto currency projects & ports collection

05/07/2024 @ Saigon Cryptocurrency Node

This post is all about crypto currency project and it’s default ports. After a while, setup and deploy many project, this is a collection.

Name Port Description NAT port forwarding
Bitcoin 8332 RPC NO
  8333 P2P YES
Monero 18080 P2P YES
  18081 Restricted RPC YES (With Restricted RPC ONLY)
    Full RPC NO
Alephium 9973 P2P YES
  10973 Mining API YES (If mining)
  11973 WebSocket API NO
  12973 JSON API / Swagger NO
Kaspa 16110 gRPC for miner + Go Wallet NO
  16111 P2P YES
  17110 wRPC Borsh for Rusty Wallet Yes if want to allow remote wallet
Spectre 18110 RPC for miner + Go Wallet NO
  18111 P2P YES
  19110 Websocket for Rusty Wallet YES if want to allow remote wallet
Dynex 17333 P2P YES
  17336 P2P YES
Beam 10000 P2P YES