I went with your suggestion, its definitely a work in progress, but there is progress.
I have a nano with DHT22 sensor and a relay for heating on/off.
I played with the I_Arduino.xml and L_Arduino.lua files and added
HVAC = {26, "urn:schemas-upnp-org:device:HVAC_ZoneThermostat:1", "D_HVAC_ZoneThermostat1.xml", "HVAC "}
HVAC = {40, "urn:upnp-org:serviceId:TemperatureSetpoint1", "CurrentSetpoint", "" }
function SetTheNewHvacTemp(device, NewCurrentSetpoint)
sendCommand(luup.devices[device].id,"HVAC",NewCurrentSetpoint)
end
to L_Arduino.lua
and
<action>
<serviceId>urn:upnp-org:serviceId:TemperatureSetpoint1</serviceId>
<name>SetCurrentSetpoint</name>
<job>
if (p ~= nil) then p.SetTheNewHvacTemp(lul_device, lul_settings.NewCurrentSetpoint) end
return 4,0
</job>
</action>
to I_Arduino.xml
Also added V_HVAC and S_HVAC to MyMessage.h for Arduino.
And I get this on Vera Edge UI7
As of now I can change the setpoint, although it comes back from the node as 27.6 which throws off the vera temp display, makes it 2 line but shows it, I can also send the states "CoolOn", "HeatOn" and so on.
I haven't worked out how to get the temp on the card instead of separate, or the battery level yet.
Here is serial from node
Here is my node sketch
#include <SPI.h>
#include <MySensor.h>
#include <DHT.h>
#include <Bounce2.h>
#define NODE_ID AUTO
#define SKETCH_NAME "MySensor_Heater"
#define SKETCH_VERSION "1.1"
#define NODE_REPEAT true
#define CHILD_ID_HUM 0
#define CHILD_ID_TEMP 1
#define CHILD_ID_HVAC 2
#define CHILD_ID_BATT 3
#define CHILD_ID_HEATER_SW 4
#define HUMIDITY_SENSOR_DIGITAL_PIN 3
#define RELAY_PIN 4 // Arduino Digital I/O pin number for relay
#define BUTTON_PIN 5 // Arduino Digital I/O pin number for button
#define RELAY_ON 0
#define RELAY_OFF 1
unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
Bounce debouncer = Bounce();
int oldValue=0;
bool state;
MySensor gw;
DHT dht;
float lastTemp;
float lastHum;
boolean metric = true;
unsigned long CHECK_TIME = millis();
String heaterMode = "Off";
int setPoint = 20;
MyMessage msgHum(CHILD_ID_HUM, V_HUM);
MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
MyMessage msgHeaterSW(CHILD_ID_HEATER_SW,V_HEATER_SW);
//MyMessage msgHeaterState(CHILD_ID_HEATER_STATE,V_HEATER);
MyMessage msgHvac(CHILD_ID_HVAC, V_HVAC);
MyMessage msgBattery(CHILD_ID_BATT, I_BATTERY_LEVEL);
void setup()
{
gw.begin(incomingMessage,NODE_ID,NODE_REPEAT);
dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
// Send the Sketch Version Information to the Gateway
gw.sendSketchInfo(SKETCH_NAME, SKETCH_VERSION);
// Setup the button
pinMode(BUTTON_PIN,INPUT);
// Activate internal pull-up
digitalWrite(BUTTON_PIN,HIGH);
// After setting up the button, setup debouncer
debouncer.attach(BUTTON_PIN);
debouncer.interval(5);
// Register all sensors to gw (they will be created as child devices)
gw.present(CHILD_ID_HUM, S_HUM);
gw.present(CHILD_ID_TEMP, S_TEMP);
//gw.present(CHILD_ID_HEATER_SW, S_HEATER);
//gw.present(CHILD_ID_HEATER_STATE, S_HEATER);
gw.present(CHILD_ID_HVAC, S_HVAC);
metric = gw.getConfig().isMetric;
// Make sure relays are off when starting up
digitalWrite(RELAY_PIN, RELAY_OFF);
// Then set relay pins in output mode
pinMode(RELAY_PIN, OUTPUT);
// Set relay to last known state (using eeprom storage)
//state = gw.loadState(CHILD_ID);
//digitalWrite(RELAY_PIN, state?RELAY_ON:RELAY_OFF);
}
void loop()
{
gw.process();
debouncer.update();
// Get the update value
int value = debouncer.read();
if (value != oldValue && value==0) {
gw.send(msgHvac.set(state?false:true), true); // Send new state and request ack back
}
oldValue = value;
// Check Temp and Humidity sensor every set ammount of time
unsigned long NOW_TIME = millis();
if(NOW_TIME - CHECK_TIME >= SLEEP_TIME) {
getTemps();
CHECK_TIME = NOW_TIME;
}
}
void getTemps(){
delay(dht.getMinimumSamplingPeriod());
float temperature = dht.getTemperature();
if (isnan(temperature)) {
Serial.println("Failed reading temperature from DHT");
} else if (temperature != lastTemp) {
lastTemp = temperature;
if (!metric) {
temperature = dht.toFahrenheit(temperature);
}
gw.send(msgTemp.set(temperature, 1));
//gw.send(msgHvac.set(temperature, 1));
gw.send(msgBattery.set(65, 1));
Serial.print("T: ");
Serial.println(temperature);
}
float humidity = dht.getHumidity();
if (isnan(humidity)) {
Serial.println("Failed reading humidity from DHT");
} else if (humidity != lastHum) {
lastHum = humidity;
gw.send(msgHum.set(humidity, 1));
Serial.print("H: ");
Serial.println(humidity);
}
//gw.sleep(SLEEP_TIME); //sleep a bit
}
void incomingMessage(const MyMessage &message) {
Serial.println(message.type);
//Serial.println(message.value);
// We only expect one type of message from controller. But we better check anyway.
if (message.isAck()) {
Serial.println("This is an ack from gateway");
}
if (message.type == V_HVAC) {
// Change relay state
Serial.println("Message received");
setPoint = String(message.data).toInt();
Serial.println("New Set Temp is : " + String(setPoint));
gw.send(msgHvac.set(setPoint, 1));
// Store state in eeprom
//gw.saveState(CHILD_ID, state);
// Write some debug info
Serial.print("Incoming change for sensor:");
Serial.print(message.sensor);
Serial.print(", New status: ");
Serial.println(message.data);
}
if (message.type == V_HEATER_SW) {
Serial.println("Switch Message received");
Serial.println(String(message.data));
if(String(message.data) == "HeatOn"){
Serial.println("Heating ON");
digitalWrite(RELAY_PIN, RELAY_ON);
//gw.send(msgHeaterSW.set("HeatOn", 1));
}
if(String(message.data) == "CoolOn"){
Serial.println("Heating OFF");
digitalWrite(RELAY_PIN, RELAY_OFF);
//gw.send(msgHeaterSW.set("CoolOn", 1));
}
}
}
L_Arduino.lua
I_Arduino1.xml
MyMessage.h
I have a couple of StellaZ Zwave radiator thermostats that use the hvac files, and they have many variables for temps and batteries and setpoints, but it is beyond me how to enable these for the mysensors nodes.
We also need to be able to add a scene that goes
If currentTemp is > currentSetpoint
Turn on heat
and looking at scenes to switch on heating, it seems you have to add a temp to create a scene involving temperature. I don't know LUUA code at all at the moment so I do not know if you can create a function that ignores the temp you had to add to create it and looks at current temp and setpoint. babbling now.
Over to you