예제 #1
0
 async def on_message(self, topic, msg, retain):
     _log = logging.getLogger("easyGPIO")
     if topic.endswith("/set") is False:
         if retain:
             pin = topic[topic.rfind("GPIO/") + 5:]
         else:
             # topic without /set ignored if not retained
             return False
     else:
         pin = topic[topic.rfind("GPIO/") + 5:topic.rfind("/set")]
     print("__gpio pin", pin, msg, retain)
     try:
         _p = Pin(pin)
     except Exception as e:
         await _log.logAsync("pin {!r} does not exist: {!s}".format(pin, e))
         return False
     if msg != "":
         value = None
         if msg in _mqtt.payload_on:
             value = 1
         elif msg in _mqtt.payload_off:
             value = 0
         try:
             value = int(msg)
         except:
             pass
         if value is None:
             await _log.logAsync(
                 "error",
                 "pin {!r} got no supported value {!r}".format(pin, msg))
             return False
         Pin(pin, machine.Pin.OUT).value(value)
         return True
     else:
         return Pin(pin, machine.Pin.IN).value()
예제 #2
0
def sensor(package, component, constructor_args=None, temp_function=None, humid_function=None,
           init_function=None, init_args=None, sensor_component_name=None,
           mqtt_topic=None, interval=None,
           precision_temp=2, precision_humid=1, temp_offset=0, humid_offset=0):
    sensor_component_name = sensor_component_name or component
    log = logging.getLogger(sensor_component_name)
    conf = {"_order": [sensor_component_name],
            sensor_component_name: {"package": package, "component": component,
                                    "constructor_args": constructor_args,
                                    "init_function": init_function, "init_args": init_args}}
    if config.registerComponents(conf) == False:
        log.critical("Can't wrap component {!s} as sensor registration failed".format(
            sensor_component_name))
        return False
    gc.collect()
    del conf
    gc.collect()
    component = config.getComponent(sensor_component_name)
    if component is None:
        log.critical("Can't wrap component {!s} as sensor does not exist in config.COMPONENTS".format(
            sensor_component_name))
        return False
    for f in [temp_function, humid_function]:
        if f is not None and hasattr(component, f) == False:
            log.critical("Sensor {!s} has no function {!s}, can't register".format(
                sensor_component_name, f))
            return False
    interval = interval or config.INTERVAL_SEND_SENSOR
    mqtt_topic = mqtt_topic or mqtt.getDeviceTopic(sensor_component_name)
    return SensorWrapper(sensor_component_name, component, temp_function, humid_function,
                         mqtt_topic, interval, precision_temp, precision_humid, temp_offset,
                         humid_offset)
예제 #3
0
 def __init__(self, component_name, version, unit_index: int, discover=True, logger=None):
     """
     Base component class
     :param component_name: name of the component that is subclassing this switch (used for discovery and topics)
     :param version: version of the component module. will be logged over mqtt
     :param unit_index: counter of the registerd unit of this sensor_type (used for default topics)
     :param discover: if the component should send a discovery message, used in Home-Assistant.
     :param logger: optional logger instance. If not provided, one will be created with the component name
     """
     self._next_component = None  # needed to keep a list of registered components
     global _components
     if _components is None:
         _components = self
     else:
         c = _components
         while c is not None:
             if c._next_component is None:
                 c._next_component = self
                 break
             c = c._next_component
     # Workaround to prevent every component object from creating a new asyncio task for
     # network oriented initialization as this would cause a big RAM demand.
     global _init_queue_start
     if _init_queue_start is None:
         _init_queue_start = self
         asyncio.create_task(self.__initNetworkProcess())
     self.COMPONENT_NAME = component_name
     self.VERSION = version
     self._count = unit_index
     self.__discover = discover
     self._log = logger or logging.getLogger("{!s}{!s}".format(component_name, self._count))
