
なぜ「手動の温度管理」はあなたのビジネス(人生)を密かに破壊するのか?
「今日も現場の温度、大丈夫だろうか…」 この記事を開いたあなたは、おそらくそんな微かな不安を毎日、無意識に抱えているはずです。 「今のところ問題は起きていない。でも、もし異常が起きたとき、自分は真っ先に気づけるだろうか?」 その「見えないリスクへの予期不安」が、あなたの貴重な集中力を少しずつ削っています。
実は、多くの一流経営者や現場責任者が、あなたと同じ悩みを抱えていました。そして、彼らが最後に行き着いた答えが、この記事で公開する「デバイス代だけで構築できる、プロに頼めば効果なデバイスとシステムの構築で数十万クラスの管理システム」です!
アプリ確認の「1日3分」が奪い去る、年間18時間の集中力

「アプリを開いて確認するだけ」という行為は、実は脳に大きな負荷をかけています。確認を忘れた時のリスク、そして「異常に気づけない」という不安。
最後に行き着いた答えが、この記事で公開する「数十万クラスの管理システムを、デバイス代だけで自作する」という選択です。
SwitchBot温度・湿度計プラスが「最強の投資」と言い切れる理由

他社製品が数万円する中、数千円でこの「精度」と「API開放」は異常です。本記事では、この家庭用ガジェットを「工場の心臓部」に変える魔法を教えます。
LINE Notifyの限界を突破!「新バージョン」の圧倒的付加価値
前回の記事では「LINE Notify」を紹介しましたが、今回は「LINE公式アカウント(Messaging API)」を採用します。
※LINE Notifyは2025年3月31日をもってサービス終了
【見やすい】見惚れる「ダッシュボード型レポート」

これが実際のLINEにくる画像レポートです!
文字だけの通知はもう終わりです。スマホを開いた瞬間に、針が動くメーター画像と24時間の履歴表が目に飛び込んできます。この「0.1秒で状況を判断できる視認性」こそが、真のDXです。
ちなみに細かいレポートはLooker Studioで見るようにしています。
【知識不要!コピペで実装】Switchbot APIで実現する温湿度管理の自動化 | Google連携からLINE通知までAIを活用してIoT化でシステム構築
【完全図解】LINE Messaging APIと連携するための3ステップ
ここからは、実際の操作画面をイメージしながら進めてください。
LINE公式アカウントの作成とAPIの有効化
LINE Developers にアクセスし、個人のLINEアカウントでログインします。
「プロバイダー」を新規作成(名前は「MyDX」など何でもOK)。
「Messaging API」を新規作成。チャネル名(Botの名前)を決めます。
作成後、「Messaging API設定」タブの一番下にある「チャネルアクセストークン(長期)」を発行してメモ(コピー)してください。これがコードの LINE_TOKEN になります。

