openLuup: Tasmota MQTT Bridge
-
@buxton said in openLuup: Tasmota MQTT Bridge:
some oddball variables that I'd like to incorporate
...trivial to add with a custom rule.
-
@akbooer said in openLuup: Tasmota MQTT Bridge:
...now done in latest development version v21.5.11.
Installed and it seems to work as it should. Next step is to upgrade on my main OpenLuup server after some runtime on the test server.
-
therealdbreplied to ArcherS on May 12, 2021, 5:36 PM last edited by therealdb May 12, 2021, 1:45 PM
@archers said in openLuup: Tasmota MQTT Bridge:
2021-05-11 10:05:35.103 luup.variable_set:: 52.urn:bochicchio-com:serviceId:VirtualHeater1.SetPowerURL was: EMPTY now: http:// #hooks:0
2021-05-11 10:05:35.103 luup.variable_set:: 52.urn:bochicchio-com:serviceId:VirtualHeater1.SetPowerOffURL was: EMPTY now: http:// #hooks:0This is by design. As you can see, you've not set SetPowerURL and SetPowerOffURL to anything significant, like the mqtt message, so it's not sending anything, and it's acting with the default behavior: if you're not replying with 200-ish HTTP response, it will not change variables. When using mqtt:// prefix, it will update immediately.
I'll work on this anyway, since it's not sending temperature command at the moment, but I think it's a good addition in your use case - and to other people as well.
Please try with mqtt commands and let me know, because I have it working good.
EDIT: it's done, just set SetSetpointURL variable to
mqtt://cmnd/TasmotaIR/IRhvac/=/{"Vendor":"FUJITSU_AC","Model":1,"Mode":"Heat","Power":"On","Celsius":"On","Temp":%s,"FanSpeed":"Auto","SwingV":"Off","SwingH":"Off","Quiet":"Off","Turbo":"Off","Econo":"Off","Light":"Off","Filter":"Off","Clean":"Off","Beep":"Off","Sleep":-1}
(notice the %s). it's sending the temperature that's set. it's beta3 on GitHub, from master branch.
-
ArcherSreplied to therealdb on May 12, 2021, 6:36 PM last edited by ArcherS May 12, 2021, 3:16 PM
@therealdb my feeling was that I had missed something.
Yes I think it could be a good usecase.Edit: I got to send the Mqtt message a few times, but not every time. Not sure why it does not send every time though. Does it matter if it is "off" or "heat"?
Edit 2: It seems as if it works!
Mode "off" and then the set temp sends the Mqtt message. Maybe if was a poll delay or something. I will test some more.
I tried to add the above mqtt:// into the SetSetpoint URL but nothing seems to be sent, i.e. nothing is appearing in the Tasmota Console.This is what I see in the log (device no 52):
2021-05-12 20:18:02.023 openLuup.server:: GET /data_request?id=lu_status2&output_format=json&DataVersion=843427346&Timeout=60&MinimumDelay=1500&_=1620843427214 HTTP/1.1 tcp{client}: 0x1b09e50 2021-05-12 20:18:14.970 openLuup.server:: GET /data_request?id=action&output_format=json&DeviceNum=52&serviceId=urn:upnp-org:serviceId:TemperatureSetpoint1_Heat&action=SetCurrentSetpoint&NewCurrentSetpoint=19 HTTP/1.1 tcp{client}: 0x2204008 2021-05-12 20:18:14.972 luup.call_action:: 52.urn:upnp-org:serviceId:TemperatureSetpoint1_Heat.SetCurrentSetpoint 2021-05-12 20:18:14.973 openLuup.server:: request completed (44 bytes, 1 chunks, 2 ms) tcp{client}: 0x2204008 2021-05-12 20:18:20.877 openLuup.server:: GET /console?page=log.1 HTTP/1.1 tcp{client}: 0x2204008 2021-05-12 20:18:20.981 openLuup.server:: request completed (185478 bytes, 0 chunks, 102 ms) tcp{client}: 0x2204008 2021-05-12 20:18:21.107 openLuup.server:: GET /favicon.ico HTTP/1.1 tcp{client}: 0x2204008 2021-05-12 20:18:21.107 openLuup.servlet:: file not found:favicon.ico 2021-05-12 20:18:21.108 openLuup.server:: request completed (126 bytes, 0 chunks, 0 ms) tcp{client}: 0x2204008 2021-05-12 20:18:21.108 openLuup.io.server:: HTTP:3480 connection closed openLuup.server.receive closed tcp{client}: 0x2204008 2021-05-12 20:18:23.314 openLuup.io.server:: HTTP:3480 connection from 192.168.1.145 tcp{client}: 0x1c7ed70 2021-05-12 20:18:23.316 openLuup.server:: GET /console?page=log HTTP/1.1 tcp{client}: 0x1c7ed70
I also tried with a number, e.g. "20" instead of %s but no difference.
Startup log, it seems as if I have the right version:
2021-05-12 20:29:18.833 luup_log:52: VirtualHeater starting... 2021-05-12 20:29:18.834 luup_log:52: VirtualDevices[3.0-beta3@52]:Plugin starting 2021-05-12 20:29:18.834 luup.device_message:: device=52, status=4, message=Starting..., timeout=5, source=VirtualDevices 2021-05-12 20:29:18.834 luup_log:52: VirtualDevices[3.0-beta3@52]:Child #52 - "VirtualHeater2" 2021-05-12 20:29:18.835 luup.variable_watch:: callback=virtualThermostatWatch, watching=52.urn:upnp-org:serviceId:HVAC_UserOperatingMode1.ModeTarget 2021-05-12 20:29:18.837 luup.variable_watch:: callback=virtualThermostatWatch, watching=52.urn:upnp-org:serviceId:HVAC_UserOperatingMode1.ModeStatus 2021-05-12 20:29:18.838 luup.variable_watch:: callback=virtualThermostatWatch, watching=52.urn:upnp-org:serviceId:TemperatureSetpoint1.CurrentSetpoint 2021-05-12 20:29:18.840 luup.variable_watch:: callback=virtualThermostatWatch, watching=52.urn:upnp-org:serviceId:TemperatureSetpoint1_Heat.CurrentSetpoint 2021-05-12 20:29:18.841 luup.variable_watch:: callback=virtualThermostatWatch, watching=52.urn:upnp-org:serviceId:TemperatureSensor1.CurrentTemperature 2021-05-12 20:29:18.841 luup.set_failure:: status = 0 2021-05-12 20:29:18.841 luup.variable_set:: 52.urn:micasaverde-com:serviceId:HaDevice1.CommFailure was: 0 now: 0 #hooks:0 2021-05-12 20:29:18.842 luup.variable_set:: 52.urn:micasaverde-com:serviceId:HaDevice1.CommFailureTime was: 0 now: 0 #hooks:0 2021-05-12 20:29:18.842 openLuup.scheduler:: [52] VirtualHeater2 device startup completed: status=true, msg=Ready, name=VirtualDevices
-
@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