Skip to content

Commit a8f3d68

Browse files
committed
init
1 parent 8850135 commit a8f3d68

File tree

5 files changed

+600
-0
lines changed

5 files changed

+600
-0
lines changed

Waveshare_43inch_ePaper.py

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
#!/usr/bin/env python
2+
#coding: utf-8
3+
4+
'''
5+
部分函数取自https://github.com/yy502/ePaperDisplay.git
6+
由于不太习惯原作的行文风格,故重造一遍。。。
7+
'''
8+
9+
import sys, os
10+
import serial
11+
import struct
12+
import time
13+
14+
FONT_SIZE_32 = 0x01
15+
FONT_SIZE_48 = 0x02
16+
FONT_SIZE_64 = 0x03
17+
18+
MEM_FLASH = 0x00
19+
MEM_SD = 0x01
20+
21+
ROTATION_NORMAL = 0x00
22+
ROTATION_180 = 0x01
23+
24+
# commands
25+
CMD_HANDSHAKE = 0x00 # handshake
26+
CMD_SET_MEMORY = 0x07 # get memory mode
27+
CMD_SET_ROTATION = 0x0d
28+
CMD_UPDATE = 0x0A # update
29+
CMD_LOAD_FONT = 0x0E # copy font files from SD card to NandFlash.
30+
# Font files include GBK32/48/64.FON
31+
# 48MB allocated in NandFlash for fonts
32+
# LED will flicker 3 times when starts and ends.
33+
CMD_LOAD_PIC = 0x0F # Import the image files from SD card to the NandFlash.
34+
# LED will flicker 3 times when starts and ends.
35+
# 80MB allocated in NandFlash for images
36+
CMD_SET_COLOR = 0x10 # set colour
37+
CMD_SET_EN_FONT = 0x1E # set English font
38+
CMD_SET_CH_FONT = 0x1F # set Chinese font
39+
40+
CMD_DRAW_LINE = 0x22 # draw line
41+
CMD_CLEAR = 0x2E # clear screen use back colour
42+
CMD_DRAW_STRING = 0x30 # draw string
43+
CMD_DRAW_BITMAP = 0x70 # draw bitmap
44+
45+
COLOR_BLACK = 0x00
46+
COLOR_DARK_GRAY = 0x01
47+
COLOR_GRAY = 0x02
48+
COLOR_WHITE = 0x03
49+
50+
51+
class Screen:
52+
def __init__(self, tty):
53+
self.tty = tty
54+
55+
def _build_frame(self, cmd, args=None):
56+
length = 9
57+
if args is not None:
58+
length += len(args)
59+
frame = '\xA5' + struct.pack('>h', length) + chr(cmd)
60+
if args is not None:
61+
frame += args
62+
frame += '\xCC\x33\xC3\x3C'
63+
parity = 0x00
64+
for i in xrange(0, len(frame)):
65+
parity = parity ^ ord(frame[i])
66+
frame += chr(parity)
67+
return frame
68+
69+
def _send(self, frame):
70+
self.socket.write(frame)
71+
rt = self.socket.read(10)
72+
73+
def connect(self):
74+
self.socket = serial.Serial(port=self.tty, \
75+
baudrate=115200, \
76+
stopbits=serial.STOPBITS_ONE, \
77+
bytesize=serial.EIGHTBITS, \
78+
timeout=0.03)
79+
80+
def disconnect(self):
81+
self.socket.close()
82+
83+
def handshake(self):
84+
self._send(self._build_frame(CMD_HANDSHAKE))
85+
86+
def set_memory(self, mem):
87+
self._send(self._build_frame(CMD_SET_MEMORY, chr(mem)))
88+
89+
def set_rotation(self, r):
90+
self._send(self._build_frame(CMD_SET_ROTATION, chr(r)))
91+
92+
def clear(self):
93+
self._send(self._build_frame(CMD_CLEAR))
94+
95+
def update(self):
96+
self._send(self._build_frame(CMD_UPDATE))
97+
98+
def line(self, x0, y0, x1, y1):
99+
args = struct.pack('>hhhh', x0, y0, x1, y1)
100+
self._send(self._build_frame(CMD_DRAW_LINE, args))
101+
102+
def set_color(self, front, background):
103+
self._send(self._build_frame(CMD_SET_COLOR, chr(front) + chr(background)))
104+
105+
def set_en_font_size(self, size):
106+
self._send(self._build_frame(CMD_SET_EN_FONT, chr(size)))
107+
108+
def set_ch_font_size(self, size):
109+
self._send(self._build_frame(CMD_SET_CH_FONT, chr(size)))
110+
111+
def _get_real_font_size(self, font_size):
112+
return [0, 32, 48, 64][font_size]
113+
114+
def get_text_width(self, txt, size=FONT_SIZE_32):
115+
size = self._get_real_font_size(size)
116+
width = 0
117+
for c in txt:
118+
if c in "'":
119+
width += 5
120+
elif c in "ijl|":
121+
width += 6
122+
elif c in "f":
123+
width += 7
124+
elif c in " It![].,;:/\\":
125+
width += 8
126+
elif c in "r-`(){}":
127+
width += 9
128+
elif c in '"':
129+
width += 10
130+
elif c in "*":
131+
width += 11
132+
elif c in "x^":
133+
width += 12
134+
elif c in "Jvz":
135+
width += 13
136+
elif c in "cksy":
137+
width += 14
138+
elif c in "Labdeghnopqu$#?_1234567890":
139+
width += 15
140+
elif c in "T+<>=~":
141+
width += 16
142+
elif c in "FPVXZ":
143+
width += 17
144+
elif c in "ABEKSY&":
145+
width += 18
146+
elif c in "HNUw":
147+
width += 19
148+
elif c in "CDR":
149+
width += 20
150+
elif c in "GOQ":
151+
width += 21
152+
elif c in "m":
153+
width += 22
154+
elif c in "M":
155+
width += 23
156+
elif c in "%":
157+
width += 24
158+
elif c in "@":
159+
width += 27
160+
elif c in "W":
161+
width += 28
162+
else: # non-ascii or Chinese character
163+
width += 32
164+
return int(width * (size / 32.0))
165+
166+
167+
def text(self, x0, y0, text):
168+
args = struct.pack('>hh', x0, y0)
169+
if isinstance(text, str):
170+
text = text.decode('utf-8')
171+
text = text.encode('gb2312')
172+
args = args + text + '\x00'
173+
self._send(self._build_frame(CMD_DRAW_STRING, args))
174+
175+
def wrap_text(self, x0, y0, limit, text, font_size=FONT_SIZE_32, line_space=10):
176+
177+
line_height = self._get_real_font_size(font_size)
178+
line = ''
179+
width = 0
180+
cy = y0
181+
182+
if not isinstance(text, unicode):
183+
text = text.decode('utf-8')
184+
185+
for c in text:
186+
line += c
187+
width += self.get_text_width(c, font_size)
188+
if width + font_size * 32 > limit:
189+
self.text(x0, cy, line)
190+
cy += line_height + line_space
191+
line = ''
192+
width = 0
193+
194+
if len(line):
195+
self.text(x0, cy, line)
196+
197+
def load_pic(self):
198+
self._send(self._build_frame(CMD_LOAD_PIC))
199+
200+
def bitmap(self, x0, y0, image):
201+
if isinstance(image, str):
202+
image = image.decode('utf-8')
203+
args = struct.pack('>hh', x0, y0)
204+
args = args + image.encode('ascii') + '\x00'
205+
self._send(self._build_frame(CMD_DRAW_BITMAP, args))
206+
207+

