# Buildics API

> BUILDICS® IoTプラットフォームのREST APIとセンサー仕様を使ったシステム構築ガイド。BUILDICS APIの呼び出し、ゲートウェイ監視、センサーデータ取得、濾水/漏水センサー判定、Dify AI連携、CORSプロキシ設定を含む。センサー監視アプリ、ダッシュボード、IoTシステム構築時に使用。

- Skill: `qiangzhu8888/buildics-api` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add qiangzhu8888/buildics-api`
- Raw SKILL.md: https://api.skillmd.com/api/skills/qiangzhu8888/buildics-api/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Integrations & APIs
- Author: qiangzhu8888 (https://skillmd.com/u/qiangzhu8888)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/qiangzhu8888/buildics-api

---


# BUILDICS® API & センサー仕様

## 基本情報

| 項目 | 値 |
|------|-----|
| ベースURL例 | `https://www.buildics.jp/api` |
| 全エンドポイント | `POST` メソッド |
| Content-Type | `application/json;charset=UTF-8` |
| 認証ヘッダー | `Apikey: {API_KEY}` |
| 非ASCII Keyの場合 | `X-Apikey-Encoding: base64` を追加 |

## API一覧

| # | エンドポイント | 説明 |
|---|---------------|------|
| 1 | `/common/queryAssetInfo` | 資産データ照会 |
| 2 | `/common/querySpaceInfo` | 空間データ照会 |
| 3 | `/common/queryAssetInfoByClass` | カテゴリー別資産検索 |
| 4 | `/common/queryAlarmDevice` | 異常デバイス照会 |
| 5 | `/common/queryClass` | 資産分類照会 |
| 6 | `/common/problem-reports/summaries` | 不具合一覧 |
| 7 | `/common/getS3FileUrl` | S3ファイルURL取得 |
| 8 | `/common/addBuilding` | ビル情報追加 |
| 9 | `/common/queryBuilding` | ビル情報照会 |
| 10 | `/common/queryKanriRoidMaintenanceRecord` | 管理ロイド修繕履歴 |
| 11 | `/common/queryCancelAlarmDevice` | 警報解除履歴 |
| 12 | `/common/apgateway/status` | APゲートウェイステータス |
| 13 | `/common/device/queryDeviceData` | デバイスデータ照会（最大7日） |
| 14 | `/common/device/sendCommand` | デバイスコマンド送信 |

## IoTアプリで頻用するAPI

### ゲートウェイ状態確認 (`/common/apgateway/status`)

```javascript
// リクエスト
const body = {
  startTime: Date.now() - 24 * 60 * 60 * 1000,  // 24時間前（ms）
  endTime: Date.now()
};

// レスポンス data[] の各要素
{
  model: "GW-2024-Pro",
  imei: "123456789012345",
  mac: "AA:BB:CC:DD:EE:FF",
  address: "3階サーバールーム",
  gps: "",
  latestHeartbeatTs: 1700000000000,  // ms
  onlineStatus: 1  // 0: オフライン, 1: オンライン
}
```

ゲートウェイIDは IMEI、MACアドレス、モデル名で部分一致検索。

### センサーデータ照会 (`/common/device/queryDeviceData`)

```javascript
// リクエストは必ず配列で送る
const body = [{
  deviceId: "4F025893",
  startTime: Date.now() - 7 * 24 * 60 * 60 * 1000,  // 最大7日前
  endTime: Date.now()
}];

// レスポンス data の構造
{
  deviceId: "4F025893",
  deviceSn: "SN-123456",
  latestRawData: '{"temperature":23.5,"humidity":45}',  // JSON文字列
  latestDataTime: "1700000000000",  // ms（文字列型に注意）
  typeUnit: "℃,%",        // カンマ区切りで複数単位
  dataValue: "23.5,60.2"  // カンマ区切りで複数値
}
```

**注意:** `startTime`/`endTime` は省略可。省略時は最新データのみ返る。

### コマンド送信 (`/common/device/sendCommand`)