예제 #4
0
    async def _setValue(self, sensor_type, value, timeout=10):
        """
        Set the newly read value for the given sensor_type
        :param sensor_type:
        :param value:
        :param timeout: timeout for logging if value is None or exception in processing value.
        If sensor is designed to be read quickly and logging if no value could be read is not
        relevant, then the sensor _read function should not call _setValue if it has no value.
        :return:
        """
        self._checkType(sensor_type)
        s = self._values[sensor_type]
        if value is not None:
            if type(value) in (int, float):
                try:
                    value = round(value, s[0])
                    value += s[1]
                except Exception as e:
                    log = self._log or logging.getLogger(self.COMPONENT_NAME)
                    await log.asyncLog("error",
                                       "Error processing value:",
                                       e,
                                       timeout=timeout)
                    value = None
            elif type(value) not in (bool, str):
                log = self._log or logging.getLogger(self.COMPONENT_NAME)
                await log.asyncLog("error",
                                   "Error processing value:",
                                   value,
                                   "no known type",
                                   timeout=timeout)
                value = None

        else:
            log = self._log or logging.getLogger(self.COMPONENT_NAME)
            await log.asyncLog("warn",
                               "Got no value for",
                               sensor_type,
                               timeout=timeout)
        s[-1] = value
        if value:
            s[-2] = time.ticks_ms()
예제 #5
0
 async def on_message(self, topic, msg, retained):
     _log = logging.getLogger("gpio")
     if msg in _mqtt.payload_on:
         self.pin.value(1)
         return True
     elif msg in _mqtt.payload_off:
         self.pin.value(0)
         return True
     else:
         _log.error("Unknown payload {!r}, GPIO {!s}".format(msg, self.pin))
         return False
예제 #6
0
 async def _loop(self):
     await asyncio.sleep(12)
     if platform != "linux":
         s = network.WLAN(network.STA_IF)
     else:
         s = None
     while True:
         gc.collect()
         logging.getLogger("RAM").info(gc.mem_free(), local_only=True)
         await config.getMQTT().publish(_mqtt.getDeviceTopic("ram_free"),
                                        gc.mem_free())
         if s is not None:
             try:
                 await config.getMQTT().publish(
                     _mqtt.getDeviceTopic("rssi"), s.status("rssi"))
             except Exception as e:
                 await logging.getLogger("STATS").asyncLog(
                     "error", "Error checking rssi: {!s}".format(e))
                 s = None
         await asyncio.sleep(self._interval)
예제 #7
0
 def __init__(self,
              sensor_type,
              mqtt_topic=None,
              command_topic=None,
              value_template=None,
              stale_time=900,
              **kwargs):
     # This makes it possible to use multiple instances of BaseRemote
     global _unit_index
     _unit_index += 1
     self._value_type = None  # in case of dictionary it will be determined by json
     v = value_template
     if "value_json." in value_template:
         self._dict_tpl = v[v.find("value_json.") +
                            len("value_json."):v.rfind("}}")].strip()
         if "|" in self._dict_tpl:
             self._dict_tpl = self._dict_tpl[:self._dict_tpl.find("|")]
     else:
         self._dict_tpl = None
     if "|" in value_template:
         v = v[v.find("|") + 1:v.rfind("}}")].strip()
         tp = {"float": float, "int": int, "bool": bool, "string": str}
         if v in tp:
             self._value_type = tp[v]
         else:
             raise TypeError(
                 "value_template type {!s} not supported".format(v))
     self._log = logging.getLogger("{}_{}{}".format(COMPONENT_NAME,
                                                    sensor_type,
                                                    _unit_index))
     super().__init__(COMPONENT_NAME,
                      __version__,
                      _unit_index,
                      discover=False,
                      interval_publish=-1,
                      interval_reading=-1,
                      logger=self._log,
                      expose_intervals=False,
                      **kwargs)
     self._addSensorType(sensor_type, 2, 0, value_template, "")
     # no unit_of_measurement as only used for mqtt discovery
     self._stale_time = stale_time
     self._topic = mqtt_topic
     if mqtt_topic is None:
         self._command_topic = command_topic or _mqtt.getDeviceTopic(
             "{!s}{!s}/topic/set".format(COMPONENT_NAME, self._count))
         _mqtt.subscribeSync(self._command_topic,
                             self._changeTopic,
                             self,
                             check_retained_state=True)
     else:
         self._command_topic = None
         _mqtt.subscribeSync(self._topic, self.on_message, self)
