Add additional custom lint checks (#790)

This commit is contained in:
Otto Winter 2019-10-23 14:43:27 +02:00
parent 42b4a166ec
commit 8867a0fcfb
No known key found for this signature in database
GPG Key ID: DB66C0BE6013F97E
28 changed files with 214 additions and 109 deletions

View File

@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome.components import sensor, binary_sensor
from esphome.const import CONF_ID, CONF_CHANNELS, CONF_VALUE, CONF_TYPE, UNIT_EMPTY, \
ICON_CHECK_CIRCLE_OUTLINE, CONF_BINARY_SENSOR
ICON_CHECK_CIRCLE_OUTLINE, CONF_BINARY_SENSOR, CONF_GROUP
DEPENDENCIES = ['binary_sensor']
@ -11,7 +11,6 @@ binary_sensor_map_ns = cg.esphome_ns.namespace('binary_sensor_map')
BinarySensorMap = binary_sensor_map_ns.class_('BinarySensorMap', cg.Component, sensor.Sensor)
SensorMapType = binary_sensor_map_ns.enum('SensorMapType')
CONF_GROUP = 'group'
SENSOR_MAP_TYPES = {
CONF_GROUP: SensorMapType.BINARY_SENSOR_MAP_TYPE_GROUP,
}

View File

@ -1,18 +1,14 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate, remote_transmitter, remote_receiver, sensor
from esphome.const import CONF_ID, CONF_SENSOR
from esphome.components.remote_base import CONF_TRANSMITTER_ID, CONF_RECEIVER_ID
from esphome.const import CONF_ID, CONF_SENSOR, CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT
AUTO_LOAD = ['sensor', 'climate_ir']
coolix_ns = cg.esphome_ns.namespace('coolix')
CoolixClimate = coolix_ns.class_('CoolixClimate', climate.Climate, cg.Component)
CONF_TRANSMITTER_ID = 'transmitter_id'
CONF_RECEIVER_ID = 'receiver_id'
CONF_SUPPORTS_HEAT = 'supports_heat'
CONF_SUPPORTS_COOL = 'supports_cool'
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(CoolixClimate),
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),

View File