```javascript
// リクエストは必ず配列で送る
const body = [{
  imei: "123456789012345",
  command: JSON.stringify({ gpio: 1 })  // commandは文字列化したJSON
}];
```

## レスポンス共通形式

**注意:** エンドポイントによりキーが大文字・小文字で異なる。

```javascript
// 大文字版（queryAssetInfo, querySpaceInfo）
{ Code: 200, Msg: "成功", Data: [...] }

// 小文字版（その他のエンドポイント）
{ code: 200, msg: "成功", data: [...] }
```

| コード | 説明 |
|--------|------|
| 200 | 成功 |
| 500 | サーバ内部エラー |
| 20001 | 照会エラー（msgを確認） |

## センサー種別判定ロジック

`typeUnit`（小文字化）でセンサー種別を自動判定。

```javascript
function detectSensorType(typeUnit, dataValue) {
  const unit = typeUnit.toLowerCase().trim();
  const val = parseFloat(dataValue);

  // 漏水センサー: unitが空でdataValueが0か1
  if (unit === '' && (val === 0 || val === 1)) {
    return { type: '漏水センサー', icon: val === 1 ? '🚨💦' : '🛡️💧', binary: true };
  }
  if (unit.includes('℃') || unit.includes('°c') || unit.includes('temp') || unit.includes('度'))
    return { type: '温度センサー', icon: '🌡️', color: '#FF6B6B' };
  if (unit.includes('rh') || unit.includes('humidity') || unit.includes('湿度') || unit === '%')
    return { type: '湿度センサー', icon: '💧', color: '#4ECDC4' };
  if (unit.includes('ppm') || unit.includes('co2'))
    return { type: 'CO2センサー', icon: '🌿', color: '#95E1D3' };
  if (unit.includes('hpa') || unit.includes('pa') || unit.includes('気圧') || unit.includes('pressure'))
    return { type: '気圧センサー', icon: '🌪️', color: '#A8E6CF' };
  if (unit.includes('lx') || unit.includes('lux') || unit.includes('照度'))
    return { type: '照度センサー', icon: '☀️', color: '#FFD93D' };
  if (unit.includes('kwh') || unit.includes('kw') || unit.includes(' w') || unit === 'w')
    return { type: '電力センサー', icon: '⚡', color: '#F7DC6F' };
  if (unit.includes('water') || unit.includes('水') || unit.includes('濾水') ||
      unit.includes('l/min') || unit.includes('m3'))
    return { type: '濾水センサー', icon: '💧', color: '#00A8E1' };
  
  return { type: 'センサー', icon: '📊', color: '#95A5A6' };
}
```

### センサー種別早見表

| typeUnit（例） | 判定種別 | アイコン | カラー |
|---------------|---------|---------|--------|
| `℃`, `°C`, `temp` | 温度センサー | 🌡️ | `#FF6B6B` |
| `%`, `%RH`, `humidity` | 湿度センサー | 💧 | `#4ECDC4` |
| `ppm`, `CO2` | CO2センサー | 🌿 | `#95E1D3` |
| `hPa`, `Pa` | 気圧センサー | 🌪️ | `#A8E6CF` |
| `lx`, `lux` | 照度センサー | ☀️ | `#FFD93D` |
| `W`, `kW`, `kWh` | 電力センサー | ⚡ | `#F7DC6F` |
| `water`, `水`, `濾水`, `L/min`, `m3` | 濾水センサー | 💧 | `#00A8E1` |
| **空文字** + dataValue 0 or 1 | **漏水センサー** | 🚨💦/🛡️💧 | - |

## 複数測定値（マルチバリュー）形式

センサーが複数値を返す場合、カンマ区切りで同インデックス対応。

```javascript
// APIレスポンス例
{ dataValue: "25.5,60.2,1013.25", typeUnit: "℃,%,hPa" }

// パース方法
const values = dataValue.split(',');
const units = typeUnit.split(',');
// values[0]="25.5" → units[0]="℃" (温度)
// values[1]="60.2" → units[1]="%" (湿度)
// values[2]="1013.25" → units[2]="hPa" (気圧)
```

