중년코딩
615
2019-05-08 07:54:56 작성 2019-05-14 11:24:28 수정됨
15
5827

[중년코딩|1-1] 게으른 사람이 밭에 물을 주는 법


직장생활 15년만에 Python으로 코딩을 시작한 게으른 중년 대머리 아저씨입니다.

회사에서는 인사, 총무 업무를 맡고 있습니다.

혼자서 공부하려니 진도가 안 나가서 공부하는 과정을 여기 적어보려 합니다.

모든 프로젝트는 1편: 사양 정의, 필요 모듈 및 알고리즘 정리, 2편: 구현 및 첨삭, 3편: 최종 산출물 요약 형태로 구성할 계획입니다.

현재 구상중인 프로젝트는 게으른 성격을 반영하여...

1. 옥상 텃밭에 날씨에 따라 자동으로 물주기

2. 회사 출입카드를 인식해서 라벨프린터에서 이름 출력하기

3. NLP를 이용한 야식 주문 취합 슬랙 챗봇

4. 회의실 예약 상황 QR코드 및 자동 예약

5. 식당이름을 얘기하면 메뉴를 알려주는 슬랙 챗봇

등, 없어도 내 몸 불편한 거 말고는 하등에 지장이 없거나 이미 어느 정도는 솔루션이 나와 있어 손만 까닥하면 할 수 있지만 그 손 하나 까닥하는 게 귀찮아서 며칠을 만들고 있는, 다시말해 쓸데없는 주제들입니다. 

프로그램 사양서 짜본 적도 없고, 함수가 뭔지 람다가 뭔지도 모르는 초보입니다. Python 위주이긴 하지만 라즈베리파이나 아두이노, 제가 제일 자신있어하는 스프레드시트가 튀어나올 가능성이 높습니다. 게으른 성격상 언제 그만 둘지도 모르지만, 일단 옥상 텃밭 물주기부터 시작해 봅니다.(엄청 깁니다.)



# 현재 능력치: 딕셔너리 써 본 적 있음(쓸 때마다 헷갈림). 클래스 써 본 적 있음(왜 쓰는지 아직 잘 이해 안 됨). 크롤링은 좀 해봄.


I. 목적

1. 옥상 텃밭에 아침 6시에 자동으로 물을 10분간 준다.

2. 비가 오는 날에는 안 준다.

3. 물을 주고 있는 상태가 30분 이상 계속되면 알림을 준다.

II. 가용자원(H/W 및 S/W)

1. Sonoff Basic: wifi로 껐다 켰다 할 수 있는 IoT 스위치로 자체 앱, IFTTT, 구글 홈, Alexa와 연동 가능하나 API를 제공하지 않음
*후회: 집에 놀고 있는 Sonoff Basic을 굳이 쓰겠다는 일념을 가지지 말았어야 했습니다. 요즘은 IoT 콘센트가 많이 나오고 스마트씽스니 뭐니 연동이 잘 돼서, python 프로그래밍까지 하지 않아도 해결 가능합니다... 날씨 상관없이 자동으로 물주는 것만 하려면 그냥 구글 홈에 루틴 등록하면 끝입니다... 하지만, 전 게으르니까 해봅니다.

2. 220v 솔레노이드 밸브 및 점적호스: 전원을 인가하면 열리고 끊으면 닫히는 알리 익스프레스발 4딸라짜리 밸브. 그리고 관수용 점적호스
*후회: 솔레노이드 밸브는 12v, 24v, 220v가 있는데 12v 살 걸 그랬어요... 감전될까 무서움.

