去年は原発事故を引き金に、計画停電や節電やらと大変な思いをした。
そんななか、少しでも節電意識を高めたいと、「東京電力メーター」を作って公開した。
で、今年の夏は原発再稼働の問題もあり、東電エリアだけの話ではなく、全国的に電力不足に陥りそうな感じ。これはマズい。
そんな訳で「東京電力メーター」もアプリ名に反し、関西電力、東北電力、九州電力の電力使用率も表示できるよう対応してみた。

前にも、東北電力、関西電力に対応したモノを作ったけど、その後、関西電力がcsv公開を一時止めたりしたので、今回は、関西電力を復活したり、九州電力を追加したりと、最新の公開データに合わせて修正した。
[4つの電力会社に対応]




でも何で、東京電力、関西電力、東北電力、九州電力のみの対応かというと、その他の電力会社から現状、CSVデータが公開されていないから。
あと、電力会社毎に微妙にCSVデータ形式が違うので取り込むのが大変だったりする。
でも、各電力会社からデータが公開されたら、東京電力メーターとしても前向きに実装したいと考えているので、CSVが公開されることを期待しながら待つとしよう。
[電力会社ごとのデータ公開状況]
| 電力会社 | 電力の使用状況 | 電力の使用状況データ | 備考 (東電仕様との主な違い) |
||
|---|---|---|---|---|---|
| ファイル | 1時間毎 | 5分間隔 | |||
| 北海道電力 | でんき予報 | CSV | ○ | × | 1時間毎のデータが公開されるようになった。 残念ながら5分間隔のデータや節電お願い文などは無い。 ピーク時供給力が時間帯(XX:00~YY:00)ではなく時台(XX:00)。 |
| 東北電力 | でんき予報 | CSV | ○ | ○ | 「節電お願い文」の英語版は無いが、それ以外はほぼ東電仕様。 |
| 東京電力 | でんき予報 | CSV | ○ | ○ | |
| 中部電力 | × |
× |
× |
× | 2012/3/30で終了。今後の復活に期待。 (供給力などのヘッダ名違い、翌日データ、節電お願い文、5分間隔値などが無い) |
| 北陸電力 | でんき予報 | × | × | × | 2012/5/6より掲載される予定。 |
| 中国電力 | × | × | × | × | 節電要請無しのため? |
| 関西電力 | でんき予報 | CSV | ○ | ○ ※3分間隔 |
東電に比べ使用率,予想気温(最低/最高),気温実績(最低/最高),翌日の使用率,予想気温(最低/最高)が追加され、逆に「節電お願い文」の英語版なし。 |
| 四国電力 | × | × | × | × | 節電要請無しのため? |
| 九州電力 | でんき予報 | CSV XML ※日毎URLが異なる |
× | ○ | 電力の使用状況データのファイル名は日付が付くので注意。 ピーク時供給力が時間帯(XX:00~YY:00)ではなく時台(XX:00)。 1時間毎のデータ、翌日データ、節電お願い文が無い。 XMLデータがあるのはGood。 |
| 沖縄電力 | × | × | × | × | 節電要請無しのため? |
電力会社ごとに異なるCSVフォーマットの差をプログラム側で吸収しなければならず、ゴチャゴチャになってしまったけど以下がガジェットのソースコード。
設定ダイアログ
HTMLソース:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>東京電力メーター</title>
<meta http-equiv="Content-Style-Type" content="text/css"/>
<link href="css/settings.css" rel="stylesheet" type="text/css"/>
<script src="js/settings.js" type="text/javascript"></script>
</head>
<body>
<table width="100%">
<tr>
<td valign="top">
<form>
<select name="gyosya" onchange="getUsageRate(this[this.selectedIndex].value);">
<option value="東京電力">東京電力
<option value="東北電力">東北電力
<option value="関西電力">関西電力
<option value="九州電力">九州電力
</select>
<select name="intervalTime">
<option value="5">5分
<option value="10">10分
<option value="15">15分
<option value="30">30分
<option value="60">60分
</select>
更新
</form>
</td>
<td align="right" valign="top">
<font size="1">
<script type="text/javascript">document.write("Ver " + System.Gadget.version);</script><br>
<a href="http://www.osadasoft.com/" target="_blank">© osadasoft</a>
</font>
</td>
</tr>
</table>
<h5>電力使用状況(1時間平均)</h5>
<div id="vArea" align="center"></div>
<div id="linkArea" align="right"></div>
</body>
</html>
JavaScriptソース:
window.onload = onLoad;
System.Gadget.onSettingsClosing = onSettingsClosing;
img_over = new Image(10,1);
img_over.src = "img/red.png";
img_out = new Image(10,1);
img_out.src = "img/blue.png";
var gyosya = "";
function onSettingsClosing (event) {
if (event.closeAction == event.Action.commit) {
// OK ボタン
System.Gadget.Settings.writeString("IntervalTime", document.getElementById('intervalTime').value);
System.Gadget.Settings.writeString("GyosyaType", document.getElementById('gyosya').value);
}
}
function onLoad(){
// 更新間隔
var idx = 0;
var intervalTime = System.Gadget.Settings.readString("IntervalTime");
if(intervalTime=="") intervalTime = 15; // 初期値=15分
var max = document.getElementById('intervalTime').options.length;
for(i=0;i<max;i++){
if(document.getElementById('intervalTime').options[i].value == intervalTime){
idx = i;
break;
}
}
document.getElementById('intervalTime').options[idx].selected = true;
// 電力会社
gyosya = System.Gadget.Settings.readString("GyosyaType");
getUsageRate(gyosya);
System.Gadget.settingsUI="settings.html";
document.getElementById('gyosya').value = gyosya;
}
function getUsageRate(_gyosya) {
gyosya = _gyosya;
var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
switch(_gyosya){
case "東北電力":
xmlHttp.open("GET",
"http://setsuden.tohoku-epco.co.jp/common/demand/juyo_tohoku.csv?" + (new Date()).getTime());
document.getElementById("linkArea").innerHTML =
"<font size=1><a href='http://setsuden.tohoku-epco.co.jp/graph.html'>でんき予報</a></font>";
break;
case "関西電力":
xmlHttp.open("GET",
"http://www.kepco.co.jp/yamasou/juyo1_kansai.csv?" + (new Date()).getTime());
document.getElementById("linkArea").innerHTML =
"<font size=1><a href='http://www.kepco.co.jp/setsuden/graph/index.html'>でんき予報</a></font>";
break;
case "九州電力":
dt = new Date();
mm=dt.getMonth()+1;
dd=dt.getDate();
if(mm<10) mm="0"+mm;
if(dd<10) dd="0"+dd;
xmlHttp.open("GET",
"http://www.kyuden.co.jp/power_usages/csv/electric_power_usage" + dt.getYear()+mm+dd + ".csv?" + (new Date()).getTime());
document.getElementById("linkArea").innerHTML =
"<font size=1><a href='http://www.kyuden.co.jp/power_usages/pc.html'>でんき予報</a></font>";
break;
case "東京電力":
default:
gyosya = "東京電力";
xmlHttp.open("GET",
"http://www.tepco.co.jp/forecast/html/images/juyo-j.csv?" + (new Date()).getTime());
document.getElementById("linkArea").innerHTML =
"<font size=1><a href='http://www.tepco.co.jp/forecast/index-j.html'>でんき予報</a></font>";
break;
}
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState==4 && xmlHttp.status==200){
document.getElementById("vArea").innerHTML = analyzeData(xmlHttp.responseText);
}else{
document.getElementById("vArea").innerHTML = "<br><br><font size='2'>読込中...</font>";
}
}
xmlHttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
xmlHttp.send(null);
}
function analyzeData(_sCsv){
var sLine;
var sVal="<table><tr><td valign='bottom' style='height:100px;background:white;'><p align=center>";
var cnt=0,idx=0,vPeak=0,vPeakTime="",mNo="",mComment="";
var idxHoure,idxComment;
switch(gyosya){
case "九州電力":
sVal += "でんき予報を参照してください。";
sVal += "</p></td></tr></table>";
return sVal;
break;
case "関西電力":
idxHoure = 11;
idxComment = 46;
break;
case "東北電力":
idxHoure = 8;
idxComment = 40;
break;
case "東京電力":
default:
idxHoure = 8;
idxComment = 40;
break;
}
while(true){
var crIdx = _sCsv.indexOf("\r\n",idx);
if(crIdx!=-1){
sLine = _sCsv.substring(idx,crIdx);
}else{
sLine = _sCsv.substring(idx,_sCsv.length);
break;
}
idx = crIdx+2;
if(cnt>=idxHoure && cnt<=idxHoure+23){
// 9~32行目(1時間ごとの電力)
var sIdx = 0;
var sDate,sTime,sToday,sYesterday;
for(i=0;i<=3;i++){
var eIdx = sLine.indexOf(",",sIdx);
if(eIdx==-1){
sYesterday = sLine.substring(sIdx,sLine.length);
}else{
switch(i){
case 0:
sDate = sLine.substring(sIdx,eIdx);
break;
case 1:
sTime = sLine.substring(sIdx,eIdx);
break;
case 2:
sToday = sLine.substring(sIdx,eIdx);
break;
}
sIdx = eIdx+1;
}
}
if(sToday=="0"){
sVal += "<img src='img/trans.png' width='10px'>";
}else{
sVal += "<img name='gImg" + cnt + "' src='img/blue.png' alt='" + sDate + " " + sTime + " " + sToday
+ "万kW' width='10px' height='" + (sToday/50) + "px' onMouseOver=Img_Over('gImg" + cnt
+ "') onMouseOut=Img_Out('gImg" + cnt + "')>";
}
}else if(cnt==2){
// 3行目(ピーク)
var sIdx = 0;
for(i=0;i<=2;i++){
var eIdx = sLine.indexOf(",",sIdx);
switch(i){
case 0:
vPeak = sLine.substring(sIdx,eIdx);
break;
case 1:
vPeakTime = sLine.substring(sIdx,eIdx);
break;
}
sIdx = eIdx+1;
}
}else if(cnt==idxComment){
// 41行目(節電お願い文)
var idx = sLine.indexOf(",");
if(idx!=-1 && idx+1<sLine.length){
mComment = sLine.substring(idx+1,sLine.length);
}
}
cnt++;
}
sVal += "</p></td></tr></table>";
if(mComment!=""){
sVal += "<h5>節電コメント</h5><font size=-3>" + mComment + "</font><br>";
}
return sVal;
}
function Img_Over(ImgName) {
if (document.images) document.images[ImgName].src = eval("img_over.src");
}
function Img_Out(ImgName) {
if (document.images) document.images[ImgName].src = eval("img_out.src");
}
■メーター表示
HTMLソース:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta http-equiv="Pragma" content="no-cache"> <meta http-equiv="Cache-Control" content="no-cache"> <meta http-equiv="Expires" content="Thu, 01 Dec 1994 16:00:00 GMT"> <title>東京電力メーター</title> <link href="css/gadget.css" rel="stylesheet" type="text/css"/> <meta http-equiv="Content-Style-Type" content="text/css"/> <script src="js/gadget.js" type="text/javascript" charset="utf-8"></script> <body onload="run()"> <g:background src="img/background.png"> <g:image id="s" unselectable="on" src="img/needle.png" style="position:absolute;left:60px;top:0px;width:13px;height:134px;z-index:10" /> <g:image id="c" unselectable="on" src="img/center.png" style="position:absolute;left:60px;top:0px;width:12px;height:134px;z-index:11" /> <div id="vTypeArea" style="position:absolute;top:34px;left:27px;width:80px;z-index:1;font-size:xx-small;color:#888888;text-align:center;"></div> <div id="vTextArea" style="position:absolute;top:48px;left:25px;width:85px;z-index:1;font-size:xx-small;color:#AAAAAA;text-align:center;"></div> <div id="vLinkArea" style="position:absolute;top:87px;left:70px;width:50px;z-index:20;text-align:center;"></div> </body>
JavaScriptソース:
var to;
var nVal=0;
var vVal=0;
var gyosya = "";
var intervalTime;
System.Gadget.onSettingsClosed = run;
function run(){
System.Gadget.settingsUI="settings.html";
s.Rotation = 180;
s.addShadow("grey", 2, 40, 2, 2);
clearTimeout(to);
getUsageRate();
if( !isFinite( intervalTime) || intervalTime==0){
intervalTime = 15; // 数値以外または、0の場合はデフォルト値を設定
}
to = setTimeout("run()",1000 * 60 * intervalTime);
}
function getUsageRate() {
var xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
intervalTime = System.Gadget.Settings.readString("IntervalTime");
gyosya = System.Gadget.Settings.readString("GyosyaType");
switch(gyosya){
case "東北電力":
xmlHttp.open("GET","http://setsuden.tohoku-epco.co.jp/common/demand/juyo_tohoku.csv?" + (new Date()).getTime());
break;
case "関西電力":
xmlHttp.open("GET","http://www.kepco.co.jp/yamasou/juyo1_kansai.csv?" + (new Date()).getTime());
break;
case "九州電力":
dt = new Date();
mm=dt.getMonth()+1;
dd=dt.getDate();
if(mm<10) mm="0"+mm;
if(dd<10) dd="0"+dd;
xmlHttp.open("GET","http://www.kyuden.co.jp/power_usages/csv/electric_power_usage" + dt.getYear()+mm+dd + ".csv?" + (new Date()).getTime());
break;
case "東京電力":
default:
gyosya = "東京電力";
xmlHttp.open("GET","http://www.tepco.co.jp/forecast/html/images/juyo-j.csv?" + (new Date()).getTime());
break;
}
xmlHttp.onreadystatechange = function(){
if(xmlHttp.readyState==4 && xmlHttp.status==200){
document.getElementById("vTypeArea").innerHTML = gyosya;
document.getElementById("vTextArea").innerHTML = analyzeData(xmlHttp.responseText);
document.getElementById("vLinkArea").innerHTML = "<a href='#' onclick='javascript:getUsageRate();'>" + nVal.toFixed(1) + "%</a>";
viewNeedle();
}else{
document.getElementById("vLinkArea").innerHTML = "<a href='#' onclick='javascript:getUsageRate();'>更新中</a>";
}
}
xmlHttp.setRequestHeader("If-Modified-Since", "Thu, 01 Jun 1970 00:00:00 GMT");
xmlHttp.send(null);
}
function analyzeData(_sCsv){
var sLine,sVal="";
var cnt=0,idx=0,vPeak=0,idxMinute,numOfLines;
switch(gyosya){
case "関西電力":
idxMinute = 49;
numOfLines = 479;
break;
case "九州電力":
idxMinute = 8;
numOfLines = 287;
break;
case "東京電力":
case "東北電力":
default:
idxMinute = 44;
numOfLines = 287;
break;
}
while(true){
var crIdx = _sCsv.indexOf("\r\n",idx);
if(crIdx!=-1){
sLine = _sCsv.substring(idx,crIdx);
}else{
sLine = _sCsv.substring(idx,_sCsv.length);
break;
}
idx = crIdx+2;
if(cnt>=idxMinute && cnt<=idxMinute + numOfLines){
var sDate = getData(sLine,1);
var sTime = getData(sLine,2);
var sToday = getData(sLine,3);
if(sToday!="0" && sToday!=""){
nVal = (sToday/vPeak)*100;
sVal = "";
if(vPeak==0){
sVal += "ピーク値取得エラー";
}else{
if(sToday==0){
sVal += "現在値取得エラー";
}else{
sVal += sTime + " 現在<br><br> " + sToday + "/" + vPeak + "万kW<br>";
}
}
}
}else if(cnt==2){
// 3行目(ピーク)
vPeak = sLine.substring(0,sLine.indexOf(",",0));
}
cnt++;
}
if(sVal==""){
if(vPeak==0){
sVal += "ピーク値取得エラー";
}else{
sVal += "現在値取得エラー";
}
}
return sVal;
}
function viewNeedle(){
var cnt=0;
if(vVal.toFixed(0)>=nVal.toFixed(0)){
for(i=vVal.toFixed(0);i>=nVal.toFixed(0);i--){
cnt++;
setTimeout("setRotation(" + i + ")",20*cnt);
}
}else{
for(i=vVal.toFixed(0);i<=nVal.toFixed(0);i++){
cnt++;
setTimeout("setRotation(" + i + ")",20*cnt);
}
}
setTimeout("setRotation(" + nVal.toFixed(1) + ")",20*(cnt+1));
vVal = nVal;
}
function setRotation(_val){
s.Rotation = 2.7*_val+180;
}
function getData(str,tgt){
var sIdx=0,eIdx=0;
for(i=0;i<tgt;i++){
eIdx = str.indexOf(",",sIdx);
if(eIdx==-1){
eIdx = str.length-1;
if(i == tgt - 1) eIdx++;
}
if(i == tgt - 1) break;
sIdx = eIdx+1;
}
return str.substring(sIdx,eIdx);
}
東京電力メーターのダウンロードはこちらから。
http://www.osadasoft.com/software/toden/
ちなみに、ガジェットファイルは「Toden.Gadget」などのように、拡張子が”Gadget”となっている。
この拡張子を”zip”に変更し、圧縮ファイルを解凍すると、そのままHTML,CSS,JavaScript,画像ファイルを見ることが出来る。






