-
Notifications
You must be signed in to change notification settings - Fork 65
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
600 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
#!/usr/bin/env python | ||
#coding: utf-8 | ||
|
||
''' | ||
部分函数取自https://github.com/yy502/ePaperDisplay.git | ||
由于不太习惯原作的行文风格,故重造一遍。。。 | ||
''' | ||
|
||
import sys, os | ||
import serial | ||
import struct | ||
import time | ||
|
||
FONT_SIZE_32 = 0x01 | ||
FONT_SIZE_48 = 0x02 | ||
FONT_SIZE_64 = 0x03 | ||
|
||
MEM_FLASH = 0x00 | ||
MEM_SD = 0x01 | ||
|
||
ROTATION_NORMAL = 0x00 | ||
ROTATION_180 = 0x01 | ||
|
||
# commands | ||
CMD_HANDSHAKE = 0x00 # handshake | ||
CMD_SET_MEMORY = 0x07 # get memory mode | ||
CMD_SET_ROTATION = 0x0d | ||
CMD_UPDATE = 0x0A # update | ||
CMD_LOAD_FONT = 0x0E # copy font files from SD card to NandFlash. | ||
# Font files include GBK32/48/64.FON | ||
# 48MB allocated in NandFlash for fonts | ||
# LED will flicker 3 times when starts and ends. | ||
CMD_LOAD_PIC = 0x0F # Import the image files from SD card to the NandFlash. | ||
# LED will flicker 3 times when starts and ends. | ||
# 80MB allocated in NandFlash for images | ||
CMD_SET_COLOR = 0x10 # set colour | ||
CMD_SET_EN_FONT = 0x1E # set English font | ||
CMD_SET_CH_FONT = 0x1F # set Chinese font | ||
|
||
CMD_DRAW_LINE = 0x22 # draw line | ||
CMD_CLEAR = 0x2E # clear screen use back colour | ||
CMD_DRAW_STRING = 0x30 # draw string | ||
CMD_DRAW_BITMAP = 0x70 # draw bitmap | ||
|
||
COLOR_BLACK = 0x00 | ||
COLOR_DARK_GRAY = 0x01 | ||
COLOR_GRAY = 0x02 | ||
COLOR_WHITE = 0x03 | ||
|
||
|
||
class Screen: | ||
def __init__(self, tty): | ||
self.tty = tty | ||
|
||
def _build_frame(self, cmd, args=None): | ||
length = 9 | ||
if args is not None: | ||
length += len(args) | ||
frame = '\xA5' + struct.pack('>h', length) + chr(cmd) | ||
if args is not None: | ||
frame += args | ||
frame += '\xCC\x33\xC3\x3C' | ||
parity = 0x00 | ||
for i in xrange(0, len(frame)): | ||
parity = parity ^ ord(frame[i]) | ||
frame += chr(parity) | ||
return frame | ||
|
||
def _send(self, frame): | ||
self.socket.write(frame) | ||
rt = self.socket.read(10) | ||
|
||
def connect(self): | ||
self.socket = serial.Serial(port=self.tty, \ | ||
baudrate=115200, \ | ||
stopbits=serial.STOPBITS_ONE, \ | ||
bytesize=serial.EIGHTBITS, \ | ||
timeout=0.03) | ||
|
||
def disconnect(self): | ||
self.socket.close() | ||
|
||
def handshake(self): | ||
self._send(self._build_frame(CMD_HANDSHAKE)) | ||
|
||
def set_memory(self, mem): | ||
self._send(self._build_frame(CMD_SET_MEMORY, chr(mem))) | ||
|
||
def set_rotation(self, r): | ||
self._send(self._build_frame(CMD_SET_ROTATION, chr(r))) | ||
|
||
def clear(self): | ||
self._send(self._build_frame(CMD_CLEAR)) | ||
|
||
def update(self): | ||
self._send(self._build_frame(CMD_UPDATE)) | ||
|
||
def line(self, x0, y0, x1, y1): | ||
args = struct.pack('>hhhh', x0, y0, x1, y1) | ||
self._send(self._build_frame(CMD_DRAW_LINE, args)) | ||
|
||
def set_color(self, front, background): | ||
self._send(self._build_frame(CMD_SET_COLOR, chr(front) + chr(background))) | ||
|
||
def set_en_font_size(self, size): | ||
self._send(self._build_frame(CMD_SET_EN_FONT, chr(size))) | ||
|
||
def set_ch_font_size(self, size): | ||
self._send(self._build_frame(CMD_SET_CH_FONT, chr(size))) | ||
|
||
def _get_real_font_size(self, font_size): | ||
return [0, 32, 48, 64][font_size] | ||
|
||
def get_text_width(self, txt, size=FONT_SIZE_32): | ||
size = self._get_real_font_size(size) | ||
width = 0 | ||
for c in txt: | ||
if c in "'": | ||
width += 5 | ||
elif c in "ijl|": | ||
width += 6 | ||
elif c in "f": | ||
width += 7 | ||
elif c in " It![].,;:/\\": | ||
width += 8 | ||
elif c in "r-`(){}": | ||
width += 9 | ||
elif c in '"': | ||
width += 10 | ||
elif c in "*": | ||
width += 11 | ||
elif c in "x^": | ||
width += 12 | ||
elif c in "Jvz": | ||
width += 13 | ||
elif c in "cksy": | ||
width += 14 | ||
elif c in "Labdeghnopqu$#?_1234567890": | ||
width += 15 | ||
elif c in "T+<>=~": | ||
width += 16 | ||
elif c in "FPVXZ": | ||
width += 17 | ||
elif c in "ABEKSY&": | ||
width += 18 | ||
elif c in "HNUw": | ||
width += 19 | ||
elif c in "CDR": | ||
width += 20 | ||
elif c in "GOQ": | ||
width += 21 | ||
elif c in "m": | ||
width += 22 | ||
elif c in "M": | ||
width += 23 | ||
elif c in "%": | ||
width += 24 | ||
elif c in "@": | ||
width += 27 | ||
elif c in "W": | ||
width += 28 | ||
else: # non-ascii or Chinese character | ||
width += 32 | ||
return int(width * (size / 32.0)) | ||
|
||
|
||
def text(self, x0, y0, text): | ||
args = struct.pack('>hh', x0, y0) | ||
if isinstance(text, str): | ||
text = text.decode('utf-8') | ||
text = text.encode('gb2312') | ||
args = args + text + '\x00' | ||
self._send(self._build_frame(CMD_DRAW_STRING, args)) | ||
|
||
def wrap_text(self, x0, y0, limit, text, font_size=FONT_SIZE_32, line_space=10): | ||
|
||
line_height = self._get_real_font_size(font_size) | ||
line = '' | ||
width = 0 | ||
cy = y0 | ||
|
||
if not isinstance(text, unicode): | ||
text = text.decode('utf-8') | ||
|
||
for c in text: | ||
line += c | ||
width += self.get_text_width(c, font_size) | ||
if width + font_size * 32 > limit: | ||
self.text(x0, cy, line) | ||
cy += line_height + line_space | ||
line = '' | ||
width = 0 | ||
|
||
if len(line): | ||
self.text(x0, cy, line) | ||
|
||
def load_pic(self): | ||
self._send(self._build_frame(CMD_LOAD_PIC)) | ||
|
||
def bitmap(self, x0, y0, image): | ||
if isinstance(image, str): | ||
image = image.decode('utf-8') | ||
args = struct.pack('>hh', x0, y0) | ||
args = args + image.encode('ascii') + '\x00' | ||
self._send(self._build_frame(CMD_DRAW_BITMAP, args)) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
*/30 * * * * root /opt/epaper_clock/weather_fetcher.py | ||
*/1 * * * * root /opt/epaper_clock/home_air_sensor.py | ||
*/1 * * * * root /opt/epaper_clock/weather_time_render.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
#!/usr/bin/env python | ||
import sys, os | ||
import Adafruit_DHT as dht | ||
import json | ||
import time | ||
h,t = dht.read_retry(dht.DHT22, 4) | ||
result = {} | ||
result['temp'] = t | ||
result['humidity'] = h | ||
result['update'] = int(time.time()) | ||
data_file = os.path.dirname(os.path.abspath(__file__)) + '/home_air.json' | ||
json.dump(result, file(data_file, 'w')) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#!/usr/bin/env python | ||
#coding: utf-8 | ||
import sys, os | ||
import requests | ||
import json | ||
import re | ||
from lxml import etree | ||
import time | ||
|
||
output_file = os.path.dirname(os.path.abspath(__file__)) + '/weather.json' | ||
|
||
def fail_exit(msg): | ||
rt = {} | ||
rt['error'] = msg | ||
json.dump(rt, file(output_file, 'w')) | ||
sys.exit(1) | ||
|
||
try: | ||
r = requests.get('http://weather.sina.com.cn/' \ | ||
, timeout=10) | ||
r.encoding = 'utf-8' | ||
html = r.text | ||
except Exception, e: | ||
fail_exit(unicode(e)) | ||
|
||
result = {} | ||
result['city_name'] = None | ||
result['current_temp'] = None | ||
result['current_weather'] = None | ||
result['current_wind'] = None | ||
result['current_humidity']= None | ||
result['current_aq'] = None | ||
result['current_aq_desc'] = None | ||
result['today_weather'] = None | ||
result['today_temp_low'] = None | ||
result['today_temp_hig'] = None | ||
result['tomorrow_weather']= None | ||
result['tomorrow_temp_low']=None | ||
result['tomorrow_temp_hig']=None | ||
result['tomorrow_wind'] = None | ||
result['tomorrow_aq'] = None | ||
result['tomorrow_aq_desc']= None | ||
|
||
tree = etree.HTML(html) | ||
rt = tree.xpath('//*[@id="slider_ct_name"]') | ||
if len(rt): | ||
result['city_name'] = rt[0].text | ||
rt = tree.xpath('//*[@id="slider_w"]//div[@class="slider_degree"]') | ||
if len(rt): | ||
result['current_temp'] = rt[0].text.replace(u'℃', '') | ||
rt = tree.xpath('//*[@id="slider_w"]//p[@class="slider_detail"]') | ||
if len(rt): | ||
tmp0 = re.sub(r'\s', '', rt[0].text) | ||
tmp0 = tmp0.split('|') | ||
if len(tmp0) >= 3: | ||
result['current_weather'] = tmp0[0].strip() | ||
result['current_wind'] = tmp0[1].strip() | ||
tmp1 = re.search(r'([\-\d]+)%', tmp0[2]) | ||
if tmp1 is not None: | ||
result['current_humidity'] = tmp1.group(1) | ||
tmp0 = None | ||
tmp1 = None | ||
|
||
rt = tree.xpath('//*[@id="slider_w"]/div[1]/div/div[4]/div/div[1]/p') | ||
if len(rt): | ||
result['current_aq'] = rt[0].text | ||
|
||
rt = tree.xpath('//*[@id="slider_w"]/div[1]/div/div[4]/div/div[2]/p[1]') | ||
if len(rt): | ||
result['current_aq_desc'] = rt[0].text | ||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[1]/p[3]/img') | ||
if len(rt) == 1: | ||
result['today_weather'] = rt[0].get('alt') | ||
elif len(rt) == 2: | ||
tmp0 = rt[0].get('alt') | ||
tmp1 = rt[1].get('alt') | ||
if tmp0 == tmp1: | ||
result['today_weather'] = tmp0 | ||
else: | ||
result['today_weather'] = tmp0 + u'转' + tmp1 | ||
tmp0 = None | ||
tmp1 = None | ||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[1]/p[5]') | ||
if len(rt): | ||
tmp0 = rt[0].text.split('/') | ||
if len(tmp0) > 1: | ||
result['today_temp_hig'] = tmp0[0].replace(u'°C', '').strip() | ||
result['today_temp_low'] = tmp0[1].replace(u'°C', '').strip() | ||
else: | ||
result['today_temp_low'] = tmp0[0].replace(u'°C', '').strip() | ||
tmp0 = None | ||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[3]/img') | ||
if len(rt): | ||
tmp0 = rt[0].get('alt') | ||
tmp1 = rt[1].get('alt') | ||
if tmp0 == tmp1: | ||
result['tomorrow_weather'] = tmp0 | ||
else: | ||
result['tomorrow_weather'] = tmp0 + u'转' + tmp1 | ||
tmp0 = None | ||
tmp1 = None | ||
|
||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[5]') | ||
if len(rt): | ||
tmp0 = rt[0].text.split('/') | ||
result['tomorrow_temp_hig'] = tmp0[0].replace(u'°C', '').strip() | ||
result['tomorrow_temp_low'] = tmp0[1].replace(u'°C', '').strip() | ||
tmp0 = None | ||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[6]') | ||
if len(rt): | ||
result['tomorrow_wind'] = rt[0].text.strip() | ||
|
||
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/ul/li') | ||
if len(rt): | ||
result['tomorrow_aq'] = rt[0].text | ||
result['tomorrow_aq_desc'] = rt[1].text | ||
|
||
keys_require = ['city_name', \ | ||
'current_temp', \ | ||
'current_weather', \ | ||
'current_wind', \ | ||
'current_humidity', \ | ||
'current_aq', \ | ||
'current_aq_desc', \ | ||
'today_weather', \ | ||
'today_temp_low', \ | ||
'tomorrow_weather', \ | ||
'tomorrow_temp_low', \ | ||
'tomorrow_temp_hig', \ | ||
'tomorrow_wind'] | ||
|
||
for key in keys_require: | ||
if result.get(key) is None: | ||
fail_exit('can not get key %s' % key) | ||
|
||
result['update'] = int(time.time()) | ||
json.dump(result, file(output_file, 'w')) |
Oops, something went wrong.