GithubHelp home page GithubHelp logo

enocean's Introduction

Python EnOcean

Build Status Coverage Status

A Python library for reading and controlling EnOcean devices.

Started as a part of Forget Me Not design challenge @ element14.

Install

If not installed already, install pip by running

sudo apt-get install python-pip

After pip is installed, install the module by running

sudo pip install enocean (or sudo pip install git+https://github.com/kipe/enocean.git if you want the "bleeding edge").

After this, it's just a matter of running enocean_example.py and pressing the learn button on magnetic contact or temperature switch or pressing the rocker switch.

You should be displayed with a log of the presses, as well as parsed values (assuming the sensors are the ones provided in the EnOcean Starter Kit).

The example script can be stopped by pressing CTRL+C

enocean's People

Contributors

amairesse avatar argorain avatar awrede avatar flopon avatar flow-ree avatar kipe avatar msinn avatar ravualhemio avatar relihanl avatar romor avatar stv0g avatar sylvaincherrier avatar the01 avatar twendt avatar zpfvo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

enocean's Issues

wait for response before returning

Icurrently, when one uses communicator.send() to write a packet, he will soon get a ResponsePacket

The specification (ESP3) states that :
If the answer time between REQUEST/EVENT and RESPONSE exceeds 500ms a timeout is identified as well.

For now, RESPONSE handling and timeout detection is left to the user. Maybe it's by design to stay low level and not handle this logic? Otherwise, I think it would be nice to have some sort of blocking method like (naive implementation) :

def send(packet):
    global communicator
    communicator.send(packet)
    packet = communicator.receive.get(block=True, timeout=0.5) # spec-defined timeout is 500ms
    if isinstance(packet, ResponsePacket):
        print("got response : ", packet.response)
        return
    else:
        #fixme : queue-back this package?
        #throw error
        print ("non-response packet in send() : ", packet)

packages received when the communicator has a callback would have to always be queued, and we need something a bit more subtle to be able to re-queue packages that came when we were waiting for the ResponsePacket.

is some (refined & tested) version of this desirable or out of this library's scope?

Creating RadioPacket with an rangeitem {value} description

Iam trying to create a D2-01-01 radio packet.
Problem is, that some datapoints are defined as range items using ne {value} escape for parsing.
It seems like it is not possible to create packages from such a description because it cant find the value in the profile.

Example:

<enum description="Output value" shortcut="OV" offset="17" size="7">
  <item description="Output value 0% or OFF" value="0" />
  <rangeitem description="Output value {value}% or ON" start="1" end="100" />
  <rangeitem description="Not used" start="101" end="126" />
  <item description="output value not valid / not set" value="127" />
</enum>

When Iam trying to set OV to Output value 100% or ON it will not find the corresponding value. Is there a way around it or do u have to redefine the EEP.xml to a Integer profile.

Improovment

I'm developing an async version of your code using asyncio and pyserial-asyncio. This version will be no blocking and will run in an asynchronous thread (No lock inside a thread, no queue) . If you are interested i'll do a pull request, else i'll release it as an indipendent library. This version is going to be compatible from python > 3.7. I'm almost done. Let me know what do you think

Include recieved time in Packet

     +---+
     |   |
     | P |
     |   |
     +---+ Packet
         | physically
         | arriVed
+-------------------------------------------+  Communicatior
|        |       +---+   +---+              |  Queue
|        |       |   |   |   |              |
|        v       | P |   | P | +            |
|                |   |   |   | |            |
|                +---+   +---+ |            |
+-------------------------------------------+
                               | +---+
                               | |   |  p.recieve.get()
                               v | P |
                                 |   |
                                 +---+

Above is my understanding on how the package acquiring as done currently. The part of the Communicator responsible for filling up the queue is run in a separate thread. Once we get the package from the queue with p.recieve.get() we should know what was the actual arrival time of the package. In case of to slow processing of the queue items, we might conclude (based on the actual received time) that the EnOcean device to which we wanted to send the respond to isn't listening any more.

Delete stale branches

There are a bunch of outdates branches in this repo with confusing names.
Maybe we can clean it up a bit?

Making the logging mechanism more customisable

I am just starting to work with the Python logging mechanism so additional comment are well appropriated.
I believe the current logging implementation should be more customisable from the "library user" point of view.
Will do some experimenting but can't commit to a pull request any time soon.

Quote from python logging documentation:

It is strongly advised that you do not add any handlers other than NullHandler to your library’s loggers. This is because the configuration of handlers is the prerogative of the application developer who uses your library. The application developer knows their target audience and what handlers are most appropriate for their application: if you add handlers ‘under the hood’, you might well interfere with their ability to carry out unit tests and deliver logs which suit their requirements.

Send a switch on command to a Plug Adapter

Hi,
I use this python library, and it works well. But i have a problem.
I have 3 plug adapters (2 ubiwizz DO21-11B-E and 1 another, i can't find its reference).

I pair each device with my enocean controler of my raspberry.

When i send a packet (i build the packet with the enocean ID), all the plug switch on !
I can't find how to select only one...

this is my code : i try to reproduce the on - released message send by a button :

Building my two messages :

    self.pressed_on=[0xf6, 0x10]
    self.pressed_on.extend(self.id)
    self.pressed_on.append(0x30)
   self.released=[0xf6, 0x0]
    self.released.extend(self.id)
    self.released.append(0x20)

Then i set the communication (self.p is a Packet, self.c is a Communicator)

    self.p = Packet(PACKET.COMMON_COMMAND, [0x08])
    self.c = SerialCommunicator()
    self.c.start()
    self.c.send(self.p)

Ok, just send the message

    self.p = Packet(PACKET.RADIO, data=self.pressed_on)
    self.p.build()
    self.c.send(self.p)
    self.p = Packet(PACKET.RADIO, data=self.released)
    self.p.build()
    self.c.send(self.p)

Then, all light switch on ! (but self.id contains only the specific id of the target)

Thanks if you can help.

Occupancy Sensor and raw data package

Sorry I'm new here. Didnt know how to pose a question or if this is ok. I have two issues:

first: I want to parse a data package for my PEHA enocean occupancy sensor. Am I right, that you are not supporting that yet?
snd: Is there a way to get the original data packet I receive from the serial port? Before you interprete and put it into a dict.

install

Hi,
When I used sudo pip install enocean, I got the version 0.31 and not master branch ?
Thanks,

example stops when using contact switch

Hello,

I setup my raspberry pi to to run the example with the transceiver hooked up to listen for events from the starter kit contact switch, temperature sensor, and rocker switch. The temp and rocker work fine, but when I activate the contact switch the example_enocean.py file stops with:

2016-02-02 09:09:29,547 - enocean.communicators.Communicator - DEBUG - 01:81:19:2D->FF:FF:FF:FF (-58 dBm): 0x01 ['0xd5', '0x0', '0x1', '0x81', '0x19', '0x2d', '0x80'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x3a', '0x0'] {} 2016-02-02 09:09:29,558 - enocean.communicators.SerialCommunicator - INFO - SerialCommunicator stopped

What is going on?

How can I add a new type

First of all, thanks for all the code you provide in this repo! Very clearly written and has support for many different types already!
I have the NODON SIN-2-FP-01 module to control my heating, so I would like to add a new type:

RORG D2
FUNC 01
TYPE 0C
(specifically command 0x8: Actuator Set Pilot Wire Mode, to set the heating to Off, Comfort, Eco, ... )

Could you give some indication if I can add this type myself? And which files would need to be modified?

Thanks a lot for any hints !

Best regards,
Pieter

Some questions about pairing and sending command relay

Hi,

I pair a Nodon In wall module with a Nodon windows switch and pairing is ok, the switch can control first relay module.
I received this messages with enocean_example.py:

2017-05-25 14:15:52,437 - enocean.protocol.packet - INFO - Sending response to UTE teach-in.
2017-05-25 14:15:52,438 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-49 dBm): 0x01 ['0xd4', '0xa0', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x31', '0x0'] OrderedDict()
2017-05-25 14:15:52,439 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-05-25 14:15:52,440 - enocean.communicators.SerialCommunicator - DEBUG - FF:C0:AC:80->01:9D:1C:18 (-255 dBm): 0x01 ['0xd4', '0x91', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0xff', '0xc0', '0xac', '0x80', '0x0'] ['0x3', '0x1', '0x9d', '0x1c', '0x18', '0xff', '0x0'] OrderedDict()
2017-05-25 14:15:52,550 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0'] [] OrderedDict()
2017-05-25 14:16:02,618 - enocean.protocol.packet - INFO - Sending response to UTE teach-in.
2017-05-25 14:16:02,619 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-52 dBm): 0x01 ['0xd4', '0xa0', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x34', '0x0'] OrderedDict()
2017-05-25 14:16:02,619 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-05-25 14:16:02,620 - enocean.communicators.SerialCommunicator - DEBUG - FF:C0:AC:80->01:9D:1C:18 (-255 dBm): 0x01 ['0xd4', '0x91', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0xff', '0xc0', '0xac', '0x80', '0x0'] ['0x3', '0x1', '0x9d', '0x1c', '0x18', '0xff', '0x0'] OrderedDict()
2017-05-25 14:16:02,730 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0'] [] OrderedDict()
2017-05-25 14:16:05,720 - enocean.protocol.packet - INFO - Sending response to UTE teach-in.
2017-05-25 14:16:05,721 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-48 dBm): 0x01 ['0xd4', '0xa0', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()
2017-05-25 14:16:05,721 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-05-25 14:16:05,721 - enocean.communicators.SerialCommunicator - DEBUG - FF:C0:AC:80->01:9D:1C:18 (-255 dBm): 0x01 ['0xd4', '0x91', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0xff', '0xc0', '0xac', '0x80', '0x0'] ['0x3', '0x1', '0x9d', '0x1c', '0x18', '0xff', '0x0'] OrderedDict()
2017-05-25 14:16:05,832 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0'] [] OrderedDict()
2017-05-25 14:16:08,807 - enocean.protocol.packet - INFO - Sending response to UTE teach-in.
2017-05-25 14:16:08,808 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-48 dBm): 0x01 ['0xd4', '0xa0', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()
2017-05-25 14:16:08,809 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-05-25 14:16:08,809 - enocean.communicators.SerialCommunicator - DEBUG - FF:C0:AC:80->01:9D:1C:18 (-255 dBm): 0x01 ['0xd4', '0x91', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0xff', '0xc0', '0xac', '0x80', '0x0'] ['0x3', '0x1', '0x9d', '0x1c', '0x18', '0xff', '0x0'] OrderedDict()
2017-05-25 14:16:08,810 - enocean.communicators.SerialCommunicator - DEBUG - 05:04:09:BD->FF:FF:FF:FF (-45 dBm): 0x01 ['0xd5', '0x0', '0x5', '0x4', '0x9', '0xbd', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x2d', '0x0'] OrderedDict()
2017-05-25 14:16:08,839 - enocean.protocol.packet - INFO - >> Module ID: 050409BD, Signal: -45dBm
2017-05-25 14:16:08,840 - enocean.protocol.packet - INFO - >> CO: {u'value': u'open', u'description': u'Contact', u'unit': u'', u'raw_value': 0}
2017-05-25 14:16:08,920 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0'] [] OrderedDict()
2017-05-25 14:16:18,966 - enocean.communicators.SerialCommunicator - DEBUG - 05:04:09:BD->FF:FF:FF:FF (-45 dBm): 0x01 ['0xd5', '0x8', '0x5', '0x4', '0x9', '0xbd', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x2d', '0x0'] OrderedDict()
2017-05-25 14:16:18,971 - enocean.protocol.packet - INFO - >> Module ID: 050409BD, Signal: -45dBm
2017-05-25 14:16:18,973 - enocean.protocol.packet - INFO - >> CO: {u'value': u'open', u'description': u'Contact', u'unit': u'', u'raw_value': 0}
2017-05-25 14:16:19,069 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-48 dBm): 0x01 ['0xd2', '0x4', '0x60', '0xe4', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()

In this messages base ID of USB controller is FF:C0:AC:80, relay module ID is 01:9D:1C:18 and Windows switch ID is 05:04:09:BD

  • My first question:

What this message means:

2017-05-25 14:15:52,439 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-05-25 14:15:52,440 - enocean.communicators.SerialCommunicator - DEBUG - FF:C0:AC:80->01:9D:1C:18 (-255 dBm): 0x01 ['0xd4', '0x91', '0x2', '0x46', '0x0', '0x12', '0x1', '0xd2', '0xff', '0xc0', '0xac', '0x80', '0x0'] ['0x3', '0x1', '0x9d', '0x1c', '0x18', '0xff', '0x0'] OrderedDict()
2017-05-25 14:15:52,550 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0'] [] OrderedDict()

Is that said that the usb controller is also paired with the micromodule?

  • 2nd question

If the usb controller is properly paired with the relay module, I did not understand the examples given in the issues to be able to control these relays from the controller.

Can you give me some code example?

  • 3rd question

After pairing the two modules, I received now this messages when Nodon windows sensor switch trig:
Windows switch "closed", received message from Nodon in wall module when relais trig to off:

2017-05-25 14:23:39,842 - enocean.communicators.SerialCommunicator - DEBUG - 05:04:09:BD->FF:FF:FF:FF (-45 dBm): 0x01 ['0xd5', '0x9', '0x5', '0x4', '0x9', '0xbd', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x2d', '0x0'] OrderedDict()
2017-05-25 14:23:39,862 - enocean.protocol.packet - INFO - >> Module ID: 050409BD, Signal: -45dBm
2017-05-25 14:23:39,864 - enocean.protocol.packet - INFO - >> CO: {u'value': u'closed', u'description': u'Contact', u'unit': u'', u'raw_value': 1}
2017-05-25 14:23:39,943 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-48 dBm): 0x01 ['0xd2', '0x4', '0x60', '0x80', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()

Windows switch "open", received message from Nodon in wall module when relais trig to on:

2017-05-25 14:26:06,111 - enocean.communicators.SerialCommunicator - DEBUG - 05:04:09:BD->FF:FF:FF:FF (-45 dBm): 0x01 ['0xd5', '0x8', '0x5', '0x4', '0x9', '0xbd', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x2d', '0x0'] OrderedDict()
2017-05-25 14:26:06,112 - enocean.protocol.packet - INFO - >> Module ID: 050409BD, Signal: -45dBm
2017-05-25 14:26:06,113 - enocean.protocol.packet - INFO - >> CO: {u'value': u'open', u'description': u'Contact', u'unit': u'', u'raw_value': 0}
2017-05-25 14:26:06,215 - enocean.communicators.SerialCommunicator - DEBUG - 01:9D:1C:18->FF:FF:FF:FF (-48 dBm): 0x01 ['0xd2', '0x4', '0x60', '0xe4', '0x1', '0x9d', '0x1c', '0x18', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()

There is switch message like CO: {u'value': u'open', u'description': u'Contact', u'unit': u'', u'raw_value': 0}
But relay message does not seem to be decoded.

Sorry for all these beginner questions and thank you in advance for your help

Profile A5-07-01

Hello,
i have a Mvt detector which used the A5-07-01 Profile.
I think the EEP.xml file should be update, because this profile seems to be given for temp sensor.
I have modified this file on my own computer in order to make my mvt detector been correctly recognized







I will make a pull request, if you agree on this update.

Include additional information in EEP

If applicable, we should include information about the teach-in variant, support for ADT etc in the EEP.xml also. At least some profiles do include this information in the documentation, and thus it should be set in our version. At least multiple VLD profiles include this information.
Not sure if any of our current profiles define these, but the structure of EEP.xml should be revised to include these. Also, majority of this information could be done

The revised structure should include information about

  • data exchange
    • directions of communication, whether or not the device also listens to us...
    • addressing (mainly support for ADT?)
  • teach-in
    • method
    • variant

Maybe something like the following example, with support for multiple teach-ins, where the first one is preferred. The point of using a list would be to include the variations we have seen with real hardware, to make an educated guess for the correct variant.

<data>
  ...
</data>
<teachin>
  <!--
  number of devices is just a tally of devices we have actually
  observed to use the variation -> thus making it more likely canditate.
  -->
  <variant type="2" number_of_devices="4" />
  <variant type="1" number_of_devices="1" />
  <!--
  As for devices using UTE, the learn -message differs from the normal message,
  so teach-in could and should be left out?
  -->
</teachin>
<dataexchange>
  <direction> <!-- only one should be applicable? -->
    <unidirectional />
    <bidirectional />
  </direction>
  <supports_adt /> <!-- included only, if ADT is supported, otherwise left out -->
</dataexchange>

Create new methods for building packets.

As shown by issue #13, the current method for creating and sending packages is a bit complicated.
Maybe we should build methods for creating packages based on EEP.xml?

My initial idea is to create an Packet (class?) -method with the following style:

p = Packet.create(
    type=PACKET.RADIO,                     # required
    rorg=0xA5, func=0x02, type=0x06,       # required
    destination=[0x01, 0x03, 0x02, 0x13],  # optional, defaults to [0x00, 0x00, 0x00, 0x00] (broadcast)
    learn=False,                           # optional, default to false
    TMP=40.23                              # **kwargs, setting the values based on EEP.xml
)
c.send(p)

I can create the methods, but as I don't have any devices to send data to, at least help with testing would be required.

Comments?

ESP2 Support

Hi,

some installations require the support for ESP2 (e.g. Eltako 14-Series Devices) since they were defined before ESP3 was out. Since these devices are still relatively new and support will last for many years on, it would be awesome to have ESP2 support. I have a whole house installation based on these devices, so I'm able to test almost any kind of 14-Series Device (at least the standard ones like switches, dimmers, shutters, etc. etc.).

What would be your preferred way of extending the codebase for ESP2 support? I would love to do so in the future and feed the result back to the project. Let me know guys what you think...

P.S: https://www.enocean.com/fileadmin/redaktion/support/dolphin-api/esp2_page.html

Communicator: UTE teaching / base_id crasesh when a callback is registered

When the Communicator (Serial or TCP) is created with a callback, the "base_id" getter stops working if the value has not been set previously.

When a callback is set on the Communicator, the receive queue is never filled with messages. They are only pushed to the registered callback. This causes the wait loop of the "base_id" getter to never receive the response from the module as the receive loop in the getter only queries this queue.

As result, the creation of the UTE response package fails because the "create_response_packet" method of the packet receives a "sender_id" value of "None".

This even crashes the main run loop and nothing can be received anymore.

Publish new supported EEP to pypi

Hi! I saw support for EEP A5-09-04 was added in january.

@kipe It would really appreciate it if a version supporting this can be published to pypi (e.g. 50.2).

Version published in pypi

Hi,

is there a special reason, why the version of this package on pypi.python.org is still on version 0.31?
I am currently working on refactoring the EnOcean components in Home Assistant and that would require the latest version.
I could point to the Github repo, but I would rather use pypi if possible.

Regards,
Timo

Update tests to use bytearray

Tests should use bytearray as well.
Initial tests showed some problems, mainly related to 0x55 appearing in the message as well as data. This might affect the message handling in real use-cases as well, so marked as bug.

EEP -data remaining when creating multiple packets

The EEP-object is only loaded once (i.e. when first initializing the Packet -class). It's designed this way, as it includes the loading of EEP.xml, which in the future is quite resource intensive, being full of profiles ;)
Because of this, EEP-class shouldn't retain any data. Currently it holds _profile and _data_description, which are improperly used, and can therefore cause unexpected behavior.

The issue is demonstrated by the test in commit b26fbc9.

Get module ID

Hello

I new on ocean devices.
I just tested a Nodon "Door / Windows sensor" (EPP: D5-00-01) with the example program: enocean_example.py.
This works well, I get the status of the switch:

2017-05-10 14:56:10,467 - enocean.communicators.SerialCommunicator - DEBUG - 05:04:09:BD->FF:FF:FF:FF (-60 dBm): 0x01 ['0xd5', '0x8', '0x5', '0x4', '0x9', '0xbd', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x3c', '0x0'] OrderedDict()
CO: {u'value': u'open', u'description': u'Contact', u'unit': u'', u'raw_value': 0}

I will have a question for a dedicated use, how I can find the module ID in the code to make the difference between 2 identical devices ?
I see it in debug messages (05: 04: 09: BD) but I have not found a function allowing to use it.

Thank you for the work you have done and thank you for sharing it

ubiwizz "MICITRV004-QM" Profile A5-20-01

Hi,

I try to communicate with this EnOcean Thermostat,
I can read packet, but i can't set a new target temp.

I think the problem was link to the learn function.

My question is probably stupid and i'm sure it's easy but,
how can i put the controller in teach-in ?

And after what packet i need to send to set the target temp.
I don't receive all data (contain in the eep ) from the device,
only current temp and target temp...

Really sorry, but i try to add this device in home assistant.

My test code :

`#!/home/hass/homeassistant/bin/python3

-- encoding: utf-8 --

from enocean.consolelogger import init_logging
import enocean.utils
from enocean.communicators.serialcommunicator import SerialCommunicator
from enocean.protocol.packet import RadioPacket
from enocean.protocol.constants import PACKET, RORG
import sys
import traceback

try:
import queue
except ImportError:
import Queue as queue

def assemble_radio_packet(transmitter_id):
return RadioPacket.create(rorg=RORG.BS4, rorg_func=0x20, rorg_type=0x01,
sender=transmitter_id,
destination=[0x05, 0x06, 0x78, 0xBE],
TMP=20)

init_logging()
communicator = SerialCommunicator('/dev/ttyS1')
communicator.teach_in = True
communicator.start()
print('The Base ID of your module is %s.' % enocean.utils.to_hex_string(communicator.base_id))

if communicator.base_id is not None:
print('Sending example package.')
communicator.send(assemble_radio_packet(communicator.base_id))

endless loop receiving radio packets

while communicator.is_alive():
try:
# Loop to empty the queue...
packet = communicator.receive.get(block=True, timeout=1)

    if packet.packet_type == PACKET.RADIO and packet.rorg == RORG.BS4:
        # parse packet with given FUNC and TYPE
        for k in packet.parse_eep(0x02, 0x05):
            print('%s: %s' % (k, packet.parsed[k]))
    if packet.packet_type == PACKET.RADIO and packet.rorg == RORG.BS1:
        # alternatively you can select FUNC and TYPE explicitely
        packet.select_eep(0x00, 0x01)
        # parse it
        packet.parse_eep()
        for k in packet.parsed:
            print('%s: %s' % (k, packet.parsed[k]))
    if packet.packet_type == PACKET.RADIO and packet.rorg == RORG.RPS:
        for k in packet.parse_eep(0x02, 0x02):
            print('%s: %s' % (k, packet.parsed[k]))
except queue.Empty:
    continue
except KeyboardInterrupt:
    break
except Exception:
    traceback.print_exc(file=sys.stdout)
    break

if communicator.is_alive():
communicator.stop()`

Create EnOceanStorage for storing learned devices

More specific issue, derived from #15.

@romor wrote:

  • in EnOcean, the sender address can be either a Unique ID (manufacturer chip-ID) or an address based on the Base-ID
  • the Base-ID can be set and read by COMMAN_COMMAND CO_WR_IDBASE (07) and CO_RD_IDBASE (08) and must be in range 0xFF800000-0xFFFFFF80 with the last 7 bits set to zero
  • these seven bits are used to emulate 128 IDs and are usually incremented for each device learnt, so one module can emulate 128 senders using the Base-ID
  • the actuator learns this unique Sender-ID during teach-in and uses this for addressing

So, I see two possible approaches for this enocean library:

  1. the callback specified above, which leaves the user the obligation to determine the address (or the offset to the base-ID) based on the destination address
  2. the enocean library maintains this mapping, which implies the need to store, read, reset,... this

I'll start working on a storage, which would take care of this. According to some tests, JSON seems to be fastest way of storing the data, so I propose we use it to implement the storage.

My proposed structure is something similar to this:

{
    "storage_version": 1,
    "used_transmitter_ids": [1, 4, 12],
    "devices": {
        "0xF6": {},
        "0xD5": {
            "01:64:18:39": {
                "func": "0x00",
                "type": "0x01",
                "transmitter_id": 4
            }
        },
        "0xA5": {
            "01:94:E3:B9": {
                "func": "0x02",
                "type": "0x05",
                "transmitter_id": 12
            },
            "01:94:E4:B9": {
                "func": "0x02",
                "type": "0x02",
                "transmitter_id": 1
            }
        }
    }
}

Is there anything that should be altered or added in the first implementation phase? This structure should be created in a way that future needs can be quite easily added. Also, I included a storage_version, which can be used to create any required conversions.

Create timing tests

As discussed in #15.

  • We should implement some kind of timing tests.
    • How long does it to parse, create, build a Packet?
    • How long does it to create a response packet to match a teach-in?
  • These tests could be then replicated on low-end hardware like the Raspberry Pi, to see if we can stick to the time constraints set by the specification.
    • If not, optimise, optimise, optimise... Though this should be done anyways, I know at least a few places to look 😝

Serial I/O error can't be detected as serial port runs in a thread

When there is an error on the serial port, as the serial port is in a thread, the serial.SerialException is not propagated to the calling thread. This means the serial thread continues to run, the port remain open a the calling thread is unaware of the issue.

Solution:
Change the code to exit the thread if there is an error, allowing the parent thread to restart it or raise the issue with the admin.

CRC8D for Radio_ERP1

Screen Shot 2021-02-23 at 11 16 14 PM

Hi,

I do not see a data CRC in here for Radio_ERP1 type in telegram or the ESP3 packet (on dolphinview). Is that not a part of the packet? I'm using the ESP3 packet shown in the above image as example as input but I see a failure when the CRC for data is calculated.

Create SUPPORTED_PROFILES.md

We could (and should) create a XML -> Markdown -generator, which would create SUPPORTED_PROFILES.md, allowing easier browsing of profiles through Github. In my opinion it should create something similar to the official documentation. Maybe leave out the bits, offsets etc, as they shouldn't be something the end-user ever touches (at least in the long run)...

Requesting A.C. Current Clamp EEP (D2-32-02) (FUNC 0x32 and TYPE 0x02)

I am already using this library for my other enocean sensors but I want to use the same for reading my enocean Current Transformers. But the func for 0x32 is not available for parsing. I would like to request for this to be added to the EEP.xml

I am not sure if I can do this myself, if yes please point me in a direction so that I can attempt this myself.

Thanks in advance.

Below I am pasting the xml file I found for the particular func 0x32 and type 0x02
I am unsure about how to convert this xml in the EEP.xml file format

    <profile>
    <rorg>
    <number>0xD2</number>
    <title>VLD Telegram</title>
    <telegram>VLD</telegram>
    
    <func>
    <number>0x32</number>
    <title>A.C. Current Clamp</title>
    <type>
        <number>0x02</number>
        <title>Type 0x02</title>
        <status>released</status>
        <description>
          <span style="background-color:#CDFF7D;border-bottom:2px groove #000000;font-style:italic;">
          Submitter: Pressac Communications Ltd</span>
          <br/>
          <br/>
          <img>graphics/D2-32-02.png</img>
          <br/>
          <span style="border-bottom:2px groove #000000;">Notes</span>
          <br/>1) If Power Fail bit is set, all channel readings will be set to
          zero when this final telegram is sent.
          <br/>2) Scale/divisor is set to 0 or 1 for all channels only, not individually.
        </description>
        <case>
          <datafield>
            <reserved/>
            <bitoffs>2</bitoffs>
            <bitsize>6</bitsize>
          </datafield>
          <datafield>
            <reserved/>
            <bitoffs>44</bitoffs>
            <bitsize>4</bitsize>
          </datafield>
          <datafield>
            <data>Power Fail</data>
            <shortcut>PF</shortcut>
            <description>See Note 1</description>
            <info/>
            <bitoffs>0</bitoffs>
            <bitsize>1</bitsize>
            <enum>
              <item>
                <value>0</value>
                <description>False</description>
              </item>
              <item>
                <value>1</value>
                <description>True</description>
              </item>
            </enum>
          </datafield>
          <datafield>
            <data>Divisor</data>
            <shortcut>DIV</shortcut>
            <description>Divisor for all channels</description>
            <info/>
            <bitoffs>1</bitoffs>
            <bitsize>1</bitsize>
            <enum>
              <item>
                <value>0</value>
                <description>x/1</description>
              </item>
              <item>
                <value>1</value>
                <description>x/10</description>
              </item>
            </enum>
          </datafield>
          <datafield>
            <data>Channel 1</data>
            <shortcut>CH1</shortcut>
            <description>Current value</description>
            <info/>
            <bitoffs>8</bitoffs>
            <bitsize>12</bitsize>
            <range>
              <min>0</min>
              <max>0xFFF</max>
            </range>
            <scale>
              <min>0</min>
              <max>4095 (409,5)</max>
            </scale>
            <unit>A</unit>
          </datafield>
          <datafield>
            <data>Channel 2</data>
            <shortcut>CH2</shortcut>
            <description>Current value</description>
            <info/>
            <bitoffs>20</bitoffs>
            <bitsize>12</bitsize>
            <range>
              <min>0</min>
              <max>0xFFF</max>
            </range>
            <scale>
              <min>0</min>
              <max>4095 (409,5)</max>
            </scale>
            <unit>A</unit>
          </datafield>
          <datafield>
            <data>Channel 3</data>
            <shortcut>CH3</shortcut>
            <description>Current value</description>
            <info/>
            <bitoffs>32</bitoffs>
            <bitsize>12</bitsize>
            <range>
              <min>0</min>
              <max>0xFFF</max>
            </range>
            <scale>
              <min>0</min>
              <max>4095 (409,5)</max>
            </scale>
            <unit>A</unit>
          </datafield>
        </case>
      </type></func></rorg><rorg>D2</rorg></profile>
    </eep>

Implement fetching of module ID

Every message should be send with the correct module ID, from which the message originates.
A simple test implementing this is created in f6825c4. However, it's not tested and thus isn't included in the Communicator initialization.

Once tested, the module ID should be fetched when initializing the Communicator. If ID is not set, sending of messages should be prevented.

I currently have no hardware for testing this, so help wanted.

Missing device class

So far I have a successful communication example of controlling an EnOcean actuator.
I seem to be missing a Devce class which would represent a device.

Use case example:

  1. Device object is initialised with profile and chipid received from the TEACHIN packet
  2. After a successful teach in procedure the physical device start sending DATA packets.
  3. Because the DATA packets are sent from a familiar chipid we map it to the Device object and have the profile for data packets.

I will start an implementation and if it matures will make a pull request

Create an Enum-range to EEP.xml.

We really need a new kind of Enum-variable, as VLD messages in particular seem to like to set enums up to 7 bits :S

The way I'd see this working is something like:

<enum description="Output value" shortcut="OV" offset="17" size="7">
  <item description="Output value 0% or OFF" value="0" />
  <item description="Output value {value}% or ON" start="1" end="100" />
  <item description="Not used" start="101" end="126" />
  <item description="output value not valid / not set" value="127" />
</enum>

So in essence, we would need a new item parser, which takes into account start and end of range and formats description accordingly. value -type isn't useful here, as it provides no possibility for error cases, and further more the enum really should correspond to an integer value instead of a float.

That functionality should correspond to what I'm currently (forced to) implementing:

<enum description="Output value" shortcut="OV" offset="17" size="7">
  <item description="Output value 0% or OFF" value="0" />
  <item description="Output value 1% or ON" value="1" />
  <item description="Output value 2% or ON" value="2" />
  <item description="Output value 3% or ON" value="3" />
  <item description="Output value 4% or ON" value="4" />
...
  <item description="Output value 99% or ON" value="99" />
  <item description="Output value 100% or ON" value="100" />
  <item description="Not used" value="101" />
  <item description="Not used" value="102" />
  <item description="Not used" value="103" />
...
  <item description="Not used" value="125" />
  <item description="Not used" value="126" />
  <item description="output value not valid / not set" value="127" />
</enum>

Please create changelog and tag release versions

There are no releases tagged in Git or releases on Github for this package, yet there are several releases published on PyPi. I tried using one of the examples under the examples/ src directory with the latest release from PyPi but it appears there are significant changes in this repo since the last published release. Without a changelog or tags it's very difficult to see what's changed between any of the published releases or even to correlate a git revision with any published release.

If you could please create tags for existing releases (or even the latest release!) then I can at least look at the examples folder as it existed for the latest published release in PyPi. Thanks!

Raw packet sending

Hello,

I like you package but I need to send raw packages without adding them to EEP.xml. Is there such way possible at this moment?

I somehow hacked this inside because I wasn't able to find anything such. Would you welcome and accept this enhancement as PR?

Thank you,
Vojtech

Restructure Packet

As discussed in #14.

@kipe wrote:

Might need to change the Packet.data to Packet.message and create a new Packet.data to reflect the actual, documented data? This would be a very major change, which I'm a bit reluctant to do. On the other hand, it would be fairly easy to do at this point and way more logical (for example, Packet.optional_data, Packet.sender etc already point to the correct data)...

@romor wrote:

Packet could then only consist of Packet.message while data, rorg, status,... could all be properties just accessing the corresponding entry in Packet.message. Alternatively it could be the other way round such that Packet holds data, rorg, status, ... and Packet.message could just be generated from the other variables. The seconds looks more reasonable to me.

Not sure which way this should be handled, as it's largely dependent on whether we're sending or receiving the message...

direction field in EEP

The interpretation of some EEPs is not sufficiently specified with RORG, FUNC and TYPE but needs an additional direction flag (see e.g. A5-20-01).

How could this be covered best?
By an optional directionattribute of the profile xml tag?
Or an optional direction tag as a child of the profile xml tag?

PTM215 DB sending teach-in requests

Hi all,

i'm coming from https://github.com/romor/enocean-mqtt where I have an issue with a PTM215 DB Switch. That repository is based on kipe/enocean and it receives the parsed RF messages.

Enocean-mqtt always tells me, that the incoming request is a learn request. The maintainer suggested to start a discussion here if such a switching actuator should raise teach-in requests at all.

Any ideas?

thanks

Log of enocean_example.py

2017-06-28 09:34:38,870 - enocean.communicators.SerialCommunicator - DEBUG - FE:F9:59:1B->FF:FF:FF:FF (-48 dBm): 0x01 ['0xf6', '0x30', '0xfe', '0xf9', '0x59', '0x1b', '0x30'] ['0x3', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()
R1: {u'value': u'Button AO', u'description': u'Rocker 1st action', u'unit': u'', u'raw_value': 1}
EB: {u'value': u'pressed', u'description': u'Energy bow', u'unit': u'', u'raw_value': 1}
R2: {u'value': u'Button AI', u'description': u'Rocker 2nd action', u'unit': u'', u'raw_value': 0}
SA: {u'value': u'No 2nd action', u'description': u'2nd action', u'unit': u'', u'raw_value': 0}
T21: {u'value': True, u'description': u'T21', u'unit': u'', u'raw_value': 1}
NU: {u'value': True, u'description': u'NU', u'unit': u'', u'raw_value': 1}
2017-06-28 09:34:39,211 - enocean.communicators.SerialCommunicator - DEBUG - FE:F9:59:1B->FF:FF:FF:FF (-48 dBm): 0x01 ['0xf6', '0x0', '0xfe', '0xf9', '0x59', '0x1b', '0x20'] ['0x3', '0xff', '0xff', '0xff', '0xff', '0x30', '0x0'] OrderedDict()
R1: {u'value': u'Button AI', u'description': u'Rocker 1st action', u'unit': u'', u'raw_value': 0}
EB: {u'value': u'released', u'description': u'Energy bow', u'unit': u'', u'raw_value': 0}
R2: {u'value': u'Button AI', u'description': u'Rocker 2nd action', u'unit': u'', u'raw_value': 0}
SA: {u'value': u'No 2nd action', u'description': u'2nd action', u'unit': u'', u'raw_value': 0}
T21: {u'value': True, u'description': u'T21', u'unit': u'', u'raw_value': 1}
NU: {u'value': False, u'description': u'NU', u'unit': u'', u'raw_value': 0}

Error while receiving package

Hi,

I get an error while receiving package from Hoppe Window handle (rorg=0xF6func=10, type=00):

root@raspberrypi:/home/pi# python3.4 /usr/local/bin/enocean_example.py
2017-02-06 19:57:19,529 - enocean.communicators.SerialCommunicator - INFO - SerialCommunicator started
2017-02-06 19:57:19,529 - enocean.protocol.packet - WARNING - Replacing Packet.optional with default value.
2017-02-06 19:57:19,630 - enocean.communicators.SerialCommunicator - INFO - Sending packet
2017-02-06 19:57:19,630 - enocean.communicators.SerialCommunicator - DEBUG - 0x05 ['0x8'] [] OrderedDict()
2017-02-06 19:57:19,732 - enocean.communicators.SerialCommunicator - DEBUG - 0x02 ['0x0', '0xff', '0xb2', '0x78', '0x80'] ['0xa'] OrderedDict()
The Base ID of your module is FF:B2:78:80.
.....

2017-02-06 19:58:05,549 - enocean.communicators.SerialCommunicator - DEBUG - 01:8E:56:0D->FF:FF:FF:FF (-74 dBm): 0x01 ['0xf6', '0xe0', '0x1', '0x8e', '0x56', '0xd', '0x20'] ['0x2', '0xff', '0xff', '0xff', '0xff', '0x4a', '0x0'] OrderedDict()
Traceback (most recent call last):
File "/usr/local/bin/enocean_example.py", line 52, in
for k in packet.parse_eep(0x02, 0x02):
File "/usr/local/lib/python3.4/dist-packages/enocean/protocol/packet.py", line 272, in parse_eep
provides, values = self.eep.get_values(self._profile, self._bit_data, self._bit_status)
File "/usr/local/lib/python3.4/dist-packages/enocean/protocol/eep.py", line 199, in get_values
output.update(self._get_enum(source, bitarray))
File "/usr/local/lib/python3.4/dist-packages/enocean/protocol/eep.py", line 97, in _get_enum
'value': value_desc['description'].format(value=raw_value),
TypeError: 'NoneType' object is not subscriptable
2017-02-06 19:58:05,655 - enocean.communicators.SerialCommunicator - INFO - SerialCommunicator stopped

receiving a package from not defined device (D2-06-01) I get normal debug messages - without errors.

Any idea what can be wrong?

I have used the Zip file and extracted, because installed files were older (and shorter)

Michael

Print the profile parameters as defined in the xml

When new people are exploring EnOcean and the library it would be very practical if the print of p.parsed would align to the order in the xml.
And the xml to follow the order specified in the protocol documentation :)

Issue with python 3.4+

When installing this package, I received an error and after a bit of googling I found the cause for the error here:
altdesktop/i3ipc-python#15

As far as I'm concerned, it is only an issue for python 3.4(+?).
So I suggest to replace enum34 with enum-compat :)
Thanks for the app anyway

A5-12-01 (pressac variation) showing as temperature sensor?

I am using one of these http://www.pressac.com/current-transducer-enocean-ct-clamp which seems to be found as a temperature sensor:

2017-09-02 12:38:53,976 - enocean.communicators.SerialCommunicator - DEBUG - 01:85:8D:92->FF:FF:FF:FF (-80 dBm): 0x01 ['0xa5', '0x0', '0x0', '0x12', '0x5d', '0x1', '0x85', '0x8d', '0x92', '0x0'] ['0x1', '0xff', '0xff', '0xff', '0xff', '0x50', '0x0'] OrderedDict()
TMP: {u'value': 37.1764705882353, u'description': u'Temperature (linear)', u'unit': u'\xb0C', u'raw_value': 18}

Any idea why?. Using your latest enocean library(thanks!)

Re-structure Communicator

Based on discussion in 3bc2957

@romor wrote:

Just my impression: I do not think that it is a nice solution to store a reference to communicator in UTETeachIn class. It could be provided as an argument to send_response() instead.

But even this is not nice, IMO. I do not think that a Packet class should autonomously send radio packets. I think this should be handled by the Communicator class instead.

@kipe wrote:

Good points, and I agree with you.
Communicator should indeed handle all sending and receiving, however I'm not sure if it's possible to implement without a reference at the moment. As the implementation is currently, the base Communicator doesn't implement any kind of loop. This makes it difficult to implement any kind of "packet interception" to the Communicator (I'd like all communicators to behave the same).

One option would be to call something like Communicator.send_responses() on each loop in the implementations. This would then check, if there's responses to be sent and sent them.

Another option would be to re-structure the communicators to implement a SerialCommunicator.loop() or something like that, which would take care of the implementation specific behavior, while Communicator.run() would implement the main loop. In this implementation, SerialCommunicator.loop() would return a list of new packages to be parsed, and Communicator.run() would take care of handling them (mainly putting to receive -queue), sending a response as needed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.