Skip to content

Commit 5574fde

Browse files
committed
Merge remote-tracking branch 'origin/dev'
2 parents ecc74eb + 1f2480b commit 5574fde

4 files changed

Lines changed: 57 additions & 26 deletions

File tree

picframe/controller.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,14 @@ def brightness(self):
197197
def brightness(self, val):
198198
self.__viewer.set_brightness(float(val))
199199

200+
@property
201+
def matting_images(self):
202+
return self.__viewer.get_matting_images()
203+
204+
@matting_images.setter
205+
def matting_images(self, val):
206+
self.__viewer.set_matting_images(float(val))
207+
200208
@property
201209
def location_filter(self):
202210
return self.__location_filter

picframe/interface_mqtt.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ def on_connect(self, client, userdata, flags, rc):
8484
self.__setup_sensor(client, sensor_topic_head, "tags_filter", "mdi:image-search", available_topic)
8585
self.__setup_sensor(client, sensor_topic_head, "image_counter", "mdi:camera-burst", available_topic)
8686
self.__setup_sensor(client, sensor_topic_head, "image", "mdi:file-image", available_topic, has_attributes=True)
87-
8887

8988
## numbers
9089
self.__setup_number(client, number_topic_head, "brightness", 0.0, 1.0, 0.1, "mdi:brightness-6", available_topic)
9190
self.__setup_number(client, number_topic_head, "time_delay", 1, 400, 1, "mdi:image-plus", available_topic)
9291
self.__setup_number(client, number_topic_head, "fade_time", 1, 50, 1,"mdi:image-size-select-large", available_topic)
92+
self.__setup_number(client, number_topic_head, "matting_images", 0.0, 1.0, 0.01, "mdi:image-frame", available_topic)
9393

9494
## selects
9595
_, dir_list = self.__controller.get_directory_list()
@@ -150,7 +150,7 @@ def __setup_sensor(self, client, sensor_topic_head, topic, icon, available_topic
150150
"dev":{"ids":[self.__device_id]}})
151151
client.publish(config_topic, config_payload, qos=0, retain=True)
152152
client.subscribe(self.__device_id + "/" + topic, qos=0)
153-
153+
154154
def __setup_number(self, client, number_topic_head, topic, min, max, step, icon, available_topic):
155155
config_topic = number_topic_head + "_" + topic + "/config"
156156
command_topic = self.__device_id + "/" + topic
@@ -175,7 +175,7 @@ def __setup_select(self, client, select_topic_head, topic, options, icon, availa
175175
command_topic = self.__device_id + "/" + topic
176176
state_topic = "homeassistant/sensor/" + self.__device_id + "/state"
177177
name = self.__device_id + "_" + topic
178-
178+
179179
config_payload = json.dumps({"name": name,
180180
"icon": icon,
181181
"options": options,
@@ -186,7 +186,7 @@ def __setup_select(self, client, select_topic_head, topic, options, icon, availa
186186
"uniq_id": name,
187187
"dev":{"ids":[self.__device_id]}})
188188
client.publish(config_topic, config_payload, qos=0, retain=True)
189-
if init:
189+
if init:
190190
client.subscribe(command_topic, qos=0)
191191

192192
def __setup_switch(self, client, switch_topic_head, topic, icon,
@@ -356,6 +356,10 @@ def on_message(self, client, userdata, message):
356356
elif message.topic == self.__device_id + "/brightness":
357357
self.__logger.info("Recieved brightness: %s", msg)
358358
self.__controller.brightness = float(msg)
359+
# matting_images
360+
elif message.topic == self.__device_id + "/matting_images":
361+
self.__logger.info("Received matting_images: %s", msg)
362+
self.__controller.matting_images = float(msg)
359363
# location filter
360364
elif message.topic == self.__device_id + "/location_filter":
361365
self.__logger.info("Recieved location filter: %s", msg)
@@ -381,7 +385,7 @@ def publish_state(self, image, image_attr):
381385

382386
sensor_state_payload = {}
383387

384-
## sensor
388+
## sensor
385389
# directory sensor
386390
actual_dir, dir_list = self.__controller.get_directory_list()
387391
sensor_state_payload["directory"] = actual_dir
@@ -406,6 +410,8 @@ def publish_state(self, image, image_attr):
406410
sensor_state_payload["fade_time"] = self.__controller.fade_time
407411
# brightness
408412
sensor_state_payload["brightness"] = self.__controller.brightness
413+
# matting_images
414+
sensor_state_payload["matting_images"] = self.__controller.matting_images
409415

410416
# send last will and testament
411417
available_topic = switch_topic_head + "/available"

picframe/viewer_display.py

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def __init__(self, config):
5353
self.__blend_type = {"blend":0.0, "burn":1.0, "bump":2.0}[config['blend_type']]
5454
self.__font_file = os.path.expanduser(config['font_file'])
5555
self.__shader = os.path.expanduser(config['shader'])
56-
self.__show_text_tm = config['show_text_tm']
56+
self.__show_text_tm = float(config['show_text_tm'])
5757
self.__show_text_fm = config['show_text_fm']
5858
self.__show_text_sz = config['show_text_sz']
5959
self.__show_text = parse_show_text(config['show_text'])
@@ -163,7 +163,26 @@ def set_brightness(self, val):
163163
self.__slide.unif[55] = val # take immediate effect
164164

165165
def get_brightness(self):
166-
return float("{:.2f}".format(self.__slide.unif[55])) # TODO There seems to be a rounding issue. set 0.77 get 0.7699999809265137
166+
return round(self.__slide.unif[55], 2) # this will still give 32/64 bit differences sometimes, as will the float(format()) system
167+
168+
def set_matting_images(self, val): # needs to cope with "true", "ON", 0, "0.2" etc.
169+
try:
170+
float_val = float(val)
171+
if round(float_val, 4) == 0.0: # pixellish over a 4k monitor
172+
val = "true"
173+
if round(float_val, 4) == 1.0:
174+
val = "false"
175+
except: # ignore exceptions, error handling is done in following function
176+
pass
177+
self.__mat_images, self.__mat_images_tol = self.__get_mat_image_control_values(val)
178+
179+
def get_matting_images(self):
180+
if self.__mat_images and self.__mat_images_tol > 0:
181+
return self.__mat_images_tol
182+
elif self.__mat_images and self.__mat_images_tol == -1:
183+
return 0
184+
else:
185+
return 1
167186

168187
@property
169188
def clock_is_on(self):
@@ -233,7 +252,6 @@ def __get_aspect_diff(self, screen_size, image_size):
233252
diff_aspect = 1 - (image_aspect / screen_aspect)
234253
else:
235254
diff_aspect = 1 - (screen_aspect / image_aspect)
236-
237255
return (screen_aspect, image_aspect, diff_aspect)
238256

239257

@@ -258,7 +276,7 @@ def __tex_load(self, pics, size=None):
258276
return None
259277
if pics[0].orientation != 1:
260278
im = self.__orientate_image(im, pics[0])
261-
279+
262280
if pics[1]:
263281
im2 = get_image_meta.GetImageMeta.get_image_object(pics[1].fname)
264282
if im2 is None:
@@ -323,29 +341,24 @@ def __tex_load(self, pics, size=None):
323341
#raise # only re-raise errors here while debugging
324342
return tex
325343

326-
def __sanitize_string(self, path_name):
327-
name = os.path.basename(path_name)
328-
#name = ''.join([c for c in name if c in self.__codepoints])
329-
return name
330-
331344
def __make_text(self, pic, paused, side=0, pair=False):
332345
# if side 0 and pair False then this is a full width text and put into
333346
# __textblocks[0] otherwise it is half width and put into __textblocks[position]
334347
info_strings = []
335348
if pic is not None and (self.__show_text > 0 or paused): #was SHOW_TEXT_TM > 0.0
336349
if (self.__show_text & 1) == 1 and pic.title is not None: # title
337-
info_strings.append(self.__sanitize_string(pic.title))
350+
info_strings.append(pic.title)
338351
if (self.__show_text & 2) == 2 and pic.caption is not None: # caption
339-
info_strings.append(self.__sanitize_string(pic.caption))
352+
info_strings.append(pic.caption)
340353
if (self.__show_text & 4) == 4: # name
341-
info_strings.append(self.__sanitize_string(pic.fname))
354+
info_strings.append(os.path.basename(pic.fname))
342355
if (self.__show_text & 8) == 8 and pic.exif_datetime > 0: # date
343356
fdt = time.strftime(self.__show_text_fm, time.localtime(pic.exif_datetime))
344357
info_strings.append(fdt)
345358
if (self.__show_text & 16) == 16 and pic.location is not None: # location
346359
info_strings.append(pic.location) #TODO need to sanitize and check longer than 0 for real
347360
if (self.__show_text & 32) == 32: # folder
348-
info_strings.append(self.__sanitize_string(os.path.basename(os.path.dirname(pic.fname))))
361+
info_strings.append(os.path.basename(os.path.dirname(pic.fname)))
349362
if paused:
350363
info_strings.append("PAUSED")
351364
final_string = " • ".join(info_strings)
@@ -370,6 +383,8 @@ def __make_text(self, pic, paused, side=0, pair=False):
370383
y = (block.sprite.height - self.__display.height + self.__show_text_sz) // 2
371384
block.sprite.position(x, y, 0.1)
372385
block.sprite.set_alpha(0.0)
386+
if side == 0:
387+
self.__textblocks[1] = None
373388
self.__textblocks[side] = block
374389

375390
def __draw_clock(self):
@@ -424,11 +439,9 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,
424439
loop_running = self.__display.loop_running()
425440
tm = time.time()
426441
if pics is not None:
427-
if fade_time <= 0.5:
428-
fade_time = 0.5
429442
#self.__sbg = self.__sfg # if the first tex_load fails then __sfg might be Null TODO should fn return if None?
430443
self.__next_tm = tm + time_delay
431-
self.__name_tm = tm + fade_time + float(self.__show_text_tm) # text starts after slide transition
444+
self.__name_tm = tm + fade_time + self.__show_text_tm # text starts after slide transition
432445
new_sfg = self.__tex_load(pics, (self.__display.width, self.__display.height))
433446
if new_sfg is not None: # this is a possible return value which needs to be caught
434447
self.__sbg = self.__sfg
@@ -437,7 +450,10 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,
437450
#return (True, False) # return early
438451
(self.__sbg, self.__sfg) = (self.__sfg, self.__sbg) # swap existing images over
439452
self.__alpha = 0.0
440-
self.__delta_alpha = 1.0 / (self.__fps * fade_time) # delta alpha
453+
if fade_time > 0.5:
454+
self.__delta_alpha = 1.0 / (self.__fps * fade_time) # delta alpha
455+
else:
456+
self.__delta_alpha = 1.0 # else jump alpha from 0 to 1 in one frame
441457
# set the file name as the description
442458
if self.__show_text_tm > 0.0:
443459
for i, pic in enumerate(pics):
@@ -491,9 +507,10 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,
491507

492508
if self.__alpha >= 1.0 and tm < self.__name_tm:
493509
# this sets alpha for the TextBlock from 0 to 1 then back to 0
494-
dt = (self.__show_text_tm - self.__name_tm + tm + 0.1) / self.__show_text_tm
495-
ramp_pt = max(4.0, self.__show_text_tm / 4.0)
496-
alpha = max(0.0, min(1.0, ramp_pt * (self.__alpha- abs(1.0 - 2.0 * dt)))) # cap text alpha at image alpha
510+
dt = 1.1 - (self.__name_tm - tm) / self.__show_text_tm # i.e. dt from 0.1 to 1.1
511+
ramp_pt = max(4.0, self.__show_text_tm / 4.0) # always > 4 so text fade will always < 4s
512+
# create single saw tooth over 0 to __show_text_tm
513+
alpha = max(0.0, min(1.0, ramp_pt * (1.0 - abs(1.0 - 2.0 * dt)))) # function only run if image alpha is 1.0 so can use 1.0 - abs...
497514
for block in self.__textblocks:
498515
if block is not None:
499516
block.sprite.set_alpha(alpha)

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
install_requires=[
3434
'Pillow',
3535
'ExifRead',
36-
'pi3d>=2.47',
36+
'pi3d>=2.49',
3737
'PyYAML',
3838
'paho-mqtt',
3939
'IPTCInfo3',

0 commit comments

Comments
 (0)