@ -1,13 +1,12 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import output
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE
from esphome.const import CONF_ID, CONF_LAMBDA, CONF_OUTPUTS, CONF_TYPE, CONF_BINARY
from .. import custom_ns
CustomBinaryOutputConstructor = custom_ns.class_('CustomBinaryOutputConstructor')
CustomFloatOutputConstructor = custom_ns.class_('CustomFloatOutputConstructor')
CONF_BINARY = 'binary'
CONF_FLOAT = 'float'
CONFIG_SCHEMA = cv.typed_schema({

View File

@ -1,7 +1,7 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.const import CONF_ID, CONF_TRIGGER_ID
from esphome.const import CONF_ID, CONF_TRIGGER_ID, CONF_FILE, CONF_DEVICE
from esphome.components import uart
DEPENDENCIES = ['uart']
@ -14,10 +14,8 @@ DFPlayerIsPlayingCondition = dfplayer_ns.class_('DFPlayerIsPlayingCondition', au
MULTI_CONF = True
CONF_FOLDER = 'folder'
CONF_FILE = 'file'
CONF_LOOP = 'loop'
CONF_VOLUME = 'volume'
CONF_DEVICE = 'device'
CONF_EQ_PRESET = 'eq_preset'
CONF_ON_FINISHED_PLAYBACK = 'on_finished_playback'

View File

@ -50,7 +50,7 @@ void ESP32BLEBeacon::ble_core_task(void *params) {
ble_setup();
while (true) {
delay(1000);
delay(1000); // NOLINT
}
}
void ESP32BLEBeacon::ble_setup() {

View File

@ -134,7 +134,7 @@ bool ESP32BLETracker::ble_setup() {
}
// BLE takes some time to be fully set up, 200ms should be more than enough
delay(200);
delay(200); // NOLINT
return true;
}

View File

@ -2,7 +2,7 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import pins
from esphome.const import CONF_FREQUENCY, CONF_ID, CONF_NAME, CONF_PIN, CONF_SCL, CONF_SDA, \
ESP_PLATFORM_ESP32
ESP_PLATFORM_ESP32, CONF_DATA_PINS, CONF_RESET_PIN, CONF_RESOLUTION, CONF_BRIGHTNESS
ESP_PLATFORMS = [ESP_PLATFORM_ESP32]
DEPENDENCIES = ['api']
@ -35,23 +35,19 @@ FRAME_SIZES = {
'UXGA': ESP32CameraFrameSize.ESP32_CAMERA_SIZE_1600X1200,
}
CONF_DATA_PINS = 'data_pins'
CONF_VSYNC_PIN = 'vsync_pin'
CONF_HREF_PIN = 'href_pin'
CONF_PIXEL_CLOCK_PIN = 'pixel_clock_pin'
CONF_EXTERNAL_CLOCK = 'external_clock'
CONF_I2C_PINS = 'i2c_pins'
CONF_RESET_PIN = 'reset_pin'
CONF_POWER_DOWN_PIN = 'power_down_pin'
CONF_MAX_FRAMERATE = 'max_framerate'
CONF_IDLE_FRAMERATE = 'idle_framerate'
CONF_RESOLUTION = 'resolution'
CONF_JPEG_QUALITY = 'jpeg_quality'
CONF_VERTICAL_FLIP = 'vertical_flip'
CONF_HORIZONTAL_MIRROR = 'horizontal_mirror'
CONF_CONTRAST = 'contrast'
CONF_BRIGHTNESS = 'brightness'
CONF_SATURATION = 'saturation'
CONF_TEST_PATTERN = 'test_pattern'

View File

@ -108,6 +108,8 @@ void ESP32TouchComponent::dump_config() {
}
void ESP32TouchComponent::loop() {
const uint32_t now = millis();
bool should_print = this->setup_mode_ && now - this->setup_mode_last_log_print_ > 250;
for (auto *child : this->children_) {
uint16_t value;
if (this->iir_filter_enabled_()) {
@ -119,14 +121,14 @@ void ESP32TouchComponent::loop() {
child->value_ = value;
child->publish_state(value < child->get_threshold());
if (this->setup_mode_) {
if (should_print) {
ESP_LOGD(TAG, "Touch Pad '%s' (T%u): %u", child->get_name().c_str(), child->get_touch_pad(), value);
}
}
if (this->setup_mode_) {
if (should_print) {
// Avoid spamming logs
delay(250);
this->setup_mode_last_log_print_ = now;
}
}

View File

@ -50,6 +50,7 @@ class ESP32TouchComponent : public Component {
touch_volt_atten_t voltage_attenuation_{};
std::vector<ESP32TouchBinarySensor *> children_;
bool setup_mode_{false};
uint32_t setup_mode_last_log_print_{};
uint32_t iir_filter_{0};
};

View File

@ -10,7 +10,7 @@ void MPR121Component::setup() {
ESP_LOGCONFIG(TAG, "Setting up MPR121...");
// soft reset device
this->write_byte(MPR121_SOFTRESET, 0x63);
delay(100);
delay(100); // NOLINT
if (!this->write_byte(MPR121_ECR, 0x0)) {
this->error_code_ = COMMUNICATION_FAILED;
this->mark_failed();

View File

@ -201,7 +201,7 @@ void MQTTClientComponent::check_connected() {
this->status_clear_warning();
ESP_LOGI(TAG, "MQTT Connected!");
// MQTT Client needs some time to be fully set up.
delay(100);
delay(100); // NOLINT
this->resubscribe_subscriptions_();

View File

@ -19,7 +19,7 @@ void MS5611Component::setup() {
this->mark_failed();
return;
}
delay(100);
delay(100); // NOLINT
for (uint8_t offset = 0; offset < 6; offset++) {
if (!this->read_byte_16(MS5611_CMD_READ_PROM + (offset * 2), &this->prom_[offset])) {
this->mark_failed();

View File

@ -266,7 +266,7 @@ void OTAComponent::handle_() {
delay(10);
ESP_LOGI(TAG, "OTA update finished!");
this->status_clear_warning();
delay(100);
delay(100); // NOLINT
App.safe_reboot();
error:

View File

@ -12,24 +12,24 @@ pmsx003_ns = cg.esphome_ns.namespace('pmsx003')
PMSX003Component = pmsx003_ns.class_('PMSX003Component', uart.UARTDevice, cg.Component)
PMSX003Sensor = pmsx003_ns.class_('PMSX003Sensor', sensor.Sensor)
CONF_PMSX003 = 'PMSX003'
CONF_PMS5003T = 'PMS5003T'
CONF_PMS5003ST = 'PMS5003ST'
TYPE_PMSX003 = 'PMSX003'
TYPE_PMS5003T = 'PMS5003T'
TYPE_PMS5003ST = 'PMS5003ST'
PMSX003Type = pmsx003_ns.enum('PMSX003Type')
PMSX003_TYPES = {
CONF_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
CONF_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
CONF_PMS5003ST: PMSX003Type.PMSX003_TYPE_5003ST,
TYPE_PMSX003: PMSX003Type.PMSX003_TYPE_X003,
TYPE_PMS5003T: PMSX003Type.PMSX003_TYPE_5003T,
TYPE_PMS5003ST: PMSX003Type.PMSX003_TYPE_5003ST,
}
SENSORS_TO_TYPE = {
CONF_PM_1_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_PM_2_5: [CONF_PMSX003, CONF_PMS5003T, CONF_PMS5003ST],
CONF_PM_10_0: [CONF_PMSX003, CONF_PMS5003ST],
CONF_TEMPERATURE: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_HUMIDITY: [CONF_PMS5003T, CONF_PMS5003ST],
CONF_FORMALDEHYDE: [CONF_PMS5003ST],
CONF_PM_1_0: [TYPE_PMSX003, TYPE_PMS5003ST],
CONF_PM_2_5: [TYPE_PMSX003, TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_PM_10_0: [TYPE_PMSX003, TYPE_PMS5003ST],
CONF_TEMPERATURE: [TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_HUMIDITY: [TYPE_PMS5003T, TYPE_PMS5003ST],
CONF_FORMALDEHYDE: [TYPE_PMS5003ST],
}

View File

@ -13,8 +13,8 @@ void RestartSwitch::write_state(bool state) {
if (state) {
ESP_LOGI(TAG, "Restarting device...");
// then execute
delay(100); // Let MQTT settle a bit
// Let MQTT settle a bit
delay(100); // NOLINT
App.safe_reboot();
}
}

View File

@ -3,7 +3,7 @@ import esphome.config_validation as cv
from esphome import pins, automation
from esphome.components import sensor
from esphome.const import CONF_ID, CONF_RESOLUTION, CONF_MIN_VALUE, CONF_MAX_VALUE, UNIT_STEPS, \
ICON_ROTATE_RIGHT, CONF_VALUE
ICON_ROTATE_RIGHT, CONF_VALUE, CONF_PIN_A, CONF_PIN_B
rotary_encoder_ns = cg.esphome_ns.namespace('rotary_encoder')
RotaryEncoderResolution = rotary_encoder_ns.enum('RotaryEncoderResolution')
@ -13,8 +13,6 @@ RESOLUTIONS = {
4: RotaryEncoderResolution.ROTARY_ENCODER_4_PULSES_PER_CYCLE,
}
CONF_PIN_A = 'pin_a'
CONF_PIN_B = 'pin_b'
CONF_PIN_RESET = 'pin_reset'
RotaryEncoderSensor = rotary_encoder_ns.class_('RotaryEncoderSensor', sensor.Sensor, cg.Component)

View File

@ -3,15 +3,13 @@ import esphome.config_validation as cv
from esphome.components import i2c, sensor
from esphome.const import CONF_ID, UNIT_PARTS_PER_MILLION, \
CONF_HUMIDITY, CONF_TEMPERATURE, ICON_PERIODIC_TABLE_CO2, \
UNIT_CELSIUS, ICON_THERMOMETER, ICON_WATER_PERCENT, UNIT_PERCENT
UNIT_CELSIUS, ICON_THERMOMETER, ICON_WATER_PERCENT, UNIT_PERCENT, CONF_CO2
DEPENDENCIES = ['i2c']
scd30_ns = cg.esphome_ns.namespace('scd30')
SCD30Component = scd30_ns.class_('SCD30Component', cg.PollingComponent, i2c.I2CDevice)
CONF_CO2 = 'co2'
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(SCD30Component),
cv.Required(CONF_CO2): sensor.sensor_schema(UNIT_PARTS_PER_MILLION,

View File

@ -14,8 +14,8 @@ CONF_TVOC = 'tvoc'
CONF_BASELINE = 'baseline'
CONF_UPTIME = 'uptime'
CONF_COMPENSATION = 'compensation'
CONF_COMPENSATION_HUMIDITY = 'humidity_source'
CONF_COMPENSATION_TEMPERATURE = 'temperature_source'
CONF_HUMIDITY_SOURCE = 'humidity_source'
CONF_TEMPERATURE_SOURCE = 'temperature_source'
CONFIG_SCHEMA = cv.Schema({
cv.GenerateID(): cv.declare_id(SGP30Component),
@ -24,8 +24,8 @@ CONFIG_SCHEMA = cv.Schema({
cv.Required(CONF_TVOC): sensor.sensor_schema(UNIT_PARTS_PER_BILLION, ICON_RADIATOR, 0),
cv.Optional(CONF_BASELINE): cv.hex_uint16_t,
cv.Optional(CONF_COMPENSATION): cv.Schema({
cv.Required(CONF_COMPENSATION_HUMIDITY): cv.use_id(sensor.Sensor),
cv.Required(CONF_COMPENSATION_TEMPERATURE): cv.use_id(sensor.Sensor)
cv.Required(CONF_HUMIDITY_SOURCE): cv.use_id(sensor.Sensor),
cv.Required(CONF_TEMPERATURE_SOURCE): cv.use_id(sensor.Sensor)
}),
}).extend(cv.polling_component_schema('60s')).extend(i2c.i2c_device_schema(0x58))
@ -48,7 +48,7 @@ def to_code(config):
if CONF_COMPENSATION in config:
compensation_config = config[CONF_COMPENSATION]
sens = yield cg.get_variable(compensation_config[CONF_COMPENSATION_HUMIDITY])
sens = yield cg.get_variable(compensation_config[CONF_HUMIDITY_SOURCE])
cg.add(var.set_humidity_sensor(sens))
sens = yield cg.get_variable(compensation_config[CONF_COMPENSATION_TEMPERATURE])
sens = yield cg.get_variable(compensation_config[CONF_TEMPERATURE_SOURCE])
cg.add(var.set_temperature_sensor(sens))

View File

@ -14,7 +14,7 @@ void ShutdownSwitch::write_state(bool state) {
if (state) {
ESP_LOGI(TAG, "Shutting down...");
delay(100); // Let MQTT settle a bit
delay(100); // NOLINT
App.run_safe_shutdown_hooks();
#ifdef ARDUINO_ARCH_ESP8266

View File

@ -14,7 +14,7 @@ void SPISSD1325::setup() {
this->cs_->setup(); // OUTPUT
this->init_reset_();
delay(500);
delay(500); // NOLINT
SSD1325::setup();
}
void SPISSD1325::dump_config() {

View File

@ -5,7 +5,7 @@ from esphome.const import CONF_ID
from .. import SX1509Component, sx1509_ns, CONF_SX1509_ID
CONF_ROW = 'row'
CONF_COLUMN = 'col'
CONF_COL = 'col'
DEPENDENCIES = ['sx1509']
@ -15,7 +15,7 @@ CONFIG_SCHEMA = binary_sensor.BINARY_SENSOR_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(SX1509BinarySensor),
cv.GenerateID(CONF_SX1509_ID): cv.use_id(SX1509Component),
cv.Required(CONF_ROW): cv.int_range(min=0, max=4),
cv.Required(CONF_COLUMN): cv.int_range(min=0, max=4),
cv.Required(CONF_COL): cv.int_range(min=0, max=4),
})
@ -23,6 +23,6 @@ def to_code(config):
var = cg.new_Pvariable(config[CONF_ID])
yield binary_sensor.register_binary_sensor(var, config)
hub = yield cg.get_variable(config[CONF_SX1509_ID])
cg.add(var.set_row_col(config[CONF_ROW], config[CONF_COLUMN]))
cg.add(var.set_row_col(config[CONF_ROW], config[CONF_COL]))
cg.add(hub.register_keypad_binary_sensor(var))

View File

@ -1,18 +1,14 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate, remote_transmitter, remote_receiver, sensor
from esphome.const import CONF_ID, CONF_SENSOR
from esphome.components.remote_base import CONF_TRANSMITTER_ID, CONF_RECEIVER_ID
from esphome.const import CONF_ID, CONF_SENSOR, CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT
AUTO_LOAD = ['sensor', 'climate_ir']
tcl112_ns = cg.esphome_ns.namespace('tcl112')
Tcl112Climate = tcl112_ns.class_('Tcl112Climate', climate.Climate, cg.Component)
CONF_TRANSMITTER_ID = 'transmitter_id'
CONF_RECEIVER_ID = 'receiver_id'
CONF_SUPPORTS_HEAT = 'supports_heat'
CONF_SUPPORTS_COOL = 'supports_cool'
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(Tcl112Climate),
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),

View File

@ -2,13 +2,12 @@ import esphome.codegen as cg
import esphome.config_validation as cv
from esphome import automation
from esphome.components import output
from esphome.const import CONF_ID, CONF_TYPE
from esphome.const import CONF_ID, CONF_TYPE, CONF_BINARY
from .. import template_ns
TemplateBinaryOutput = template_ns.class_('TemplateBinaryOutput', output.BinaryOutput)
TemplateFloatOutput = template_ns.class_('TemplateFloatOutput', output.FloatOutput)
CONF_BINARY = 'binary'
CONF_FLOAT = 'float'
CONF_WRITE_ACTION = 'write_action'

View File

@ -45,9 +45,9 @@ class WaveshareEPaper : public PollingComponent,
void reset_() {
if (this->reset_pin_ != nullptr) {
this->reset_pin_->digital_write(false);
delay(200);
delay(200); // NOLINT
this->reset_pin_->digital_write(true);
delay(200);
delay(200); // NOLINT
}
}
@ -144,7 +144,7 @@ class WaveshareEPaper4P2In : public WaveshareEPaper {
// COMMAND PANEL SETTING
this->command(0x00);
delay(100);
delay(100); // NOLINT
// COMMAND POWER SETTING
this->command(0x01);
@ -153,7 +153,7 @@ class WaveshareEPaper4P2In : public WaveshareEPaper {
this->data(0x00);
this->data(0x00);
this->data(0x00);
delay(100);
delay(100); // NOLINT
// COMMAND POWER OFF
this->command(0x02);

View File

@ -481,7 +481,7 @@ void WiFiComponent::retry_connect() {
// If retry failed for more than 5 times, let's restart STA
ESP_LOGW(TAG, "Restarting WiFi adapter...");
this->wifi_mode_(false, {});
delay(100);
delay(100); // NOLINT
this->num_retried_ = 0;
} else {
this->num_retried_++;

View File

@ -1,17 +1,14 @@
import esphome.codegen as cg
import esphome.config_validation as cv
from esphome.components import climate, remote_transmitter, sensor
from esphome.const import CONF_ID, CONF_SENSOR
from esphome.components.remote_base import CONF_TRANSMITTER_ID
from esphome.const import CONF_ID, CONF_SENSOR, CONF_SUPPORTS_COOL, CONF_SUPPORTS_HEAT
AUTO_LOAD = ['sensor']
yashima_ns = cg.esphome_ns.namespace('yashima')
YashimaClimate = yashima_ns.class_('YashimaClimate', climate.Climate, cg.Component)
CONF_TRANSMITTER_ID = 'transmitter_id'
CONF_SUPPORTS_HEAT = 'supports_heat'
CONF_SUPPORTS_COOL = 'supports_cool'
CONFIG_SCHEMA = cv.All(climate.CLIMATE_SCHEMA.extend({
cv.GenerateID(): cv.declare_id(YashimaClimate),
cv.GenerateID(CONF_TRANSMITTER_ID): cv.use_id(remote_transmitter.RemoteTransmitterComponent),

View File

@ -63,8 +63,8 @@ CONF_BROKER = 'broker'
CONF_BSSID = 'bssid'
CONF_BUFFER_SIZE = 'buffer_size'
CONF_BUILD_PATH = 'build_path'
CONF_BUSY_PIN = 'busy_pin'
CONF_BUS_VOLTAGE = 'bus_voltage'
CONF_BUSY_PIN = 'busy_pin'
CONF_CALIBRATE_LINEAR = 'calibrate_linear'
CONF_CALIBRATION = 'calibration'
CONF_CAPACITANCE = 'capacitance'
@ -84,23 +84,23 @@ CONF_CO2 = 'co2'
CONF_CODE = 'code'
CONF_COLD_WHITE = 'cold_white'
CONF_COLD_WHITE_COLOR_TEMPERATURE = 'cold_white_color_temperature'
CONF_COLORS = 'colors'
CONF_COLOR_CORRECT = 'color_correct'
CONF_COLOR_TEMPERATURE = 'color_temperature'
CONF_COLORS = 'colors'
CONF_COMMAND = 'command'
CONF_COMMAND_TOPIC = 'command_topic'
CONF_COMMENT = 'comment'
CONF_COMMIT = 'commit'
CONF_COMPONENTS = 'components'
CONF_COMPONENT_ID = 'component_id'
CONF_COMPONENTS = 'components'
CONF_CONDITION = 'condition'
CONF_CONDITION_ID = 'condition_id'
CONF_CONDUCTIVITY = 'conductivity'
CONF_COOL_ACTION = 'cool_action'
CONF_COUNT_MODE = 'count_mode'
CONF_CRON = 'cron'
CONF_CSS_URL = 'css_url'
CONF_CS_PIN = 'cs_pin'
CONF_CSS_URL = 'css_url'
CONF_CURRENT = 'current'
CONF_CURRENT_OPERATION = 'current_operation'
CONF_CURRENT_RESISTOR = 'current_resistor'
@ -122,12 +122,12 @@ CONF_DELTA = 'delta'
CONF_DEVICE = 'device'
CONF_DEVICE_CLASS = 'device_class'
CONF_DIMENSIONS = 'dimensions'
CONF_DIRECTION = 'direction'
CONF_DIR_PIN = 'dir_pin'
CONF_DIRECTION = 'direction'
CONF_DISCOVERY = 'discovery'
CONF_DISTANCE = 'distance'
CONF_DISCOVERY_PREFIX = 'discovery_prefix'
CONF_DISCOVERY_RETAIN = 'discovery_retain'
CONF_DISTANCE = 'distance'
CONF_DIV_RATIO = 'div_ratio'
CONF_DNS1 = 'dns1'
CONF_DNS2 = 'dns2'
@ -152,8 +152,8 @@ CONF_FAMILY = 'family'
CONF_FAST_CONNECT = 'fast_connect'
CONF_FILE = 'file'
CONF_FILTER = 'filter'
CONF_FILTERS = 'filters'
CONF_FILTER_OUT = 'filter_out'
CONF_FILTERS = 'filters'
CONF_FLASH_LENGTH = 'flash_length'
CONF_FOR = 'for'
CONF_FORCE_UPDATE = 'force_update'
@ -172,8 +172,8 @@ CONF_GREEN = 'green'
CONF_GROUP = 'group'
CONF_HARDWARE_UART = 'hardware_uart'
CONF_HEARTBEAT = 'heartbeat'
CONF_HEATER = 'heater'
CONF_HEAT_ACTION = 'heat_action'
CONF_HEATER = 'heater'
CONF_HIDDEN = 'hidden'
CONF_HIGH = 'high'
CONF_HIGH_VOLTAGE_REFERENCE = 'high_voltage_reference'
@ -207,8 +207,8 @@ CONF_INVERTED = 'inverted'
CONF_IP_ADDRESS = 'ip_address'
CONF_JS_URL = 'js_url'
CONF_JVC = 'jvc'
CONF_KEEPALIVE = 'keepalive'
CONF_KEEP_ON_TIME = 'keep_on_time'
CONF_KEEPALIVE = 'keepalive'
CONF_LAMBDA = 'lambda'
CONF_LEVEL = 'level'
CONF_LG = 'lg'
@ -218,9 +218,9 @@ CONF_LIGHTNING_ENERGY = 'lightning_energy'
CONF_LIGHTNING_THRESHOLD = 'lightning_threshold'
CONF_LOADED_INTEGRATIONS = 'loaded_integrations'
CONF_LOCAL = 'local'
CONF_LOG_TOPIC = 'log_topic'
CONF_LOGGER = 'logger'
CONF_LOGS = 'logs'
CONF_LOG_TOPIC = 'log_topic'
CONF_LOW = 'low'
CONF_LOW_VOLTAGE_REFERENCE = 'low_voltage_reference'
CONF_MAC_ADDRESS = 'mac_address'
@ -240,13 +240,13 @@ CONF_MAX_VOLTAGE = 'max_voltage'
CONF_MEASUREMENT_DURATION = 'measurement_duration'
CONF_MEDIUM = 'medium'
CONF_METHOD = 'method'
CONF_MINUTE = 'minute'
CONF_MINUTES = 'minutes'
CONF_MIN_LENGTH = 'min_length'
CONF_MIN_LEVEL = 'min_level'
CONF_MIN_POWER = 'min_power'
CONF_MIN_TEMPERATURE = 'min_temperature'
CONF_MIN_VALUE = 'min_value'
CONF_MINUTE = 'minute'
CONF_MINUTES = 'minutes'
CONF_MISO_PIN = 'miso_pin'
CONF_MODE = 'mode'
CONF_MODEL = 'model'
@ -262,14 +262,13 @@ CONF_NBITS = 'nbits'
CONF_NEC = 'nec'
CONF_NETWORKS = 'networks'
CONF_NOISE_LEVEL = 'noise_level'
CONF_NUMBER = 'number'
CONF_NUM_ATTEMPTS = 'num_attempts'
CONF_NUM_CHANNELS = 'num_channels'
CONF_NUM_CHIPS = 'num_chips'
CONF_NUM_LEDS = 'num_leds'
CONF_NUMBER = 'number'
CONF_OFFSET = 'offset'
CONF_ON = 'on'
CONF_ONE = 'one'
CONF_ON_BOOT = 'on_boot'
CONF_ON_CLICK = 'on_click'
CONF_ON_DOUBLE_CLICK = 'on_double_click'
@ -288,6 +287,7 @@ CONF_ON_TURN_OFF = 'on_turn_off'
CONF_ON_TURN_ON = 'on_turn_on'
CONF_ON_VALUE = 'on_value'
CONF_ON_VALUE_RANGE = 'on_value_range'
CONF_ONE = 'one'
CONF_OPEN_ACTION = 'open_action'
CONF_OPEN_DURATION = 'open_duration'
CONF_OPEN_ENDSTOP = 'open_endstop'
@ -299,11 +299,11 @@ CONF_OSCILLATION_OUTPUT = 'oscillation_output'
CONF_OSCILLATION_STATE_TOPIC = 'oscillation_state_topic'
CONF_OTA = 'ota'
CONF_OUTPUT = 'output'
CONF_OUTPUTS = 'outputs'
CONF_OUTPUT_ID = 'output_id'
CONF_OUTPUTS = 'outputs'
CONF_OVERSAMPLING = 'oversampling'
CONF_PAGES = 'pages'
CONF_PAGE_ID = 'page_id'
CONF_PAGES = 'pages'
CONF_PANASONIC = 'panasonic'
CONF_PASSWORD = 'password'
CONF_PAYLOAD = 'payload'
@ -311,15 +311,15 @@ CONF_PAYLOAD_AVAILABLE = 'payload_available'
CONF_PAYLOAD_NOT_AVAILABLE = 'payload_not_available'
CONF_PHASE_BALANCER = 'phase_balancer'
CONF_PIN = 'pin'
CONF_PINS = 'pins'
CONF_PIN_A = 'pin_a'
CONF_PIN_B = 'pin_b'
CONF_PIN_C = 'pin_c'
CONF_PIN_D = 'pin_d'
CONF_PINS = 'pins'
CONF_PLATFORM = 'platform'
CONF_PLATFORMIO_OPTIONS = 'platformio_options'
CONF_PM_10_0 = 'pm_10_0'
CONF_PM_1_0 = 'pm_1_0'
CONF_PM_10_0 = 'pm_10_0'
CONF_PM_2_5 = 'pm_2_5'
CONF_PORT = 'port'
CONF_POSITION = 'position'
@ -353,8 +353,8 @@ CONF_RESTORE_MODE = 'restore_mode'
CONF_RESTORE_STATE = 'restore_state'
CONF_RESTORE_VALUE = 'restore_value'
CONF_RETAIN = 'retain'
CONF_RGBW = 'rgbw'
CONF_RGB_ORDER = 'rgb_order'
CONF_RGBW = 'rgbw'
CONF_RISING_EDGE = 'rising_edge'
CONF_ROTATION = 'rotation'
CONF_RS_PIN = 'rs_pin'
@ -377,14 +377,14 @@ CONF_SEL_PIN = 'sel_pin'
CONF_SEND_EVERY = 'send_every'
CONF_SEND_FIRST_AT = 'send_first_at'
CONF_SENSOR = 'sensor'
CONF_SENSORS = 'sensors'
CONF_SENSOR_ID = 'sensor_id'
CONF_SENSORS = 'sensors'
CONF_SEQUENCE = 'sequence'
CONF_SERVERS = 'servers'
CONF_SERVICE = 'service'
CONF_SERVICES = 'services'
CONF_SETUP_MODE = 'setup_mode'
CONF_SETUP_PRIORITY = 'setup_priority'
CONF_SEQUENCE = 'sequence'
CONF_SHUNT_RESISTANCE = 'shunt_resistance'
CONF_SHUNT_VOLTAGE = 'shunt_voltage'
CONF_SHUTDOWN_MESSAGE = 'shutdown_message'
@ -408,6 +408,8 @@ CONF_STEP_PIN = 'step_pin'
CONF_STOP = 'stop'
CONF_STOP_ACTION = 'stop_action'
CONF_SUBNET = 'subnet'
CONF_SUPPORTS_COOL = 'supports_cool'
CONF_SUPPORTS_HEAT = 'supports_heat'
CONF_SWITCHES = 'switches'
CONF_SYNC = 'sync'
CONF_TAG = 'tag'
@ -425,10 +427,10 @@ CONF_TILT = 'tilt'
CONF_TILT_ACTION = 'tilt_action'
CONF_TILT_LAMBDA = 'tilt_lambda'
CONF_TIME = 'time'
CONF_TIME_ID = 'time_id'
CONF_TIMEOUT = 'timeout'
CONF_TIMES = 'times'
CONF_TIMEZONE = 'timezone'
CONF_TIME_ID = 'time_id'
CONF_TIMING = 'timing'
CONF_TO = 'to'
CONF_TOLERANCE = 'tolerance'
@ -449,8 +451,8 @@ CONF_UNIQUE = 'unique'
CONF_UNIT_OF_MEASUREMENT = 'unit_of_measurement'
CONF_UPDATE_INTERVAL = 'update_interval'
CONF_UPDATE_ON_BOOT = 'update_on_boot'
CONF_USERNAME = 'username'
CONF_USE_ADDRESS = 'use_address'
CONF_USERNAME = 'username'
CONF_UUID = 'uuid'
CONF_VALUE = 'value'
CONF_VARIABLES = 'variables'
@ -470,8 +472,8 @@ CONF_WHITE = 'white'
CONF_WIDTH = 'width'
CONF_WIFI = 'wifi'
CONF_WILL_MESSAGE = 'will_message'
CONF_WIND_SPEED = 'wind_speed'
CONF_WIND_DIRECTION_DEGREES = 'wind_direction_degrees'
CONF_WIND_SPEED = 'wind_speed'
CONF_WINDOW_SIZE = 'window_size'
CONF_ZERO = 'zero'
@ -479,8 +481,8 @@ ICON_ARROW_EXPAND_VERTICAL = 'mdi:arrow-expand-vertical'
ICON_BATTERY = 'mdi:battery'
ICON_BRIEFCASE_DOWNLOAD = 'mdi:briefcase-download'
ICON_BRIGHTNESS_5 = 'mdi:brightness-5'
ICON_CHEMICAL_WEAPON = 'mdi:chemical-weapon'
ICON_CHECK_CIRCLE_OUTLINE = 'mdi:check-circle-outline'
ICON_CHEMICAL_WEAPON = 'mdi:chemical-weapon'
ICON_CURRENT_AC = 'mdi:current-ac'
ICON_EMPTY = ''
ICON_FLASH = 'mdi:flash'
@ -499,26 +501,26 @@ ICON_RESTART = 'mdi:restart'
ICON_ROTATE_RIGHT = 'mdi:rotate-right'
ICON_SCALE = 'mdi:scale'
ICON_SCREEN_ROTATION = 'mdi:screen-rotation'
ICON_SIGN_DIRECTION = 'mdi:sign-direction'
ICON_SIGNAL = 'mdi: signal-distance-variant'
ICON_SIGNAL_DISTANCE_VARIANT = 'mdi:signal'
ICON_SIGN_DIRECTION = 'mdi:sign-direction'
ICON_WEATHER_SUNSET = 'mdi:weather-sunset'
ICON_WEATHER_SUNSET_DOWN = 'mdi:weather-sunset-down'
ICON_WEATHER_SUNSET_UP = 'mdi:weather-sunset-up'
ICON_THERMOMETER = 'mdi:thermometer'
ICON_TIMER = 'mdi:timer'
ICON_WATER_PERCENT = 'mdi:water-percent'
ICON_WEATHER_SUNSET = 'mdi:weather-sunset'
ICON_WEATHER_SUNSET_DOWN = 'mdi:weather-sunset-down'
ICON_WEATHER_SUNSET_UP = 'mdi:weather-sunset-up'
ICON_WEATHER_WINDY = 'mdi:weather-windy'
ICON_WIFI = 'mdi:wifi'
UNIT_AMPERE = 'A'
UNIT_CELSIUS = u'°C'
UNIT_DECIBEL = 'dB'
UNIT_DEGREES = u'°'
UNIT_DEGREE_PER_SECOND = u'°/s'
UNIT_DEGREES = u'°'
UNIT_EMPTY = ''
UNIT_HZ = 'hz'
UNIT_HECTOPASCAL = 'hPa'
UNIT_HZ = 'hz'
UNIT_KELVIN = 'K'
UNIT_KILOMETER = 'km'
UNIT_KILOMETER_PER_HOUR = 'km/h'
@ -529,8 +531,8 @@ UNIT_MICROGRAMS_PER_CUBIC_METER = u'µg/m³'
UNIT_MICROSIEMENS_PER_CENTIMETER = u'µS/cm'
UNIT_MICROTESLA = u'µT'
UNIT_OHM = u'Ω'
UNIT_PARTS_PER_MILLION = 'ppm'
UNIT_PARTS_PER_BILLION = 'ppb'
UNIT_PARTS_PER_MILLION = 'ppm'
UNIT_PERCENT = '%'
UNIT_PULSES_PER_MINUTE = 'pulses/min'
UNIT_SECOND = 's'

View File

@ -7,6 +7,7 @@ import fnmatch
import os.path
import subprocess
import sys
import re
def find_all(a_str, sub):
@ -39,6 +40,7 @@ ignore_types = ('.ico', '.woff', '.woff2', '')
LINT_FILE_CHECKS = []
LINT_CONTENT_CHECKS = []
LINT_POST_CHECKS = []
def run_check(lint_obj, fname, *args):
@ -84,6 +86,31 @@ def lint_content_check(**kwargs):
return decorator
def lint_post_check(func):
_add_check(LINT_POST_CHECKS, func)
return func
def lint_re_check(regex, **kwargs):
prog = re.compile(regex, re.MULTILINE)
decor = lint_content_check(**kwargs)
def decorator(func):
def new_func(fname, content):
errors = []
for match in prog.finditer(content):
if 'NOLINT' in match.group(0):
continue
lineno = content.count("\n", 0, match.start()) + 1
err = func(fname, match)
if err is None:
continue
errors.append("{} See line {}.".format(err, lineno))
return errors
return decor(new_func)
return decorator
def lint_content_find_check(find, **kwargs):
decor = lint_content_check(**kwargs)
@ -92,9 +119,12 @@ def lint_content_find_check(find, **kwargs):
find_ = find
if callable(find):
find_ = find(fname, content)
errors = []
for line, col in find_all(content, find_):
err = func(fname)
return "{err} See line {line}:{col}.".format(err=err, line=line+1, col=col+1)
errors.append("{err} See line {line}:{col}."
"".format(err=err, line=line+1, col=col+1))
return errors
return decor(new_func)
return decorator
@ -143,6 +173,98 @@ def lint_end_newline(fname, content):
return None
CPP_RE_EOL = r'\s*?(?://.*?)?$'
def highlight(s):
return '\033[36m{}\033[0m'.format(s)
@lint_re_check(r'^#define\s+([a-zA-Z0-9_]+)\s+([0-9bx]+)' + CPP_RE_EOL,
include=cpp_include, exclude=['esphome/core/log.h'])
def lint_no_defines(fname, match):
s = highlight('static const uint8_t {} = {};'.format(match.group(1), match.group(2)))
return ("#define macros for integer constants are not allowed, please use "
"{} style instead (replace uint8_t with the appropriate "
"datatype). See also Google style guide.".format(s))
@lint_re_check(r'^\s*delay\((\d+)\);' + CPP_RE_EOL, include=cpp_include)
def lint_no_long_delays(fname, match):
duration_ms = int(match.group(1))
if duration_ms < 50:
return None
return (
"{} - long calls to delay() are not allowed in ESPHome because everything executes "
"in one thread. Calling delay() will block the main thread and slow down ESPHome.\n"
"If there's no way to work around the delay() and it doesn't execute often, please add "
"a '// NOLINT' comment to the line."
"".format(highlight(match.group(0).strip()))
)
@lint_content_check(include=['esphome/const.py'])
def lint_const_ordered(fname, content):
lines = content.splitlines()
errors = []
for start in ['CONF_', 'ICON_', 'UNIT_']:
matching = [(i+1, line) for i, line in enumerate(lines) if line.startswith(start)]
ordered = list(sorted(matching, key=lambda x: x[1].replace('_', ' ')))
ordered = [(mi, ol) for (mi, _), (_, ol) in zip(matching, ordered)]
for (mi, ml), (oi, ol) in zip(matching, ordered):
if ml == ol:
continue
target = next(i for i, l in ordered if l == ml)
target_text = next(l for i, l in matching if target == i)
errors.append("Constant {} is not ordered, please make sure all constants are ordered. "
"See line {} (should go to line {}, {})"
"".format(highlight(ml), mi, target, target_text))
return errors
@lint_re_check(r'^\s*CONF_([A-Z_0-9a-z]+)\s+=\s+[\'"](.*?)[\'"]\s*?$', include=['*.py'])
def lint_conf_matches(fname, match):
const = match.group(1)
value = match.group(2)
const_norm = const.lower()
value_norm = value.replace('.', '_')
if const_norm == value_norm:
return None
return ("Constant {} does not match value {}! Please make sure the constant's name matches its "
"value!"
"".format(highlight('CONF_' + const), highlight(value)))
CONF_RE = r'^(CONF_[a-zA-Z0-9_]+)\s*=\s*[\'"].*?[\'"]\s*?$'
with codecs.open('esphome/const.py', 'r', encoding='utf-8') as f_handle:
constants_content = f_handle.read()
CONSTANTS = [m.group(1) for m in re.finditer(CONF_RE, constants_content, re.MULTILINE)]
CONSTANTS_USES = collections.defaultdict(list)
@lint_re_check(CONF_RE, include=['*.py'], exclude=['esphome/const.py'])
def lint_conf_from_const_py(fname, match):
name = match.group(1)
if name not in CONSTANTS:
CONSTANTS_USES[name].append(fname)
return None
return ("Constant {} has already been defined in const.py - please import the constant from "
"const.py directly.".format(highlight(name)))
@lint_post_check
def lint_constants_usage():
errors = []
for constant, uses in CONSTANTS_USES.items():
if len(uses) < 4:
continue
errors.append("Constant {} is defined in {} files. Please move all definitions of the "
"constant to const.py (Uses: {})"
"".format(highlight(constant), len(uses), ', '.join(uses)))
return errors
def relative_cpp_search_text(fname, content):
parts = fname.split('/')
integration = parts[2]
@ -241,6 +363,8 @@ for fname in files:
continue
run_checks(LINT_CONTENT_CHECKS, fname, fname, content)
run_checks(LINT_POST_CHECKS, 'POST')
for f, errs in sorted(errors.items()):
print("\033[0;32m************* File \033[1;32m{}\033[0m".format(f))
for err in errs: