Skip to content

Commit 775ea95

Browse files
committed
restructured project for packaging
reformatted fluepdot.py fixed minor error
1 parent 83055d9 commit 775ea95

6 files changed

Lines changed: 192 additions & 126 deletions

File tree

.gitignore

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
11
dots.py
22
__pycache__
3-
venv
3+
venv
4+
5+
.idea
6+
src/python_fluepdot.egg-info
7+
dist

LICENSE

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
Copyright (c) 2018 The Python Packaging Authority
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy
4+
of this software and associated documentation files (the "Software"), to deal
5+
in the Software without restriction, including without limitation the rights
6+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
copies of the Software, and to permit persons to whom the Software is
8+
furnished to do so, subject to the following conditions:
9+
10+
The above copyright notice and this permission notice shall be included in all
11+
copies or substantial portions of the Software.
12+
13+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19+
SOFTWARE.

fluepdot.py

Lines changed: 0 additions & 125 deletions
This file was deleted.

pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "python-fluepdot"
7+
version = "0.0.1"
8+
authors = [
9+
{ name="KS-HTK", email="ks-htk@flipdot.org" },
10+
]
11+
description = "A small collection of functions for interacting with a fluepdot module."
12+
readme = "README.md"
13+
requires-python = ">=3.7"
14+
classifiers = [
15+
"Programming Language :: Python :: 3",
16+
"License :: OSI Approved :: MIT License",
17+
"Operating System :: OS Independent",
18+
]
19+
20+
[project.urls]
21+
"Homepage" = "https://github.com/KS-HTK/python-fluepdot"
22+
"Bug-Tracker" = "https://github.com/KS-HTK/python-fluepdot/issues"

src/fluepdot/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# __init__.py
2+
from .fluepdot import *

src/fluepdot/fluepdot.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# python fluepdot module
2+
3+
import requests
4+
import binascii
5+
from requests import Response
6+
from enum import Enum
7+
from typing import Any, Dict, Optional, List
8+
9+
"""
10+
Small library to interact with a fluepdot controlled display
11+
https://fluepdot.readthedocs.io/en/latest/
12+
13+
it should only be required to change the baseURL
14+
15+
Currently there is no support for changing the timings.
16+
"""
17+
18+
GetParam = Dict[str, Any]
19+
PostParam = str
20+
21+
22+
class Mode(Enum):
23+
FULL = 0
24+
DIFFERENTIAL = 1
25+
26+
27+
# endpoints:
28+
baseURL: str = None
29+
frameURL: str = "/framebuffer"
30+
pixelURL: str = "/pixel"
31+
textURL: str = "/framebuffer/text"
32+
fontURL: str = "/fonts"
33+
modeURL: str = "/rendering/mode"
34+
35+
# size defaults:
36+
width: int = 115
37+
height: int = 16
38+
39+
fonts: Optional[List[str]] = None
40+
41+
42+
def set_url(url: str):
43+
global baseURL
44+
baseURL = url
45+
46+
47+
def post_time() -> None:
48+
import datetime
49+
dt: str = ""
50+
while True:
51+
ndt: str = datetime.datetime.now().strftime("%d.%m.%y %H:%M")
52+
if ndt != dt:
53+
dt = ndt
54+
post_text(dt, x=8, y=1, font="fixed_7x14")
55+
56+
57+
def get_size() -> (int, int):
58+
global width, height
59+
frame = get_frame()
60+
width = len(frame[0])
61+
height = len(frame) - 1
62+
return [width, height]
63+
64+
65+
def get_frame() -> List[str]:
66+
r = _get(frameURL)
67+
return r.text.split('\n')
68+
69+
70+
def get_pixel(x: int = 0, y: int = 0) -> bool:
71+
r = _get(pixelURL, get={x, y})
72+
print(r)
73+
return False
74+
75+
76+
def get_fonts() -> None:
77+
r = _get(fontURL)
78+
fonts = r.text.split("\n")
79+
print(fonts)
80+
81+
82+
def get_mode() -> Mode:
83+
r = _get(modeURL)
84+
return Mode(r.text)
85+
86+
87+
def post_text(text: str, x: int = 0, y: int = 0, font: str = "DejaVuSans12") -> Response:
88+
return _post(textURL, get={"x": x, "y": y, "font": font}, post=text)
89+
90+
91+
def post_frame_raw(frame: str) -> Response:
92+
return _post(frameURL, post=frame)
93+
94+
95+
def post_frame(frame: List[List[bool]]) -> Response:
96+
data: List[List[str]] = [[" "] * width for _ in range(height)]
97+
for x, l in frame:
98+
for y, b in l:
99+
if b:
100+
try:
101+
data[x, y] = "X"
102+
except IndexError as e:
103+
print(e)
104+
return _post(frameURL, post=data)
105+
106+
107+
def set_pixel(x: int = 0, y: int = 0) -> Response:
108+
return _post(pixelURL, get={x, y})
109+
110+
111+
def unset_pixel(x: int = 0, y: int = 0) -> Response:
112+
return _delete(pixelURL, get={x, y})
113+
114+
115+
def set_mode(mode: Mode = Mode.FULL) -> Response:
116+
return _put(modeURL, post=str(mode.value))
117+
118+
119+
def _delete(endpoint: str, get: GetParam = {}, post: PostParam = '') -> Response:
120+
if baseURL == None:
121+
raise RuntimeError('baseURL is None, call set_url')
122+
return requests.delete(url=baseURL + endpoint, params=get)
123+
124+
125+
def _post(endpoint: str, get: GetParam = {}, post: PostParam = '') -> Response:
126+
if baseURL == None:
127+
raise RuntimeError('baseURL is None, call set_url')
128+
return requests.post(url=baseURL + endpoint, params=get, data=post)
129+
130+
131+
def _put(endpoint: str, get: GetParam = {}, post: PostParam = '') -> Response:
132+
if baseURL == None:
133+
raise RuntimeError('baseURL is None, call set_url')
134+
return requests.put(url=baseURL + endpoint, params=get, data=post)
135+
136+
137+
def _get(endpoint: str, get: GetParam = {}) -> Response:
138+
if baseURL == None:
139+
raise RuntimeError('baseURL is None, call set_url')
140+
return requests.get(url=baseURL + endpoint, params=get)
141+
142+
143+
if __name__ == "__main__":
144+
pass

0 commit comments

Comments
 (0)