White Paper
Please understand my incorrect and poor korean expression
실행결과 : 시간대별 소비전력
실행결과 : 누적전력량[wh]과 실시간소비전력
LD1210DR-040 적산전력계에서 전력펄스 신호를 받아 파일로 저장하는 프로그램입니다.
파일은 날짜.kwh, 날짜.cnt, curpower.kwh 이렇게 만들어집니다.
날짜.* 은 하루에 하나씩만들어 집니다. curpower.kwh는 현재 전력량입니다.
출력파일예)
20090114.kwh
20090114 22:48:42 Wed, 4.078, 882.850, 635.652, 213988.0,
20090114 22:48:46 Wed, 4.017, 896.256, 645.304, 221054.3,
20090114 22:48:50 Wed, 4.049, 889.173, 640.205, 217320.9,
20090114 22:48:54 Wed, 3.997, 900.740, 648.533, 223418.1,
20090114 22:48:58 Wed, 3.888, 925.990, 666.713, 236728.0,
20090114 22:49:02 Wed, 4.025, 894.474, 644.022, 220115.4,
20090114 22:49:06 Wed, 3.351, 1074.366, 773.544, 314940.5,
20090114.cnt
206
curpower.kwh
pulsewidthSec,watt,monthKwh,MonthCost
4.550, 791.273, 569.717, 165715.7,
power.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define BASETIME 100000L
void Settimer(void)
{
struct itimerval t;
t.it_interval.tv_sec = 0;
t.it_interval.tv_usec = 0;
t.it_value.tv_sec = BASETIME; /* 1시간 */
t.it_value.tv_usec = 0;
if (setitimer(ITIMER_REAL, &t, NULL) == -1){ perror("Failed to set virtual timer"); }
}
float Gettimer(void)
{
struct itimerval t;
float diftime;
if (getitimer(ITIMER_REAL, &t) == -1){perror("Failed to get virtual timer");}
diftime=(float)BASETIME-((float)(t.it_value.tv_sec)+((float)t.it_value.tv_usec/1000000.0));
return(diftime);
}
int Initprinterport(void)
{
int fd; // File Descripter
fd = open("/dev/port", O_RDWR); // open /dev/port in read & write mode
if(fd < 0) // open error, fd must be unsigned.
{
perror("/dev/port open error");
}
return(fd);
}
void Closeprinterport(int fd)
{
close(fd);
}
void Outdataprinterport(int fd,unsigned char data)
{
unsigned char buff[1];
int op;
buff[0]=data;
lseek(fd,0x378,0);
write(fd,buff,1);
}
int Getbusyprinterport(int fd)
{
unsigned char buffr[1];
int op;
lseek(fd,0x379,0);
read(fd,buffr,1);
buffr[0]>>=7;
op=(int)(0x01&buffr[0]);
return(op);
}
int main(void)
{
int i,j;
float pulse_time_per_1wh,pulse_time_error_revision;
float power_consumption_month,watt_cost,watt;
float cost,basic_cost,tax,sum[7];
int fd;
int pulsecount;
float tm,frq;
FILE *fw;
struct tm *tm_ptr, time_struc;
time_t the_time;
char buffer[255];
char filename[255];
basic_cost=6410.0;
tax=1.137; //부가가치세 10% + 전력기반기금 3.7% 즉 0.1+0.037=0.137 올라야하므로 1.137;
fd=Initprinterport();
Outdataprinterport(fd,0xff); // DATA PORT<-0XFF :D0 LED 전원공급및 전력계 OC 풀업용
printf("Copyright MADIXON all reserved\n");
// 전력계 펄스 초기화 ..
printf("Init Pulse\n");
while(1) if(Getbusyprinterport(fd)==0) break;
while(1) if(Getbusyprinterport(fd)==1) break;
printf("Measuring Watt\n");
while(1)
{
while(1) if(Getbusyprinterport(fd)==0) break;
Settimer();
while(1) if(Getbusyprinterport(fd)==1) break;
pulse_time_per_1wh=Gettimer();
if(pulse_time_per_1wh>=0.01) // 0.01초 이전 데이터는 잡음에 의한 것이므로..
{
pulse_time_error_revision=pulse_time_per_1wh+0.070; // 0.070 Falling edge로 펄스 시간으로 측정하지 않으므로 펄스폭 70mSec을 더해준다.
watt=(3600.0/pulse_time_error_revision); // 실시간 watt 계산...
power_consumption_month=((60.0*60.0*24.0*30.0)/pulse_time_error_revision)/1000.0; //kwh
watt_cost=power_consumption_month;
cost=0;
for(i=0;i<=6;i++) sum[i]=0.0;
if(watt_cost>500.0){ watt_cost=watt_cost-500.0; cost=(watt_cost*643.9); sum[6]=cost; watt_cost=500.0; }
if(watt_cost>400.0){ watt_cost=watt_cost-400.0; cost=(watt_cost*366.4); sum[5]=cost; watt_cost=400.0; }
if(watt_cost>300.0){ watt_cost=watt_cost-300.0; cost=(watt_cost*248.6); sum[4]=cost; watt_cost=300.0; }
if(watt_cost>200.0){ watt_cost=watt_cost-200.0; cost=(watt_cost*168.3); sum[3]=cost; watt_cost=200.0; }
if(watt_cost>100.0){ watt_cost=watt_cost-100.0; cost=(watt_cost*113.8); sum[2]=cost; watt_cost=100.0; }
if(watt_cost> 0.0){ watt_cost=watt_cost- 0.0; cost=(watt_cost* 55.1); sum[1]=cost; watt_cost= 0.0; }
sum[0]=sum[1]+sum[2]+sum[3]+sum[4]+sum[5]+sum[6];
cost=(sum[0]*tax)+basic_cost;
(void) time(&the_time);
tm_ptr = localtime(&the_time);
strftime(buffer,23,"%Y%m%d %H:%M:%S %a",tm_ptr);
strftime(filename,23,"./%Y%m%d.kwh",tm_ptr);
// 펄스폭,순간와트,한달예상kwh,한달예상요금
fw=fopen(filename,"awt");
fprintf(fw,"%s,%6.3f,%10.3f,%10.3f,%10.1f,\n",buffer,pulse_time_error_revision,watt,power_consumption_month,cost);
fclose(fw);
fw=fopen("./curpower.kwh","wt");
fprintf(fw,"pulsewidthSec,watt,monthKwh,MonthCost\n");
fprintf(fw,"%6.3f,%10.3f,%10.3f,%10.1f,\n",pulse_time_error_revision,watt,power_consumption_month,cost);
fclose(fw);
strftime(filename,23,"./%Y%m%d.cnt",tm_ptr);
// printf("%s\n",filename);
fw=fopen(filename,"rt");
if(fw==NULL) pulsecount=0;
else
{
fread(buffer,1,30,fw);
pulsecount=atoi(buffer);
fclose(fw);
}
// printf("%s\n",buffer);
pulsecount++;
fw=fopen(filename,"wt");
fprintf(fw,"%d\n",pulsecount);
fclose(fw);
}
}
Closeprinterport(fd);
return 0;
}
위의 소스를 컴파일 하여 power라는 파일로 만들었습니다.
$gcc power
$cp ./a.out /var/www/html/PowerMeasure
$vi /etc/rc.local
cd /var/www/html/PowerMeasure
./power &
$/sbin/shutdown -r 0