jeroenterheerdt / python-egardia

Python library to interface with Egardia / Woonveilig alarm
11 stars 10 forks source link

Enhancement Device Status #9

Closed ufulu closed 6 years ago

ufulu commented 7 years ago

Hi, is it possible to read and the state of the egardia devices, linke if a given window or door is currently open or closed, see screenshot and send this information to home assistant? sc3

Daehnie commented 7 years ago

Hi @ufulu,

where do you get these screenshot with your Door contact? Is it FHEM?

I've played a little bit with Domoticz... Here's a plugin https://github.com/StuffNL/domoticz-woonveilig With this plugin, it is also possible to see the status of our devices. Maybe it could help @jeroenterheerdt to integrate this feature into this egardiaserver.py script. (Provided of time and effort!) This would ingenious! Sorry, I would.... But I'm no developer and I've no idea about python. ;-)

ufulu commented 7 years ago

Hi @Daehnie this is a screenshot directly from the egardia webpanel when i connect to the gate via its local IP asddress. The link you sent leads to a 404 error page. As a workaround i currently use the scrape sensor to display the state of the door sensors.

jeroenterheerdt commented 7 years ago

@ufulu care to share your scrape sensor configuration?

Daehnie commented 7 years ago

Sorry...

https://github.com/StuffNL/domoticz-woonveilig

ufulu commented 7 years ago

@jeroenterheerdt I'd love to.

  1. Currently the scrape sensor doesn't support Authetification so I had to make a few adjustments to the scrape.py see here or here.
  2. After editing the scrape.py I just added to following to my config:

- platform: scrape resource: http://192.168.39.37/setting/panel.htm name: EgardiaWeb username: xxx password: !secret egardia authentication: basic select: '#sentbl > tr:nth-of-type(1) > td:nth-of-type(10)'

The weird thing is I had and still have a hard time getting the correct CSS selectors to me it is still a hit and miss, and I still have issues with it. I would be interested to see what you exactly use?

jeroenterheerdt commented 7 years ago

@ufulu interesting screenshot you have there. I do not see anything in conditions, battery and tamper. Also I do not have a RSSI and Status column (see screenshot). capture. I am running firmware CTC-1718 1.1.8 1718D0EG04J. So for me it does not really have value to extend the egardia component to provide status info of the sensors to HomeAssistant - since there is none. Is there anything I need to do on my system to make that info show up? Could you tell me if you are running other firmware? I see that there is a GET request we can use to get the list of sensors and their state (provided it is passed along ....). I use a similar approach to get the alarm status so that should not be hard. If you use this in Postman you will probably get a status report of the sensors: http://[local IP for your alarm panel]:[port of your alarm panel, defaults to 80]/action/sensorListGet. You will need to use basic authentication and pass in you egardia username / password. Let me know if this works - you might need to click 'RAW' in the output window of Postman. If this works fine then we can add a component to get the sensors from the egardia device and their status into Home Assistant. Again, much obliged if you could help me figure out why I do not get the status info and you do ;)

Daehnie commented 7 years ago

@jeroenterheerdt I‘ve exactly the same FW like you (CTC-1718 1.1.8 1718D0EG04J) and my Egardia looks like yours without any Information (tamper, battery, etc.) But with Domoticz and this Plugin above, I could See the Status of my Sensors/Devices! Maybe it could help...

jeroenterheerdt commented 7 years ago

Thanks @Daehnie - good to know the problem is not on my end. Interested in hearing from @ufulu on this.

jeroenterheerdt commented 7 years ago

@Daehnie - what do you see in Domoticz? I have not used it. Can you show me a screenshot? I had a look at the code you shared - they have the same approach as I would take. Interested in that screenshot to understand what the statuses actually mean.

Daehnie commented 7 years ago

@jeroenterheerdt - After installing this plugin in Domoticz, I've created a 'Hardware' with Type 'Woonveilig Gate 01' and insert IP-Adress, Username and Password of my Egardia Panel.

domoticz3

After all this Plugin search for all Devices at my Egardia Panel.

domoticz2

domoticz

There you can see the status of my Devices. Here's a example of the Front Door...

domoticz4

jeroenterheerdt commented 7 years ago

