[태그:] wordpress

  • 라즈베리 파이4 온도/습도센서 홈페이지에 연결(그래프 추가)

    프린터 서버로 동작하는 라즈베리 파이에 온도, 습도를 측정하는 dht11 센서를 달았다. 센서는 1,500원인데 배송비 포함 4,000원에 구매했다. 인터넷에서 바로 사용할 수 있는 python 코드를 찾았지만 동작하지 않아 gcc로 된 코드를 사용했다. 아래 그림과 같이 구성했다.

    111에러가 홈 서버 접속 시도를 차단했다. 찾아보니 서버 내 my.cnf 파일 bind 설정을 수정해야 함을 알았다.

    워드 프레스 테마 디렉토리 안 functions.php를 보면 사용자 정의 함수를 만들고, 데이터베이스를 조회할 수 있다. functions.php 파일을 수정하기 보다, header.php를 간단하게 수정했다. 스타일 등 html을 잘 모르기 때문에 가장 간단한 정보만 표시했다. 아래는 header.php 파일이다. 마지막에 4줄 정도만 넣었다.

    <?php
    /**
     * The header for our theme
     *
     * This is the template that displays all of the <head> section and everything up until <div id="content">
     *
     * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
     *
     * @package WordPress
     * @subpackage Twenty_Seventeen
     * @since Twenty Seventeen 1.0
     * @version 1.0
     */
    
    ?><!DOCTYPE html>
    <html <?php language_attributes(); ?> class="no-js no-svg">
    <head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="profile" href="https://gmpg.org/xfn/11">
    
    <?php wp_head(); ?>
    </head>
    
    <body <?php body_class(); ?>>
    <?php wp_body_open(); ?>
    <div id="page" class="site">
    	<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'twentyseventeen' ); ?></a>
    
    	<header id="masthead" class="site-header" role="banner">
    
    		<?php get_template_part( 'template-parts/header/header', 'image' ); ?>
    
    		<?php if ( has_nav_menu( 'top' ) ) : ?>
    			<div class="navigation-top">
    				<div class="wrap">
    					<?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
    				</div><!-- .wrap -->
    			</div><!-- .navigation-top -->
    		<?php endif; ?>
    
    	</header><!-- #masthead -->
    
    	<?php
    
    	/*
    	 * If a regular post or page, and not the front page, show the featured image.
    	 * Using get_queried_object_id() here since the $post global may not be set before a call to the_post().
    	 */
    	if ( ( is_single() || ( is_page() && ! twentyseventeen_is_frontpage() ) ) && has_post_thumbnail( get_queried_object_id() ) ) :
    		echo '<div class="single-featured-image-header">';
    		echo get_the_post_thumbnail( get_queried_object_id(), 'twentyseventeen-featured-image' );
    		echo '</div><!-- .single-featured-image-header -->';
    	endif;
    	?>
    
    
    	<div class="site-content-contain">
    		<div id="content" class="site-content">
    
    /*여기 추가*/
    <div align="center">
    <?php
    $mydb = new wpdb('????','?????','???','???');$results = $mydb->get_results("SELECT * FROM `dataTemperatureAndHumidity` ORDER BY `dataTemperatureAndHumidity`.`time` DESC limit 1");foreach($results as $result){echo "온도: "; echo $result->temperature; echo ", 습도: "; echo $result->humidity;echo ", 수집시각: ";echo $result->time;}
    ?></div>
    

    다음은 라즈베리안에서 돌아가는 gcc 파일이다. 인터넷 파일 그대로 사용했고, crobtab으로 30분에 한번 실행하도록 했다. 다음 컴파일 할 때 mysql과 wiringPi 옵션을 주어야 한다.

    /* mysql connect and query sample */
    #include <stdio.h>
    #include <stdlib.h>
    #include <mysql.h>
    #include <time.h>
    #include <unistd.h>
    #include <wiringPi.h>
    #include <stdint.h>
    #define MAXTIMINGS 83
    #define DHTPIN 0 
    int dht11_dat[5] = {0, } ;
    
    void read_dht11_dat()
    {
    	uint8_t laststate = HIGH ;
    	uint8_t counter = 0 ;
    	uint8_t j = 0, i ;
    	uint8_t flag = HIGH ;
    	uint8_t state = 0 ;
    	float f ;
    	dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0 ;
    	pinMode(DHTPIN, OUTPUT) ;
    	digitalWrite(DHTPIN, LOW) ;
    	delay(18) ;
    	digitalWrite(DHTPIN, HIGH) ;
    	delayMicroseconds(30) ;
    	pinMode(DHTPIN, INPUT) ;
    	for (i = 0; i < MAXTIMINGS; i++) {
    		counter = 0 ;
    		while ( digitalRead(DHTPIN) == laststate) {
    			counter++ ;
    			delayMicroseconds(1) ;
    			if (counter == 200) break ;
    		}
    		laststate = digitalRead(DHTPIN) ;
    		if (counter == 200) break ; // if while breaked by timer, break for
    		if ((i >= 4) && (i % 2 == 0)) {
    			dht11_dat[j / 8] <<= 1 ;
    			if (counter > 20) dht11_dat[j / 8] |= 1 ;
    			j++ ;
    		}
    	}
    	if ((j >= 40) && (dht11_dat[4] == ((dht11_dat[0] + dht11_dat[1] + dht11_dat[2] +
    						dht11_dat[3]) & 0xff))) {
    		printf("humidity = %d.%d %% Temperature = %d.%d *C \n", dht11_dat[0],
    				dht11_dat[1], dht11_dat[2], dht11_dat[3]) ;
    	}
    	else printf("Data get failed\n") ;
    }
    
    float RandomFloat(float a, float b) {
    	//seed 값 현재 시각으로 초기화
    	srand(time(NULL));
        float random = ((float) rand()) / (float) RAND_MAX;
    
        float diff = b - a;
        float r = random * diff;
        return a + r;
    }
     
    int main(int argc, char **argv)
    {
    		if (wiringPiSetup() == -1) exit(1) ;
    		char temp[10];
    		char humidity[10];
    
    		read_dht11_dat();
    
    		sprintf(temp, "%d.%d", dht11_dat[2], dht11_dat[3]);
    		sprintf(humidity, "%d.%d",dht11_dat[0], dht11_dat[1]);
    
    		MYSQL mysql;
    		MYSQL *conn;
            MYSQL_RES *result;
            MYSQL_ROW row;
    
    		//printf("now: %d-%d-%d %d:%d:%d\n",tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec);
     
            char query_buffer[2048];
    		conn = mysql_init(&mysql);
    
    		//float temper, centerVal;		//온도, 중심값.
    		//centerVal=25;
    		//한글을 사용하기 위해 utf-8로 설정.
    		mysql_options(conn, MYSQL_SET_CHARSET_NAME, "utf8");
    		mysql_options(conn, MYSQL_INIT_COMMAND, "SET NAMES utf8");
    		//18, 19행은 한글 사용하기 위해, mysql  옵션 수정..
    		//아래는 서버 설정에 맞도록 수정..
    		if(!mysql_real_connect(conn, "????", "????", "????", NULL, 3306, NULL, 0)){
    				fprintf(stderr,"error %s", mysql_error(conn));
    				printf("cannot connect");
    				exit(1);
    		}
    		else{
    			//아래는 test_db를 사용하도록 수정..
    				if (mysql_select_db(conn, "????")){
    						printf("cannot use databases");
    						exit(1);
    				}
    		}
    
    			time_t t =time(NULL);
    			struct tm tm = *localtime(&t);
    
    			sprintf(query_buffer, "select * from dataTemperatureAndHumidity");
    			mysql_query(conn, query_buffer);
    			result = mysql_store_result(conn);
    
    			while( (row = mysql_fetch_row(result)) != NULL){
    				printf("row[0],%s, %s, %s",row[0], row[1], row[2]);
    			}
    			sprintf(query_buffer, "INSERT INTO `dataTemperatureAndHumidity`(`time`, `temperature`, `humidity`) VALUES ('%d-%d-%d %d:%d:%d', %s, %s);",tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday,tm.tm_hour,tm.tm_min, tm.tm_sec, temp, humidity);
    
    
    
    			if (mysql_query(conn, query_buffer)){
    					printf("query faild : %s\n", query_buffer);
    					exit(1);
    			}
    
    		mysql_close(conn);
     
    }

    마누라에게 자랑하니, 왜 만들었냐고 한다. 아래 그림과 같이 잘 나온다.

    (업데이트)그래프를 그릴 수도 있다.

    https://stackoverflow.com/questions/32005229/how-do-i-generate-a-graph-in-mysql-and-php-based-on-my-sql-statement-result

    jpgraph 모듈을 설치해야 한다. 아래 사이트에서 jpgraph를 다운로드 받아 적당한 web page에 넣어 준다.

    https://jpgraph.net/doc/

    header.php에 graph를 직접 넣으면 안된다. JpGraph Error: HTTP headers have already been sent 이런 에러가 난다. php가 파일로 변환 후 html이 이미지로 표시하게 한다.

    https://stackoverflow.com/questions/10487796/jpgraph-error-http-headers-have-already-been-sent

    header.php

    <?php
    /**
     * The header for our theme
     *
     * This is the template that displays all of the <head> section and everything up until <div id="content">
     *
     * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
     *
     * @package WordPress
     * @subpackage Twenty_Seventeen
     * @since Twenty Seventeen 1.0
     * @version 1.0
     */
    
    ?><!DOCTYPE html>
    <html <?php language_attributes(); ?> class="no-js no-svg">
    <head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="profile" href="https://gmpg.org/xfn/11">
    
    <?php wp_head(); ?>
    </head>
    
    <body <?php body_class(); ?>>
    <?php wp_body_open(); ?>
    <div id="page" class="site">
    	<a class="skip-link screen-reader-text" href="#content"><?php _e( 'Skip to content', 'twentyseventeen' ); ?></a>
    
    	<header id="masthead" class="site-header" role="banner">
    
    		<?php get_template_part( 'template-parts/header/header', 'image' ); ?>
    
    		<?php if ( has_nav_menu( 'top' ) ) : ?>
    			<div class="navigation-top">
    				<div class="wrap">
    					<?php get_template_part( 'template-parts/navigation/navigation', 'top' ); ?>
    				</div><!-- .wrap -->
    			</div><!-- .navigation-top -->
    		<?php endif; ?>
    
    	</header><!-- #masthead -->
    
    	<?php
    
    	/*
    	 * If a regular post or page, and not the front page, show the featured image.
    	 * Using get_queried_object_id() here since the $post global may not be set before a call to the_post().
    	 */
    	if ( ( is_single() || ( is_page() && ! twentyseventeen_is_frontpage() ) ) && has_post_thumbnail( get_queried_object_id() ) ) :
    		echo '<div class="single-featured-image-header">';
    		echo get_the_post_thumbnail( get_queried_object_id(), 'twentyseventeen-featured-image' );
    		echo '</div><!-- .single-featured-image-header -->';
    	endif;
    	?>
    
    
    	<div class="site-content-contain">
    		<div id="content" class="site-content">
    
    <div align="center">
    <?php
    
    
    		$ydata = array();
    		$y2data = array();
    		$xdata = array();
    		$mydb = new wpdb('???','???','???','???');
    		$results = $mydb->get_results("SELECT * FROM `dataTemperatureAndHumidity` ORDER BY `dataTemperatureAndHumidity`.`time` DESC limit 30");
    		foreach($results as $result){
    			$ydata[] = $result->temperature;
    			$y2data[] = $result->humidity;
    			$xdata[] = strtotime($result->time);
    			#echo $result->time;
    		};
    		#echo gettype($xdata[0]);
    
    // Create graph instance
    require_once ('jpgraph/src/jpgraph.php');
    require_once ('jpgraph/src/jpgraph_line.php');
    require_once ('jpgraph/src/jpgraph_date.php');
    
    // Some (random) data
    #$ydata = array(11,3,8,12,5,1,9,13,5,7);
    
    // Size of the overall graph
    $width=400;
    $height=100;
    
    // Create the graph and set a scale.
    // These two calls are always required
    $graph = new Graph($width,$height);
    $graph->SetScale('datlin');
    $graph->title->Set("Temperature");
    
    $graph2 = new Graph($width,$height);
    $graph2->SetScale('datlin');
    $graph2->title->Set("Humidity");
    
    // Create the linear plot
    $lineplot=new LinePlot($ydata, $xdata);
    $lineplot2=new LinePlot($y2data, $xdata);
    
    // Add the plot to the graph
    $graph->Add($lineplot);
    $graph2->Add($lineplot2);
    
    // Display the graph
    $graph->Stroke("./temperature.jpg");
    $graph2->Stroke("./humidity.jpg");
    
    ?></div>
    <div align = "center"><img src = "./temperature.jpg"/> <img src = "./humidity.jpg" /> </div>
    

    잘 표시된다. 홈 페이지가 갈수록 괴상하게 변한다.

  • wordprss jetpack의 self signed certification

    워드프레스가 제공하는 강력한 플러그인 중 하나가 jetpack이다. 설치하고 활성화하면 되는데, https를 야매로 사용하면서 잘 안됐다. 이런 현상이 2013년부터 나왔는데, 아직도 안된다니 한심하다.

    인터넷을 뒤지다 보니, 좋은 해결을 보게 되었다.
    plugin 디렉토리의 경로 하나만 고쳐주면 된다.

  • WordPress로 에버노트 대신하기

    WordPress로 에버노트 대신하기

    워드 프레스 템플릿으로 에버노트 대신하기

    에버노트를 한 5년정도 잘 사용했었다. 작년에 에버노트의 내용을 백업하기 위해 database에 접근했으나, 에버노트 제작사에서 접근을 허용하지 않았다. 관련 프로그램들이 있었으나, 잘 되지 않았고, 데이터가 너무 많은지 파일을 받는데 한계가 있었다. 내가 만든 데이터인데 내가 제대로 소유를 못하고 있다고 생각하니 씁씁했다. 이번 기회에 에버노트를 떠나기로 하고, WordPress로 만든 블로그에 에버노트를 대신할 기능을 추가했다. 기능은 부족하지만, 나름 써보니 괜찮은 듯 하다. 텍스트는 어느 정도 입력, 조회, 수정이 가능했었고, 오늘 몇번의 시행착오 끝에 한개의 사진을 추가 가능하도록 했다.

    페이지로 php를 제공하는 템플릿 만들기

    워드프레스는 기본으로 php를 사용할 수 없다. 다행히? 사용자가 page에서 템플릿을 만든다면 사용할 수 있다. 작업을 조회/수정/입력하는 템플릿을 3개를 만들었다.

    작업 조회하는 php

    이 템플릿은 mysql에 접근하여 완료되지 않은 작업을 표시한다. 사용자가 작업을 추가할 경우, 그룹ID를 할당하는데, 이 그룹ID를 기준으로 작업을 표시한다. mysql의 database는 두 개를 만들었는데 하나는 작업 내용이고, 하나는 이미지 파일의 경로이다. 조회를 눌렀을 때, grpId로 그림의 경로가 있으면 이를 화면에 표시한다.

    wordpress 설치 디렉토리 중 wp-content가 내용을 담당하고 있다. 사용하는 theme의 경로로 이동한 다음 다음 3개의 파일을 만들었다.
    myJob.php, myJobInsert.php, myJobModify.php
    아래 Template Name을 원하는 내용으로 변경하고 page를 만들 때 이를 선택하면 해당 파일의 php 기능을 사용할 수 있다.

    <?php /* Template Name: myJob*/ ?>
    <?php
    get_header(); ?>
    
    <div id="main-content" class="main-content">
    
    <?php
        if ( is_front_page() && twentyfourteen_has_featured_posts() ) { 
            // Include the featured content template.
            get_template_part( 'featured-content' );
    
        }   
    ?>
    

    대략 아래와 같이 작업을 한다.
    1. 로그인이 되어 있는지 확인
    2. mysql user와 password를 시스템에서 읽어옮
    3. 데이터 베이스에 연결
    4. query를 날림..쿼리는 대략 다음과 같이 했다.

    $query="select * from
            (select * from  
            (select* from `workList` order by `id` desc, `업데이트일` desc) as target 
    group by `grpId`)
    as target2 where year(`완료일`) = '0000' order by `마감일` asc";
    

    php에서 template table을 만들 수 있으나, 셰션이 끊기면 임시 테이블도 없어진다. 귀찬고 데이터도 얼마 되지 않아 select를 중첩했다.
    5. query의 결과를 html로 표시해 주는 부분
    6. 이미지가 있으면 이미지도 같이 표시

    작업을 입력하는 php

    이 템플릿은 그룹ID를 할당하여 작업을 입력한다. 오늘 사진도 한장 입력을 할 수 있도록 수정했다. submit 버튼을 누르면 가장 마지막의 GrpId로 오늘 날자를 업데이트 날자로 하여 새로 항목을 만든다. 파일을 업로드 했다면, 파일 경로를 내용에 대한 데이터와 연결한다.

    템플릿은 위와 같은 방법을 만들었다. html에서 form을 설정하여 해당 내용을 $_POST로 데이터 베이스에 변수로 들어가도록 했다.
    1. 로그인 확인 및 데이터베이스에 연결
    2. 가장 마지막의 grpId를 확인
    3. +1을 하여 사용할 grpId로 설정
    4. 오늘 날자, 오늘 날자+14일을 확인하여 업데이트일, 목표일로 자동 설정
    5. form으로 해당하는 내용을 표시
    6. 이미지를 입력할 경우, 파일 이름과 경로를 설정
    7. 사용자가 submit 버튼을 누르면 내용과 이미지의 경로를 데이터베이스에 입력하고, 이미지를 설정한 경로에 업로드

    작업을 수정하는 php

    조회된 작업 중, 수정을 원하는 부분이 있으면 grpId를 확인해야 한다. 작업을 수정한는 페이지에서 Id를 입력하여 내용을 표시한 다음, 내가 원하는 내용으로 업데이트한다. 조회 버튼을 눌렀을 경우, 가장 나중에 작업된 내용이 표시된다.