예제 #8
0
 def __init__(self, id=0, timeout=120, use_rtc_memory=True):
     self._timeout = timeout / 10
     self._counter = 0
     self._timer = machine.Timer(id)
     self._use_rtc_memory = use_rtc_memory
     self._has_filesystem = False
     self.init()
     asyncio.get_event_loop().create_task(self._resetCounter())
     if sys_vars.hasFilesystem():
         self._has_filesystem = True
         try:
             with open("watchdog.txt", "r") as f:
                 if f.read() == "True":
                     logging.getLogger("WDT").warn("Reset reason: Watchdog")
         except Exception as e:
             print(e)  # file probably just does not exist
         try:
             with open("watchdog.txt", "w") as f:
                 f.write("False")
         except Exception as e:
             logging.getLogger("WDT").error("Error saving to file: {!s}".format(e))
     elif use_rtc_memory and platform == "esp8266":
         rtc = machine.RTC()
         if rtc.memory() == b"WDT reset":
             logging.getLogger("WDT").critical("Reset reason: Watchdog")
         rtc.memory(b"")
예제 #9
0
 def __init__(self,
              component_name,
              version,
              unit_index: int,
              discover,
              interval_publish=None,
              interval_reading=None,
              mqtt_topic=None,
              log=None,
              expose_intervals=False,
              intervals_topic=None):
     """
     :param component_name: Name of the component, used for default topics and logging
     :param version: version of the component module, used for logging purposes
     :param unit_index: counter of the registerd unit of this sensor_type (used for default topics)
     :param discover: if the sensor component should send its homeassistnat discovery message
     :param interval_publish: seconds, set to interval_reading to publish every reading. -1 for not publishing.
     :param interval_reading: seconds, set to -1 for not reading/publishing periodically. >0 possible for reading, 0 not allowed for reading..
     Be careful with relying on reading sensors quickly because every publish
     will take at most 5 seconds per sensor_type until it times out.
     If you rely on quick and reliable sensor reading times choose interval_publish=-1 and start
     your own coroutine for publishing values.
     :param mqtt_topic: optional custom mqtt topic
     :param expose_intervals: Expose intervals to mqtt so they can be changed remotely
     :param intervals_topic: if expose_intervals then use this topic to change intervals.
     Defaults to <home>/<device-id>/<COMPONENT_NAME><_unit_index>/interval/set
     """
     super().__init__(component_name, version, unit_index, discover)
     self._values = {}
     self._log = log or logging.getLogger(component_name)
     # _intpb can be >0, -1 for not publishing or 0/None for INTERVAL_SENSOR_PUBLISH
     self._intpb: float = interval_publish or config.INTERVAL_SENSOR_PUBLISH
     self._intrd: float = config.INTERVAL_SENSOR_READ if interval_reading is None else interval_reading
     if self._intpb < self._intrd:
         raise ValueError(
             "interval_publish can't be lower than interval_reading")
     self._topic = mqtt_topic  # can be None
     self._event = None
     self._reading: bool = False  # cheaper than Lock
     if expose_intervals:
         _mqtt.subscribeSync(intervals_topic or _mqtt.getDeviceTopic(
             "{!s}/interval/set".format(self._default_name())),
                             self.setInterval,
                             self,
                             qos=1,
                             check_retained_state=True)
     self._loop_coro = None
     if self._intrd > 0:  # if interval_reading==-1 no loop will be started
         self._loop_coro = self._loop()
         asyncio.get_event_loop().create_task(self._loop_coro)
         # self._loop_coro will get canceled when component is removed.
     gc.collect()
