jalmeroth / homie-python Goto Github PK
View Code? Open in Web Editor NEWA Python-implementation of the homie v2 convention.
Home Page: https://github.com/marvinroger/homie
A Python-implementation of the homie v2 convention.
Home Page: https://github.com/marvinroger/homie
I try to run an example temperature_sensor.py in a raspberry py and in a Desktop PC with Ubuntu 16.04 with the same result.
Homie.setup()
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 211, in setup
self._initialize()
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 147, in _initialize
self.mqtt.connect(self.host, self.port, self.keepalive)
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 760, in connect
return self.reconnect()
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 932, in reconnect
return self._send_connect(self._keepalive, self._clean_session)
File "/usr/local/lib/python2.7/dist-packages/paho/mqtt/client.py", line 2114, in _send_connect
keepalive))
struct.error: cannot convert argument to integer
I'm working with your dev branch for the homie-control devices. I've just migrated from your v1 to v2 branch and noticed that you currently have to call
Homie.subscribe(switchNode, "on", switchOnHandler) switchNode.advertise("on").settable(switchOnHandler)
I would expect the node once advertised and settable to be auto subscribed as per the esp platform and thus not require the Homie.subscribe call. Does this sound reasonable, Is it a planned feature? I can have a go at adding this if you've not started on something, i've spotted
Homie.subscribeProperty
and homie is passed through to the node, so no reason we couldnt call subscribeProperty when the property is registered on the node.
This is cute, but do you really want to do this with a popen()
? It looks horridly ineffective and it's much more expensive in terms of processing than a simple open()
. :-)
Hi @jalmeroth!
Many thanks for developing this awesome library, it works really great and simplifies the creation of homie nodes using a computer like a rasberry pi!
However, I have a little problem when the library calls the Homie.setup() function and the device doesn't have IP connectivity (the WiFi is not reliable at that moment or the script has started too early and the device is not connected to the router). This is error:
[Errno -2] Name or service not known
Is it possible to change the setup behavior to wait until the connection is done?
Thanks for your help and keep up with the great work!
There seems to be no way to add new subscriptions (using Homie.subscribe()
) once the Homie object has been set up (with Homie.setup()
). When I try, I get BaseException: ✖ subscribe(): has to be called before setup()
. Is this a Homie convention rule, a design decision, or just a limitation of this library?
I wanted to use homie-python to model a Snapcast server's clients (which have settable volume, zone, etc) as Homie device nodes. However, snapcast clients can connect and disconnect from the server at will, and new clients can show up at any time. This doesn't seem to work inside the limitations of not being able to subscribe() to new nodes later in the lifecycle of my program.
Implement username/password authentication
Can I specify the config file name? so rather than having a generic machine homie-config.json one, I'll need one per script (this one raspberry pi has a dht sensor connected, and also pulls values from two bluetooth sensors). So it would be two scripts I'm needing to run. So preferably I'd have homie-config-dht.json, and homie-config-bluetooth.json.
Also, awesome work, took about 5 mins to convert one of my scripts to use the homie implementation.
I'm seeing 127.0.0.1
for $localip
even when connecting to a remote broker. I've just looked around a bit, and I think this could be more reliable:
hostname = 'hippo'
port = 1883
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((hostname, port))
print(s.getsockname()[0])
s.close()
It opens a socket connection to the broker / port (we know it'll have to be online!) and returns the local address. Wrapped in a bit of error handling, it may be more exact.
I'm implementing homie for crownstones (a bluetooth switch/dimmer/presence detector/power monitor)
It works with a bluetooth mesh network to which you can add new nodes. It would be nice if those new nodes also show up in MQTT.
However I can't do that now as we can't subscribe to properties after setup, but I don't see anything in the spec which would disallow this.
Hi guys,
I would like to open a discussion about your use-cases for this project and where to go from here.
My initial need to kick-off this project was to have a dedicated Raspberry Pi mimicking a Homie-ESP8266 device. Having worked with the homie-esp8266 implementation at that time I started to port its functionality to Python.
Unfortunately, the current dev-branch is neither very pythonic nor as compatible to homie-esp8266 as it was in the beginning. I am struggling between focusing to comply to the homie-convention while being pythonic or continuing to try adopting the functionality/feature-set of homie-esp8266.
Whats your opinion about this? I would like to hear some feedback.
Cheers,
Jan
Forgive my ignorance by not being able to tell at a glance: would this also work on Python 2.7? It seems so to me (but I'll gladly test).
The reason for asking: I believe there are still lots of Python 2.x installations, particularly on older Raspberry Pis which is the kind of platform homie-python3
would target, I'd say.
Something went wrong with the last update.
self.publishLocalipAndMac()
File "/Library/Python/2.7/site-packages/homie/main.py", line 349, in publishLocalipAndMac
payload=localMac, retain=True)
UnboundLocalError: local variable 'localMac' referenced before assignment
I thought my code was wrong so i tested with demo example in readme just changing the config from file to dictionary.
Same error. And worst, nothing is published to the broker.
Here is the code
import homie
import time
config = {
"HOST": "localhost",
"PORT": 1883,
"KEEPALIVE": 10,
"DEVICE_ID": "onid2",
"DEVICE_NAME": "name",
"TOPIC": "topic/services"
}
Homie = homie.Homie(config)
temperatureNode = Homie.Node("temperature", "temperature")
def main():
Homie.setFirmware("awesome-temperature", "1.0.0")
temperatureNode.advertise("degrees")
Homie.setup()
while True:
temperature = 22.0
print("Temperature: {:0.2f} C".format(temperature))
temperatureNode.setProperty("degrees").send(temperature)
time.sleep(1)
if __name__ == '__main__':
try:
main()
except (KeyboardInterrupt, SystemExit):
logger.info("Quitting.")
You mentioned to me you were thinking of doing OTA updates via git. How would this work? With an inotify type of reloading of my homie3-app.py
?
You may have seen in Homie 2.0 wishlist that Marvin is considering doing OTA via MQTT (which I think is grand). Would this be an idea for homie-python3
as well? I'm thinking along the lines of publishing a blob of Python code, the homie3-app.py
, say, which, if it can be loaded, replaces the current version (backing up the old version?).
This would make my life easier in homie-ota, as we could possibly manage both systems more or less identically. Just a thought...
„[properties] must be unique on a per-node basis, and which adhere to the ID format.“
https://github.com/marvinroger/homie/tree/v2#node-properties
Implement TLS
Just going to look at moving an old script that runs as two pythong scripts, one for tmp one for fan control to homie.
It had been a while, so i performed a pip install --upgrade homie and it lists in pip as .4.1
But upon running I'm getting:
Setting up GPIO ports
GPIO ports set up on port 18
Starting homie
Traceback (most recent call last):
File "mqtt.homie.fancontrol.py", line 93, in <module>
main(args.configfile)
File "mqtt.homie.fancontrol.py", line 41, in main
Homie = homie.Homie(configfile)
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 74, in __init__
self._initAttrs(config)
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 119, in _initAttrs
config.get(
AttributeError: 'str' object has no attribute 'get'
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 462, in _exitus
self.mqtt_topic + "/$online",
AttributeError: 'Homie' object has no attribute 'mqtt_topic'
Error in sys.exitfunc:
Traceback (most recent call last):
File "/usr/lib/python2.7/atexit.py", line 24, in _run_exitfuncs
func(*targs, **kargs)
File "/usr/local/lib/python2.7/dist-packages/homie/main.py", line 462, in _exitus
self.mqtt_topic + "/$online",
AttributeError: 'Homie' object has no attribute 'mqtt_topic'
Which seems to be part of the homie framework. my config as follows:
{
"HOST": "localhost",
"PORT": 1883,
"KEEPALIVE": 10,
"USERNAME": "",
"PASSWORD": "",
"CA_CERTS": "",
"DEVICE_ID": "cupboard",
"DEVICE_NAME": "cupboard",
"TOPIC": "sensors/dht",
"dht": {
"frequency": 300,
"pin": 4
},
"relay": {
"pin": 18,
"log": "/var/log/mqtt/fancontrol-homie.log"
}
}
Any ideas? Here's the code https://github.com/psyciknz/OpenHAB-Scripts/blob/master/mqtt.homie.fancontrol.py
It seems that the MQTT 3.1.1 specification doesn't force brokers to store retained messages sent with QOS = 0. Here you can find a conversation about that in the Moquette broker GitHub repository: https://github.com/andsel/moquette/issues/125.
I propose to publish all messages with QOS = 1, because that is also what Homie recommends (https://github.com/homieiot/convention#qos-and-retained-messages).
PS: I will try to provide a PR for it 👍
Hey,
Clones this and took a peak at the code. This is a way to add any python capable device in the homie universe right?
I'm wanting to build a homie-ota/homie dashboard in python/js/ruby but without re-inventing the wheel since you guys did some good work.
Can you suggest the best way to go about using your library? Looked at the docs and examples but the docs just seem like a re-hash of all the methods and functions.
I'll probably re-use the node and a few other classes in this but would rather not cannibalize :) .
Hi @jalmeroth!
How are things going on? 👍
I'm writing a new app/script using the homie-python library but I have encountered a problem with the usage of the "signal" module. My app uses different threads and creates homie devices dynamically, but I'm getting the following error when instantiating a new homie device:
File "/home/aitor/git/bluetooth-remote-to-homie/homie_bluetooth.py", line 16, in __init__
self.homie_ = homie.Homie(self.homie_info)
File "/usr/local/lib/python3.5/dist-packages/homie/main.py", line 59, in __init__
signal.signal(signal.SIGTERM, self._sigTerm)
File "/usr/lib/python3.5/signal.py", line 47, in signal
handler = _signal.signal(_enum_to_int(signalnum), _enum_to_int(handler))
ValueError: signal only works in main thread
Do you think that the signal module is necessary for the library? The "_sigTerm" and "_sigHup" functions just print a debug message and they rise the "SystemExit" exception, nothing critical.
What is your opinion about removing the signal dependency? I can submit a PR to address this topic, it's just a matter of removing 11 lines of code 😉
Best regards,
Aitor
Just a reminder that LWT handling is currently missing.
Is this to make python based sensor scripts use a similar framework as homie? Ie a downloadable config file etc?
If so great work. Right after completing my first wemos d1 mini project, I thoguht to myself, hmm my python scripts for raspberry pi would be great to run under the same framework...
So I have a Paradox Alarm project https://github.com/psyciknz/ParadoxIP150v2 That I use for getting my alarm into OpenHAB and Home Assistant (long story, but I use both).
Just trying to figure out with the homie convention, what would be the best fit for:
PIR Sensors
Reed Switches (these are covered already)
Partitions with multiple arm states (armed_away, armed_night, disarmed etc).
Thoughts how I might do it?
In the arduino version of homie, it calls homie.loop to go to sleep.
Here in homie.python, we're using time.sleep(#).
I currently have mine set a 1 as per examples, but for a fan control script, what would happen if this was much higher? The homie.loop includes looping, sleep and keeping a mqttc client awake for callbacks.
On Python 2.7, homie-python
cannot be stopped with CTRL-C.
(Oh, I notice you've changed the name from homie-python3
to homie-python
; well done. :-)
device topic is homie/163e6029db/$mac
but the mac is 00:16:3e:60:29:db
the leading 00 has been trimmed off.
I think it cloud be really helpful to load settings from a json or dictionary object and not only from file on local filesystem.
I have different settings in remote database and it's hard to save each of them on disk locally just to load once.
In case of a connection lost (for example if the mqtt broker is restarted), it seems that it does not reconnect so the published items are lost until I restart the program.
Can we make netifaces optional?
I am running homie-python on a router and it does not have netifaces compiled.
I've resorted to this in order to adjust configuration parameters for testing:
config = {
"HOST": "localhost",
"PORT": 1888,
"KEEPALIVE": 10,
"DEVICE_ID": "xxxxxxxx",
"DEVICE_NAME": "xxxxxxxx",
"TOPIC": "devices"
}
Homie = homie.Homie(**config)
I wonder if it would be sensible to be able to pass a filename to homie.Homie()
for it to read the configuration from. Alternatively, maybe support configuration via environment variables?
Be it with or without Homie.quit()
, I think homie-python
should publish a retained $offline false
when it exits to indicate that the "device" actually is offline, irrespective of whether it crashed (i.e. in which case LWT would fire).
What do you think?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.