epaper_clock.cron.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
*/30 * * * * root /opt/epaper_clock/weather_fetcher.py
2+
*/1 * * * * root /opt/epaper_clock/home_air_sensor.py
3+
*/1 * * * * root /opt/epaper_clock/weather_time_render.py

home_air_sensor.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env python
2+
import sys, os
3+
import Adafruit_DHT as dht
4+
import json
5+
import time
6+
h,t = dht.read_retry(dht.DHT22, 4)
7+
result = {}
8+
result['temp'] = t
9+
result['humidity'] = h
10+
result['update'] = int(time.time())
11+
data_file = os.path.dirname(os.path.abspath(__file__)) + '/home_air.json'
12+
json.dump(result, file(data_file, 'w'))

weather_fetcher.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#!/usr/bin/env python
2+
#coding: utf-8
3+
import sys, os
4+
import requests
5+
import json
6+
import re
7+
from lxml import etree
8+
import time
9+
10+
output_file = os.path.dirname(os.path.abspath(__file__)) + '/weather.json'
11+
12+
def fail_exit(msg):
13+
rt = {}
14+
rt['error'] = msg
15+
json.dump(rt, file(output_file, 'w'))
16+
sys.exit(1)
17+
18+
try:
19+
r = requests.get('http://weather.sina.com.cn/' \
20+
, timeout=10)
21+
r.encoding = 'utf-8'
22+
html = r.text
23+
except Exception, e:
24+
fail_exit(unicode(e))
25+
26+
result = {}
27+
result['city_name'] = None
28+
result['current_temp'] = None
29+
result['current_weather'] = None
30+
result['current_wind'] = None
31+
result['current_humidity']= None
32+
result['current_aq'] = None
33+
result['current_aq_desc'] = None
34+
result['today_weather'] = None
35+
result['today_temp_low'] = None
36+
result['today_temp_hig'] = None
37+
result['tomorrow_weather']= None
38+
result['tomorrow_temp_low']=None
39+
result['tomorrow_temp_hig']=None
40+
result['tomorrow_wind'] = None
41+
result['tomorrow_aq'] = None
42+
result['tomorrow_aq_desc']= None
43+
44+
tree = etree.HTML(html)
45+
rt = tree.xpath('//*[@id="slider_ct_name"]')
46+
if len(rt):
47+
result['city_name'] = rt[0].text
48+
rt = tree.xpath('//*[@id="slider_w"]//div[@class="slider_degree"]')
49+
if len(rt):
50+
result['current_temp'] = rt[0].text.replace(u'℃', '')
51+
rt = tree.xpath('//*[@id="slider_w"]//p[@class="slider_detail"]')
52+
if len(rt):
53+
tmp0 = re.sub(r'\s', '', rt[0].text)
54+
tmp0 = tmp0.split('|')
55+
if len(tmp0) >= 3:
56+
result['current_weather'] = tmp0[0].strip()
57+
result['current_wind'] = tmp0[1].strip()
58+
tmp1 = re.search(r'([\-\d]+)%', tmp0[2])
59+
if tmp1 is not None:
60+
result['current_humidity'] = tmp1.group(1)
61+
tmp0 = None
62+
tmp1 = None
63+
64+
rt = tree.xpath('//*[@id="slider_w"]/div[1]/div/div[4]/div/div[1]/p')
65+
if len(rt):
66+
result['current_aq'] = rt[0].text
67+
68+
rt = tree.xpath('//*[@id="slider_w"]/div[1]/div/div[4]/div/div[2]/p[1]')
69+
if len(rt):
70+
result['current_aq_desc'] = rt[0].text
71+
72+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[1]/p[3]/img')
73+
if len(rt) == 1:
74+
result['today_weather'] = rt[0].get('alt')
75+
elif len(rt) == 2:
76+
tmp0 = rt[0].get('alt')
77+
tmp1 = rt[1].get('alt')
78+
if tmp0 == tmp1:
79+
result['today_weather'] = tmp0
80+
else:
81+
result['today_weather'] = tmp0 + u'转' + tmp1
82+
tmp0 = None
83+
tmp1 = None
84+
85+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[1]/p[5]')
86+
if len(rt):
87+
tmp0 = rt[0].text.split('/')
88+
if len(tmp0) > 1:
89+
result['today_temp_hig'] = tmp0[0].replace(u'°C', '').strip()
90+
result['today_temp_low'] = tmp0[1].replace(u'°C', '').strip()
91+
else:
92+
result['today_temp_low'] = tmp0[0].replace(u'°C', '').strip()
93+
tmp0 = None
94+
95+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[3]/img')
96+
if len(rt):
97+
tmp0 = rt[0].get('alt')
98+
tmp1 = rt[1].get('alt')
99+
if tmp0 == tmp1:
100+
result['tomorrow_weather'] = tmp0
101+
else:
102+
result['tomorrow_weather'] = tmp0 + u'转' + tmp1
103+
tmp0 = None
104+
tmp1 = None
105+
106+
107+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[5]')
108+
if len(rt):
109+
tmp0 = rt[0].text.split('/')
110+
result['tomorrow_temp_hig'] = tmp0[0].replace(u'°C', '').strip()
111+
result['tomorrow_temp_low'] = tmp0[1].replace(u'°C', '').strip()
112+
tmp0 = None
113+
114+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/p[6]')
115+
if len(rt):
116+
result['tomorrow_wind'] = rt[0].text.strip()
117+
118+
rt = tree.xpath('//*[@id="blk_fc_c0_scroll"]/div[2]/ul/li')
119+
if len(rt):
120+
result['tomorrow_aq'] = rt[0].text
121+
result['tomorrow_aq_desc'] = rt[1].text
122+
123+
keys_require = ['city_name', \
124+
'current_temp', \
125+
'current_weather', \
126+
'current_wind', \
127+
'current_humidity', \
128+
'current_aq', \
129+
'current_aq_desc', \
130+
'today_weather', \
131+
'today_temp_low', \
132+
'tomorrow_weather', \
133+
'tomorrow_temp_low', \
134+
'tomorrow_temp_hig', \
135+
'tomorrow_wind']
136+
137+
for key in keys_require:
138+
if result.get(key) is None:
139+
fail_exit('can not get key %s' % key)
140+
141+
result['update'] = int(time.time())
142+
json.dump(result, file(output_file, 'w'))

0 commit comments

Comments
 (0)