Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
helgeerbe committed Nov 4, 2021
2 parents ecc74eb + 1f2480b commit 5574fde
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 26 deletions.
8 changes: 8 additions & 0 deletions picframe/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,14 @@ def brightness(self):
def brightness(self, val):
self.__viewer.set_brightness(float(val))

@property
def matting_images(self):
return self.__viewer.get_matting_images()

@matting_images.setter
def matting_images(self, val):
self.__viewer.set_matting_images(float(val))

@property
def location_filter(self):
return self.__location_filter
Expand Down
16 changes: 11 additions & 5 deletions picframe/interface_mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,12 @@ def on_connect(self, client, userdata, flags, rc):
self.__setup_sensor(client, sensor_topic_head, "tags_filter", "mdi:image-search", available_topic)
self.__setup_sensor(client, sensor_topic_head, "image_counter", "mdi:camera-burst", available_topic)
self.__setup_sensor(client, sensor_topic_head, "image", "mdi:file-image", available_topic, has_attributes=True)


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

## selects
_, dir_list = self.__controller.get_directory_list()
Expand Down Expand Up @@ -150,7 +150,7 @@ def __setup_sensor(self, client, sensor_topic_head, topic, icon, available_topic
"dev":{"ids":[self.__device_id]}})
client.publish(config_topic, config_payload, qos=0, retain=True)
client.subscribe(self.__device_id + "/" + topic, qos=0)