Many thanks - I get it now. I will talk to the guys in the core dev team of Home Assistant on how to do this best and will report back.

Daehnie commented 7 years ago

Ok, I'm curios of your answer!

ufulu commented 7 years ago

Hi @jeroenterheerdt and @Daehnie

my firmware as reported by egardia is: HPGW-L1-XA35A 2.9.2.6.1. the whole panel looks like this:

sh4

Turns out that after taking a closer look at the box itself, I seem to have the gate02. So this might be the reason for the different frontends? You see I inherited this alarm system after moving into the house and am only now getting to know the system after I started setting up home assistant. After looking into the code @Daehnie posted I think that this is the way to go as using the scrape sensor is unreliably at best and just a workaround.

Using Postman to query http://192.168.39.37/action/deviceListGet I receive a JSON with all relevant Data:

{  
   "senrows":[  
      {  
         "area":1,
         "zone":1,
         "type":4,
         "type_f":"Door Contact",
         "name":"Badfenster - Mitte",
         "cond":"",
         "cond_ok":"1",
         "battery":"",
         "battery_ok":"1",
         "tamper":"",
         "tamper_ok":"1",
         "bypass":"No",
         "rssi":"Strong, 9",
         "status":"Door Close",
         "id":"RF:007fc310",
         "su":1
      },
   ]
}

I have no clue about domoticz and only very rudimentary knowledge about python so I don't know how hard their solution would be to port to home assistant.

Nonetheless I am very eager to learn more and and would love to support you @jeroenterheerdt in any way I can.

Cheers!

jeroenterheerdt commented 7 years ago

@ufulu can you confirm my component works with your gate02 system? I have the gate01 and have only tested it with that, but would love to add gate02 to the list of systems this works with. Also, thanks for the extra info - I agree that your newer version adds better tracking of sensor status. I will investigate on how to add that and get back to you and @Daehnie for testing. Just checking @Daehnie what system do you have? I assume gate01 since we run the same firmware, can you confirm?

Daehnie commented 7 years ago

@jeroenterheerdt Yes, I can confirm that I have Gate01. Come back if you integrate that feature and I will help to test!

jeroenterheerdt commented 7 years ago

@ufulu @Daehnie I have started building this feature. Could you help me by testing the following: please get a new version of the egardiadevice component onto your system (clone it from the GitHub into a new folder). Then run test.py (you will need to edit test.py first to plug in your egardia IP, username and password) and paste the output here. Also let me know what the state of your sensors were when you ran this, i.e.: were all door lock sensors closed, etc. Thanks for helping!

Daehnie commented 7 years ago

@jeroenterheerdt Result: DISARM {'6': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '6', 'area': '1', 'tamp': '', 'name': 'Kueche', 'zone': '7', 'attr': 'Burglar', 'cond': ''}, '3': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '3', 'area': '1', 'tamp': '', 'name': 'Gaeste-WC', 'zone': '3', 'attr': 'Burglar', 'cond': ''}, '8': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '8', 'area': '1', 'tamp': '', 'name': 'Arbeitszimmer', 'zone': '9', 'attr': 'Burglar', 'cond': ''}, '7': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '7', 'area': '1', 'tamp': '', 'name': 'Ylvie', 'zone': '8', 'attr': 'Burglar', 'cond': ''}, '4': {'bypass': 'No', 'type': 'IR Sensor', 'battery': '', 'no': '4', 'area': '1', 'tamp': '', 'name': 'Wohnzimmer', 'zone': '4', 'attr': 'Entry', 'cond': ''}, '10': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '10', 'area': '1', 'tamp': '', 'name': 'Wohnzimmer', 'zone': '11', 'attr': 'Burglar', 'cond': 'Open'}, '11': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '11', 'area': '1', 'tamp': '', 'name': 'Essecke', 'zone': '12', 'attr': 'Burglar', 'cond': ''}, '9': {'bypass': 'No', 'type': 'Door Contact', 'battery': '', 'no': '9', 'area': '1', 'tamp': '', 'name': 'Haustuer', 'zone': '10', 'attr': 'Entry', 'cond': ''}}

Disarm is correct! And Sensor '10' 'Wohnzimmer' was 'open' is also correct. All other sensors were closed.

ufulu commented 7 years ago

Hi @jeroenterheerdt,

