diff --git a/.gitignore b/.gitignore index 663c1ed..dc80c9d 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.pyc *.sublime-* __pycache__ +build/* dist/* homie.egg-info/* MANIFEST diff --git a/homie-python.json.example b/examples/homie-python.json.example similarity index 100% rename from homie-python.json.example rename to examples/homie-python.json.example diff --git a/relay_switch.py b/examples/relay_switch.py similarity index 52% rename from relay_switch.py rename to examples/relay_switch.py index 2be6514..14dc307 100755 --- a/relay_switch.py +++ b/examples/relay_switch.py @@ -6,24 +6,24 @@ logger = logging.getLogger(__name__) config = homie.loadConfigFile("homie-python.json") -Homie = homie.Homie(config) -switchNode = Homie.Node("switch", "switch") +device = homie.Device(config) +switchNode = device.addNode("switch", "switch", "switch") +switchProperty = switchNode.addProperty("on") - -def switchOnHandler(mqttc, obj, msg): - payload = msg.payload.decode("UTF-8").lower() - if payload == 'true': +def switchOnHandler(property, value): + if value == 'true': logger.info("Switch: ON") - switchNode.setProperty("on").send("true") + property.update("true") else: logger.info("Switch: OFF") - switchNode.setProperty("on").send("false") + property.update("false") def main(): - Homie.setFirmware("relay-switch", "1.0.0") - switchNode.advertise("on").settable(switchOnHandler) - Homie.setup() + device.setFirmware("relay-switch", "1.0.0") + switchProperty.settable(switchOnHandler) + + device.setup() while True: time.sleep(1) diff --git a/relay_switch_with_config.py b/examples/relay_switch_with_config.py similarity index 60% rename from relay_switch_with_config.py rename to examples/relay_switch_with_config.py index 538dfcf..986536b 100755 --- a/relay_switch_with_config.py +++ b/examples/relay_switch_with_config.py @@ -17,24 +17,23 @@ "TOPIC": "homie" } -Homie = homie.Homie(config) -switchNode = Homie.Node("switch", "switch") +device = homie.Device(config) +switchNode = device.addNode("switch", "switch", "switch") +switchProperty = switchNode.addProperty("on") - -def switchOnHandler(mqttc, obj, msg): - payload = msg.payload.decode("UTF-8").lower() - if payload == 'true': +def switchOnHandler(property, value): + if value == 'true': logger.info("Switch: ON") - switchNode.setProperty("on").send("true") + property.update("true") else: logger.info("Switch: OFF") - switchNode.setProperty("on").send("false") + property.update("false") def main(): - Homie.setFirmware("relay-switch", "1.0.0") - switchNode.advertise("on").settable(switchOnHandler) - Homie.setup() + device.setFirmware("relay-switch", "1.0.0") + switchProperty.settable(switchOnHandler) + device.setup() while True: time.sleep(1) diff --git a/examples/remote_with_config.py b/examples/remote_with_config.py new file mode 100644 index 0000000..6260db4 --- /dev/null +++ b/examples/remote_with_config.py @@ -0,0 +1,50 @@ +#!/usr/bin/env python +import time +import random +import homie +import logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +config = { + "HOST": "iot.eclipse.org", + "PORT": 1883, + "KEEPALIVE": 10, + "USERNAME": "", + "PASSWORD": "", + "CA_CERTS": "", + "DEVICE_ID": "remote-control", + "DEVICE_NAME": "xxxxxxxx", + "TOPIC": "homie" +} + +device = homie.Device(config) +remoteNode = device.addNode("remote", "Remote", "Buttons") +playButtonProperty = remoteNode.addProperty("play", "Play Button", datatype="enum", format="PRESSED,RELEASED", retained=False) +nextButtonProperty = remoteNode.addProperty("next", "Next Button", datatype="enum", format="PRESSED,RELEASED", retained=False) +prevButtonProperty = remoteNode.addProperty("prev", "Prev Button", datatype="enum", format="PRESSED,RELEASED", retained=False) + + +def main(): + device.setFirmware("remote-control", "1.0.0") + + device.setup() + + buttonPressFrecuency = 30 + lastButtonPressTime = 0 + + while True: + # We simulate that the button is pressed (and released) every 30 seconds + if (time.time() - lastButtonPressTime) > buttonPressFrecuency: + playButtonProperty.update("PRESSED") + time.sleep(0.3) + playButtonProperty.update("RELEASED") + logger.info("Play button pressed and released") + lastButtonPressTime = time.time() + time.sleep(1) + +if __name__ == '__main__': + try: + main() + except (KeyboardInterrupt, SystemExit): + logger.info("Quitting.") \ No newline at end of file diff --git a/temperatureDS18B20_raspi.py b/examples/temperatureDS18B20_raspi.py similarity index 79% rename from temperatureDS18B20_raspi.py rename to examples/temperatureDS18B20_raspi.py index 23433e6..a815942 100644 --- a/temperatureDS18B20_raspi.py +++ b/examples/temperatureDS18B20_raspi.py @@ -19,8 +19,9 @@ TEMPERATURE_INTERVAL = 60 config = homie.loadConfigFile("homie-python.json") -Homie = homie.Homie(config) -temperatureNode = Homie.Node("temperature", "temperature") +device = homie.Device(config) +temperatureNode = device.addNode("temperature", "temperature", "temperature") +temperatureProperty = temperatureNode.addProperty("temperature", "Temperature value", "ºC", "float") def read_temp_raw(): f = open(device_file, 'r') @@ -41,15 +42,14 @@ def read_temp(): return temp_c def main(): - Homie.setFirmware("raspi-temperatureDS18B20", "1.0.0") - temperatureNode.advertise("degrees") + device.setFirmware("raspi-temperatureDS18B20", "1.0.0") - Homie.setup() + device.setup() while True: temperature = read_temp() logger.info("Temperature: {:0.2f} °C".format(temperature)) - temperatureNode.setProperty("degrees").send(temperature) + temperatureProperty.update(temperature) time.sleep(TEMPERATURE_INTERVAL) if __name__ == '__main__': diff --git a/temperature_raspi.py b/examples/temperature_raspi.py similarity index 68% rename from temperature_raspi.py rename to examples/temperature_raspi.py index c1db48e..0921ecc 100755 --- a/temperature_raspi.py +++ b/examples/temperature_raspi.py @@ -9,8 +9,9 @@ TEMPERATURE_INTERVAL = 60 config = homie.loadConfigFile("homie-python.json") -Homie = homie.Homie(config) -temperatureNode = Homie.Node("temperature", "temperature") +device = homie.Device(config) +temperatureNode = device.addNode("temperature", "temperature", "temperature") +temperatureProperty = temperatureNode.addProperty("temperature", "Temperature value", "ºC", "float") def getCpuTemperature(): @@ -21,15 +22,14 @@ def getCpuTemperature(): def main(): - Homie.setFirmware("raspi-temperature", "1.0.0") - temperatureNode.advertise("degrees") + device.setFirmware("raspi-temperature", "1.0.0") - Homie.setup() + device.setup() while True: temperature = getCpuTemperature() logger.info("Temperature: {:0.2f} °C".format(temperature)) - temperatureNode.setProperty("degrees").send(temperature) + temperatureProperty.update(temperature) time.sleep(TEMPERATURE_INTERVAL) if __name__ == '__main__': diff --git a/temperature_sensor.py b/examples/temperature_sensor.py similarity index 51% rename from temperature_sensor.py rename to examples/temperature_sensor.py index e5ccc27..e3d9840 100755 --- a/temperature_sensor.py +++ b/examples/temperature_sensor.py @@ -6,30 +6,30 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -TEMPERATURE_INTERVAL = 3 +TEMPERATURE_INTERVAL = 60 config = homie.loadConfigFile("homie-python.json") -Homie = homie.Homie(config) -temperatureNode = Homie.Node("temperature", "temperature") -humidityNode = Homie.Node("humidity", "humidity") +device = homie.Device(config) +temperatureNode = device.addNode("temperature", "temperature", "temperature") +humidityNode = device.addNode("humidity", "humidity", "humidity") +temperatureProperty = temperatureNode.addProperty("temperature", "Temperature value", "ºC", "float") +humidityProperty = humidityNode.addProperty("humidity", "Humidity value", "%", "float", "0.0:100.0") def main(): - Homie.setFirmware("awesome-temperature", "1.0.0") - temperatureNode.advertise("degrees") - humidityNode.advertise("humidity") + device.setFirmware("awesome-temperature", "1.0.0") - Homie.setup() + device.setup() while True: temperature = 22.0 humidity = 60.0 logger.info("Temperature: {:0.2f} °C".format(temperature)) - temperatureNode.setProperty("degrees").send(temperature) + temperatureProperty.update(temperature) logger.info("Humidity: {:0.2f} %".format(humidity)) - humidityNode.setProperty("humidity").send(humidity) + humidityProperty.update(humidity) time.sleep(TEMPERATURE_INTERVAL) diff --git a/examples/thermostat_with_config.py b/examples/thermostat_with_config.py new file mode 100644 index 0000000..e82b8be --- /dev/null +++ b/examples/thermostat_with_config.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python +import time +import random +import homie +import logging +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +config = { + "HOST": "iot.eclipse.org", + "PORT": 1883, + "KEEPALIVE": 10, + "USERNAME": "", + "PASSWORD": "", + "CA_CERTS": "", + "DEVICE_ID": "xxxxxxxx", + "DEVICE_NAME": "xxxxxxxx", + "TOPIC": "homie" +} + +device = homie.Device(config) +thermostatNode = device.addNode("thermostat", "Thermostat", "thermostat") +temperatureProperty = thermostatNode.addProperty("temperature", "Indoor Temperature", "ºC", "float", "0:50") +setpointProperty = thermostatNode.addProperty("setpoint", "Setpoint", "ºC", "float", "10:30") +modeProperty = thermostatNode.addProperty("mode", "Thermostat Mode", datatype="enum", format="NORMAL,COLD,HEAT") + +def modeHandler(property, value): + logger.info("Changing thermostat mode to {}".format(value)) + property.update(value) + +def setpointHandler(property, value): + logger.info("Changing thermostat setpoint to {}ºC".format(value)) + property.update(value) + + +def main(): + device.setFirmware("thermostat", "1.0.0") + modeProperty.settable(modeHandler) + setpointProperty.settable(setpointHandler) + + device.setup() + + reportFrecuency = 60 + lastTemperatureTime = 0 + + setpointProperty.update(21.5) + modeProperty.update("NORMAL") + while True: + if (time.time() - lastTemperatureTime) > reportFrecuency: + temperature = random.uniform(20,25) + temperatureProperty.update("{0:.2f}".format(temperature)) + logger.info("New temperature value: {0:.2f}ºC".format(temperature)) + lastTemperatureTime = time.time() + time.sleep(1) + +if __name__ == '__main__': + try: + main() + except (KeyboardInterrupt, SystemExit): + logger.info("Quitting.") diff --git a/homie/helpers.py b/homie/helpers.py index 1791da1..af6c1e4 100644 --- a/homie/helpers.py +++ b/homie/helpers.py @@ -13,9 +13,53 @@ def generateDeviceId(): return "{:02x}".format(get_mac()) -def isIdFormat(idString): +def isValidId(idString): """Validate device Id.""" logger.debug("isIdFormat") if isinstance(idString, str): r = re.compile('(^(?!\-)[a-z0-9\-]+(?