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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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"/>
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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 ?
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?
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.
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.
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
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
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
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
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
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
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
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"/>
Thanks, its working fine!