예제 #10
0
    def __init__(self, uart_number, uart_tx, uart_rx, set_pin=None, reset_pin=None,
                 interval_passive_mode=None, active_mode=True, eco_mode=True,
                 interval=None, mqtt_topic=None):
        interval = interval or config.INTERVAL_SEND_SENSOR
        interval_passive_mode = interval_passive_mode or interval
        self.component_name = component_name
        self.topic = mqtt_topic or mqtt.getDeviceTopic(self.component_name)
        self.log = logging.getLogger(self.component_name)
        uart = machine.UART(uart_number, tx=uart_tx, rx=uart_rx, baudrate=9600)

        ##############################
        # create sensor object
        super().__init__(uart, config.Lock(), set_pin, reset_pin, interval_passive_mode,
                         active_mode=active_mode, eco_mode=eco_mode)
        gc.collect()
        if (interval == interval_passive_mode and active_mode is False) or interval == 0:
            self.registerCallback(self.airQuality)
        else:
            # possible to have different timings in passive_read and publish interval
            # useful if other components use readings of sensor too
            asyncio.get_event_loop().create_task(self._loop(self.airQuality(), interval))
예제 #11
0
 def __init__(self, component_name, component, temp_function, humid_function, mqtt_topic,
              interval, precision_temp, precision_humid, temp_offset, humid_offset):
     self.sensor = component
     gen = None
     if temp_function is not None:
         self._temp = _async_wrapper(getattr(component, temp_function))
         self._prec_temp = int(precision_temp)
         self._offs_temp = float(temp_offset)
         self.temperature = self.__temperature
         gen = self.temperature
     if humid_function is not None:
         self._humid = _async_wrapper(getattr(component, humid_function))
         self._prec_humid = int(precision_humid)
         self._offs_humid = float(humid_offset)
         self.humidity = self.__humidity
         gen = self.humidity
     if temp_function is not None and humid_function is not None:
         self.tempHumid = self.__tempHumid
         gen = self.tempHumid
     self.topic = mqtt_topic or mqtt.getDeviceTopic(component_name)
     self.log = logging.getLogger(component_name)
     self.component_name = component_name
     asyncio.get_event_loop().create_task(self._loop(gen, interval))
예제 #12
0
# Author: Kevin Köck
# Copyright Kevin Köck 2019-2020 Released under the MIT license
# Created on 2019-09-09

__updated__ = "2019-11-11"
__version__ = "0.1"

from pysmartnode.utils.component.switch import ComponentSwitch as _Switch
from pysmartnode import config
from pysmartnode import logging

mqtt = config.getMQTT()
log = logging.getLogger("Switch")


class Switch(_Switch):
    def __init__(self):
        super().__init__("testswitch",
                         __version__,
                         0,
                         mqtt_topic=mqtt.getDeviceTopic("switch",
                                                        is_request=True),
                         friendly_name="Testswitch",
                         initial_state=None,
                         discover=False)
        log.info("State: {!s}".format(self._state), local_only=True)

    async def _on(self):
        log.info("State: {!s}".format(True if self._state is False else False),
                 local_only=True)
        return True
예제 #13
0
from pysmartnode import logging
from pysmartnode.utils.abutton import Pushbutton
from pysmartnode.utils.component import Component
from pysmartnode.components.machine.pin import Pin
from pysmartnode.utils.event import Event
import machine
import uasyncio as asyncio

loaded_components = {
    "machine": machine
}  # so that button actions can be from these classes, e.g. machine.reset()

COMPONENT_NAME = "Button"

_log = logging.getLogger("button")
_unit_index = -1


