mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 15:08:10 +01:00
Store Raw Remote Codes in PROGMEM (#392)
* Store Raw Remote Codes in PROGMEM * Lint * Lint * Fix
This commit is contained in:
parent
8ce176aaba
commit
596f995af8
7 changed files with 75 additions and 36 deletions
|
@ -10,8 +10,9 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CHANNEL, CONF_CODE, CONF_COMMAN
|
||||||
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \
|
CONF_DEVICE, CONF_FAMILY, CONF_GROUP, CONF_LG, CONF_NAME, CONF_NBITS, CONF_NEC, \
|
||||||
CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \
|
CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, CONF_RC_SWITCH_TYPE_A, \
|
||||||
CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \
|
CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, CONF_SAMSUNG, CONF_SONY, \
|
||||||
CONF_STATE
|
CONF_STATE, CONF_ID
|
||||||
from esphomeyaml.cpp_generator import Pvariable, get_variable
|
from esphomeyaml.cpp_generator import Pvariable, get_variable, progmem_array
|
||||||
|
from esphomeyaml.cpp_types import int32
|
||||||
|
|
||||||
DEPENDENCIES = ['remote_receiver']
|
DEPENDENCIES = ['remote_receiver']
|
||||||
|
|
||||||
|
@ -35,6 +36,18 @@ RCSwitchTypeBReceiver = remote_ns.class_('RCSwitchTypeBReceiver', RCSwitchRawRec
|
||||||
RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver)
|
RCSwitchTypeCReceiver = remote_ns.class_('RCSwitchTypeCReceiver', RCSwitchRawReceiver)
|
||||||
RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawReceiver)
|
RCSwitchTypeDReceiver = remote_ns.class_('RCSwitchTypeDReceiver', RCSwitchRawReceiver)
|
||||||
|
|
||||||
|
|
||||||
|
def validate_raw(value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return vol.Schema({
|
||||||
|
cv.GenerateID(): cv.declare_variable_id(int32),
|
||||||
|
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
|
||||||
|
})(value)
|
||||||
|
return validate_raw({
|
||||||
|
CONF_DATA: value
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
|
cv.GenerateID(): cv.declare_variable_id(RemoteReceiver),
|
||||||
vol.Optional(CONF_LG): vol.Schema({
|
vol.Optional(CONF_LG): vol.Schema({
|
||||||
|
@ -56,7 +69,7 @@ PLATFORM_SCHEMA = cv.nameable(binary_sensor.BINARY_SENSOR_PLATFORM_SCHEMA.extend
|
||||||
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
||||||
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
|
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
|
||||||
}),
|
}),
|
||||||
vol.Optional(CONF_RAW): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
|
vol.Optional(CONF_RAW): validate_raw,
|
||||||
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
|
||||||
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
|
||||||
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
|
||||||
|
@ -82,7 +95,8 @@ def receiver_base(full_config):
|
||||||
if key == CONF_SONY:
|
if key == CONF_SONY:
|
||||||
return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
|
return SonyReceiver.new(name, config[CONF_DATA], config[CONF_NBITS])
|
||||||
if key == CONF_RAW:
|
if key == CONF_RAW:
|
||||||
return RawReceiver.new(name, *config)
|
arr = progmem_array(config[CONF_ID], config[CONF_DATA])
|
||||||
|
return RawReceiver.new(name, arr, len(config[CONF_DATA]))
|
||||||
if key == CONF_RC_SWITCH_RAW:
|
if key == CONF_RC_SWITCH_RAW:
|
||||||
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
|
return RCSwitchRawReceiver.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
|
||||||
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
|
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
|
||||||
|
|
|
@ -6,8 +6,8 @@ from esphomeyaml.components import display
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE
|
from esphomeyaml.const import CONF_FILE, CONF_GLYPHS, CONF_ID, CONF_SIZE
|
||||||
from esphomeyaml.core import CORE, HexInt
|
from esphomeyaml.core import CORE, HexInt
|
||||||
from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp
|
from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp
|
||||||
from esphomeyaml.cpp_types import App
|
from esphomeyaml.cpp_types import App, uint8
|
||||||
from esphomeyaml.py_compat import sort_by_cmp
|
from esphomeyaml.py_compat import sort_by_cmp
|
||||||
|
|
||||||
DEPENDENCIES = ['display']
|
DEPENDENCIES = ['display']
|
||||||
|
@ -74,7 +74,7 @@ FONT_SCHEMA = vol.Schema({
|
||||||
vol.Required(CONF_FILE): validate_truetype_file,
|
vol.Required(CONF_FILE): validate_truetype_file,
|
||||||
vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
|
vol.Optional(CONF_GLYPHS, default=DEFAULT_GLYPHS): validate_glyphs,
|
||||||
vol.Optional(CONF_SIZE, default=20): vol.All(cv.int_, vol.Range(min=1)),
|
vol.Optional(CONF_SIZE, default=20): vol.All(cv.int_, vol.Range(min=1)),
|
||||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None),
|
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(uint8),
|
||||||
})
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(validate_pillow_installed, FONT_SCHEMA)
|
CONFIG_SCHEMA = vol.All(validate_pillow_installed, FONT_SCHEMA)
|
||||||
|
@ -108,14 +108,12 @@ def to_code(config):
|
||||||
glyph_args[glyph] = (len(data), offset_x, offset_y, width, height)
|
glyph_args[glyph] = (len(data), offset_x, offset_y, width, height)
|
||||||
data += glyph_data
|
data += glyph_data
|
||||||
|
|
||||||
raw_data = MockObj(config[CONF_RAW_DATA_ID])
|
rhs = safe_exp([HexInt(x) for x in data])
|
||||||
add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
|
prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||||
raw_data, len(data),
|
|
||||||
safe_exp([HexInt(x) for x in data]))))
|
|
||||||
|
|
||||||
glyphs = []
|
glyphs = []
|
||||||
for glyph in config[CONF_GLYPHS]:
|
for glyph in config[CONF_GLYPHS]:
|
||||||
glyphs.append(Glyph(glyph, raw_data, *glyph_args[glyph]))
|
glyphs.append(Glyph(glyph, prog_arr, *glyph_args[glyph]))
|
||||||
|
|
||||||
rhs = App.make_font(glyphs, ascent, ascent + descent)
|
rhs = App.make_font(glyphs, ascent, ascent + descent)
|
||||||
Pvariable(config[CONF_ID], rhs)
|
Pvariable(config[CONF_ID], rhs)
|
||||||
|
|
|
@ -8,8 +8,8 @@ from esphomeyaml.components import display, font
|
||||||
import esphomeyaml.config_validation as cv
|
import esphomeyaml.config_validation as cv
|
||||||
from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE
|
from esphomeyaml.const import CONF_FILE, CONF_ID, CONF_RESIZE
|
||||||
from esphomeyaml.core import CORE, HexInt
|
from esphomeyaml.core import CORE, HexInt
|
||||||
from esphomeyaml.cpp_generator import MockObj, Pvariable, RawExpression, add, safe_exp
|
from esphomeyaml.cpp_generator import Pvariable, progmem_array, safe_exp
|
||||||
from esphomeyaml.cpp_types import App
|
from esphomeyaml.cpp_types import App, uint8
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ IMAGE_SCHEMA = vol.Schema({
|
||||||
vol.Required(CONF_ID): cv.declare_variable_id(Image_),
|
vol.Required(CONF_ID): cv.declare_variable_id(Image_),
|
||||||
vol.Required(CONF_FILE): cv.file_,
|
vol.Required(CONF_FILE): cv.file_,
|
||||||
vol.Optional(CONF_RESIZE): cv.dimensions,
|
vol.Optional(CONF_RESIZE): cv.dimensions,
|
||||||
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(None),
|
cv.GenerateID(CONF_RAW_DATA_ID): cv.declare_variable_id(uint8),
|
||||||
})
|
})
|
||||||
|
|
||||||
CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, IMAGE_SCHEMA)
|
CONFIG_SCHEMA = vol.All(font.validate_pillow_installed, IMAGE_SCHEMA)
|
||||||
|
@ -56,10 +56,8 @@ def to_code(config):
|
||||||
pos = x + y * width8
|
pos = x + y * width8
|
||||||
data[pos // 8] |= 0x80 >> (pos % 8)
|
data[pos // 8] |= 0x80 >> (pos % 8)
|
||||||
|
|
||||||
raw_data = MockObj(config[CONF_RAW_DATA_ID])
|
rhs = safe_exp([HexInt(x) for x in data])
|
||||||
add(RawExpression('static const uint8_t {}[{}] PROGMEM = {}'.format(
|
prog_arr = progmem_array(config[CONF_RAW_DATA_ID], rhs)
|
||||||
raw_data, len(data),
|
|
||||||
safe_exp([HexInt(x) for x in data]))))
|
|
||||||
|
|
||||||
rhs = App.make_image(raw_data, width, height)
|
rhs = App.make_image(prog_arr, width, height)
|
||||||
Pvariable(config[CONF_ID], rhs)
|
Pvariable(config[CONF_ID], rhs)
|
||||||
|
|
|
@ -11,8 +11,9 @@ from esphomeyaml.const import CONF_ADDRESS, CONF_CARRIER_FREQUENCY, CONF_CHANNEL
|
||||||
CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, \
|
CONF_NAME, CONF_NBITS, CONF_NEC, CONF_PANASONIC, CONF_PROTOCOL, CONF_RAW, CONF_RC_SWITCH_RAW, \
|
||||||
CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, \
|
CONF_RC_SWITCH_TYPE_A, CONF_RC_SWITCH_TYPE_B, CONF_RC_SWITCH_TYPE_C, CONF_RC_SWITCH_TYPE_D, \
|
||||||
CONF_REPEAT, CONF_SAMSUNG, CONF_SONY, CONF_STATE, CONF_TIMES, \
|
CONF_REPEAT, CONF_SAMSUNG, CONF_SONY, CONF_STATE, CONF_TIMES, \
|
||||||
CONF_WAIT_TIME
|
CONF_WAIT_TIME, CONF_ID
|
||||||
from esphomeyaml.cpp_generator import Pvariable, add, get_variable
|
from esphomeyaml.cpp_generator import Pvariable, add, get_variable, progmem_array
|
||||||
|
from esphomeyaml.cpp_types import int32
|
||||||
|
|
||||||
DEPENDENCIES = ['remote_transmitter']
|
DEPENDENCIES = ['remote_transmitter']
|
||||||
|
|
||||||
|
@ -36,7 +37,18 @@ RCSwitchTypeBTransmitter = remote_ns.class_('RCSwitchTypeBTransmitter', RCSwitch
|
||||||
RCSwitchTypeCTransmitter = remote_ns.class_('RCSwitchTypeCTransmitter', RCSwitchRawTransmitter)
|
RCSwitchTypeCTransmitter = remote_ns.class_('RCSwitchTypeCTransmitter', RCSwitchRawTransmitter)
|
||||||
RCSwitchTypeDTransmitter = remote_ns.class_('RCSwitchTypeDTransmitter', RCSwitchRawTransmitter)
|
RCSwitchTypeDTransmitter = remote_ns.class_('RCSwitchTypeDTransmitter', RCSwitchRawTransmitter)
|
||||||
|
|
||||||
validate_raw_data = [vol.Any(vol.Coerce(int), cv.time_period_microseconds)]
|
|
||||||
|
def validate_raw(value):
|
||||||
|
if isinstance(value, dict):
|
||||||
|
return vol.Schema({
|
||||||
|
cv.GenerateID(): cv.declare_variable_id(int32),
|
||||||
|
vol.Required(CONF_DATA): [vol.Any(vol.Coerce(int), cv.time_period_microseconds)],
|
||||||
|
vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)),
|
||||||
|
})(value)
|
||||||
|
return validate_raw({
|
||||||
|
CONF_DATA: value
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
|
PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
|
||||||
cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter),
|
cv.GenerateID(): cv.declare_variable_id(RemoteTransmitter),
|
||||||
|
@ -59,10 +71,7 @@ PLATFORM_SCHEMA = cv.nameable(switch.SWITCH_PLATFORM_SCHEMA.extend({
|
||||||
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
vol.Required(CONF_ADDRESS): cv.hex_uint16_t,
|
||||||
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
|
vol.Required(CONF_COMMAND): cv.hex_uint32_t,
|
||||||
}),
|
}),
|
||||||
vol.Optional(CONF_RAW): vol.Any(validate_raw_data, vol.Schema({
|
vol.Optional(CONF_RAW): validate_raw,
|
||||||
vol.Required(CONF_DATA): validate_raw_data,
|
|
||||||
vol.Optional(CONF_CARRIER_FREQUENCY): vol.All(cv.frequency, vol.Coerce(int)),
|
|
||||||
})),
|
|
||||||
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_RAW): RC_SWITCH_RAW_SCHEMA,
|
||||||
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_TYPE_A): RC_SWITCH_TYPE_A_SCHEMA,
|
||||||
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
|
vol.Optional(CONF_RC_SWITCH_TYPE_B): RC_SWITCH_TYPE_B_SCHEMA,
|
||||||
|
@ -94,14 +103,9 @@ def transmitter_base(full_config):
|
||||||
if key == CONF_SONY:
|
if key == CONF_SONY:
|
||||||
return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS])
|
return SonyTransmitter.new(name, config[CONF_DATA], config[CONF_NBITS])
|
||||||
if key == CONF_RAW:
|
if key == CONF_RAW:
|
||||||
if isinstance(config, dict):
|
arr = progmem_array(config[CONF_ID], config[CONF_DATA])
|
||||||
data = config[CONF_DATA]
|
return RawTransmitter.new(name, arr, len(config[CONF_DATA]),
|
||||||
carrier_frequency = config.get(CONF_CARRIER_FREQUENCY)
|
config.get(CONF_CARRIER_FREQUENCY))
|
||||||
else:
|
|
||||||
data = config
|
|
||||||
carrier_frequency = None
|
|
||||||
return RawTransmitter.new(name, data,
|
|
||||||
carrier_frequency)
|
|
||||||
if key == CONF_RC_SWITCH_RAW:
|
if key == CONF_RC_SWITCH_RAW:
|
||||||
return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
|
return RCSwitchRawTransmitter.new(name, build_rc_switch_protocol(config[CONF_PROTOCOL]),
|
||||||
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
|
binary_code(config[CONF_CODE]), len(config[CONF_CODE]))
|
||||||
|
|
|
@ -46,6 +46,7 @@ RESERVED_IDS = [
|
||||||
|
|
||||||
'App', 'pinMode', 'delay', 'delayMicroseconds', 'digitalRead', 'digitalWrite', 'INPUT',
|
'App', 'pinMode', 'delay', 'delayMicroseconds', 'digitalRead', 'digitalWrite', 'INPUT',
|
||||||
'OUTPUT',
|
'OUTPUT',
|
||||||
|
'uint8_t', 'uint16_t', 'uint32_t', 'uint64_t', 'int8_t', 'int16_t', 'int32_t', 'int64_t',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -261,10 +261,13 @@ class ID(object):
|
||||||
self.type = type
|
self.type = type
|
||||||
|
|
||||||
def resolve(self, registered_ids):
|
def resolve(self, registered_ids):
|
||||||
|
from esphomeyaml.config_validation import RESERVED_IDS
|
||||||
|
|
||||||
if self.id is None:
|
if self.id is None:
|
||||||
base = str(self.type).replace('::', '_').lower()
|
base = str(self.type).replace('::', '_').lower()
|
||||||
name = ''.join(c for c in base if c.isalnum() or c == '_')
|
name = ''.join(c for c in base if c.isalnum() or c == '_')
|
||||||
self.id = ensure_unique_string(name, registered_ids)
|
used = set(registered_ids) | set(RESERVED_IDS)
|
||||||
|
self.id = ensure_unique_string(name, used)
|
||||||
return self.id
|
return self.id
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -317,6 +317,27 @@ class ExpressionStatement(Statement):
|
||||||
return u"{};".format(self.expression)
|
return u"{};".format(self.expression)
|
||||||
|
|
||||||
|
|
||||||
|
class ProgmemAssignmentExpression(AssignmentExpression):
|
||||||
|
def __init__(self, type, name, rhs, obj):
|
||||||
|
super(ProgmemAssignmentExpression, self).__init__(
|
||||||
|
type, '', name, rhs, obj
|
||||||
|
)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
type_ = self.type
|
||||||
|
return u"static const {} {}[] PROGMEM = {}".format(type_, self.name, self.rhs)
|
||||||
|
|
||||||
|
|
||||||
|
def progmem_array(id, rhs):
|
||||||
|
rhs = safe_exp(rhs)
|
||||||
|
obj = MockObj(id, u'.')
|
||||||
|
assignment = ProgmemAssignmentExpression(id.type, id, rhs, obj)
|
||||||
|
CORE.add(assignment)
|
||||||
|
CORE.register_variable(id, obj)
|
||||||
|
obj.requires.append(assignment)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
def statement(expression): # type: (Union[Expression, Statement]) -> Statement
|
def statement(expression): # type: (Union[Expression, Statement]) -> Statement
|
||||||
if isinstance(expression, Statement):
|
if isinstance(expression, Statement):
|
||||||
return expression
|
return expression
|
||||||
|
|
Loading…
Reference in a new issue