【秘策】「グループID」を一瞬で特定する
LINE Notifyと違い、送り先のIDを特定するのが少し大変ですが、本記事のコードには「IDを自動返信してくれるデバッグ機能」を盛り込んでいます。Botをグループに招待して一言しゃべれば、IDが届きます。これが
LINE_DESTです。
SwitchBot API v1.1の認証設定
最新のv1.1では「シークレットトークン」が必要です。
隠しメニュー「開発者モード」を解放する
SwitchBotアプリの「プロフィール」>「設定」>「アプリバージョン」を10回連打します。
出現した「開発者オプション」を開き、「トークン」と「シークレット」をメモします。
【コピペで完成】GAS(Google Apps Script)の実装
Googleスプレッドシートの「拡張機能」から「Apps Script」を開き、以下の「黄金コード」を貼り付けてください。
/* ==========================================
設定エリア(ここを書き換えるだけ!)
========================================== */
const LINE_TOKEN = '取得したチャネルアクセストークン';
const LINE_DEST = '取得したグループID';
const API_TOKEN = 'SwitchBotトークン';
const SECRET_TOKEN = 'SwitchBotシークレット';
const SPREADSHEET_ID = 'スプレッドシートのID';
const SHEET_NAME = 'シート名(本社2階作業場など)';
/**
* メイン関数:Looker Studioを凌駕するデザインで送信
*/
function sendPremiumDashboard() {
const sheet = SpreadsheetApp.openById(SPREADSHEET_ID).getSheetByName(SHEET_NAME);
const allData = sheet.getDataRange().getValues();
const devices = ["デバイス名1", "デバイス名2", "デバイス名3", "デバイス名4", "デバイス名5"];
devices.forEach(deviceName => {
const deviceRows = allData.filter(row => String(row[0]).trim() === deviceName);
if (deviceRows.length === 0) return;
// 最新のデータから日付を特定
const lastEntry = deviceRows[deviceRows.length - 1];
const dataDateStr = (lastEntry[2] instanceof Date) ? Utilities.formatDate(lastEntry[2], "Asia/Tokyo", "yyyy/MM/dd") : String(lastEntry[2]);
// その日のデータを1時間ごとに集計
const hourlyMap = {};
deviceRows.filter(row => {
const rDate = (row[2] instanceof Date) ? Utilities.formatDate(row[2], "Asia/Tokyo", "yyyy/MM/dd") : String(row[2]);
return rDate === dataDateStr;
}).forEach(row => {
const displayTime = getHHmm(row[3]);
const hourKey = displayTime.split(":")[0] + ":00";
if (!hourlyMap[hourKey]) hourlyMap[hourKey] = row;
});
const hourlyData = Object.keys(hourlyMap).sort().map(h => hourlyMap[h]).slice(-24);
// QuickChartでメーター画像を生成(ドライブを介さない魔法!)
const chartOpts = (val, color, title) => encodeURIComponent(JSON.stringify({
type: 'radialGauge', data: { datasets: [{ data: [val], backgroundColor: color }] },
options: { centerPercentage: 75, title: { display: true, text: title, fontSize: 18 }, trackColor: '#eee' }
}));
const tempUrl = "https://quickchart.io/chart?c=" + chartOpts(lastEntry[4], '#ff7675', `現温 ${lastEntry[4]}℃`);
const humiUrl = "https://quickchart.io/chart?c=" + chartOpts(lastEntry[5], '#3498db', `現湿 ${lastEntry[5]}%`);
const battUrl = "https://quickchart.io/chart?c=" + chartOpts(lastEntry[8], '#2ecc71', `電池 ${lastEntry[8]}%`);
// Flex Message(24時間表 & メーター)
const flexContents = {
"type": "bubble", "size": "giga",
"header": { "type": "box", "layout": "vertical", "contents": [
{ "type": "box", "layout": "horizontal", "contents": [
{ "type": "text", "text": deviceName + "温度管理", "weight": "bold", "color": "#f1c40f", "size": "sm", "flex": 7 },
{ "type": "text", "text": dataDateStr, "size": "xxs", "color": "#aaaaaa", "align": "end", "flex": 3, "gravity": "bottom" }
]},
{ "type": "text", "text": "24時間 状況推移レポート", "weight": "bold", "size": "lg", "margin": "md", "color": "#2d3436" }
]},
"body": { "type": "box", "layout": "horizontal", "spacing": "md", "contents": [
{ "type": "box", "layout": "vertical", "flex": 4, "contents": [
{ "type": "image", "url": tempUrl, "size": "full", "aspectRatio": "1:1" },
{ "type": "image", "url": humiUrl, "size": "full", "aspectRatio": "1:1" },
{ "type": "image", "url": battUrl, "size": "full", "aspectRatio": "1:1" }
]},
{ "type": "box", "layout": "vertical", "flex": 6, "backgroundColor": "#f8f9fa", "paddingAll": "8px", "cornerRadius": "md", "contents": [
{ "type": "box", "layout": "horizontal", "contents": [
{ "type": "text", "text": "時刻", "size": "xxs", "color": "#999999", "flex": 3 },
{ "type": "text", "text": "温度", "size": "xxs", "color": "#999999", "align": "center", "flex": 3 },
{ "type": "text", "text": "湿度", "size": "xxs", "color": "#999999", "align": "end", "flex": 3 }
]},
{ "type": "separator", "margin": "xs" },
{ "type": "box", "layout": "vertical", "spacing": "xs", "margin": "sm", "contents":
hourlyData.map(row => ({
"type": "box", "layout": "horizontal", "contents": [
{ "type": "text", "text": getHHmm(row[3]), "size": "xxs", "color": "#2d3436", "flex": 3, "weight": "bold" },
{ "type": "text", "text": row[4] + "℃", "size": "xxs", "align": "center", "weight": "bold", "color": "#d63031", "flex": 3 },
{ "type": "text", "text": row[5] + "%", "size": "xxs", "align": "end", "color": "#0984e3", "flex": 3 }
]
}))
}
]}
]}
};
UrlFetchApp.fetch('https://api.line.me/v2/bot/message/push', {
method: 'post', contentType: 'application/json',
headers: { Authorization: 'Bearer ' + LINE_TOKEN },
payload: JSON.stringify({ to: LINE_DEST, messages: [{ type: "flex", altText: "温湿度定期レポ", contents: flexContents }] })
});
Utilities.sleep(1000);
});
}
function getHHmm(v) {
if (v instanceof Date) return Utilities.formatDate(v, "Asia/Tokyo", "HH:mm");
const m = String(v).match(/\d{1,2}:\d{2}/);
return m ? m[0] : "00:00";
}まとめ
「自分には難しそう」と感じましたか? ご安心ください。コードを貼り付け、「実行」ボタンをクリックした瞬間、あなたのスマホは「24時間、不眠不休で現場を見守る有能な部下」に変わります。
数千円の投資で手に入る「安心感」と、自動化によって生まれる新しい「時間」。 さあ、あなたも今すぐSwitchBotを手に入れて、次世代の管理システムをその手にしてください!












