openLuup: Tasmota MQTT Bridge
-
@therealdb said in openLuup: Tasmota MQTT Bridge:
@archers temp is sent for set target only, but I could add easily to power on/off.
Thanks for all the effort! It could be a useful addition for a more generic usecase, i.e. to have the posibility to add on/off in the same way as for temperature with a vaiable similar to %s.
I tested on my Fujitsu and "Power":"On" resp "Power":"Off" in the Mqtt message turns it on and off so it seems quite straight forward.For my particular usecase I may go in a slightly different direction. My idea is to put the Tasmota IR so that it can both send commands to the HVAC and also that it can capture commands from the remote via Mqtt and IrReceived.
I have tested this a bit and it seems to work quite well. I setup at Reactor pulling the data sent from the remote to the HVAC and also sending data to the HVAC, so far only when changing the temp, but I may add e.g. fan speed. -
@archers heater is a bit behind the others, where I’m already supporting mqtt messages to update values. I could add it easily over the weekend. You’ll find two variables to update. Send me your messages, so I could try to replicate it and give you precise instructions. It’s one of the things I’ll change in my setup, so it’s work I’m doing for myself as well
-
@therealdb for my Fujutsu unit:
Message to turn off device:
mqtt://cmnd/TasmotaIR/IRhvac/=/{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"Off","Celsius":"On","Temp":20,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
Message to turn on device:
mqtt://cmnd/TasmotaIR/IRhvac/=/{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
I do not know if it would be possible to control the fan also, I am not sure there is a good controller for it. If so the fan is controlled with the "Fanspeed" being set to five values 1-4 and auto: "Min", "Low", "Medium", Max" and "Auto" e.g.
mqtt://cmnd/TasmotaIR/IRhvac/=/{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Max","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
-
@archers after we’re done with heaters, I’ll definitely add a thermostat to the mix, even if it’s a mess and it’s not easy. In the meantime, you could control it with a dimmer. Maybe it’s time to add transformation to the mix, so we could easily produce a range (1…4) from 0/100.
Anyway, I was speaking of mqtt messages to get the status, if available in your use case - ie when changing the mode via the official remote.
-
ArcherSreplied to therealdb on May 14, 2021, 7:16 AM last edited by ArcherS May 14, 2021, 3:22 AM
@therealdb I also thought of using a dimmer or something similar.
When I press the remote and the IR reveiver in the Tasmota captures that I get an IrReceived message in the Console:
07:45:47 MQT: tele/TasmotaIR/RESULT = {"IrReceived":{"Protocol":"FUJITSU_AC","Bits":128,"Data":"0x0x1463001010FE0930400400000000206C","Repeat":0,"IRHVAC":{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}}}
It always contains the same elements as above, i.e. it reports all of the status fields every time.
So e.g. when changing the fan to "Min":
01:57:31 RSL: tele/tasmota_E0D649/RESULT = {"IrReceived":{"Protocol":"FUJITSU_AC","Bits":128,"Data":"0x0x1463001010FE09304004040000002068","Repeat":0,"IRHVAC":{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Min","SwingV":"Off","SwingH":"Off","Quiet":"On","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}}} IRVAC{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Min","SwingV":"Off","SwingH":"Off","Quiet":"On","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
The FanSpeed values are:
"FanSpeed":"Min"
"FanSpeed":"Low"
"FanSpeed":"Medium"
"FanSpeed":"Max"
"FanSpeed":"Auto"When powered on:
01:55:23 RSL: tele/tasmota_E0D649/RESULT = {"IrReceived":{"Protocol":"FUJITSU_AC","Bits":128,"Data":"0x0x1463001010FE0930410400000000206B","Repeat":0,"IRHVAC":{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":20,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}}}
When powered off:
00:26:45 RSL: tele/tasmota_E0D649/RESULT = {"IrReceived":{"Protocol":"FUJITSU_AC","Bits":56,"Data":"0x0x146300101002FD","Repeat":0,"IRHVAC":{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Off","Power":"Off","Celsius":"On","Temp":16,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}}}
For some reason it also sends "Mode":"Off" when powered off and not only "Power":"Off"
When changing mode you get for the four modes:
"Mode":"Heat"
"Mode":"Cool"
"Mode":"Dry"
"Mode":"Auto"When I have looked in the Tasmota IR wiki there is some info on this also.
Both the IrReceived and IRhvac send protocols seem quite generic in terms of the mode, fan speed etc. -
therealdbreplied to ArcherS on May 15, 2021, 11:05 AM last edited by therealdb May 15, 2021, 7:05 AM
@archers ok, new build is on GitHub.
if you want to match for tele/tasmota_E0D649/RESULT topic with a message that contains IrReceived.IRHVAC.Power and a value of Off (case sensitive) use
tele/tasmota_E0D649/RESULT/=/IrReceived.IRHVAC.Power/=/Off
As you can see, we could also match a path and get its value:
tele/tasmota_E0D649/RESULT/=/IrReceived.IRHVAC.Temp/=/*
I've also added the ability to get the current temperature via MQTT as well. I'll update the docs later, with the new formats.
-
ArcherSreplied to therealdb on May 15, 2021, 7:17 PM last edited by ArcherS May 15, 2021, 6:02 PM
@therealdb said in openLuup: Tasmota MQTT Bridge:
if you want to match for tele/tasmota_E0D649/RESULT topic with a message that contains IrReceived.IRHVAC.Power and a value of Off (case sensitive) use
Should it be mqtt://tele/tasmota_E0D649/RESULT/=/IrReceived.IRHVAC.Power/=/Off etc?
I tried both with and without "mqtt://" but I cannot see any changes on the varibles of the device.
Checked the log and it says beta 4 so it should be installed properly.Edit: problem solved, see below.
The variables I have for the device are as below, there could very well be something wrong with them; I have not yet got full controll of the settings for heater device. -
ArcherSreplied to ArcherS on May 15, 2021, 10:00 PM last edited by ArcherS May 15, 2021, 6:27 PM
@therealdb now it works!
I managed to find what I think was the error. I somehow some time ago have managed to copy all the VirtualDevices files into a sub-folder in the cmh-ludl folder. Stupid error my my side that gave a lot of strange behaviour...
I simply removed the sub-folder and reloaded the master branch from the "plugins" tab in AltUi and then it worked as it should.In other words it should be mqtt://tele/tasmota_E0D649/RESULT/=/IrReceived.IRHVAC.Power/=/Off etc i.e. with the mqtt:// prefix.
Thanks for a great addition to the plugin, I will play some more with this one and see that it works as supposed.
Edit: I discovered that the changing the temp on the OpenLuup device via "SetSetpointURL" does only work when the "ModeState" is "Heating".
It seems as if "ModeState" reverts to "Idle" and then changing the temperature from the OpenLuup device with the "SetSetpointURL" does not work. Is this something that can be changed? -
@archers said in openLuup: Tasmota MQTT Bridge:
In other words it should be mqtt://tele/tasmota_E0D649/RESULT/=/IrReceived.IRHVAC.Power/=/Off etc i.e. with the mqtt:// prefix.
No need to use the prefix for the incoming messages, but it should discard it anyway.
I’ll take a look at setpoint, but I fear it’s not updating it because of the way heaters are coded. Maybe a thermostat in your case could be better, but it’ll need more work on my part.
-
@therealdb you are of course correct, I tested and it works both with and without the mqtt:// prefix for the incoming messages.
I changed the "CurrentTemperature" to a value that always will be lower than the setpoints ( in my case 10 degrees), by doing this the "ModeState" stays at "Heating" which means that the changing the temperature from the OpenLuup device works. Quite obvious of course when you think of it.
All in all it works as it should, thanks for the hard work!
-
@archers great!
I’m thinking of creating a cooler device, because I need it myself. It’s really stupid imho that they created heaters, complex thermostats, but no humidifier, dehumidifier or cooler device. But since we’re not tied to Vera anymore, I guess it’s time to add them, as I did with my own virtual alarm/alarm partition.
-
@akbooer I think I found the culprit causing the random connection disconnects to Mosquitto. The LWT payload for a given device is a simple string, which doesn't seem to decode in the json decode call. So I added the below code to send a json string to the decoder. The errors have disappeared and I now see the LWT variable in the service variables. The variable reads "LWT : Online"
--line 165 local valid = {SENSOR = true, STATE = true, RESULT = true, LWT = true}
--line 172 -- begin code local info, err = json.decode (message) if message then if not info then -- json did not decode because of single string parameter message = '{' .. '"' .. mtype .. '"' .. ':' .. '"' .. message .. '"' .. '}' end end -- end code local info, err = json.decode (message)
This is probably not the way you would handle the error, but it does work.
-
akbooerreplied to Buxton on Jun 8, 2021, 11:00 AM last edited by akbooer Jun 8, 2021, 7:00 AM
Great work!
There may be some compatibility problem betwen JSON decoders – which one are you using (openLuup / Cjson / RapidJson) ? The beginning of the Startup Log should tell you...
2021-06-06 20:08:48.470 openLuup.json:: version RapidJSON (0.6.1) + openLuup (2021.05.01) @akbooer
-
Should now be fixed in development v21.6.8.
My implementation, FYI:
local tasmota, mtype = tasmotas: match "^(.-)/(%u+)" local valid do -- thanks @Buxton for LWT as text message local j, t = "json", "text" valid = {SENSOR = j, STATE = j, RESULT = j, LWT = t} end local decoder = valid[mtype] if not (tasmota and decoder) then _log (table.concat ({"Topic ignored", topic, message}, " : ")) return end local info, err if decoder == "text" then info = {[mtype] = message} else info, err = json.decode (message) if not info then _log ("JSON error: " .. (err or '?')) _log ("Received message ignored: " .. message) return end end
-
@akbooer Yes, that should work. However, the LWT MQTT specification calls for a standard message, so a tasmota upgrade could change the text message to a json message. Is there a way to test the message for a non-json string, and then filter accordingly. I fear the hardcoded flags will inevitably break....
-
Yes, I thought of doing it that way. A simple check for a leading [ or { should be adequate.
This is the one thing I don’t like about Tasmota (as mentioned a while ago) … no real standards.
-
OK, so here's what it will be now, a hybrid of our approaches...
local valid = {SENSOR = 1, STATE = 1, RESULT = 1, LWT = 1} -- thanks @Buxton for LWT as text message if not (tasmota and valid[mtype]) then _log (table.concat ({"Topic ignored", topic, message}, " : ")) return end local info = json.decode (message) or {[mtype] = message} -- treat invalid JSON as plain text