Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

eq3device/eq3interface: #12

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
83 changes: 78 additions & 5 deletions lib/eq3device.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ let EQ3BLE = function(device) {
}

EQ3BLE.is = function(peripheral) {
return peripheral.advertisement.localName === 'CC-RT-BLE'
var res = (peripheral.advertisement.localName === 'CC-RT-BLE')||(peripheral.advertisement.localName === 'CC-RT-M-BLE');
return res;
}

NobleDevice.Util.inherits(EQ3BLE, NobleDevice)
Expand Down Expand Up @@ -74,48 +75,120 @@ EQ3BLE.prototype.connectAndSetup = function() {
})
}


// ALL sends now result in a parsed response.
// al pafrsed responses include 'raw' for diagnostic purposes
// possible responses:
// 00 => { unknown:true, raw: }
// 01 => { sysinfo:{ ver:,type: },raw: }
// 02 01 => { raw:, status: { manual:,holiday:,boost:,lock:,dst:,openWindow:,lowBattery:,valvePosition,targetTemperature,ecotime: <Date if in holiday mode>,},
// valvePosition,targetTemperature } (last two for legacy use)
// 02 02 => { raw:, dayresponse:{ day:<day 0=sat>} }
// 02 80 => { raw:, ok:true }
// 04 => { raw:, timerequest:true }
// 21 => { raw:, dayschedule: { day:<day 0=sat>, segments:[7 x {temp:<temp>, endtime:{ hour:<hour>, min:<min>}}, ...]}}
// A0 -> { firwareupdate:true, raw:info }
// A1 -> { firwareupdate:true, raw:info }

// this sets the date; else the date can get set to old data in the buffer!!!
EQ3BLE.prototype.getInfo = function() {
return this.writeAndGetNotification(eq3interface.payload.getInfo())
.then(info => eq3interface.parseInfo(info))
return this.writeAndGetNotification(eq3interface.payload.setDatetime(new Date()))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

breaks setDateTime(date)?!

setting the date will overwritten everytime one tries to get the info.

Is this still true since you changed the getInfo buffer from 0x03 to 0x00?

// this sets the date; else the date can get set to old data in the buffer!!!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with the right date? not sure how else to trigger the status :). just copying the android app....

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, let me get back to you. I had some very nice reverse-engineered documents from someone else somewhere.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All right, I believe the engineers made the decision to update the thermostats clock whenever a phone is connected. Mixing responsibilities of functions is not a very nice thing to do...

By the way, the documentation I mentioned: https://github.com/Heckie75/eQ-3-radiator-thermostat/blob/master/eq-3-radiator-thermostat-api.md

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice documentation. I'm sure we don't cover it all.

.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
// gets version, returns 01 resp
EQ3BLE.prototype.getSysInfo = function() {
return this.writeAndGetNotification(eq3interface.payload.getSysInfo())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.setBoost = function(enable) {
if (enable) {
return this.writeAndGetNotification(eq3interface.payload.activateBoostmode())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
return this.writeAndGetNotification(eq3interface.payload.deactivateBoostmode())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.automaticMode = function() {
return this.writeAndGetNotification(eq3interface.payload.setAutomaticMode())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.manualMode = function() {
return this.writeAndGetNotification(eq3interface.payload.setManualMode())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.ecoMode = function() {
return this.writeAndGetNotification(eq3interface.payload.setEcoMode())

// sending ecoMode() empty just turns on holiday mode (holiday+manual).
// sending with just temp ecoMode(12) turns on holiday mode, returns a time? (now+1day?)
// - bad news, old data!
// sending with empty temp and date ecoMode(0, date) turns on holiday mode (holiday+manual),
// but does not return a date (same as ecoMode()?)
// I think if the command is 'short', it can use bytes from the last command instead!!!
// so, always do ecoMode() or ecoMode(temp, date)
EQ3BLE.prototype.ecoMode = function(temp, date) {
return this.writeAndGetNotification(eq3interface.payload.setEcoMode(temp, date))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.setLock = function(enable) {
if (enable) {
return this.writeAndGetNotification(eq3interface.payload.lockThermostat())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
return this.writeAndGetNotification(eq3interface.payload.unlockThermostat())
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.turnOff = function() {
return this.setTemperature(4.5)
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.turnOn = function() {
return this.setTemperature(30)
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}
EQ3BLE.prototype.setTemperature = function(temperature) {
return this.writeAndGetNotification(eq3interface.payload.setTemperature(temperature))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// +-7 degrees

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't resist

Suggested change
// +-7 degrees
// temerature offset ranging from -7 to +7 degrees celsius

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree; expect in your pull request :)

EQ3BLE.prototype.setTemperatureOffset = function(offset) {
return this.writeAndGetNotification(eq3interface.payload.setTemperatureOffset(offset))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// duration in minutes
EQ3BLE.prototype.updateOpenWindowConfiguration = function(temperature, duration) {
return this.writeAndGetNotification(eq3interface.payload.setWindowOpen(temperature, duration))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// set date and return status
EQ3BLE.prototype.setDateTime = function(date) {
return this.writeAndGetNotification(eq3interface.payload.setDatetime(date))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// schedule functions
// retrieve schedule for a day, where day=0 = saturday
// responds with 21 (see above) day like below (setDay)
EQ3BLE.prototype.getDay = function(day) {
return this.writeAndGetNotification(eq3interface.payload.getDay(day))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// set schedule for a day
// day is { day: <daynum, 0=sat>, segments:[7 x {temp:<temp>, endtime:{ hour:<hour>, min:<min>}}, ...]}
// responds 02 02 (see top)
EQ3BLE.prototype.setDay = function(day) {
return this.writeAndGetNotification(eq3interface.payload.setDay(day))
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}

// a raw send function; so we can spoof anything
EQ3BLE.prototype.sendRaw = function(buf) {
return this.writeAndGetNotification(buf)
.then(info => eq3interface.parseInfo(info), err => {return { error: err }});
}



module.exports = EQ3BLE
Loading