Skip to content

Commit 277fa2e

Browse files
committed
Add StripInfo
1 parent 1ed96dc commit 277fa2e

7 files changed

Lines changed: 422 additions & 128 deletions

File tree

animatedledstrip/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@
77
from .global_vars import ANIMATION_DATA_PREFIX, ANIMATION_INFO_PREFIX, DELIMITER, \
88
END_ANIMATION_PREFIX, SECTION_PREFIX, STRICT_TYPE_CHECKING, STRIP_INFO_PREFIX
99
from .param_usage import ParamUsage
10+
from .strip_info import StripInfo

animatedledstrip/animation_info.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def __init__(self):
4646
self.spacing_default: int = 3
4747

4848
@classmethod
49-
def from_json(cls, input_str: AnyStr):
49+
def from_json(cls, input_str: AnyStr) -> 'AnimationInfo':
5050
"""Create an AnimationInfo instance from a JSON representation"""
5151
# Parse the JSON
5252
input_json = json.loads(input_str[5:])

animatedledstrip/animation_sender.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,27 @@
2727
from .animation_info import AnimationInfo
2828
from .end_animation import EndAnimation
2929
from .global_vars import *
30+
from .strip_info import StripInfo
3031

3132

3233
class AnimationSender(object):
3334
"""Handles communications with the server"""
3435

35-
address: str
36-
port: int
37-
connection: 'socket.socket' = socket.socket()
38-
connected: bool = False
39-
recv_thread: Optional['Thread'] = None
40-
running_animations: Dict[str, 'AnimationData'] = {}
41-
supported_animations: List['AnimationInfo'] = []
42-
43-
receiveCallback: Optional[Callable[[bytes], Any]] = None
44-
newAnimationDataCallback: Optional[Callable[['AnimationData'], Any]] = None
45-
newAnimationInfoCallback: Optional[Callable[['AnimationInfo'], Any]] = None
46-
newEndAnimationCallback: Optional[Callable[['EndAnimation'], Any]] = None
47-
4836
def __init__(self, ip_address: str, port_num: int):
4937
self.address: str = ip_address
5038
self.port: int = port_num
39+
self.connection: 'socket.socket' = socket.socket()
40+
self.connected: bool = False
41+
self.recv_thread: Optional['Thread'] = None
42+
self.running_animations: Dict[str, 'AnimationData'] = {}
43+
self.stripInfo: Optional['StripInfo'] = None
44+
self.supported_animations: List['AnimationInfo'] = []
45+
46+
self.receiveCallback: Optional[Callable[[bytes], Any]] = None
47+
self.newAnimationDataCallback: Optional[Callable[['AnimationData'], Any]] = None
48+
self.newAnimationInfoCallback: Optional[Callable[['AnimationInfo'], Any]] = None
49+
self.newEndAnimationCallback: Optional[Callable[['EndAnimation'], Any]] = None
50+
self.newStripInfoCallback: Optional[Callable[['StripInfo'], Any]] = None
5151

5252
def start(self) -> 'AnimationSender':
5353
"""Connect to the server"""
@@ -71,6 +71,8 @@ def end(self) -> 'AnimationSender':
7171
# Connection has been closed, so set connected = False
7272
self.connected = False
7373

74+
self.stripInfo = None
75+
7476
# If the separate thread for receiving animations was started, join it with the main thread.
7577
# The loop should stop because the connection is closed and connected is False,
7678
# allowing it to return
@@ -142,7 +144,14 @@ def parse_data(self):
142144
pass # TODO
143145

144146
elif split_input.startswith(STRIP_INFO_PREFIX):
145-
pass # TODO
147+
# Create the StripInfo instance
148+
info = StripInfo.from_json(split_input)
149+
150+
self.stripInfo = info
151+
152+
# Call callback
153+
if self.newStripInfoCallback:
154+
self.newStripInfoCallback(info)
146155

147156
else:
148157
logging.warning('Unrecognized data type: {} ({})'.format(split_input[:4], split_input))

animatedledstrip/strip_info.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Copyright (c) 2019-2020 AnimatedLEDStrip
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
11+
# all 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
19+
# THE SOFTWARE.
20+
21+
import json
22+
from typing import AnyStr, Optional
23+
24+
from .utils import check_data_type
25+
26+
27+
class StripInfo(object):
28+
"""Stores information about a LED strip"""
29+
30+
def __init__(self):
31+
self.num_leds: int = 0
32+
self.pin: Optional[int] = None
33+
self.image_debugging: bool = False
34+
self.file_name: Optional[str] = None
35+
self.renders_before_save: Optional[int] = None
36+
self.thread_count: int = 100
37+
38+
@classmethod
39+
def from_json(cls, input_str: AnyStr) -> 'StripInfo':
40+
"""Create an StripInfo instance from a JSON representation"""
41+
# Parse the JSON
42+
input_json = json.loads(input_str[5:])
43+
44+
# Create a new StripInfo instance
45+
new_instance = cls()
46+
47+
# Get each property from the JSON, reverting to defaults if it can't be found
48+
new_instance.num_leds = input_json.get('numLEDs', new_instance.num_leds)
49+
new_instance.pin = input_json.get('pin', new_instance.pin)
50+
new_instance.image_debugging = input_json.get('imageDebugging', new_instance.image_debugging)
51+
new_instance.file_name = input_json.get('fileName', new_instance.file_name)
52+
new_instance.renders_before_save = input_json.get('rendersBeforeSave', new_instance.renders_before_save)
53+
new_instance.thread_count = input_json.get('threadCount', new_instance.thread_count)
54+
55+
# Double check that everything has the right data type
56+
new_instance.check_data_types()
57+
58+
return new_instance
59+
60+
def check_data_types(self) -> bool:
61+
"""Check that all parameter types are correct"""
62+
good_types = True
63+
64+
good_types = good_types and check_data_type('num_leds', self.num_leds, int)
65+
good_types = good_types and check_data_type('pin', self.pin, int, allow_none=True)
66+
good_types = good_types and check_data_type('image_debugging', self.image_debugging, bool)
67+
good_types = good_types and check_data_type('file_name', self.file_name, str, allow_none=True)
68+
good_types = good_types and check_data_type('renders_before_save', self.renders_before_save, int, allow_none=True)
69+
good_types = good_types and check_data_type('thread_count', self.thread_count, int)
70+
71+
return good_types

get_raw.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from led_client import AnimationSender
1+
from animatedledstrip import AnimationSender
22

33

44
sender = AnimationSender("10.0.0.55", 6)

0 commit comments

Comments
 (0)