class Button(Pushbutton, Component):
    def __init__(self,
                 pin,
                 pull=None,
                 pressed_component=None,
                 pressed_method="on",
                 released_component=None,
                 released_method="off",
                 double_pressed_component=None,
                 double_pressed_method="on",
                 long_pressed_component=None,
                 long_pressed_method="on",
예제 #14
0
'''
Created on 14.04.2018

@author: Kevin
'''

__updated__ = "2018-05-22"
__version__ = "1.1"

import gc
from pysmartnode import config
from pysmartnode import logging

log = logging.getLogger("machine.debug")
import uasyncio as asyncio
import time

gc.collect()


def overwatch(coro_name, threshold, asyncr=False):
    def func_wrapper(coro):
        if asyncr is True:
            raise TypeError("overwatch does not support coroutines")
            # as it makes not sense. a freeze would trigger every coroutine
        else:

            def wrapper(*args, **kwargs):
                startt = time.ticks_ms()
                res = coro(*args, **kwargs)
                if str(type(res)) == "<class 'generator'>":
예제 #15
0
파일: gpio.py 프로젝트: knyete/pysmartnode
    }
}
"""

__updated__ = "2018-03-25"
__version__ = "0.1"

import gc

from machine import Pin
from pysmartnode import config
from pysmartnode import logging

mqtt = config.getMQTT()

log = logging.getLogger("gpio")
gc.collect()


class GPIO:
    def __init__(self, pin, mqtt_topic=None):
        if type(pin) == str:
            pin = config.pins[pin]
        mqtt_topic = mqtt_topic or mqtt.getDeviceTopic("GPIO/" + str(pin), is_request=True)
        self.pin = pin
        Pin(self.pin, Pin.OUT, value=0)
        mqtt.scheduleSubscribe(mqtt_topic, self.setValue)

    # publishing is done by mqtt class as long as topic has "/set" at the end
    async def setValue(self, topic, msg, retain):
        if msg != "":
예제 #16
0
        "package":          ".machine.easyGPIO",
        "component":        "GPIO",
        "constructor_args": {
            "discover_pins": ["D0", "D1", "D2"]
        }
    }
}

# Alternatively you can register components manually, which saves a lot of RAM as the dict doesn't get loaded into RAM:

from pysmartnode import config
from pysmartnode import logging
import uasyncio as asyncio

loop = asyncio.get_event_loop()
_log = logging.getLogger("components.py")


async def main():
    await asyncio.sleep(2)  # waiting period so RAM can settle and network connect
    try:
        import somemodule
    except Exception as e:
        _log.error("Can't import module, error {!s}".format(e))

    someinstance = somemodule.Someclass(pin=35)
    loop.create_task(someinstance.getTemperatureContinuosly())  # if someinstance doesn't start the method itself

    config.addNamedComponent("mycomponent", someinstance)
    # This is optional, it just puts your component in the dictionary where all registered components are
예제 #17
0
__printRAM(_mem, "Imported .sys_vars")

import uasyncio as asyncio

LEN_ASYNC_QUEUE = 16 if platform == "esp8266" else 32
loop = asyncio.get_event_loop(runq_len=LEN_ASYNC_QUEUE, waitq_len=LEN_ASYNC_QUEUE)

gc.collect()
__printRAM(_mem, "Imported uasyncio")

gc.collect()
__printRAM(_mem, "Imported os")
from pysmartnode import logging

gc.collect()
_log = logging.getLogger("config")

gc.collect()
__printRAM(_mem, "Imported logging")

if MQTT_TYPE == 1:
    from pysmartnode.networking.mqtt_iot import MQTTHandler, Lock
else:  # 0 and wrong configuration options
    from pysmartnode.networking.mqtt_direct import MQTTHandler, Lock  # Lock possibly needed by other modules

gc.collect()
__printRAM(_mem, "Imported MQTTHandler")

COMPONENTS = {}  # dictionary of all configured components
COMPONENTS["mqtt"] = MQTTHandler(MQTT_RECEIVE_CONFIG)
_components = None  # pointer list of all registered components, used for mqtt
예제 #18
0
gc.collect()
print(gc.mem_free())

from pysmartnode import config
from pysmartnode import logging
import uasyncio as asyncio
import sys
import os

if sys.platform != "linux":
    import machine

    rtc = machine.RTC()

_log = logging.getLogger("main")

if config.WEBREPL_ACTIVE:
    try:
        import webrepl_cfg
    except ImportError:
        try:
            with open("webrepl_cfg.py", "w") as f:
                f.write("PASS = %r\n" % config.WEBREPL_PASSWORD)
        except Exception as e:
            _log.critical("Can't start webrepl: {!s}".format(e),
                          local_only=True)
    try:
        import webrepl

        webrepl.start()
예제 #19
0
파일: ram.py 프로젝트: knyete/pysmartnode
"""