def __setup_number(self, client, number_topic_head, topic, min, max, step, icon, available_topic):
config_topic = number_topic_head + "_" + topic + "/config"
command_topic = self.__device_id + "/" + topic
Expand All @@ -175,7 +175,7 @@ def __setup_select(self, client, select_topic_head, topic, options, icon, availa
command_topic = self.__device_id + "/" + topic
state_topic = "homeassistant/sensor/" + self.__device_id + "/state"
name = self.__device_id + "_" + topic

config_payload = json.dumps({"name": name,
"icon": icon,
"options": options,
Expand All @@ -186,7 +186,7 @@ def __setup_select(self, client, select_topic_head, topic, options, icon, availa
"uniq_id": name,
"dev":{"ids":[self.__device_id]}})
client.publish(config_topic, config_payload, qos=0, retain=True)
if init:
if init:
client.subscribe(command_topic, qos=0)

def __setup_switch(self, client, switch_topic_head, topic, icon,
Expand Down Expand Up @@ -356,6 +356,10 @@ def on_message(self, client, userdata, message):
elif message.topic == self.__device_id + "/brightness":
self.__logger.info("Recieved brightness: %s", msg)
self.__controller.brightness = float(msg)
# matting_images
elif message.topic == self.__device_id + "/matting_images":
self.__logger.info("Received matting_images: %s", msg)
self.__controller.matting_images = float(msg)
# location filter
elif message.topic == self.__device_id + "/location_filter":
self.__logger.info("Recieved location filter: %s", msg)
Expand All @@ -381,7 +385,7 @@ def publish_state(self, image, image_attr):

sensor_state_payload = {}

## sensor
## sensor
# directory sensor
actual_dir, dir_list = self.__controller.get_directory_list()
sensor_state_payload["directory"] = actual_dir
Expand All @@ -406,6 +410,8 @@ def publish_state(self, image, image_attr):
sensor_state_payload["fade_time"] = self.__controller.fade_time
# brightness
sensor_state_payload["brightness"] = self.__controller.brightness
# matting_images
sensor_state_payload["matting_images"] = self.__controller.matting_images

# send last will and testament
available_topic = switch_topic_head + "/available"
Expand Down
57 changes: 37 additions & 20 deletions picframe/viewer_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def __init__(self, config):
self.__blend_type = {"blend":0.0, "burn":1.0, "bump":2.0}[config['blend_type']]
self.__font_file = os.path.expanduser(config['font_file'])
self.__shader = os.path.expanduser(config['shader'])
self.__show_text_tm = config['show_text_tm']
self.__show_text_tm = float(config['show_text_tm'])
self.__show_text_fm = config['show_text_fm']
self.__show_text_sz = config['show_text_sz']
self.__show_text = parse_show_text(config['show_text'])
Expand Down Expand Up @@ -163,7 +163,26 @@ def set_brightness(self, val):
self.__slide.unif[55] = val # take immediate effect

def get_brightness(self):
return float("{:.2f}".format(self.__slide.unif[55])) # TODO There seems to be a rounding issue. set 0.77 get 0.7699999809265137
return round(self.__slide.unif[55], 2) # this will still give 32/64 bit differences sometimes, as will the float(format()) system

def set_matting_images(self, val): # needs to cope with "true", "ON", 0, "0.2" etc.
try:
float_val = float(val)
if round(float_val, 4) == 0.0: # pixellish over a 4k monitor
val = "true"
if round(float_val, 4) == 1.0:
val = "false"
except: # ignore exceptions, error handling is done in following function
pass
self.__mat_images, self.__mat_images_tol = self.__get_mat_image_control_values(val)

def get_matting_images(self):
if self.__mat_images and self.__mat_images_tol > 0:
return self.__mat_images_tol
elif self.__mat_images and self.__mat_images_tol == -1:
return 0
else:
return 1

@property
def clock_is_on(self):
Expand Down Expand Up @@ -233,7 +252,6 @@ def __get_aspect_diff(self, screen_size, image_size):
diff_aspect = 1 - (image_aspect / screen_aspect)
else:
diff_aspect = 1 - (screen_aspect / image_aspect)

return (screen_aspect, image_aspect, diff_aspect)


Expand All @@ -258,7 +276,7 @@ def __tex_load(self, pics, size=None):
return None
if pics[0].orientation != 1:
im = self.__orientate_image(im, pics[0])

if pics[1]:
im2 = get_image_meta.GetImageMeta.get_image_object(pics[1].fname)
if im2 is None:
Expand Down Expand Up @@ -323,29 +341,24 @@ def __tex_load(self, pics, size=None):
#raise # only re-raise errors here while debugging
return tex

def __sanitize_string(self, path_name):
name = os.path.basename(path_name)
#name = ''.join([c for c in name if c in self.__codepoints])
return name

def __make_text(self, pic, paused, side=0, pair=False):
# if side 0 and pair False then this is a full width text and put into
# __textblocks[0] otherwise it is half width and put into __textblocks[position]
info_strings = []
if pic is not None and (self.__show_text > 0 or paused): #was SHOW_TEXT_TM > 0.0
if (self.__show_text & 1) == 1 and pic.title is not None: # title
info_strings.append(self.__sanitize_string(pic.title))
info_strings.append(pic.title)
if (self.__show_text & 2) == 2 and pic.caption is not None: # caption
info_strings.append(self.__sanitize_string(pic.caption))
info_strings.append(pic.caption)
if (self.__show_text & 4) == 4: # name
info_strings.append(self.__sanitize_string(pic.fname))
info_strings.append(os.path.basename(pic.fname))
if (self.__show_text & 8) == 8 and pic.exif_datetime > 0: # date
fdt = time.strftime(self.__show_text_fm, time.localtime(pic.exif_datetime))
info_strings.append(fdt)
if (self.__show_text & 16) == 16 and pic.location is not None: # location
info_strings.append(pic.location) #TODO need to sanitize and check longer than 0 for real
if (self.__show_text & 32) == 32: # folder
info_strings.append(self.__sanitize_string(os.path.basename(os.path.dirname(pic.fname))))
info_strings.append(os.path.basename(os.path.dirname(pic.fname)))
if paused:
info_strings.append("PAUSED")
final_string = " • ".join(info_strings)
Expand All @@ -370,6 +383,8 @@ def __make_text(self, pic, paused, side=0, pair=False):
y = (block.sprite.height - self.__display.height + self.__show_text_sz) // 2
block.sprite.position(x, y, 0.1)
block.sprite.set_alpha(0.0)
if side == 0:
self.__textblocks[1] = None
self.__textblocks[side] = block

def __draw_clock(self):
Expand Down Expand Up @@ -424,11 +439,9 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,
loop_running = self.__display.loop_running()
tm = time.time()
if pics is not None:
if fade_time <= 0.5:
fade_time = 0.5
#self.__sbg = self.__sfg # if the first tex_load fails then __sfg might be Null TODO should fn return if None?
self.__next_tm = tm + time_delay
self.__name_tm = tm + fade_time + float(self.__show_text_tm) # text starts after slide transition
self.__name_tm = tm + fade_time + self.__show_text_tm # text starts after slide transition
new_sfg = self.__tex_load(pics, (self.__display.width, self.__display.height))
if new_sfg is not None: # this is a possible return value which needs to be caught
self.__sbg = self.__sfg
Expand All @@ -437,7 +450,10 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,
#return (True, False) # return early
(self.__sbg, self.__sfg) = (self.__sfg, self.__sbg) # swap existing images over
self.__alpha = 0.0
self.__delta_alpha = 1.0 / (self.__fps * fade_time) # delta alpha
if fade_time > 0.5:
self.__delta_alpha = 1.0 / (self.__fps * fade_time) # delta alpha
else:
self.__delta_alpha = 1.0 # else jump alpha from 0 to 1 in one frame
# set the file name as the description
if self.__show_text_tm > 0.0:
for i, pic in enumerate(pics):
Expand Down Expand Up @@ -491,9 +507,10 @@ def slideshow_is_running(self, pics=None, time_delay = 200.0, fade_time = 10.0,

if self.__alpha >= 1.0 and tm < self.__name_tm:
# this sets alpha for the TextBlock from 0 to 1 then back to 0
dt = (self.__show_text_tm - self.__name_tm + tm + 0.1) / self.__show_text_tm
ramp_pt = max(4.0, self.__show_text_tm / 4.0)
alpha = max(0.0, min(1.0, ramp_pt * (self.__alpha- abs(1.0 - 2.0 * dt)))) # cap text alpha at image alpha
dt = 1.1 - (self.__name_tm - tm) / self.__show_text_tm # i.e. dt from 0.1 to 1.1
ramp_pt = max(4.0, self.__show_text_tm / 4.0) # always > 4 so text fade will always < 4s
# create single saw tooth over 0 to __show_text_tm
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...
for block in self.__textblocks:
if block is not None:
block.sprite.set_alpha(alpha)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
install_requires=[
'Pillow',
'ExifRead',
'pi3d>=2.47',
'pi3d>=2.49',
'PyYAML',
'paho-mqtt',
'IPTCInfo3',
Expand Down

0 comments on commit 5574fde

Please sign in to comment.