Closed psyciknz closed 4 years ago
Hmm I see the node code, how does a node relate to a device? And where can I add nodes (which I assume a single properties to one device?
So i have a class now, that inherits Device_Base... I've got all my alarm zones as Property_Contacts and I add them to the self.nodes.
But now I see that a node and different to a property, So I'm trying this:
try:
node = self.get_node(label)
self.logger.info("HOMIE: Found existing node for '%s'" % label)
node.update_contact()
except:
#has a node so use it.
self.logger.info("HOMIE: Adding new contact node for '%s'" % label)
try:
#move contact_node to class, and set each zone as a node.
node = Node_Contact(self,name=label)
node.id = label
self.add_node(node)
A label is all the zone names (about 32 of them), It seems to add all my nodes, and then once added, it picks up the node that then getsa value change, but I'm trying to update the contact value, and the update_contact
method isn't there. I guess I can pull the property explicit, but it looks like it should be there.
The Homie convention specifies a Device as the root. Each device has one or more Nodes. Each node has one or more Properties. For your situation, you could start with a device that represents the alarm system, then add a node containing all of the contacts, and then add each zone as a property. If you post your device and node code here I'll have a look at what is missing.
I was thinking overnight, I wonder if it would be: Alarm = device Zones, partitions etc are nodes ( ie each zone/PIR sensor is its own node) Zone open, zone trouble are properties of a zone node..
That seems to be how jpbarraca/pai is set out structurally so seems to fit. And works for my brain.
So here's what I'm trying. I'm having to use the base object for most of them. The class I'm in is a subclass of Device_Base.
So for an item, element = zone, attribute= open and label = "Main Door PIR" (which gets sanitised to maindoorpir - after looking tat the device id assert you have)
if element == 'zone' and (attribute == "open"): #or attribute == "alarm"):
try:
label_sanitised = label.replace('_','').lower()
node = self.get_node(label_sanitised)
self.logger.info("HOMIE: Found existing node for '%s'" % label)
if value:
node.set_property_value(attribute.lower(),"OPEN")
else:
node.set_property_value(attribute.lower(),"CLOSED")
except Exception as e:
#has a node so use it.
self.logger.info("HOMIE: Adding new contact node for '%s'" % label)
try:
#move contact_node to class, and set each zone as a node.
node = Node_Base(self,name=label,id=label_sanitised,type_=element)
#node.id = label
newProperty = Property_Contact(node,id=attribute.lower(),name=attribute)
node.add_property(newProperty)
#self.nodes[label] = node
self.add_node(node)
except Exception as e:
self.logger.error("HOMIE: Error creating node: " + str(e))
It add the nodes (each pir) successfully, and pulls one to update it's value. But it's falling over on the node.set_property_value sayingAttributeError("'Node_Base' object has no attribute 'set_property_value'",)
.
Any thoughts? (all code in this branch: https://github.com/psyciknz/pai/tree/homie )
Having all the subclass, apart from confusing wasn't working for me. So I've now made a new Device variable in my class: alarm_device. I've got mqtt started etc, and are adding the nodes and properties:
try:
#move contact_node to class, and set each zone as a node.
zone_node = Node_Base(self.alarm_Device,name=label,id=label_sanitised,type_=element)
**newProperty = Property_Boolean(zone_node,attribute,attribute)**
zone_node.add_property(newProperty)
self.alarm_Device.add_node(zone_node)
except Exception as e:
self.logger.error("HOMIE: Error creating node: " + str(e))
Bu ti have it get an assertion error here. I can see you validate the id (mine for the property is "open") which is fine, I see an assert node - which has just been created, but can't tell if this is the issue., and later an assert on the value, which I'm not setting at this point.
I'll commit the code and give it a rest for now....there's been a number of comments from me as you can see me working through various issues.
I'll dig more into this tomorrow - but I am on CST :)
Quick question, it looks like you are adding device dynamically as you get events from them? Is there a way to get a list of them first?
I'll dig more into this tomorrow - but I am on CST :)
No worries....there's a bit there.
Quick question, it looks like you are adding device dynamically as you get events from them? Is there a way to get a list of them first?
No, this is the first time I know what all the devices are (and depending who uses this implementation, they're not fixed between systems). I don't want to make it too easy!! :)
Changes below for your code - need to update to Homie3 0.1.2
label_sanitised = label.replace('_','').lower()
zone_node = self.alarm_Device.get_node (label_sanitised)
if zone_node is None: # create node
zone_node = Node_Base(self.alarm_Device,name=label,id=label_sanitised,type_=element)
self.alarm_Device.add_node(zone_node)
property_contact = zone_node.get_property (attribute.lower())
if property_contact is None:
property_contact = Property_Boolean(zone_node,attribute.lower(),attribute)
zone_node.add_property(property_contact)
property_contact.value = value```
Hi sorry, got busy.
I did an update from github of the library and tried that code you posted.
But there's still as exception being rasied when trying to get a node that doesn't (yet) exist. So not sure if there's something else I need to look at to make the get_node just return None.
So I've reverted my code and now I get an exception on a new property: newProperty = Property_Boolean(zone_node,attribute,attribute)
Where attribute = "open"
I had to make an alteration to your property_base.validate_id to:
r = re.compile(r'(^(?!\-)[a-z0-9\-]+(?<!\-)$)')
adding the r, as it complained about escaping the backspaces. What version of python are you running with? I've got 3.6.
I am running 3.7. According to the Homie convention, backspaces are not allowed in a device id.
Topic IDs An MQTT topic consists of one or more topic levels, separated by the slash character (/). A topic level ID MAY contain lowercase letters from a to z, numbers from 0 to 9 as well as the hyphen character (-).
A topic level ID MUST NOT start or end with a hyphen (-). The special character $ is used and reserved for Homie attributes. The underscore (_) is used and reserved for Homie node arrays.
None
The current release does check if the node exists or not - should not cause an exception. Please have a look at device_base.py line 165
if node_id in self.nodes:
return self.nodes [node_id]
else:
return None
Sorry, the backspace comment was in reference to the regex string. I copied your validate_id code, and my pylint flagged the regex string as needing escaping.
On Sat, 1 Jun 2019 at 00:22, Michael Cumming notifications@github.com wrote:
I am running 3.7. According to the Homie convention, backspaces are not allowed in a device id.
Topic IDs An MQTT topic consists of one or more topic levels, separated by the slash character (/). A topic level ID MAY contain lowercase letters from a to z, numbers from 0 to 9 as well as the hyphen character (-).
A topic level ID MUST NOT start or end with a hyphen (-). The special character $ is used and reserved for Homie attributes. The underscore (_) is used and reserved for Homie node arrays.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mjcumming/HomieV3/issues/6?email_source=notifications&email_token=ABI2I4ZC5PSIUVWXTSBX2CDPYEKBVA5CNFSM4HNIVII2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWVCHEA#issuecomment-497689488, or mute the thread https://github.com/notifications/unsubscribe-auth/ABI2I43XPGNT6GIXC5DGLV3PYEKBVANCNFSM4HNIVIIQ .
hmm I was definitely getting a KeyError when I called get with a new node that I had not created yet. I mean I can deal with it using the exception code, so not too fussed. My bigger problem is creating the property getting an assert error.
Is that a new thing or been there a while? I'm not that sure how to verify what version of code of your's I'm running. I just updated via pip (diret from your github/master) yesterday.
On Sat, 1 Jun 2019 at 00:25, Michael Cumming notifications@github.com wrote:
None
The current release does check if the node exists or not - should not cause an exception. Please have a look at device_base.py line 165
if node_id in self.nodes: return self.nodes [node_id] else: return None```
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/mjcumming/HomieV3/issues/6?email_source=notifications&email_token=ABI2I45FJJ5A4AS5FW5JLXTPYEKM7A5CNFSM4HNIVII2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODWVCNJQ#issuecomment-497690278, or mute the thread https://github.com/notifications/unsubscribe-auth/ABI2I46L7LFZS56W32SCYQTPYEKM7ANCNFSM4HNIVIIQ .
You can force pip to install a specific version
pip install Homie3==0.1.8
Updaed homie with the command above (any way of verifying the version?)
I'm still getting an assertionerror on:
newProperty = Property_Boolean(zone_node,id=attribute.lower(),name=attribute.lower(),value=value)
Where zone has just been created, and attribute = 'open'
Whether it's the assert node or assert(validate_id) I can't tell.
Any way you can attach something to the asserts so i can tell which one it's failing on?
likely the id.
Can you print out the id before creating the property so we can see what characters are in it?
Here's the code:
self.logger.info("HOMIE: Adding new property boolean '%s'" % attribute)
newProperty = Property_Boolean(zone_node,id=attribute.lower(),name=attribute.lower(),value=value)
zone_node.add_property(newProperty)
That logger line looks like:
INFO:PAI.paradox.interfaces.homie_mqtt_interface:HOMIE: Adding new property boolean 'open'
when run
it must be failing on zone_node - the property value "open" should work.
I’ve inserted all that assert code of yours in line with my node and property creation and the node was ok. But the property had an issue. But I think it was the defect string that it had an issue with.
Is there another way you can do these tests to throw and error and pass a message so we can know for sure?
I saw this old issue: https://github.com/mjcumming/HomieV3/issues/4
And followed up with your answer about the homie convention.....I think your idea of a bridge device is what I should look at.
I'm trying to convert an alarm....so if we think about that, that 32 zones, 2 partitions and a number of other devices. My initial try was each zone was a node.....but that means each node is making a new connection, with it's own attributes.
Now that I think about it, I think the alarm as one device and create logs of different properties for each of the zones.
So would I subclass the device_base and make my own device type? Make make up a way of adding all the properties to it?