Yes the component works with the gate02. I could gather all the codes and the status of my alarm updated acordingly. I just haven‘t gotten it to start on boot as I am running HA in Docker. Great that you are progressing! Unfortunately I will probably only get to test your new version ononday as i am gone for the weekend...

jeroenterheerdt commented 7 years ago

@ufulu @daehnie thanks for the quick replies. Looking forward to your test results @ufulu! Have a good weekend!

ufulu commented 7 years ago

Good morning,

I just tried the test script but receive the following error. I guess it is just a user error on my side as I manage to get a valid json object when using postman to query the egardia api. Any clue what I am doing wrong?

/usr/src/app/homeassistant/components/sensor/test# python test.py 
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    e = egardiadevice.EgardiaDevice("192.168.39.37",80,"xxx","xxx","")
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 30, in __init__
    self._sensors = self.getsensors()
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 71, in getsensors
    sensord = self.parseJson(sensors)
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 147, in parseJson
    data = json.loads(crappy_json, strict=False)
  File "/usr/local/lib/python3.6/json/__init__.py", line 367, in loads
    return cls(**kw).decode(s)
  File "/usr/local/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
jeroenterheerdt commented 7 years ago

@ufulu could you post the output from postman please?

jeroenterheerdt commented 7 years ago

By the way did you pass in your username and password? The output you pasted here shows placeholders for it. Or have you done that yourself?

ufulu commented 7 years ago

yes i replaced my user name and password with xxx. ;) and the password is correct, i copy pasted them from postman to be sure. The postman output is as follows:

{ "senrows": [ {"area": 1, "zone": 1, "type": 4, "type_f": "Door Contact", "name": "Badfenster - Mitte", "cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1", "tamper": "", "tamper_ok": "1", "bypass": "No", "rssi": "Strong, 9", "status": "Door Close", "id": "RF:007fc310", "su": 1}, {"area": 1, "zone": 2, "type": 15, "type_f": "Keypad", "name": "Fernbedienung", "cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1", "tamper": "", "tamper_ok": "1", "bypass": "No", "rssi": "Strong, 9", "status": "", "id": "RF:024bf670", "su": 0}] }

jeroenterheerdt commented 7 years ago

Ah, I see what the issue is, the GATE02 returns more columns. For example, it also returns a type_f column, which I do not fix in the JSON parser: GATE01 only returns type. Egardia does return invalid JSON, so I need to fix it.

jeroenterheerdt commented 7 years ago

@ufulu could you re-clone the solution from GitHub and re-run the test.py? Please place the output here.

ufulu commented 7 years ago

Thank you @jeroenterheerdt now I get a 404:

/usr/src/app/homeassistant/components/sensor/test# python test.py 
<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"/><link rel="stylesheet" type="text/css" href="/css/main.css"/><title>Document Error: Site or Page Not Found</title></head><body><h2>Access Error: Site or Page Not Found</h2><a href="/index.htm" target="_top">Go to home</a></body></html>
Traceback (most recent call last):
  File "test.py", line 2, in <module>
    e = egardiadevice.EgardiaDevice("192.168.39.37",80,"xxx","xxx","")
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 30, in __init__
    self._sensors = self.getsensors()
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 71, in getsensors
    sensord = self.parseJson(sensors)
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 148, in parseJson
    data = json.loads(crappy_json, strict=False)
  File "/usr/local/lib/python3.6/json/__init__.py", line 367, in loads
    return cls(**kw).decode(s)
  File "/usr/local/lib/python3.6/json/decoder.py", line 339, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "/usr/local/lib/python3.6/json/decoder.py", line 357, in raw_decode
    raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
jeroenterheerdt commented 7 years ago

Weird what is the URL you called in postman that generated the output you posted earlier?

ufulu commented 7 years ago

http://192.168.39.37/action/deviceListGet

jeroenterheerdt commented 7 years ago

Ah, that makes sense since gate01 provides only sensorlistGet, and that is what the code now calls. I can try to make it dependent on the gate version.

jeroenterheerdt commented 7 years ago

@ufulu @Daehnie I would appreciate if you could pull the latest version and give it another try. Please post any output here. Note that the test now requires to pass in a new parameter indicating your version (GATE-01 or GATE-02).