__updated__ = "2018-04-21"
__version__ = "0.3"

import gc

from pysmartnode import config

mqtt = config.getMQTT()
import uasyncio as asyncio

gc.collect()
from pysmartnode import logging

log = logging.getLogger("RAM")


async def __gc(interval):
    while True:
        gc.collect()
        log.info(gc.mem_free(), local_only=True)
        await asyncio.sleep(interval)


async def __ram(topic, interval, interval_gc=10):
    asyncio.get_event_loop().create_task(__gc(interval_gc))
    await asyncio.sleep(12)
    while True:
        gc.collect()
        await mqtt.publish(topic, gc.mem_free())
예제 #20
0
gc.collect()
print(gc.mem_free())

from pysmartnode import config
from pysmartnode import logging
import uasyncio as asyncio
import sys
import os

if sys.platform != "linux":
    import machine

    rtc = machine.RTC()

_log = logging.getLogger("pysmartnode")
gc.collect()

loop = asyncio.get_event_loop()


async def _resetReason():
    # may be empty if eps8266 resets during reboot because of various reasons
    # (e.g. some of mine often keep rebooting 5 times until the start correctly and rtc.memory is empty then)
    if sys.platform == "esp8266" and rtc.memory() != b"":
        await _log.asyncLog("critical",
                            "Reset reason: {!s}".format(rtc.memory().decode()))
        rtc.memory(b"")
    elif sys.platform == "esp32_LoBo" and rtc.read_string() != "":
        await _log.asyncLog("critical",
                            "Reset reason: {!s}".format(rtc.memory()))
예제 #21
0
    package: .devices.arduinoGPIO.arduinoControl
    component: ADC
    constructor_args: {
        arduinoControl: "arduinoControlName"   # ArduinoControl instance
        rom: "ArduinoROM"        # Arduino device ROM 
        pin: 0                   # Pin number
        # vcc: 5                 # Arduino VCC voltage 
    }
}
"""

from pysmartnode.libraries.arduinoGPIO.arduinoGPIO.arduinoControl import ArduinoControl as _ArduinoControl
from pysmartnode.components.machine.pin import Pin as PyPin
from pysmartnode import logging

log = logging.getLogger("Arduino")


class ArduinoControl(_ArduinoControl):
    def __init__(self, pin: any, expected_devices=None):
        """
        Class to remotely control an Arduino
        :param pin: Pin number/name/object of the onewire connection
        :param expected_devices: used to warn if devices go missing (filters non-arduino devices)
        """
        pin = PyPin(pin)
        if type(expected_devices) == list:
            for i in range(len(expected_devices)):
                if type(expected_devices[i]) == str:
                    expected_devices[i] = self.str2rom(expected_devices[i])
        super().__init__(pin, expected_devices)
예제 #22
0
    }
}
"""

__updated__ = "2018-05-29"
__version__ = "0.1"

import gc
import uasyncio as asyncio
import machine
from pysmartnode.utils import sys_vars

gc.collect()
from pysmartnode import logging

log = logging.getLogger("WDT")


class WDT:
    def __init__(self, id=0, timeout=120):
        self._timeout = timeout / 10
        self._counter = 0
        self._timer = machine.Timer(id)
        self.init()
        asyncio.get_event_loop().create_task(self._resetCounter())
        if sys_vars.hasFilesystem():
            try:
                with open("watchdog.txt", "r") as f:
                    if f.read() == "True":
                        log.warn("Reset reason: Watchdog")
            except Exception as e:
예제 #23
0
__updated__ = "2018-05-20"
__version__ = "0.3"

import gc
from pysmartnode import logging

try:
    import ssd1306
except:
    from pysmartnode.libraries import ssd1306
from pysmartnode import config

_mqtt = config.getMQTT()

_log = logging.getLogger("SSD1306")
gc.collect()


