2026年6月6日 星期六

ASUS Ascent GX10 AI agent 開發工具設定與安裝

入手一台ASUS Ascent GX10非常期待能夠做一些有用的專案, 在此之前先來把一些要用到的工具確認跟安裝好.
1. SSH 連線
可以不用連接螢幕用NB或是手機連進去GX10主機.
在GX10主機安裝好後, 就可以直接使用.

2. FTP 資料檔案傳輸
方便傳輸需要的檔案更新.
在GX10主機安裝好後, 就可以直接使用. 設定SFTP格式.







3. 遠端桌面連接
可直接進入主機的GUI畫面操作

4. TailScale 內外網路穿透工具
可在不同網路存取控制GX10主機
安裝後設定開機自動啟用Tailscale服務

sudo systemctl enable --now tailscaled


5. Openclaw
下載並安裝 Openclaw










6. Ollama

下載並安裝 Ollama

curl -fsSL https://ollama.com/install.sh | sh











7. Docker 
在GX10主機安裝好後, 就可以直接使用.




2026年4月23日 星期四

樹莓派 透過RTSP 同時傳送影像和聲音

MediaMTX

MediaMTX 是一個開箱即用且零依賴的即時媒體伺服器和媒體代理,可讀取、發布、代理、記錄和播放視訊和音訊串流。它被設計為一個「媒體路由器」,可將媒體串流從一端路由到另一端。

目前支援:
RTSP(Port 請參見服務的「網路」分頁)
RTMP(Port 請參見服務的「網路」分頁)
LL-HLS(綁定域名)

將 MediaMTX 變成系統服務

建立服務檔案:

sudo nano /etc/systemd/system/mediamtx.service


[Unit]

Description=MediaMTX Realtime Stream Server

After=network.target

 

[Service]

ExecStart=/home/pi/mediamtx/mediamtx

WorkingDirectory=/home/pi/mediamtx

Restart=always

User=pi

 

[Install]

WantedBy=multi-user.target


啟用並執行

執行以下指令讓設定生效:


sudo systemctl daemon-reload

sudo systemctl enable mediamtx

sudo systemctl start mediamtx


再利用由 FFmpeg 同時處理 stdin (影像) 和 alsa (聲音)

def start_stream():
    global stream_process

    if stream_process is not None:
        return "already running"
    # sudo fuser -k /dev/gpiochip0
    # pkill -f search_bot.py
    command = [
        'ffmpeg',
        '-f', 'v4l2',
        '-i', '/dev/video0',
        '-f', 'alsa',
        '-i', 'default',
        '-c:v', 'libx264',
        '-af', 'volume=1.5',
        '-preset', 'ultrafast',
        '-tune', 'zerolatency',
        '-c:a', 'libopus',
        '-b:a', '128k',
        '-ar', '48000',
        '-f', 'rtsp',
        '-rtsp_transport', 'tcp',
        'rtsp://127.0.0.1:8554/cam'
    ]

    #stream_process = subprocess.Popen(command)
    stream_process = subprocess.Popen(
        command,
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL
    )
    return "started"

利用VLC RTSP function


2026年3月25日 星期三

樹莓派Tailscale設定,免費內網穿透VPN

Tailscale是一款開源的虛擬區域網路(virtual LAN)軟體,可將多個裝置組成虛擬內網,互相連線,存取共享資源。

舉例來說,你可以用Tailscale連線到自架的Rustdesk遠端桌面,或是SSH遠端登入主機。過程只需要透過一組虛擬區域IP遠端連線,再也不需要port forwarding,將機器暴露到公網了。
因此就利用這個工具架設在樹莓派中, 從任何地方來控制樹莓派!

使用前需要到Tailscale公司的網站註冊一個帳號。Tailscale有免費版與付費版方案。免費版方案最多加入100個裝置,最多邀請3名帳號加入自己的網路。

你的使用者帳號會有自己的虛擬區網,稱之為「Tailnet」。你會將所有的裝置都加入進去,形成一個虛擬區網。原理圖如下:

# 樹莓派安裝:
curl -fsSL https://tailscale.com/install.sh | sh
# 安裝後設定開機自動啟用Tailscale服務:
sudo systemctl enable --now tailscaled
# 檢查服務狀態
sudo systemctl status tailscaled
sudo tailscale up
# Windows安裝
Tailscale支援Windows 10以上系統。至官網下載exe安裝。

安裝完後
兩個裝置都登入同個帳號把裝置加進去!

可透過SSH操作:
FTP運行:
VNC連線:




利用telegram來控制 crontab 任務的啟動或關閉

既然用了telegram bot就想說用這個tool來控制系統中的crontab任務列表
先查看crontab -l
再利用crontab -e

再透過 python code:
import logging
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, Update
from telegram.ext import Application, CommandHandler, CallbackQueryHandler, ContextTypes
from crontab import CronTab

# --- 設定區 ---
TOKEN = 'your bot token'
USER_ID = your chat id 不是字串

# 初始化日誌
logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.INFO)

def get_cron_keyboard():
    cron = CronTab(user=True)
    keyboard = []
   
    for index, job in enumerate(cron):
        status_icon = "🟢 啟用中" if job.is_enabled() else "🔴 已暫停"
       
        # --- 自定義名稱邏輯 ---
        cmd = job.command
        if "email_notify_v2.py" in cmd:
            display_name = "任務通知 V2"
        elif "email_notify.py" in cmd:
            display_name = "任務通知 V1"
        else:
            # 如果不是以上兩個,就顯示指令的前 20 個字
            display_name = cmd.split('/')[-1][:20]
        # ---------------------

        label = f"{status_icon} | {display_name}"
        keyboard.append([InlineKeyboardButton(label, callback_data=str(index))])
   
    return InlineKeyboardMarkup(keyboard) if keyboard else None

async def start(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """驗證身分並列出所有任務清單"""
    if update.effective_user.id != USER_ID:
        return
   
    markup = get_cron_keyboard()
    if markup:
        await update.message.reply_text("📋 **當前系統排程清單**\n點擊按鈕即可切換 啟動/暫停:",
                                      reply_markup=markup, parse_mode='Markdown')
    else:
        await update.message.reply_text("目前系統中沒有任何 Crontab 任務。")

async def button_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
    """處理按鈕點擊:切換任務狀態"""
    query = update.callback_query
    if query.from_user.id != USER_ID:
        await query.answer("權限不足")
        return

    await query.answer()
    job_index = int(query.data)
   
    # 重新讀取並操作
    cron = CronTab(user=True)
    try:
        job = cron[job_index]
        # 切換開關
        job.enable(not job.is_enabled())
        # 寫回系統
        cron.write()
       
        # 更新訊息與按鈕狀態
        await query.edit_message_text(
            text="✅ **狀態已更新**\n點擊下方按鈕繼續管理:",
            reply_markup=get_cron_keyboard(),
            parse_mode='Markdown'
        )
    except IndexError:
        await query.edit_message_text("❌ 找不到該任務,可能已被手動刪除。")

if __name__ == '__main__':
    app = Application.builder().token(TOKEN).build()
   
    app.add_handler(CommandHandler("start", start))
    app.add_handler(CallbackQueryHandler(button_callback))
   
    print("Bot 啟動中... 請在 Telegram 輸入 /start")
    app.run_polling()

運作情形

這樣控制定時任務就方便了!!!