ufulu commented 7 years ago

Nice one @jeroenterheerdt 👍

/usr/src/app/homeassistant/components/sensor/test# python test.py
{
  "senrows": [
{"area": 1, "zone": 1, "type": 4, "type_f": "Door Contact", "name": "Badfenster - Mitte",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": "No", "rssi": "Strong, 9",
"status": "Door Close", "id": "RF:007fc310", "su": 1},
{"area": 1, "zone": 2, "type": 15, "type_f": "Keypad", "name": "Fernbedienung",
"cond": "", "cond_ok": "1", "battery": "", "battery_ok": "1",
"tamper": "", "tamper_ok": "1", "bypass": "No", "rssi": "Strong, 9",
"status": "", "id": "RF:024bf670", "su": 0}]
}

Traceback (most recent call last):
  File "test.py", line 2, in <module>
    e = egardiadevice.EgardiaDevice("192.168.39.37",80,"xxx","xxx","","GATE-02")
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 45, in __init__
    self._sensors = self.getsensors()
  File "/usr/src/app/homeassistant/components/sensor/test/egardiadevice.py", line 98, in getsensors
    sensors[sensor["no"]] = sensor
KeyError: 'no'

yes the Door was closed.

jeroenterheerdt commented 7 years ago

Thanks @ufulu - another bug found. @Daehnie please check at your earliest convenience. I'll wait for your final test before creating a updated version of the component to use in HA.

Daehnie commented 7 years ago

@jeroenterheerdt

First try I had an issue...

homeassistant@hassbian:/srv/homeassistant/lib/python3.5/site-packages/pythonegardia-test/src/pythonegardia $ python3 test.py Traceback (most recent call last): File "test.py", line 3, in e = egardiadevice.EgardiaDevice("192.168.178.35",80,"Username","Password","","GATE-01") File "/srv/homeassistant/lib/python3.5/site-packages/pythonegardia-test/src/pythonegardia/egardiadevice.py", line 45, in init self._sensors = self.getsensors() File "/srv/homeassistant/lib/python3.5/site-packages/pythonegardia-test/src/pythonegardia/egardiadevice.py", line 89, in getsensors raise UnauthorizedError('Unable to login to system using the credentials provided') egardiadevice.UnauthorizedError: 'Unable to login to system using the credentials provided'

But second one goes well!

homeassistant@hassbian:/srv/homeassistant/lib/python3.5/site-packages/pythonegardia-test/src/pythonegardia $ python3 test.py /-secure- { senrows : [ {no : "1", type : "Remote Controller", area : "1", zone : "1", name : "User", attr : "Personal Att", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "2", type : "Remote Keypad", area : "1", zone : "2", name : "Eingangstuer", attr : "", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "3", type : "Door Contact", area : "1", zone : "3", name : "Gaeste-WC", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "4", type : "IR Sensor", area : "1", zone : "4", name : "Wohnzimmer", attr : "Entry", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "5", type : "Remote Controller", area : "1", zone : "6", name : "User 2", attr : "Personal Att", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "6", type : "Door Contact", area : "1", zone : "7", name : "Kueche", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "7", type : "Door Contact", area : "1", zone : "8", name : "Ylvie", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "8", type : "Door Contact", area : "1", zone : "9", name : "Arbeitszimmer", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "9", type : "Door Contact", area : "1", zone : "10", name : "Haustuer", attr : "Entry", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "10", type : "Door Contact", area : "1", zone : "11", name : "Wohnzimmer", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}, {no : "11", type : "Door Contact", area : "1", zone : "12", name : "Essecke", attr : "Burglar", cond : "", battery : "", tamp : "", bypass : "No"}] } / DISARM {'3': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '3', 'zone': '3', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Gaeste-WC'}, '7': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '7', 'zone': '8', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Ylvie'}, '4': {'area': '1', 'bypass': 'No', 'type': 'IR Sensor', 'no': '4', 'zone': '4', 'tamp': '', 'battery': '', 'attr': 'Entry', 'cond': '', 'name': 'Wohnzimmer'}, '9': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '9', 'zone': '10', 'tamp': '', 'battery': '', 'attr': 'Entry', 'cond': '', 'name': 'Haustuer'}, '6': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '6', 'zone': '7', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Kueche'}, '8': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '8', 'zone': '9', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Arbeitszimmer'}, '11': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '11', 'zone': '12', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Essecke'}, '10': {'area': '1', 'bypass': 'No', 'type': 'Door Contact', 'no': '10', 'zone': '11', 'tamp': '', 'battery': '', 'attr': 'Burglar', 'cond': '', 'name': 'Wohnzimmer'}}

