Mac mini の整備済製品を購入しました。
12コアCPUと16コアGPUを搭載したApple M4 Proチップ
ギガビットEthernet
64GB
512GB
整備済製品は10−15%安く購入できるのでお買い得です。
https://www.apple.com/jp/shop/refurbished/mac
Mac mini の整備済製品を購入しました。
12コアCPUと16コアGPUを搭載したApple M4 Proチップ
ギガビットEthernet
64GB
512GB
整備済製品は10−15%安く購入できるのでお買い得です。
https://www.apple.com/jp/shop/refurbished/mac
特許庁が提供する 特許情報取得API は、
特許検索・経過管理・知財DXに非常に有用です。
しかし、
という理由から、Node.jsによるプロキシサーバ構築が実質必須になります。
本記事では、
👉 Node.jsのインストール(環境構築)
👉 プロキシAPIサーバ作成
👉 ブラウザ検索アプリ作成
まで、完全な手順書として解説します。
今回はRaspberry pi5のRaspberry
Pi OSを使用しています。Ubuntuでも可能と思いますが、動かない場合は適宜手直ししていただれば幸いです。
1. Node.js をインストールする(最初にやること)
1-1. Node.jsとは?
Node.js は JavaScriptをサーバ側で動かす実行環境
です。
今回のプロキシAPIサーバは Node.js で作成します。
1-2. Node.jsのインストール方法
✅ Linux(Raspberry Pi OS 、Ubuntu)
sudo apt update
sudo apt install nodejs npm
または、Node.jsを、以下のコマンでインストールします。
# 例えば、Node.js 18.x をインストール
curl -fsSL
https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs
1-3. インストール確認
ターミナル(コマンドプロンプト)で以下を実行します。
node -v
npm -v
バージョンが表示されれば成功です。
2. プロジェクトフォルダを作成する
mkdir jpo-api-sample
cd jpo-api-sample
3. Node.jsプロジェクト初期化
npm init -y
package.json が生成されます。
必要なライブラリをインストールします。
npm install express cors dotenv
package.json に以下を追加:
"type": "module"
例:
JSON
{
"name": "jpo-proxy",
"version": "1.0.0",
"type": "module",
"dependencies": {
"cors": "^2.8.5",
"dotenv": "^16.4.0",
"express": "^4.18.2",
"node-fetch": "^3.3.2"
}
}
4. 環境変数ファイル(.env)を作成
プロジェクト直下に .env を作成し、以下を記述します。
JPO_USERNAME=あなたの特許庁APIユーザーID
JPO_PASSWORD=あなたの特許庁APIパスワード
⚠️ このファイルはGitHub等に公開しないでください
必要に応じて安全性のため .gitignore も作成します。
4.1:.gitignore を作成
node_modules/
.env
5. ① server.js(Node.js
プロキシAPIサーバ)
以下を server.js として保存してください
(コードはそのままコピー&ペーストでOKです)。
// server.js — app_progress 専用版
import express from "express";
import cors from "cors";
// Node.js v18+ は
fetch が標準搭載
import "dotenv/config";
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.urlencoded({ extended: true
}));
// ==================================
// トークンキャッシュ
// ==================================
let cachedToken = null;
let tokenExpireAt = null;
// ==================================
// 特許庁 API: トークン取得
// ==================================
async function fetchTokenFromJpo() {
const url = "https://ip-data.jpo.go.jp/auth/token";
const params = new
URLSearchParams();
params.append("grant_type", "password");
params.append("username",
process.env.JPO_USERNAME);
params.append("password",
process.env.JPO_PASSWORD);
const response = await fetch(url, {
method:
"POST",
headers: {
"Content-Type": "application/x-www-form-urlencoded" },
body: params
});
const data = await response.json();
if (data.access_token) {
cachedToken =
data.access_token;
tokenExpireAt =
Date.now() + data.expires_in * 1000 - 5000; // 期限5秒前更新
}
return data;
}
// ==================================
// 有効なトークンを返す関数
// ==================================
async function getValidToken() {
const now = Date.now();
if (cachedToken &&
tokenExpireAt && now < tokenExpireAt) {
return cachedToken;
}
const newToken = await
fetchTokenFromJpo();
return newToken.access_token;
}
// ==================================
// 1) トークン取得 API
// ==================================
app.post("/api/token", async
(req, res) => {
try {
const token = await
getValidToken();
res.json({
access_token: token,
cached:
token === cachedToken
});
} catch (e) {
res.status(500).json({
error: e.toString() });
}
});
// ==================================
// 2) app_progress(特許経過情報)
// 出願番号(10桁)例: 2023063418
// ==================================
app.get("/api/app_progress/:number",
async (req, res) => {
try {
const token = await
getValidToken();
const number =
req.params.number;
const url =
https://ip-data.jpo.go.jp/api/patent/v1/app_progress/${number};
const response = await
fetch(url, {
headers: {
"Authorization": Bearer ${token}
}
});
const text = await
response.text();
//
-------------------------------
// JSON でも HTML でも安全に返す
//
-------------------------------
try {
const json =
JSON.parse(text);
return
res.status(response.status).json(json);
} catch {
return
res.status(response.status).json({
error: "JPO API returned non-JSON response",
status: response.status,
body: text
});
}
} catch (e) {
res.status(500).json({
error: e.toString() });
}
});
// ==================================
// サーバ起動
// ==================================
app.listen(3000, () => {
console.log("✅ app_progress 専用 JPO Proxy Server 起動!");
console.log("✅ トークン取得:
POST http://localhost:3000/api/token");
console.log("✅ 経過情報: GET http://localhost:3000/api/app_progress/{出願番号}");
});
6. サーバを起動する
node server.js
以下が表示されれば成功です。
✅ app_progress 専用 JPO Proxy Server 起動!
7. ② ブラウザアプリ(index.html)
次に、検索用のHTMLを作成します。
以下を index.html として保存し、ブラウザで開いてください。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta
charset="UTF-8">
<title>特許経過情報(app_progress)検索</title>
<style>
body {
font-family:
sans-serif;
margin: 40px
auto;
max-width:
700px;
}
label {
font-weight:
bold;
}
input {
width: 100%;
padding:
8px;
margin: 8px
0 16px 0;
font-size:
16px;
}
button {
padding:
10px 20px;
font-size:
17px;
cursor:
pointer;
}
pre {
background:
#f7f7f7;
border: 1px
solid #ccc;
padding:
15px;
white-space:
pre-wrap;
margin-top:
20px;
}
</style>
</head>
<body>
<h2>📄 特許経過情報(app_progress)検索</h2>
<label>出願番号(10桁数字:例 2023063418)</label>
<input id="appNumber"
placeholder="2023063418">
<button onclick="search()">検索する</button>
<pre id="result">ここに検索結果が表示されます</pre>
<script>
async function search() {
const num =
document.getElementById("appNumber").value.trim();
const result =
document.getElementById("result");
if (!num.match(/^[0-9]{10}$/)) {
result.textContent =
"⚠️ 出願番号は10桁の数字を入力してください。";
return;
}
result.textContent = "問い合わせ中…";
try {
const res = await
fetch(http://localhost:3000/api/app_progress/${num});
const json = await
res.json();
result.textContent =
JSON.stringify(json, null, 2);
} catch (err) {
result.textContent =
"エラーが発生しました:\n" + err;
}
}
</script>
</body>
</html>
8. 動作確認
👉 特許庁の
経過情報(app_progress) が表示されます。
まとめ
✅ Node.jsインストールからスタート
✅ セキュアな特許庁APIプロキシ構築
✅ ブラウザ検索UI完成
この構成を使えば、
まで、知財DXの土台がすぐに作れます。
Raspberry Pi 5 の性能を活用し、Docker と Docker Compose を用いて Ollama(ローカルLLM) と Open WebUI(ブラウザ操作UI) を動かす手順をまとめます。
今回ご紹介する構成は、実際に Raspberry Pi 5 上でエラーなく動作した安定構成です。
🚀 1. このガイドで構築できる環境
Ollama(ローカルLLMエンジン)
→ Llama2、Mistral、TinyLlama などのLLMをローカルで動作
Open WebUI(ブラウザUI)
→ ChatGPT のようにブラウザからローカルLLMを操作可能
APIアクセス可能
→ 他のアプリケーションから HTTP API で利用可能
Raspberry Pi 5(8GB RAM推奨)で快適に動作します。
🧱 2. 必要なソフト
Docker
Docker Compose
Raspberry Pi OS 64bit または Ubuntu Server 64bit
🔧 3. Docker & Docker Compose のインストール
以下のコマンドを実行します:
Shell
sudo apt update && sudo apt upgrade -y
sudo apt install docker.io -y
sudo systemctl enable docker
sudo systemctl start docker
sudo apt install docker-compose -y
📦 4. 使用した docker-compose.yml
この構成でエラーなく動作しました。
YAML
services:
ollama:
image: ollama/ollama:latest
container_name: ollama
ports:
- "11434:11434"
volumes:
- ./ollama-data:/root/.ollama
restart: always
openwebui:
image: ghcr.io/open-webui/open-webui:main
container_name: open-webui
depends_on:
- ollama
ports:
- "3000:8080"
volumes:
- ./openwebui-data:/app/backend/data
environment:
- OLLAMA_API_BASE=http://ollama:11434
- USE_OLLAMA_DOCKER=true
- OLLAMA_BASE_URL=/ollama
- WEBUI_AUTH=False
restart: always
volumes:
ollama-data:
openwebui-data:
▶ 5. サービスの起動
docker-composeを入れたフォルダに移動して
Shell
docker-compose up -d
その他の行を表示する
起動後のアクセス:
サービス | URL |
Open WebUI | http://<RaspberryPi_IP>:3000 |
Ollama API | http://<RaspberryPi_IP>:11434 |
🧪 6. モデルの利用
コンテナに入ってモデルをダウンロード:
Shell
docker exec -it ollama bash
ollama pull tinyllama:1.1b
ollama run tinyllama:1.1b
🎉 7. 結果
ローカルLLM(Ollama)が正常動作
Web UI(Open WebUI)もエラーなしで稼働
モデルデータも永続化され、再起動時も維持
Raspberry Pi 5 でも十分に実用的なローカルAI環境を実現
🔚 まとめ
Raspberry Pi 5 は Docker と組み合わせることで、
軽量かつ強力なローカルAIサーバーとして活用できます。
シマノは2025年6月5日に、バッテリー不要で走行中に自動変速してくれる充電不要のAI学習型オートマチック変速システム「Q'AUTO(クォート)」を発表しました。
自転車の変速器は、ワイヤ変速から電動無線変速への技術革新があったのですが、とうとうAi自動変速にまで到達してしまいました。
今年はこの技術に着目し、シマノ公式WEBサイト、Youtubeおよび、特許情報プラットフォーム(J-PlatPat)での検索結果を、NotebookLMのソースにしてブログ記事を作成しました。
シマノが開発した「Q'AUTO(クォート)」は、自転車の自動変速技術に新たな可能性をもたらしました。これは単なる電動変速の延長ではなく、バッテリーレスでライダーに合わせて学習する、革新的なシステムです。
ここでは、Q'AUTOの概要から、それを支えるシマノの特許出願動向までを解説します。
Q'AUTOは「自己給電式Di2自動変速」システムであり、一世紀にわたるサイクリングの技術革新によって実現されました。
この技術は、主にE-BIKE(電動アシスト自転車)のテクノロジーとして語られてきたオート変速の概念を覆し、バッテリーを搭載しない通常の自転車でもオート変速を可能にしました。その目的は、あらゆる自転車利用者に対し、常に最適なギア(in the right gear)を提供することで、サイクリングをより楽しく、身近なものにすることです。
1. バッテリーレス・自己給電式 Q'AUTOはバッテリーが不要で、充電もいらないバッテリーレスの設計です。変速に必要な電力は、後輪のフリーハブ内部に備えられた発電機(ダイナモ)によって、ペダルを回すたびに自ら発電し蓄えられます。
2. アダプティブラーニング(適応学習機能) Q’AUTOシステムは、AI学習機能を用いてライダーのライディングスタイルに適応します。フリーハブ内部には、速度、回転数(ケイデンス)、傾斜を計測する3つのセンサーが内蔵されており、走行状況の情報を収集します。
システムは、6,500以上のアルゴリズムパターンから最適な変速タイミングを選択し、時間が経つにつれライダーの好みに応じた変速を行うようになります。わずか6kmほどの走行で、システムは学習した内容を適用し始めます。
提供された特許出願リスト(2017年から2025年公開予定分まで)を参照すると、Q'AUTOの基盤となる自動変速技術分野において、株式会社シマノが集中的かつ継続的に知的財産を構築してきたことが示されています。
リストにある「出願日」を基準に、シマノがこの技術分野に出願した件数を分析すると、開発の波が明確に見て取れます。
| 出願年 | 件数 |
|---|---|
| 2017 | 4件 |
| 2018 | 21件 |
| 2019 | 10件 |
| 2020 | 4件 |
| 2021 | 18件 |
| 2022 | 14件 |
| 2023 | 7件 |
| 2024* | 3件 |
*注:2024年以降は公開予定分(出願年ベース)
特徴的な動向Q'AUTOの主要な機能を支えていると考えられる具体的な特許出願を挙げます。
| 文献番号 | 発明の名称 | 想定されるQ'AUTOとの関連 |
|---|---|---|
| 特開2025-154149 (No. 3) | 車両用の電力供給システム、車両用の給電装置... | Q'AUTOの核心であるバッテリーレス自己給電機能 における、フリーハブ内部の発電機(ダイナモ)で生成した電力の管理や供給に関する技術開発を示唆しています。 |
| 特開2025-081130 (No. 7) | 人力駆動車制御装置、コンピュータプログラム、人力駆動車制御方法... | ライダーの走行状況を分析し、最適な変速制御データを生成・適用する、アダプティブラーニング機能 のアルゴリズム開発に関するものです。 |
| 特開2023-085936 (No. 40) | 人力駆動車用制御装置、学習モデルの作成方法... | 変速タイミングを予測し最適化するために、AI学習モデルを自転車の制御装置に組み込む技術に関わっており、Q'AUTOの「6,500以上のアルゴリズムパターン」の土台となるものです。 |
シマノのQ'AUTOは、「完全オート・充電いらずのDi2変速」を実現した革新的なテクノロジーです。このシステムは、自己給電機能とアダプティブラーニング機能を融合させることで、バッテリーレスの一般的な自転車に自動変速の利便性をもたらしました。
特許出願動向からは、特に2018年と2021年〜2022年という二つの大きな波で、変速制御、AI学習、電源管理といった核となる要素技術に対するシマノの集中的な研究開発投資が確認されます。Q'AUTOは、これらの長年の技術開発の積み重ねが結実し、ライダーが変速操作に煩わされることなく、純粋に自転車の楽しさを満喫できるように設計された、未来のサイクリング体験を提示するシステムと言えます。
今年は、BLEのセンサをMATLAB(PC)に接続する試みです。MATLAB(PC)とXPLOVA NOZA one(負荷固定のサイクルトレーナー)とを直接接続しました。Arduinoを介さずに気軽にテストすることができます。
MATLABなので、BLE機器を接続するためにコマンドを用いますが、以下で接続してデータの確認までが可能です。
blelist
→NOZA-ONE 27456-197が見つかりました。
b=ble("NOZA-ONE 27456-197")
→接続します。
c = characteristic(b,"Cycling Power","Cycling Power Measurement")
→パワーに関連するデータを取得します。
data = read(c)
→dataにパワーに関連データが入り、内容を確認できます。
自転車をこぎながら、データを確認してみ明日。実際のデータは、以下のようになっており、データのどこが計測値なのか特定する必要があります。
XPLOVA NOZA oneは負荷が固定です。3番目(15)の値に着目すると、ペダルの回転数を上げていくと上昇するため、パワーに関する値(トルク×回転数)であると考えました。詳細は以下のURLに記載されています。
0 1 15 0 221 17 0 0 0 0 0 97 187 42 0 32 188 42 0 32
Cycling Power Service
※URLが変更になる場合があるため、適宜検索で探してみてください。
やはり、コマンドたと都度結果を見ながら確認できるので、Simulink+Arduinoに比べると簡単にできると思います。
さらに、今回は取得したパワーに関連するデータを、MATLAB App Designer で可視化してみました。App Designer は、簡単にGUIが作れるのでとても有難いです。会社のMATLABでもデータ分析の自動化に活用しています。
MATLAB App Designerでは、上記コマンドを以下のように記述しています。先のペアリングのところがまだ改善の余地ありです。
------------------------------------------------------------------------------------
methods (Access = private)
function results = funciv(app)
% noza = table2array(blelist(1,2));
app.b=ble("NOZA-ONE 27456-197");
app.stop = 0;
results = app.b.Characteristics;
end
function results = funciv0(app)
c = characteristic(app.b,"Cycling Power","Cycling Power Measurement");
results = read(c);
end
end
-----------------------------------------------------------------------------------
アプリ画面は、こんな感じです。時系列のグラフおよびゲージをメインにしました。確認のためのテーブルも追加してみました。
startボタンを押すと、MATLAB(PC)とXPLOVA NOZA oneとがペアリングして、計測が開始します。stopボタンを押すと計測が終了します。
以下が、ペダルを漕いでいるときに測定したデータになります。後半、ペダルの回転数を保ったまま、ギアを下げていくとパワーに関連する値が減少していくことが確認できました。
右上のゲージも意外と良い感じでした。
今まで、測定値の可視化までなかなかできていなかったので、ここまでできてとても嬉しいです。リアルタイムで、測定値を見みられるのはとても良いですね。あとは、物理値との整合性です。ここは、来年の課題になってしまいました。
65Wの電源を購入して、ACアダプタを持ち歩かなくてもよくなりました。
UGREEN USB Type CケーブルPD対応100W/5A
以前使っていたミニPCが壊れてしまったので、新しく購入しました。
持ち歩きように使います。
今回は、SSD、メモリーが交換できるタイプにしてみました。
ACアダプタが65W必要で、以前使っていた45WのACアダプタは使えませんでした。