3. Sonoff-Python 모듈(https://pypi.org/project/sonoff-python/)

원래 Sonoff는 API가 없는데, HA에 붙이려고 연구하던 분들이 만들어 놓은 모듈이 있고, 그걸 가공해서 파이썬용 모듈을 만들어 놓은 분이 있습니다. 이게 아니었으면 스마트씽스에 붙이기 위해서 펌웨어를 올려야 합니다. 귀찮죠... 

4.기상청 RSS

날씨 API는 가입하기 귀찮습니다. 얼마나 귀찮은지 알아보기도 귀찮을만큼 게을러서... 그냥 기상청 RSS를 파싱해서 가져올 겁니다. 네이버 날씨를 크롤링할까도 싶었지만 제게 필요한 이후 6시간 예상 강수량을 제공해주지 않습니다.
*후회: 회원가입하고 API 쓸 걸... RSS는 날씨가 0,1,2,3 처럼 숫자로 표시되어 있어서 변환을 해줘야 합니다...

III. 구상

1. 날씨 확인

우리 동네 날씨를 검색하는 기상청 RSS에서 6시간 내 강수량(r06태그)을 가져옵니다. 

동네예보 RSS의 주소는 https://www.weather.go.kr/weather/lifenindustry/sevice_rss.jsp 여기입니다. 암호처럼 보입니다... 구글링으로 코드의 설명을 찾았습니다. http://www.kma.go.kr/images/weather/lifenindustry/timeseries_XML.pdf

<rss version="2.0">
<channel>
<title>기상청 동네예보 웹서비스 - 서울특별시 동작구 신대방제2동 도표예보</title>
<link>http://www.kma.go.kr/weather/main.jsp</link>
<description>동네예보 웹서비스</description>
<language>ko</language>
<generator>동네예보</generator>
<pubDate>2019년 05월 07일 (화)요일 23:00</pubDate>
<item>
<author>기상청</author>
<category>서울특별시 동작구 신대방제2동</category>
<title>동네예보(도표) : 서울특별시 동작구 신대방제2동 [X=59,Y=125]</title>
<link>
http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=1159068000
</link>
<guid>
http://www.kma.go.kr/weather/forecast/timeseries.jsp?searchType=INTEREST&dongCode=1159068000
</guid>
<description>
<header>
<tm>201905072300</tm>
<ts>7</ts>
<x>59</x>
<y>125</y>
</header>
<body>
<data seq="0">
<hour>3</hour>
<day>1</day>
<temp>11.0</temp>
<tmx>22.0</tmx>
<tmn>11.0</tmn>
<sky>1</sky>
<pty>0</pty>
<wfKor>맑음</wfKor>
<wfEn>Clear</wfEn>
<pop>0</pop>
<r12>0.0</r12>
<s12>0.0</s12>
<ws>1.2000000000000002</ws>
<wd>4</wd>
<wdKor>남</wdKor>
<wdEn>S</wdEn>
<reh>70</reh>
<r06>0.0</r06>
<s06>0.0</s06>
제가 필요한 부분은 data seq="0"(첫번째 3시간 예보)의 r06(6시간 예상 강우량)입니다. xml을 파싱하기 위해 여러 모듈들을 테스트해봅니다. feedparser를 포함한 몇 개를 돌려봤는데 제대로 못 돌리겠습니다. 정작 내용이 있는 body를 못 가져오는 거 같습니다. 그냥 써 본 적있는 뷰티풀 숲으로 갑니다. 나중에 생각해보니 body는 계층구조로 되어 있어서 내용이 안 읽어진 거 같지만... 이왕 뷰티풀 숲 쓰기로 했으니 그냥 갑니다.

이미 코드는 다 짠 상태인데 이 글을 적으면서 Python에서 쓸 수 있는 XML관련 내용이 정리된 사이트를 발견했습니다. 억울하네요 .https://wiki.python.org/moin/PythonXml RSS Python으로 검색했더니 feedparser가 나왔는데, XML Python으로 찾아야 elementTree가 나오는 거였군요. 뭐가 더 좋은지 잘 모르겠지만 뷰티풀 숲으로 가기로 한 거 그냥 갑니다. 사람은 일관적이어야 합니다.

rss 구조는 3시간 단위로 예보가 20개가 나옵니다. 제가 필요한 건 첫 예보(<data seq='0'>)의 6시간 강수량(<r06>)입니다. 요거만 가져오면 되는데... 왠지 날씨를 가져오는 모듈을 만들고 싶어집니다. 시간과 날씨속성을 지정하면 해당 데이터 시퀀스의 해당 날씨 항목들을 가져오는 함수를 작성하다가.... datetime 함수를 쓰기 귀찮아서 포기합니다.(여기서 30분 정도 소모...) 그래도 *args 구문을 처음으로 써봤습니다. 대견합니다. response=float(weather.find('data',{'seq':0}).r06.string) 이거 한 줄이면 되는 것을...

여기까지 한 다섯 시간 걸렸나 봅니다. ㅡ,.ㅡa

2. Sonoff 제어

매일 아침 6시에(crontab 사용 예정) 날씨 확인 결과 6시간 내 강수량이 20mm 이하면 Sonoff를 호출해서 스위치를 켭니다.

Sonoff-Python 모듈은 config.py에 Sonoff(ITEAD, ewelink) 접속 정보를 넣도록 되어 있습니다.

username # 전화번호(지역번호 포함, '+8210xxxxxxxx' 형태로 적습니다. +가 빠지면 안 됩니다.
password
api_region # 서버 접속주소입니다. 한국은 'as'로 지정합니다.
user_apikey # None
bearer_apikey # None
grace_period # 600이 기본값입니다.

넣고 테스트를 돌려보는데 오류가 납니다. 

모듈을 만든 아저씨가 HTTP_MOVED_PERMANENTLY 등 상수 선언을 안 해 놨습니다. 좀 게으른 분인가 봅니다. 그래도 이렇게 만들어주셨으니 고마운 분입니다.
HTTP_MOVED_PERMANENTLY, HTTP_NOT_FOUND, HTTP_BAD_REQUEST를 각각 Http 설명 문서를 참고해서 301, 404, 400으로 설정해줍니다.

또 오류가 납니다. get_api_region 함수가 없는데 호출하고 있습니다. 주석 처리 해줍니다. 저만큼 게으른 아저씨인가 싶습니다.

또 오류가 납니다. __init.py__에 3.6이상 버전용 코드를 만들어뒀는데 왜인지 모르겠지만 pip 인스톨로 들어온 파일에는 빠져있습니다. 수정합니다. 왜 다 만들어 놓고 커밋을 제대로 안 하셨을까요.

아진짜 또 오류가!!! outlet 파라미터 기본값을 none으로 수정해줍니다. 어? 갑자기 됩니다. 세상에...
이렇게 간단하게? 되는 거였다니... 

3. 실행 및 점검 모듈
이제 1) 아침 6시에 날씨를 체크해서 6시간내에 비가 안온다고 하면 물주기 함수를 실행하고 2) 6시 10분에 끄고 3) 주기적으로 체크해서 1시간 이상 켜짐 상태인 스위치가 있는지 체크해서 슬랙으로 알림을 주는 모듈만 더 하면 됩니다... datetime 모듈 써야겠네요.. 이런...
어쨌든 나머지는 짜집기이니 2편에 계속하기로 하고 저는 이만 출근합니다. 

