1. 개요
1부에서는 Band에 WebTile을 올려보았다. 조금 아쉬웠던 부분을 이글에서 마무리 하고자 한다.
1.1. 수정사항
- 페이지 줄이기 – 평일에는 평일 시간표만, 휴일에는 휴일 시간표만.
- 160자 제한 해결 – 현재 시간 기준으로 시간표 필터링.
위의 수정사항을 해결하기 위해서는 1부에서 사용했던 정적인 json 파일로는 어렵다. 따라서 동적인 Web 언어를 이용하여 json 파일을 생성하여 클라이언트로 내려주고자 한다.
애초에 간단하게 만들기가 목적이었기에, 별도의 서버 또는 서비스를 구축하지 않고, 현재 블로그를 실행하고 있는 WordPress에 php 파일을 하나 추가 생성하여 해결하기로 한다.
일단 난 Web은 잘 모른다. 더구나 php 는 1도 모른다. 이어지는 php 코드는 쌩초짜가 작성한 것임을 미리 밝힌다.
2. 수정
일단 HTTP Request에 대한 json Response을 반환하기위한 php파일을 생성한다. 그리고 기존의 json 파일을 객체화 시킨다.
<?php // 배차시간표 $busTimeTables = array( "weekdays" => array( array( "station" => "긴고랑", // 필터링을 위해 시간을 나타내는 문자열을 배열로 생성한다. "times" => array("06:00","06:10","06:20","06:30","06:40","06:50","07:00","07:10","07:20","07:30","07:40","07:50","08:00","08:15","08:30","08:45","09:00","09:20","09:40","10:00","10:20","10:40","11:00","11:20","11:40","12:00","12:20","12:40","13:00","13:20","13:40","14:00","14:20", "14:40","15:00","15:20","15:40","16:00","16:20","16:40","17:00","17:20","17:40","18:00","18:20","18:40","19:00","19:20","19:40","20:00","20:20","20:40","21:00","21:20","21:40","22:00","22:20") ), array( "station" => "군자역", // 필터링을 위해 시간을 나타내는 문자열을 배열로 생성한다. "times" => array("06:10","06:20","06:30","06:40","06:50","07:00","07:10","07:20","07:30","07:40","07:50","08:00","08:15","08:30","08:45","09:00","09:20","09:40","10:00","10:20","10:40","11:00","11:20","11:40","12:05","12:25","12:40","13:00","13:20","13:40","14:00","14:20","14:40", "15:00","15:20","15:40","16:00","16:20","16:40","17:00","17:25","17:45","18:00","18:20","18:40","19:00","19:20","19:40","20:00","20:20","20:40","21:00","21:20","21:40","22:00","22:20","22:30") ) ), "holidays" => array( array( "station" => "긴고랑", // 필터링을 위해 시간을 나타내는 문자열을 배열로 생성한다. "times" => array("07:00","07:25","07:50","08:15","08:40","09:05","09:30","09:55","10:20","10:45","11:10","11:35","12:00","12:25","12:50","13:15","13:40","14:05","14:30","14:55","15:20","15:45","16:10","16:35","17:00","17:25","17:50","18:15","18:40","19:05","19:30","19:55","20:20", "20:45","21:10","21:35","22:00","22:20") ), array( "station" => "군자역", // 필터링을 위해 시간을 나타내는 문자열을 배열로 생성한다. "times" => array("07:10","07:35","08:00","08:25","08:50","09:15","09:40","10:05","10:30","10:55","11:20","11:45","12:10","12:35","13:00","13:25","13:50","14:15","14:40","15:05","15:30","16:20","16:45","17:15","17:40","18:05","18:30","18:55","19:20","19:45","20:10","20:35","21:00", "21:25","21:50","22:10","22:30") ) ) ); // json Response를 위한 HTTP Header 설정 header('Content-Type: application/json'); // php 객체를 json으로 인코딩 echo json_encode($busTimeTables); ?>
2.1. 페이지 줄이기 – 평일에는 평일 시간표만, 휴일에는 휴일 시간표만.
평일과 휴일(일요일)을 구분하기 위해 아래의 함수를 추가한다. 추후 공휴일의 정보가 필요할 경우 ‘공공데이터포탈의 특일 정보제공 서비스 OpenAPI‘ 를 이용하기로 하고 지금은 단순히 일요일만 판단하기로 한다.
<?php function isHoliday($date) { return (date('w', strtotime($date)) == 0); } // HTTP GET 파라미터(date)로 날짜를 가져온다. 파라미터가 없는 경우 현재 날짜로 설정한다. $date = $_GET['date'] == null ? date('Y-m-d') : $_GET['date']; $currentDays = isHoliday($date) ? $busTimeTables['holidays'] : $busTimeTables['weekdays']; ?>
2.2. 160자 제한 해결 – 현재 시간 기준으로 시간표 필터링.
현재시간 이후의 배차시간표만 가져오기 위해 아래의 코드를 추가한다. 위에서 필터링한 $currentDays 배열에서 array_filter() 함수를 이용하여 다시 한번 필터링 한다.
<?php // HTTP GET 파라미터(time)로 시간를 가져온다. 파라미터가 없는 경우 현재 시간으로 설정한다. $time = $_GET['time'] == null ? date('H:i') : $_GET['time']; foreach ($currentDays as &$currentDay) { $filteredTimes = array_filter($currentDay['times'], function ($compareTime) use ($time) { // 문자열 비교를 통하여 시간값을 판단한다. return strcmp($time, $compareTime) <= 0; }); if (sizeof($filteredTimes) == 0) { // 막차시간 이후에 조회한 경우, 필터를 적용하지 않은 array를 가져온다. $filteredTimes = $currentDay['times']; } // 필터링된 배열을 하나의 문자열로 합친다. $filteredTimesString = implode(' ', $filteredTimes); // 기존 배열에 필터링한 문자열을 추가한다. $currentDay = array_merge($currentDay, array('filteredTimesString' => $filteredTimesString)); } unset($currentDay); ?>
2.3. 전체 소스
추가적으로 요청한 날짜와 시간을 표시하기 위해 몇가지 정보를 $currentDays 에 추가하였다. 아래는 전체 php 소스이다.
<?php // functions function isHoliday($date) { return (date('w', strtotime($date)) == 0); } $busTimeTables = array( "weekdays" => array( array( "station" => "긴고랑", "times" => array("06:00","06:10","06:20","06:30","06:40","06:50","07:00","07:10","07:20","07:30","07:40","07:50","08:00","08:15","08:30","08:45","09:00","09:20","09:40","10:00","10:20","10:40","11:00","11:20","11:40","12:00","12:20","12:40","13:00","13:20","13:40","14:00","14:20", "14:40","15:00","15:20","15:40","16:00","16:20","16:40","17:00","17:20","17:40","18:00","18:20","18:40","19:00","19:20","19:40","20:00","20:20","20:40","21:00","21:20","21:40","22:00","22:20") ), array( "station" => "군자역", "times" => array("06:10","06:20","06:30","06:40","06:50","07:00","07:10","07:20","07:30","07:40","07:50","08:00","08:15","08:30","08:45","09:00","09:20","09:40","10:00","10:20","10:40","11:00","11:20","11:40","12:05","12:25","12:40","13:00","13:20","13:40","14:00","14:20","14:40", "15:00","15:20","15:40","16:00","16:20","16:40","17:00","17:25","17:45","18:00","18:20","18:40","19:00","19:20","19:40","20:00","20:20","20:40","21:00","21:20","21:40","22:00","22:20","22:30") ) ), "holidays" => array( array( "station" => "긴고랑", "times" => array("07:00","07:25","07:50","08:15","08:40","09:05","09:30","09:55","10:20","10:45","11:10","11:35","12:00","12:25","12:50","13:15","13:40","14:05","14:30","14:55","15:20","15:45","16:10","16:35","17:00","17:25","17:50","18:15","18:40","19:05","19:30","19:55","20:20", "20:45","21:10","21:35","22:00","22:20") ), array( "station" => "군자역", "times" => array("07:10","07:35","08:00","08:25","08:50","09:15","09:40","10:05","10:30","10:55","11:20","11:45","12:10","12:35","13:00","13:25","13:50","14:15","14:40","15:05","15:30","16:20","16:45","17:15","17:40","18:05","18:30","18:55","19:20","19:45","20:10","20:35","21:00", "21:25","21:50","22:10","22:30") ) ) ); $date = $_GET['date'] == null ? date('Y-m-d') : $_GET['date']; $time = $_GET['time'] == null ? date('H:i') : $_GET['time']; $currentDays = isHoliday($date) ? $busTimeTables['holidays'] : $busTimeTables['weekdays']; foreach ($currentDays as &$currentDay) { $filteredTimes = array_filter($currentDay['times'], function ($compareTime) use ($time) { return strcmp($time, $compareTime) <= 0; }); if (sizeof($filteredTimes) == 0) { // 막차시간 이후에 조회한 경우, 필터를 적용하지 않은 array를 가져온다. $filteredTimes = $currentDay['times']; } $filteredTimesString = implode(' ', $filteredTimes); $currentDay = array_merge($currentDay, array('filteredTimesString' => $filteredTimesString)); } unset($currentDay); array_push($currentDays, (isHoliday($date) ? '공휴일' : '평일'), "$date $time"); // add 배차시간표 종류, 업데이트 시간 header('Content-Type: application/json'); echo json_encode($currentDays); ?>
위의 소스를 웹서버에 Upload하고 실행하면 현재 요일, 시간기준으로 필터링된 배차시간표를 확인 할 수 있다.
[ { "station": "긴고랑", "times": [ "06:00", "06:10", "06:20", "06:30", "06:40", "06:50", "07:00", "07:10", "07:20", "07:30", "07:40", "07:50", "08:00", "08:15", "08:30", "08:45", "09:00", "09:20", "09:40", "10:00", "10:20", "10:40", "11:00", "11:20", "11:40", "12:00", "12:20", "12:40", "13:00", "13:20", "13:40", "14:00", "14:20", "14:40", "15:00", "15:20", "15:40", "16:00", "16:20", "16:40", "17:00", "17:20", "17:40", "18:00", "18:20", "18:40", "19:00", "19:20", "19:40", "20:00", "20:20", "20:40", "21:00", "21:20", "21:40", "22:00", "22:20" ], "filteredTimesString": "16:20 16:40 17:00 17:20 17:40 18:00 18:20 18:40 19:00 19:20 19:40 20:00 20:20 20:40 21:00 21:20 21:40 22:00 22:20" }, { "station": "군자역", "times": [ "06:10", "06:20", "06:30", "06:40", "06:50", "07:00", "07:10", "07:20", "07:30", "07:40", "07:50", "08:00", "08:15", "08:30", "08:45", "09:00", "09:20", "09:40", "10:00", "10:20", "10:40", "11:00", "11:20", "11:40", "12:05", "12:25", "12:40", "13:00", "13:20", "13:40", "14:00", "14:20", "14:40", "15:00", "15:20", "15:40", "16:00", "16:20", "16:40", "17:00", "17:25", "17:45", "18:00", "18:20", "18:40", "19:00", "19:20", "19:40", "20:00", "20:20", "20:40", "21:00", "21:20", "21:40", "22:00", "22:20", "22:30" ], "filteredTimesString": "16:20 16:40 17:00 17:25 17:45 18:00 18:20 18:40 19:00 19:20 19:40 20:00 20:20 20:40 21:00 21:20 21:40 22:00 22:20 22:30" }, "평일", "2016-11-24 16:04" ]
3. 배포
배포절차는 기본적으로 1부에서 설명한 것과 같다. Step 2의 URL 을 위에서 작성한 php 링크로 변경한다. 그리고 Step 3에서 Assign your data에서 아래와 같이 Station, filteredTimesString을 데이터로 설정한다.
그리고 webtile을 Download하여 Band의 WebTile을 실행하여 동작을 확인한다.
4. manifest.json 수정
버스 배차시간표의 간격은 최소 20분인데, WebTile의 기본 요청 주기는 30분이다. 이 부분을 수정하기 위해 *.webtile 파일의 확장자를 *.webtile.zip 으로 변경하여 manifest.json 파일을 변경해야 한다. manifest.json 파일의 refreshIntervalMinutes 값을 WebTile의 허용가능한 최소 값인 15로 변경한다. 그리고 버전 정보 또한 적당히 변경한다.
{ "manifestVersion": 1, "name": "광진02", "description": "서울시 광진02 마을버스 배차시간표", "version": 3, "versionString": "1.0", "author": "Reasty", "organization": "", "contactEmail": "reastykim@gmail.com", "tileIcon": { "46": "icons/tileIcon.png" }, "icons": {}, "refreshIntervalMinutes": 15, "resources": [ { "url": "http://api.reasty.net/bus/SeoulTownBus-Gwangjin02.php", "style": "Simple", "content": { "_1_2": "[2]", "_1_0station": "[0].station", "_1_0filteredtimesstring": "[0].filteredTimesString", "_1_3": "[3]", "_1_1station": "[1].station", "_1_1filteredtimesstring": "[1].filteredTimesString" } } ], "pages": [ { "layout": "MSBand_ScrollingText", "condition": "true", "textBindings": [ { "elementId": "1", "value": "{{_1_2}} {{_1_0station}}" }, { "elementId": "2", "value": "{{_1_0filteredtimesstring}}" } ] }, { "layout": "MSBand_ScrollingText", "condition": "true", "textBindings": [ { "elementId": "1", "value": "{{_1_2}} {{_1_1station}}" }, { "elementId": "2", "value": "{{_1_1filteredtimesstring}}" } ] } ] }
5. 마무리
다소 미비하고, 약간의 버그(토요일 막차시간이후 조회하는 경우, 공휴일이 아니라 평일 시간표를 가져옴)가 있지만 여기서 마무리 하고자 한다.
실제 테스트결과 요청시간에 따라 필터링 된 배차 시간표를 확인할 수 있었다. 하지만 변경한 refreshIntervalMinutes 값처럼 15분 마다 정확하게 업데이트 되지는 않았다. Microsoft 홈페이지에서는 어떠한 정보도 찾을 수 없었다. Band와 핸드폰의 Microsoft Band앱간의 Bluetooth 통신과 연결스펙인듯 하다. 아마 이부분은 WebTile의 한계점인것 같다.
Microsoft Band의 WebTile App을 하나 만들어 보았고, 더불어 PHP도 조금 건드려 본, 간단하지만 개인적으로 제법 의미있는 프로젝트였다.
간단한 RSS Feed 정도가 WebTile에 어울릴듯하고, 조금만 더 복잡한 로직이 필요하다면 Mobile App으로 Band SDK를 연동해야 할 것같다.
ㅋㅋㅋ사진이 오래된듯?!
밴드사진? 프로필사진? ㅋ