## API呼び出し基本パターン

```javascript
const API_BASE = 'https://www.buildics.jp/api';  // 環境に合わせて変更
const API_KEY = 'YOUR_BUILDICS_API_KEY';          // 管理画面から取得

async function callBuildicsApi(endpoint, body) {
  const headers = {
    'Content-Type': 'application/json;charset=UTF-8',
    'Apikey': API_KEY
  };
  const res = await fetch(`${API_BASE}${endpoint}`, {
    method: 'POST',
    headers,
    body: JSON.stringify(body)
  });
  const json = await res.json();
  // Code または code どちらも考慮
  const code = json.code ?? json.Code;
  if (code !== 200) throw new Error(json.msg ?? json.Msg);
  return json.data ?? json.Data;
}

// 使用例
const gateways = await callBuildicsApi('/common/apgateway/status', {
  startTime: Date.now() - 86400000, endTime: Date.now()
});

const sensorData = await callBuildicsApi('/common/device/queryDeviceData', [
  { deviceId: 'MY-DEVICE-ID' }
]);
```

## CORSプロキシ設定

ブラウザから直接APIを呼ぶとCORSエラー。以下で回避。

### ローカルプロキシ（推奨）

```bash
# Node.js版
node scripts/cors-proxy-server.js
# Python版
python scripts/cors-proxy-server.py
# → http://localhost:8080/?target= を使用
```

### Cloudflare Workerプロキシ

`cloudflare-proxy/` ディレクトリに設定済み。`wrangler deploy` でデプロイ。

```javascript
// プロキシ経由での呼び出し
const PROXY = 'http://localhost:8080/?target=';
const url = PROXY + encodeURIComponent(`${API_BASE}/common/apgateway/status`);
```

## Dify AI連携（センサー分析）

Dify を使ってセンサーデータをAI分析する場合の例。
`YOUR_DIFY_ENDPOINT` と `YOUR_DIFY_API_KEY` は各自の環境に合わせて設定。

```javascript
const DIFY_ENDPOINT = 'YOUR_DIFY_ENDPOINT';  // 例: https://dify.example.com/v1/completion-messages

// 漏水センサーAI分析
const leakBody = {
  inputs: {
    place: '3階サーバールーム',
    purpose: '漏水検知',
    latest_state: 'WET',           // 'WET' or 'DRY'
    last_change_timestamp: '2025-01-15T10:30:00Z',
    now_timestamp: new Date().toISOString(),
    wet_events_last_24h: JSON.stringify([...]),
    total_wet_minutes_last_24h: '45',
    num_wet_events_last_24h: '3',
    is_under_maintenance: 'NO',
    time_context: '業務時間外',
    notes_from_system: ''
  },
  response_mode: 'blocking',
  user: 'buildics-sensor-monitor'
};

// 温湿度センサーAI分析
const tempHumBody = {
  inputs: {
    location: 'サーバールーム',
    temperature: '28.5',
    humidity: '65',
    wbgt: '25.3',        // 暑さ指数（null可）
    weather: '屋内',
    timestamp: new Date().toISOString()
  },
  response_mode: 'blocking',
  user: 'buildics-sensor-monitor'
};

const res = await fetch(DIFY_ENDPOINT, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + YOUR_DIFY_API_KEY
  },
  body: JSON.stringify(leakBody)
});
```

## しきい値設定フォーマット

```
℃:10:28, %:40:70, ppm::800
// 形式: 単位:下限:上限（片方省略可）
```

## Firebase アクセスコード管理（オプション）

```javascript
// firebase-config.json で設定
{ "databaseURL": "https://YOUR-PROJECT-rtdb.firebaseio.com" }

// アクセスコード検証パス
// accessCodes/{accessCode} → { expiryDate, encryptedData }
// 復号: PBKDF2(password) → AES-GCM
```

## 詳細リファレンス

- 全エンドポイント詳細: [api-reference.md](api-reference.md)
- センサー仕様詳細: [sensor-spec.md](sensor-spec.md)

