Skip to content

Commit

Permalink
Merge pull request #9 from Hains/python3
Browse files Browse the repository at this point in the history
Update LCD4Linux
  • Loading branch information
technl authored Feb 7, 2025
2 parents c51ef42 + 891216e commit 72754ee
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 139 deletions.
128 changes: 71 additions & 57 deletions lcd4linux/src/Photoframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
from usb.util import get_string
from PIL import Image
from struct import pack
from six import ensure_binary
from six.moves import cStringIO as StringIO


def write_jpg2frame(dev, pic):
"""Attach header to picture, pad with zeros if necessary, and send to frame"""
# Attach header to picture, pad with zeros if necessary, and send to frame
# create header and stack before picture
# middle 4 bytes have size of picture
rawdata = b"\xa5\x5a\x18\x04" + pack('<I', len(pic) + 14) + b"\x48\x00\x00\x00" + pic
Expand All @@ -22,95 +23,96 @@ def write_jpg2frame(dev, pic):


def get_known_devices():
"""Return a dict of photo frames"""
dList = []
# Return a dict of photo frames
dlist = []
# listed as: Name, idVendor, idProduct, [width , height - in pixel if applicable]
#

#0,1 Samsung SPF-75H/76H (23)
dList.append({'name': "SPF75H/76H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200f, 'width': 800, 'height': 480})
dList.append({'name': "SPF75H/76H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200e})
dlist.append({'name': "SPF75H/76H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200f, 'width': 800, 'height': 480})
dlist.append({'name': "SPF75H/76H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200e})

#2,3 Samsung SPF-87H (24)
dList.append({'name': "SPF87H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2034, 'width': 800, 'height': 480})
dList.append({'name': "SPF87H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2033})
dlist.append({'name': "SPF87H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2034, 'width': 800, 'height': 480})
dlist.append({'name': "SPF87H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2033})

#4,5 Samsung SPF-87Hold (25)
dList.append({'name': "SPF87Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2026, 'width': 800, 'height': 480})
dList.append({'name': "SPF87Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2025})
dlist.append({'name': "SPF87Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2026, 'width': 800, 'height': 480})
dlist.append({'name': "SPF87Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2025})

#6,7 Samsung SPF-83H (26)
dList.append({'name': "SPF83H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200d, 'width': 800, 'height': 600})
dList.append({'name': "SPF83H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200c})
dlist.append({'name': "SPF83H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200d, 'width': 800, 'height': 600})
dlist.append({'name': "SPF83H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200c})

#8,9 Samsung SPF-107H (27)
dList.append({'name': "SPF107H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2036, 'width': 1024, 'height': 600})
dList.append({'name': "SPF107H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2035})
dlist.append({'name': "SPF107H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2036, 'width': 1024, 'height': 600})
dlist.append({'name': "SPF107H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2035})

#10,11 Samsung SPF-105P (28)
dList.append({'name': "SPF105P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x201b, 'width': 1024, 'height': 600})
dList.append({'name': "SPF105P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x201c})
dlist.append({'name': "SPF105P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x201b, 'width': 1024, 'height': 600})
dlist.append({'name': "SPF105P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x201c})

#12,13 Samsung SPF-85H/86H (29)
dList.append({'name': "SPF85H/86H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2013, 'width': 800, 'height': 600})
dList.append({'name': "SPF85H/86H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2012})
dlist.append({'name': "SPF85H/86H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2013, 'width': 800, 'height': 600})
dlist.append({'name': "SPF85H/86H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2012})

#14,15 Samsung SPF-72H (210)
dList.append({'name': "SPF72H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200b, 'width': 800, 'height': 480})
dList.append({'name': "SPF72H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200a})
dlist.append({'name': "SPF72H Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x200b, 'width': 800, 'height': 480})
dlist.append({'name': "SPF72H Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x200a})

#16,17 Samsung SPF-700T (211)
dList.append({'name': "SPF700T Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2050, 'width': 800, 'height': 600})
dList.append({'name': "SPF700T Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204f})
dlist.append({'name': "SPF700T Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2050, 'width': 800, 'height': 600})
dlist.append({'name': "SPF700T Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x204f})

#18,19 Samsung SPF-85P/86P (212)
dList.append({'name': "SPF85P/86P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2017, 'width': 800, 'height': 600})
dList.append({'name': "SPF85P/86P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2016})
dlist.append({'name': "SPF85P/86P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2017, 'width': 800, 'height': 600})
dlist.append({'name': "SPF85P/86P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2016})

#20,21 Samsung SPF-107Hold (213)
dList.append({'name': "SPF107Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2028, 'width': 1024, 'height': 600})
dList.append({'name': "SPF107Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2027})
dlist.append({'name': "SPF107Hold Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2028, 'width': 1024, 'height': 600})
dlist.append({'name': "SPF107Hold Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2027})

#22,23 Samsung SPF-1000P (214)
dList.append({'name': "SPF1000P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2040, 'width': 1024, 'height': 600})
dList.append({'name': "SPF1000P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2039})
dlist.append({'name': "SPF1000P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2040, 'width': 1024, 'height': 600})
dlist.append({'name': "SPF1000P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2039})

#24,25 Samsung SPF-800P (215)
dList.append({'name': "SPF800P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2038, 'width': 800, 'height': 480})
dList.append({'name': "SPF800P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2037})
dlist.append({'name': "SPF800P Mini Monitor", 'idVendor': 0x04e8, 'idProduct': 0x2038, 'width': 800, 'height': 480})
dlist.append({'name': "SPF800P Mass Storage", 'idVendor': 0x04e8, 'idProduct': 0x2037})

# Amazon Fire 7 (9th Generation 2019)
dlist.append({'name': "Amazon Fire 7 Mini Monitor", 'idVendor': 0x1949, 'idProduct': 0x03C3, 'width': 1024, 'height': 600})
dlist.append({'name': "Amazon Fire 7 Mass Storage", 'idVendor': 0x1949, 'idProduct': 0x03C1})

# Pearl DPF for Testing
dList.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240})
dList.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240})
dlist.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240})
dlist.append({'name': "Pearl DPF", 'idVendor': 0x1908, 'idProduct': 0x0102, 'width': 320, 'height': 240})

return dList
return dlist


def find_device(Anzahl, device, device2):
"""Try to find device on USB bus."""
def find_device(anzahl, device, device2):
# Try to find device on USB bus.
try:
print("[LCD4linux] looking for frame", Anzahl, device['name'], device['idVendor'], device['idProduct'], device2['idProduct'])
if Anzahl == 2:
print("[LCD4linux] looking for frame", anzahl, device['name'], device['idVendor'], device['idProduct'], device2['idProduct'])
if anzahl == 2:
d = list(find(idVendor=device['idVendor'], idProduct=device['idProduct'], find_all=True)) + list(find(idVendor=device2['idVendor'], idProduct=device2['idProduct'], find_all=True))
if isinstance(d, list):
if len(d) >= 2:
d = d[1]
else:
d = None
d = d[1] if len(d) >= 2 else None
else:
d = None
else:
d = list(list(find(idVendor=device['idVendor'], idProduct=device['idProduct'], find_all=True)) + list(find(idVendor=device2['idVendor'], idProduct=device2['idProduct'], find_all=True)))[0]
except:
except Exception:
from traceback import format_exc
print("[LCD4linux] find exception")
print("Error: %s" % format_exc())
d = None
return d


def init_device(Anzahl, device0, device1):
"""First try Mini Monitor mode, then Mass storage mode"""
dev = find_device(Anzahl, device0, device1)
def init_device(anzahl, device0, device1):
# First try Mini Monitor mode, then Mass storage mode
dev = find_device(anzahl, device0, device1)

if dev is not None:
## found it, trying to init it
Expand All @@ -124,7 +126,7 @@ def init_device(Anzahl, device0, device1):
ts = time()
while True:
# may need to burn some time
dev = find_device(Anzahl, device0, device1)
dev = find_device(anzahl, device0, device1)
if dev is not None and dev.idProduct == device0["idProduct"]:
#switching successful
break
Expand All @@ -140,46 +142,58 @@ def init_device(Anzahl, device0, device1):


def frame_init(dev):
"""Init device so it stays in Mini Monitor mode"""
# Init device so it stays in Mini Monitor mode
# this is the minimum required to keep the frame in Mini Monitor mode!!!
# dev.ctrl_transfer(0xc0, 4 )
# dev.ctrl_transfer(0xc0, 0x01, 0x00, 0x00, 0x09, 0x04 )
# dev.ctrl_transfer(0xc0, 4 )
# dev.ctrl_transfer(0xc0, 0x01, 0x00, 0x00, 0x09, 0x04 )
dev.ctrl_transfer(0xc0, 0x01, 0x00, 0x00, 0x02)


def frame_switch(dev):
"""Switch device from Mass Storage to Mini Monitor"""
# Switch device from Mass Storage to Mini Monitor
CTRL_TYPE_VENDOR = (2 << 5)
CTRL_IN = 0x80
CTRL_RECIPIENT_DEVICE = 0
try:
sleep(0.5)
s = "\x00" * 251
dev.ctrl_transfer(0x00 | 0x80, 0x06, 0xfe, 0xfe, 0xfe)
except:
# dev.ctrl_transfer(0x00 | 0x80, 0x06, 0xfe, 0xfe, s, 0xfe )
# dev.ctrl_transfer(CTRL_TYPE_VENDOR | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x04, 0x00, 0x00, 1)
# result = dev.ctrl_transfer(CTRL_TYPE_VENDOR | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x04, 0x00, 0x00, 1)
# expect(result, [ 0x03 ])
# result = dev.ctrl_transfer(CTRL_TYPE_VENDOR | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x01, 0x00, 0x00, 2)
# expect(result, [ 0x09, 0x04 ])
# result = dev.ctrl_transfer(CTRL_TYPE_VENDOR | CTRL_IN | CTRL_RECIPIENT_DEVICE, 0x02, 0x00, 0x00, 1)
# expect(result, [ 0x46 ])
# settling of the bus and frame takes about 0.42 sec
# give it some extra time, but then still make sure it has settled
except Exception:
print("[LCD4linux] switching ERROR")
# from traceback import format_exc
# print format_exc()
finally:
sleep(2)


def name(dev):
try:
return get_string(dev, 1)
except:
except Exception:
try:
return get_string(dev, 256, 2)
except:
except Exception:
return None


def main():
global dev, known_devices_list

known_devices_list = get_known_devices()

# define which frame to use, here use Samsung SPF-87H
device0 = known_devices_list[0] # Mini Monitor mode
device1 = known_devices_list[1] # Mass Storage mode

dev = init_device(1, device0, device1)
print("Frame is in Mini Monitor mode and initialized. Sending pictures now")

image = Image.open("mypicture.jpg")
#manipulations to consider:
# convert
Expand Down
12 changes: 6 additions & 6 deletions lcd4linux/src/dpf.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from six import PY2
try:
from . import dpflib
except:
except Exception:
print("[LCD4linux] dpflib-Error")

PROPERTY_BRIGHTNESS = 0x01
Expand All @@ -15,7 +15,7 @@ def setBacklight(dev, value):
try:
dev.setProperty(PROPERTY_BRIGHTNESS, value)
return True
except:
except Exception:
print("[LCD4linux] Error set Backlight")
return False

Expand All @@ -29,17 +29,17 @@ def showImage(dev, image):
else:
dev.showRGBAImage(0, 0, x, y, ir.tobytes())
return True
except:
except Exception:
print("[LCD4linux] Error writing DPF Device")
return False


def open(usb):
try:
d = dpflib.open(usb)
d.setProperty(PROPERTY_ORIENTATION, 1)
# d.setProperty(PROPERTY_ORIENTATION, 1)
print("[LCD4linux] open %s" % usb)
except:
except Exception:
d = None
print("[LCD4linux] open Error: %s" % usb)
return d
Expand All @@ -49,5 +49,5 @@ def close(dev):
try:
if dev is not None:
dev.close()
except:
except Exception:
pass
26 changes: 12 additions & 14 deletions lcd4linux/src/module.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,14 +79,14 @@ def getHold(self):
return L4Lelement.Hold

def setHold(self, H):
print("[LCD4linuxE] Hold: %s" % H)
print("[LCD4linuxE] hold: %s" % H)
L4Lelement.Hold = H

def getHoldKey(self):
return L4Lelement.HoldKey

def setHoldKey(self, H=False):
print("[LCD4linuxE] HoldKey: %s" % H)
print("[LCD4linuxE] holdkey: %s" % H)
L4Lelement.HoldKey = H

def getFont(self, F="0"):
Expand All @@ -102,29 +102,27 @@ def getScreen(self):
return L4Lelement.Screen

def setScreen(self, S, Lcd="", Hold=False):
if Lcd != "":
if len(str(Lcd)) > 1 or int(Lcd) > 3:
Lcd = "1"
if Lcd != "" and (len(str(Lcd)) > 1 or int(Lcd) > 3):
Lcd = "1"
L4Lelement.Screen = str(S)
L4Lelement.LCD = str(Lcd)
L4Lelement.Hold = Hold
L4Lelement.Refresh = True

def resetBrightness(self, AKT=""):
def resetBrightness(self, AKT=[]):
if len(AKT) == 3:
L4Lelement.BrightAkt = AKT
else:
L4Lelement.Bright = [-1, -1, -1]

def setBrightness(self, LCD, BRI=-1):
if int(LCD) < 1 or int(LCD) > 3:
return
L4Lelement.Bright[int(LCD) - 1] = int(BRI)
L4Lelement.Refresh = True
if int(LCD) > 0 and int(LCD) < 4:
L4Lelement.Bright[int(LCD) - 1] = int(BRI)
L4Lelement.Refresh = True

def getBrightness(self, LCD=0, ORG=True):
if int(LCD) > 0 and int(LCD) < 4:
return L4Lelement.Bright[int(LCD) - 1] if ORG == False else L4Lelement.BrightAkt[int(LCD) - 1]
return [L4Lelement.Bright[int(LCD) - 1]] if ORG == False else [L4Lelement.BrightAkt[int(LCD) - 1]]
else:
return L4Lelement.Bright if ORG == False else L4Lelement.BrightAkt

Expand All @@ -145,14 +143,13 @@ def getstatusoutput(cmd):
sts = pipe.close()
if sts is None:
sts = 0
if text[-1:] == '\n':
if text.endswith == '\n':
text = text[:-1]
except Exception:
sts = 1
text = "- -"
print("[LCD4linux] Error on os-call")
finally:
return sts, text
return sts, text


def L4LVtest(VV):
Expand All @@ -172,6 +169,7 @@ def L4LVtest(VV):
if O != "":
try:
f = open(L4Linfo % (O, P))
B = f.readline()
OO = f.readline().strip().split()[1].startswith(VV[1:])
f.close()
except Exception:
Expand Down
Loading

0 comments on commit 72754ee

Please sign in to comment.