p.s. 어떤 피드백이든 환영합니다. 긴 글 읽어주셔서 감사합니다.



2편을 추가하였습니다. https://okky.kr/article/577316
17
8
  • 댓글 15

  • 중년코딩
    615
    2019-05-08 08:23:30

    망했습니다. crontab쓰려고 했는데 서버가 윈도우10입니다. 작업스케줄러 공부를 해야하네요... 아니면 WSL에서 크론탭이 돌아갈까요...?

  • mirheeoj
    11k
    2019-05-08 08:24:46

    텃밭에 물주는 솔루션의 가장 큰 변수는 과연 텃밭까지 닿을 수 있는 수도가 존재하는가가 아닐까 합니다.

    나머지는 기능구현으로 때울 수 있는데 인프라가 안 받쳐주면 힘들어지죠

    수동으로 물탱크 채우는 방식은 귀찮아서 목적 달성이 안되니까요. 

  • abilists.com
    1k
    2019-05-08 08:33:15

    저는 더 게을러서, 위 내용을 풀로우 차트나, 이미지 그림으로 그리는 스타일 입니다.

  • fender
    18k
    2019-05-08 08:50:56

    아직 첫 취업도 하기 전인 분들이 개발자가 낫냐 공무원이 낫냐 같은 질문을 하는 것을 보면 무언가 먹먹한 느낌이 들었는데 이 글을 보니 그런 답답함이 한 번에 해소되는 것 같습니다.

    좋은 글 감사드리며 응원하겠습니다.

  • 중년코딩
    615
    2019-05-08 09:08:08

    @열나코딩 제가 저희 아이한테 비슷한 얘기를 많이 합니다. 우리 아기 커서 화가되겠다고.ㅎㅎㅎ 본업인 인사, 총무 쪽은 이미 훌륭한 앱이 많이 나와 있습니다. 돈이 되는 일은 다들 열심히 해놨죠. 그래서 저는 쓸데없는 거만 만들려구요.

    @mirheeoj 옥상 텃밭이라 수도가 있습니다. 제가 얼마나 게으른데 수도가 없으면 시작을 안 했겠죠. 사실 그냥 5미터짜리 호스로 하루 10분 투자하면 물 다 줄 수 있습니다. 텃밭이래봤자 몇 평 되지도 않고... 근데 그게 귀찮네요.ㅎ 항상 99가 갖춰져있는데 1을 하기 귀찮을 때 다른 궁리를 하게 되는 거 같습니다.(그래서 일을 하기 귀찮나봐요 하하하하하 -_-)

    @abilists.com 오... 플로우차트를 그리는 법을 배울 정도로 부지런하시다니, 제가 이겼습니다.

    @fender 업으로 하시려는 분들은 나름의 절박함과 진지함이 있으시겠지요. 저는 이제 시작해도 이걸 업으로 하기는 여러가지로 힘들 거 같아서 낚시, 골프, 야구관람 대신하는 취미로 가꾸려고 합니다. 감사합니다.

  • 아플라
    617
    2019-05-08 11:15:25

    취미라고는 하셨지만 계획도 있으시고 열정도 남달라보이세요..

    멋지십니다!

  • 배우고싶은이
    734
    2019-05-08 13:22:47

    부럽네요 ㅠㅠ

    제 꿈이 취미로 코딩하기 인데 글쓰신 분은 이루셨네요.


    언제쯤 직업으로서의 코딩을 안할 수 있을까요 ㅠㅠ

  • sbroh
    10k
    2019-05-08 14:13:56

    2편은 언제 나오는지, 총 몇 편까지 계획 중이실지 궁금합니다. ^^

  • 중년코딩
    615
    2019-05-08 22:51:53

    @아플라 취미니까 계획도 열정도 있을 수 있는 거겠지요. 부끄럽습니다.

    @배우고싶은이 ㅎㅎ 저도 취미로 인사 총무 하고 싶긴 합니다.

    @sbroh 게을러서... 원래 오늘 2편 올릴 예정이었는데 다른 거 만드느라 쪼금 더 걸릴 거 같아요 ㅎㅎ 인생계획한 대로 뭐 됩니까? 하는 만큼 하는 거죠.ㅎ

  • 하마
    6k
    2019-05-09 08:47:42 작성 2019-05-09 08:53:36 수정됨

    팁 & 테크로 ㄱㄱ

    참고로 프로페셔널 개발자들도 님과 비슷하게 개발합니다. ㅎ 

  • Karen
    15k
    2019-05-09 14:33:02
    칼럼에 써주셔도 좋을 거 같아요ㅋㅋ!! bb
  • 롤플레이어원
    561
    2019-05-09 16:23:37

    ㅋㅋㅋㅋㅋ 재밌어요

  • punkyguy
    224
    2019-06-15 10:46:35

    ㅋㅋ 진짜 재밌네요!

  • 로그인을 하시면 댓글 을 등록할 수 있습니다.