Menu

Any feature/improvement requests are welcome

jef2000
2007-10-16
2012-12-14
  • jef2000

    jef2000 - 2007-10-16

    Hi,

    I hope the choices I made in the development of this project will satisfy as many users as possible. But in case an interesting  feature is missing or you feel something could be improved, don't hesitate to tell it.

    Thanks,

    Jean-François

     
    • uidas

      uidas - 2007-10-24

      Hi,

      You have made a very good job with linknx.

      I have one question.

      How can I add a listening group address to an object? Each object could have a sending group address and several listening group addresses.

      Some actuators have a status object than send a telegram when the state of the ouput changes. 

      Could it be done with the current linknx version ?

       
    • jef2000

      jef2000 - 2007-10-24

      Hi,

      I already discussed this kind of problem with on forums, and of course I could implement something in Linknx to deal with that, but I first would like to focus on real situations where this happens to be sure we are solving this problem the right way. Could you explain me the details of your situation so that I can see if it correspond to what I have already seen.
      To illustrate the problem I know, suppose that you have an installation with an actuator controlling staircase lighting. When you push the button, the light turns on, if you push it again, it turns off, and if you let it on it will turn off automatically after 10 minutes. The 10 minutes timer is programmed inside the actuator, but in case the 1 min timeout shutdown the light the actuator doesn't transmit the new state, and due to this the button doesn't know the light is off. In that case, nothing will happen if you push the button because the pushbutton thinks the light is still on and it will send an "off" message on the bus. There are multiple ways to solve this problem by using the "status feedback" object of the actuator:
      1) What I did in my own installation is to set the "status feedback" with the same group address as the output and the pushbutton. In that case, everything works fine.
      2) I heard about other people that define a different group-address for the "status feedback" and set this group address as second groups address for the same object of the pushbutton device.
      Is it what you are doing? In that case, I can understand the need for a second group address. I find the first solution simpler, but perhaps there are case where it doesn't work, that's why I ask you to describe your own problem.

      Perhaps I should re-design this part of Linknx to match what is implemented in BCU's:
      >Allow to set multiple group addresses on one object
      >Only the first one is be able to send telegrams, the other ones only receive
      >Define a set of Read/Write/Transmit/Update/... flags for each communication object

      This would be the most flexible solution, but is it really needed to have that much flexibility?

       
    • uidas

      uidas - 2007-10-29

      Hi,

      I usually use different group addresses for the "status feedback" objects but I can't really explain why :( All the installations I've seen are done this way.

      In my own installation I use staircase functions and an additional address for the status object. I think I could use your solution, It's simpler.

      I'll search a situation where this solution can't be applied and I'll ask the people teached me EIB. 

       
      • jef2000

        jef2000 - 2007-10-30

        I discussed it with other people on a French forum (http://groups.google.be/group/domotique-EIB/browse_thread/thread/e56e978a2028c3f0#)
        and it seems that using a second group address on a communication object is "the" way to do it. I'll try to allow it in Linknx when I have time.

         
      • jef2000

        jef2000 - 2007-11-07

        Hi,

        It's now possible to add a listening group address to an object. I just finished implementing it. I did some basic test on it and it seems to work as expected. Here's an example  of configuration:

                <object id="ecl_escalier" gad="1/1/6">Eclairage Escalier
                    <listener gad="1/1/206"/>
                </object>
                <object id="status_ecl_escalier" gad="1/1/206">Eclairage Escalier (status feedback)</object>

        With this config, any info received for 1/1/206 will also update internal state of object "ecl_escalier" (without sending a write telegram for address 1/1/6 on the bus.). If "ecl_escalier" is modified, it will only send a write telegram for group address 1/1/6, not 1/1/206

        Kr,

        Jean-François

         
    • the_ulli

      the_ulli - 2007-11-15

      Hello,
      my request is a EIS15 Object to write an 14 Byte Ascii on GA. The Goal is a interface to
      a MT701 to display any schedule for my family.

      Your Project is fine in design and code. Here the Linknx is running on a ASUS WL500GP
      with a Kamikaze 7.09 with the follow Makefile and patches.

      Wath do you think about a small schedule???

      Regards, Matthias Friedrich

      # $Id: Makefile 1146 2005-06-05 13:32:28Z nbd $

      include $(TOPDIR)/rules.mk

      PKG_NAME:=linknx
      PKG_VERSION:=0.0.1.19
      PKG_RELEASE:=1
      PKG_MD5SUM:=b88488397145425b0c742c2026945fc1

      PKG_SOURCE_URL:=http://garr.dl.sourceforge.net/sourceforge/linknx
      PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
      PKG_CAT:=zcat

      PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

      include $(INCLUDE_DIR)/package.mk

      define Package/linknx
        SECTION:=net
        CATEGORY:=Network
        TITLE:=KNX home automation platform
        URL:=http://www.ouaye.net/linknx
      endef

      define Build/Configure
          $(call Build/Configure/Default,--without-pth-test --with-pth=$(STAGING_DIR),\                         CXXFLAGS="$(TARGET_CFLAGS) -fno-builtin+ -nostdinc++" \                         CPPFLAGS="-I$(BUILD_DIR)/uClibc++-0.2.2/include -I$(STAGING_DIR)/usr/include -I$(STAGING_DIR)/include" \                         LDFLAGS="-nodefaultlibs -L$(STAGING_DIR)/usr/lib -L$(STAGING_DIR)/lib -lesmtp -luClibc++ -lc -lm -lgcc")
      endef

      define Build/Compile
          $(call Build/Compile/Default)
      endef

      define Package/linknx/install
          mkdir -p $(1)/usr/bin
          $(CP) $(PKG_BUILD_DIR)/src/linknx $(1)/usr/bin/
          mkdir -p $(1)/tmp
          $(CP) $(PKG_BUILD_DIR)/conf/linknx.xml $(1)/tmp/
      endef

      $(eval $(call BuildPackage,linknx))

      >>schnipp - patch1
      --- linknx/src/objectcontroller.cpp
      +++ linknx-0.0.1.19/src/objectcontroller.cpp
      @@ -51,6 +51,8 @@
               return new ScalingObject();
           else if (type == "heat-mode")
               return new HeatingModeObject();
      +    else if (type == "EIS15")
      +        return new StringObject();
           else
               return 0;
      }
      @@ -338,6 +340,33 @@
           out << value_m;
           return out.str();
      }
      +
      +//friedrich
      +StringObjectValue::StringObjectValue(const std::string& value)
      +{
      +    value_m =  value;
      +    std::cout << "StringObjectValue: Value: '" << value_m << "'" << std::endl;
      +
      +/*    std::istringstream val(value);
      +    val >> value_m;
      +
      +    if ( val.fail())// || !val.eof())// || value_m > 670760.96 || value_m < -671088.64)
      +    {
      +        std::stringstream msg;
      +        msg << "StringObjectValue: Bad value: '" << value << "'" << std::endl;
      +        throw ticpp::Exception(msg.str());
      +    }
      +*/
      +}
      +
      +std::string StringObjectValue::toString()
      +{
      +    std::ostringstream out;
      +    out.precision(8);
      +    out << value_m;
      +    return out.str();
      +}
      +//friedrich

      ScalingObjectValue::ScalingObjectValue(const std::string& value)
      {
      @@ -928,6 +957,106 @@
           }
      }

      +//friedrich
      +StringObject::StringObject() : value_m(0)
      +{}
      +
      +StringObject::~StringObject()
      +{}
      +
      +void StringObject::exportXml(ticpp::Element* pConfig)
      +{
      +    Object::exportXml(pConfig);
      +    pConfig->SetAttribute("type", "EIS15");
      +}
      +
      +ObjectValue* StringObject::createObjectValue(const std::string& value)
      +{
      +    return new StringObjectValue(value);
      +}
      +
      +bool StringObject::equals(ObjectValue* value)
      +{
      +    assert(value);
      +    StringObjectValue* val = dynamic_cast<StringObjectValue*>(value);
      +    if (val == 0)
      +    {
      +        std::cout << "StringObject: ERROR, equals() received invalid class object (typeid=" << typeid(*value).name() << ")" << std::endl;
      +        return false;
      +    }
      +    if (!init_m)
      +        read();
      +    std::cout << "StringObject (id=" << getID() << "): Compare value_m='" << value_m << "' to value='" << val->value_m << "'" << std::endl;
      +    return value_m == val->value_m;
      +}
      +
      +void StringObject::setValue(ObjectValue* value)
      +{
      +    assert(value);
      +    StringObjectValue* val = dynamic_cast<StringObjectValue*>(value);
      +    if (val == 0)
      +        std::cout << "StringObject: ERROR, setValue() received invalid class object (typeid=" << typeid(*value).name() << ")" << std::endl;
      +    setStringValue(val->value_m);   
      +}
      +
      +void StringObject::setValue(const std::string& value)
      +{
      +    setStringValue(value);   
      +}
      +
      +std::string StringObject::getValue()
      +{
      +    return value_m;
      +}
      +
      +void StringObject::setStringValue(const std::string& value)
      +{
      +    if (!init_m || value != value_m || forcewrite_m)
      +    {
      +        value_m = value;
      +    int count = 16;
      +   
      +        std::cout << "StringObject: Value: " << value_m << std::endl;
      +        uint8_t buf[count];
      +    memset(buf,0,sizeof(uint8_t)*count);
      +    buf[1] = 0x80;
      +   
      +    // Convert to hex
      +    for(int j=0;j<value_m.length();j++)
      +    {
      +        buf[j+2] = (int)value_m[j];
      +    }
      +   
      +        Services::instance()->getKnxConnection()->write(getGad(), buf, count);
      +        init_m = true;
      +        onUpdate();
      +    }
      +}
      +
      +void StringObject::onWrite(const uint8_t* buf, int len, eibaddr_t src)
      +{
      +    if (len < 4)
      +    {
      +        std::cout << "Invlalid packet received for StringObject (too short)" << std::endl;
      +        return;
      +    }
      +    /*double newValue;
      +    Object::onWrite(buf, len, src);
      +    int d1 = ((unsigned char) buf[2]) * 256 + (unsigned char) buf[3];
      +    int m = d1 & 0x7ff;
      +    if (d1 & 0x8000)
      +        m |= ~0x7ff;
      +    int ex = (d1 & 0x7800) >> 11;
      +    newValue = ((double)m * (1 << ex) / 100);
      +    if (!init_m || newValue != value_m)
      +    {
      +        std::cout << "New value " << newValue << " for value object " << getID() << std::endl;
      +        value_m = newValue;
      +        init_m = true;
      +        onUpdate();
      +    }*/
      +}
      +//friedrich
      ScalingObject::ScalingObject() : value_m(0)
      {}
      <<schnipp

      >>schnipp - patch2
      --- linknx/src/objectcontroller.h
      +++ linknx-0.0.1.19/src/objectcontroller.h
      @@ -244,7 +244,26 @@

           virtual void exportXml(ticpp::Element* pConfig);
      };
      -
      +//friedrich
      +class StringObject : public Object
      +{
      +public:
      +    StringObject();
      +    virtual ~StringObject();
      +
      +    virtual ObjectValue* createObjectValue(const std::string& value);
      +    virtual bool equals(ObjectValue* value);
      +    virtual void setValue(ObjectValue* value);
      +    virtual void setValue(const std::string& value);
      +    virtual std::string getValue();
      +    void setStringValue(const std::string& val);
      +    virtual void exportXml(ticpp::Element* pConfig);
      +
      +    virtual void onWrite(const uint8_t* buf, int len, eibaddr_t src);
      +protected:
      +    std::string value_m;
      +};
      +//friedrich
      class SwitchingObjectValue : public ObjectValue
      {
      public:
      @@ -310,6 +329,21 @@
           friend class ValueObject;
           double value_m;
      };
      +
      +//friedrich
      +class StringObjectValue : public ObjectValue
      +{
      +public:
      +    StringObjectValue(const std::string& value);
      +    virtual ~StringObjectValue() {};
      +    virtual std::string toString();
      +protected:
      +//    StringObjectValue(std::string value) : value_m(value) {};
      +    friend class StringObject;
      +    std::string value_m;
      +};
      +//friedrich
      +

      class ScalingObjectValue : public ObjectValue
      {
      <<schnipp

       
      • jef2000

        jef2000 - 2007-11-15

        Hi,

        And thanks for the patch, it's always pleasant to have good feedback on what I did.
        I integrated your patches for EIS15 in the CVS repository. It will be part of next release. Can you explain a little bit what is your project? When I have feedback on how people want to use Linknx, It's easier for me to make the right design decisions.

        Kr,

        Jean-François

         
    • uidas

      uidas - 2007-11-27

      Hi,

      I think an interesting option could be sending UDP datagrams in action sections.

      I've been testing gnokii-smsd with a Linksys NLSU2. It can receive SMS messages and execute scripts (modify linknx objects using XML interface), but cannot send messages when linknx's actions happens. I think I can make a program that listens a UDP socket, waits for specific data and, process it, and send a SMS.

      Useful data in UDP datagrams could be object values, or strings defined by user in xml configuration file.

      Another utility could be a serial interface, IR TX/RX, etc.

      I suppose it can be done using some TCP subscription utility. A program subscribes to some linknx objects, so, if one of them changes, linknx sends data through the connection. I don't know if TCP connections could cause problems. 

      I've compiled pthsem, eibd and linknx in NSLU2 platform and seems is working fine, I'll publish .mk files to build ipks soon (.ipk files too).

      Regards

       
    • jef2000

      jef2000 - 2007-11-27

      Hi,

      Wouldn't it be easier to use the ShellCommandAction?
      Something like
      <action type="shell-cmd" cmd="send-sms 'this is the message text'"/>

      I know that for the moment it's only possible to use a predefined text and there is no way to include an object value or something like that inside the shell command.
      For this, you could call a php (or other) script using "shell-cmd" action. this script would connect to linknx on TCP port 1028, ask the needed object(s) value(s) using the XML protocol, then format and send the SMS. Its a little bit tricky but should work.

      I agree that it would be nice to have a subscription mechanism to allow an application to connect on linknx and register itself to be notified each time the value of a specified object changes. I write it down on the TODO list.

      Regards,

      Jean-François

       
    • uidas

      uidas - 2007-11-28

      Hi,

      I've just read the source code. I didn't know about this action command. This is a simple way of sending IR codes, serial commands, object change notifications ...

      Thanks

       
    • skysurfer_14

      skysurfer_14 - 2007-12-11

      Hi Jean-François,

      i'm hooked about your software.
      I have it running on a WRT54G v4 with direct connection to a BCU2.

      Next time i want to send alarms as an email, but i see the problem, that the email account that i want to use (gmx.de), needs a password for smtp. Alternative SMTP after POP is possible. Can you add the password function to the email-command. Or is there a simple way to use other smtp-function with "shell-cmd"?

      Best regards,
      Christoph

       
    • jef2000

      jef2000 - 2007-12-12

      I added SMTP auth in linknx-0.0.1.22.
      By adding login="xxxx" and pass="yyy" in config of emailserver.
      <emailserver type="smtp" host="mail.gmx.net:25" from="you@gmx.net" login="your_id" pass="your_password"/>

       
      • skysurfer_14

        skysurfer_14 - 2007-12-14

        Thanks, its working fine!

         

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.