# load class package dynamically by config and execute functions from mqtt
# message by hasattr(...)
class SSD1306_easy(ssd1306.SSD1306_I2C):
    def __init__(self, i2c, width=128, height=32, mqtt_topic=None):
        super().__init__(width, height, i2c)
        mqtt_topic = mqtt_topic or _mqtt.getDeviceTopic("ssd1306",
                                                        is_request=True)
        _mqtt.scheduleSubscribe(mqtt_topic, self.write)
        self.fill(0)
        self.show()

    async def write(self, topic, msg, retain):
예제 #24
0
- heater reacts to temperature change every REACTION_TIME seconds and waits xxx_CYCLES before starting/shutting down heater
"""

__updated__ = "2019-06-04"
__version__ = "1.1"

from pysmartnode import config
from pysmartnode import logging
import uasyncio as asyncio
from pysmartnode.utils.event import Event
import gc
import time
from pysmartnode.utils.component import Component, DISCOVERY_SWITCH

_mqtt = config.getMQTT()
log = logging.getLogger("Heater")  # not _log as submodules import it
gc.collect()

_heater = None
_component_name = "heater"
_component_type = "sensor"


class Heater(Component):
    def __init__(self,
                 TEMP_SENSOR,
                 REACTION_TIME,
                 HYSTERESIS_LOW,
                 HYSTERESIS_HIGH,
                 SHUTDOWN_CYCLES,
                 START_CYCLES,
예제 #25
0
        #mqtt_topic: null   #optional, topic needs to have /GPIO/# at the end; to change a value publish to /GPIO/<pin>/set
    }
}
makes esp8266 listen to requested gpio changes or return pin.value() if message is published without payload
"""

__updated__ = "2018-03-22"
__version__ = "0.3"

import gc

from machine import Pin
from pysmartnode import config
from pysmartnode import logging

log = logging.getLogger("easyGPIO")
mqtt = config.getMQTT()

gc.collect()


async def __gpio(topic, msg, retain):
    if topic.rfind("/set") == -1:
        if retain:
            pin = topic[topic.rfind("GPIO/") + 5:]
        else:
            # topic without /set ignored if not retained
            return False
    else:
        pin = topic[topic.rfind("GPIO/") + 5:topic.rfind("/set")]
    print("__gpio pin", pin, msg, retain)
예제 #26
0
import ujson
import time
import uasyncio as asyncio
import os
from pysmartnode import config
from sys import platform
from pysmartnode import logging
from pysmartnode.utils import sys_vars

if config.MQTT_TYPE:
    from micropython_mqtt_as.mqtt_as_timeout_concurrent import MQTTClient
else:
    from dev.mqtt_iot import MQTTClient  # Currently not working/under development
gc.collect()

_log = logging.getLogger("MQTT")
gc.collect()

type_gen = type((lambda: (yield))())  # Generator type