jeroenterheerdt commented 7 years ago

Thanks @Daehnie!

Daehnie commented 7 years ago

Fyi

There‘s a new FW for my Panel... 1.1.9:1718D0EG04P

But, I don‘t dare to update my Panel and wait for a new Release of Pythonegardia...

Regards

jeroenterheerdt commented 7 years ago

@Daehnie, I am not able to upgrade since I killed my subscription for Egardia. I would advice against upgrading if you are happy with the way it works now. I think downgrading cannot be done.

jeroenterheerdt commented 7 years ago

BTW, I killed my Egardia monthly subscription because of the integration with HomeAssistant - saves money and provides more flexibility on what you want to do when the alarm sounds ;)

ufulu commented 7 years ago

That is what I did as well, or rather never understood why the heck I need a subscription just so that they send me notifications? Anyway could you maybe share your Home Assistant automation.yaml or whichever configuration you have setup in order to interact with homeassistant and Egardia?

jeroenterheerdt commented 7 years ago

@ufulu Egardia will not be happy with us then. We're killing their business model :)

please find my yaml attached. What I do is a couple of things:

Hope this helps, please let me know if you have other things or other ideas, happy to learn!

alarm_control_panel.zip

ufulu commented 7 years ago

Thank you @jeroenterheerdt for sharing. I am still at the very beginning of integrating Egardia into my existing Home Assistant Setup but I was wondering / hoping that I can also Arm/disarm the Egardia from within Home Assistant. Is this possible or how do you arm the system currently? I currently have the following presence detection: https://philhawthorne.com/making-home-assistants-presence-detection-not-so-binary/ and my plan is to Arm Egardia when my state changes to "just left", and Disarm it when my state changes to "just arrived".

jeroenterheerdt commented 7 years ago

Yes if you configure your Egardia component you will immediately be able to arm and disarm the alarm.

Daehnie commented 7 years ago

Hey @jeroenterheerdt @ufulu I‘ve stopped my monthly subscribtion too and send notifications to our iPhones if the alarm is triggered. This works well and I‘m playing with home assistant to integrate other things. But, everytime if I restart home assistant, my egardia component is in ‚unknown‘ status. So I cannot arm/disarm my panel via iOS App and I have to trigger it firstly by my Remote Control. If then my egardia component becomes the Code of the Panel and changes the status. Is it possible to set the component to an default status like ‚disarmed‘ After restart of home assistant?

jeroenterheerdt commented 7 years ago

@Daehnie your alarm system should get the status automatically after a couple of minutes. Just wait max 15 minutes for the status to update. If this is not happening check that your Egardiaserver is running. If it runs and status is still not updated we might have a bug here.

Daehnie commented 7 years ago

@jeroenterheerdt Hmm, I've been waiting for 20 minutes and status doesn't change. My egardiaserver.py is still running... In my homeassistant.log there is no status code from Egardiaserver. Again, first if I change the status via my egardia sensor/Remote Control. So, my Egardiaserver works correctly, or? How does it works all? Egardiaserver connects to Egardiapanel and should send a servercode to homeassistant?

jeroenterheerdt commented 7 years ago

That is weird and it is supposed to work the way you wrote. What is the assumed status of the alarm in Hass? Can you share screenshots of what is happening?

Daehnie commented 7 years ago

@Jeroenterheerdt The assumed status is ‚disarmed‘. But its still ‚unknown‘ Image Screenshot is from iOS App.

jeroenterheerdt commented 7 years ago

Is it shown as unknown as well or as disarm in the interface?

Daehnie commented 7 years ago

It is shown as unknown!

jeroenterheerdt commented 7 years ago

Weird. Have you somehow configured HA to not ask for updates of components?

jeroenterheerdt commented 7 years ago

By the way, what is the output if you run test.py when the alarm is shown as status unknown?