class MQTTHandler(MQTTClient):
    def __init__(self):
        self.payload_on = ("ON", True, "True")
        self.payload_off = ("OFF", False, "False")
        self.client_id = sys_vars.getDeviceID()
        self.mqtt_home = config.MQTT_HOME
        self._subs = []
        self._sub_task = None
        self._sub_retained = False
        super().__init__(
예제 #27
0
파일: irq.py 프로젝트: rguillon/pysmartnode
    def __await__(self):
        while not self._flag:
            yield from asyncio.sleep_ms(self.delay_ms)

    __iter__ = __await__

    def is_set(self):
        return self._flag

    def set(self):
        self._flag = True


COMPONENT_NAME = "Bell"

_log = logging.getLogger(COMPONENT_NAME)
_mqtt = config.getMQTT()
gc.collect()

_unit_index = -1


class Bell(ComponentSensor):
    def __init__(self,
                 pin,
                 debounce_time,
                 on_time=None,
                 direction=None,
                 pull_up=True,
                 friendly_name=None,
                 friendly_name_last=None,
예제 #28
0
 def __init__(self, component: ComponentSwitch, modes_enabled: list,
              mqtt_topic_mode=None, friendly_name_mode=None, discover=True):
     global _unit_index
     _unit_index += 1
     super().__init__(COMPONENT_NAME, __version__, _unit_index, discover)
     if type(component) == str:
         self._component = config.getComponent(component)
         if self._component is None:
             raise TypeError("Component {!s} not found".format(component))
     else:
         self._component = component
     if not isinstance(self._component, ComponentSwitch):
         raise TypeError("Component needs to be of instance ComponentSwitch")
     # make this class control the component
     self._component.on_message = self.on_message
     self._component_on = self._component.on
     self._component_off = self._component.off
     self._component.on = self.on
     self._component.off = self.off
     self._component.toggle = self.toggle
     if type(modes_enabled) != list:
         raise TypeError("modes enabled needs to be a list")
     count = self._component._count if hasattr(self._component, "_count") else ""
     _name = self._component._name if hasattr(self._component, "_name") else "{!s}{!s}".format(
         COMPONENT_NAME, count)
     mqtt_topic_mode = mqtt_topic_mode or _mqtt.getDeviceTopic("{!s}/mode".format(_name),
                                                               is_request=True)
     self._topic_mode = mqtt_topic_mode
     self._frn_mode = friendly_name_mode or "{!s} Mode".format(_name)
     self._mode = Mode  # Mode is default switch behaviour if no mode is enabled
     name = config.getComponentName(self._component)
     if name is None:
         self._log = logging.getLogger("{!s}".format(_name))
     else:
         self._log = logging.getLogger("{!s}_{!s}".format(name, "Switch"))
     del name
     self._mode_lock = Lock()
     gc.collect()
     r = []
     self._modes_enabled = []
     for mode in modes_enabled:
         try:
             mod = __import__(
                 "pysmartnode.components.switches.switch_extension.{}".format(mode), globals(),
                 locals(), [], 0)
         except ImportError as e:
             _log.error("Mode {!s} not available: {!s}".format(mode, e))
             r.append(mode)
             continue
         if hasattr(mod, mode):
             modeobj = getattr(mod, mode)
         else:
             _log.error("Mode {!s} has no class {!r}".format(mode, mode))
             r.append(mode)
             continue
         try:
             modeobj = modeobj(self, self._component, self._component_on, self._component_off)
         except Exception as e:
             _log.error("Error creating mode {!s} object: {!s}".format(mode, e))
             r.append(mode)
             continue
         self._modes_enabled.append(modeobj)
     if len(r) > 0:
         _log.error("Not supported modes found which will be ignored: {!s}".format(r))
     del r
예제 #29
0
__version__ = "0.3"

import gc
from pysmartnode import config
from pysmartnode import logging
from pysmartnode.utils.component import Component, DISCOVERY_SWITCH
from .popen_base import Popen

####################
_component_name = "UnixSwitch"
# define the type of the component according to the homeassistant specifications
_component_type = "switch"
####################

_mqtt = config.getMQTT()
_log = logging.getLogger(_component_name)

gc.collect()

_count = 0


class Switch(Component):
    def __init__(self, command_on, command_off, expected_return_on=None, expected_execution_time_on=0,
                 expected_return_off=None, expected_execution_time_off=0,
                 iterations=1, iter_delay=10, mqtt_topic=None, friendly_name=None):
        super().__init__()

        # This makes it possible to use multiple instances of Switch
        global _count
        self._count = _count
예제 #30
0
        #interval: 600              #optional, interval of measurement
    }
}
"""

__updated__ = "2018-05-20"
__version__ = "0.7"

from machine import Pin, ADC
from pysmartnode import config
from sys import platform
import uasyncio as asyncio
import gc
from pysmartnode import logging

log = logging.getLogger("soil")
mqtt = config.getMQTT()
Lock = config.Lock


class SoilMoisture:
    def __init__(self,
                 adc_pin,
                 water_voltage,
                 air_voltage,
                 sensor_types,
                 power_pin=None,
                 power_warmup=None,
                 publish_converted_value=False,
                 mqtt_topic=None,
                 interval=None):