Closed heinemannj closed 1 year ago
Please have a look at the sysinfo plugin on how to implement the selection of a subset of output values. ESPEasy only allows upto 4 task values, and you're using 18. So I'm a bit surprised things don't crash as you are running out of range on some objects.
If you want to use all values and share the same device, you may also have a look at the Eastron plugin.
First of all: I'm able to setup a plugin with the really annoying limitation of 4 output values
My workarround - obviously a shot from behind through the chest in the eye:
1) Generate events for all required 18 sensor readings:
case PLUGIN_READ:
{
P112_data_struct *P112_data =
static_cast<P112_data_struct *>(getPluginTaskData(event->TaskIndex));
if (P112_data->begin()) {
if (PCONFIG(3)) // Integrated LEDs?
{
P112_data->sensor.takeMeasurementsWithBulb();
} else {
P112_data->sensor.takeMeasurements();
}
String RuleEvent;
RuleEvent = getTaskDeviceName(event->TaskIndex);
RuleEvent += '#';
if (PCONFIG(3)) // Calibrated Measurements?
{
eventQueue.add(RuleEvent + "410=" + P112_data->sensor.getCalibratedA());
eventQueue.add(RuleEvent + "435=" + P112_data->sensor.getCalibratedB());
eventQueue.add(RuleEvent + "460=" + P112_data->sensor.getCalibratedC());
eventQueue.add(RuleEvent + "485=" + P112_data->sensor.getCalibratedD());
eventQueue.add(RuleEvent + "510=" + P112_data->sensor.getCalibratedE());
eventQueue.add(RuleEvent + "535=" + P112_data->sensor.getCalibratedF());
eventQueue.add(RuleEvent + "560=" + P112_data->sensor.getCalibratedG());
eventQueue.add(RuleEvent + "585=" + P112_data->sensor.getCalibratedH());
eventQueue.add(RuleEvent + "610=" + P112_data->sensor.getCalibratedR());
eventQueue.add(RuleEvent + "645=" + P112_data->sensor.getCalibratedI());
eventQueue.add(RuleEvent + "680=" + P112_data->sensor.getCalibratedS());
eventQueue.add(RuleEvent + "705=" + P112_data->sensor.getCalibratedJ());
eventQueue.add(RuleEvent + "730=" + P112_data->sensor.getCalibratedT());
eventQueue.add(RuleEvent + "760=" + P112_data->sensor.getCalibratedU());
eventQueue.add(RuleEvent + "810=" + P112_data->sensor.getCalibratedV());
eventQueue.add(RuleEvent + "860=" + P112_data->sensor.getCalibratedW());
eventQueue.add(RuleEvent + "900=" + P112_data->sensor.getCalibratedK());
eventQueue.add(RuleEvent + "940=" + P112_data->sensor.getCalibratedL());
UserVar[event->BaseVarIndex + 0] = P112_data->sensor.getCalibratedC();
UserVar[event->BaseVarIndex + 1] = P112_data->sensor.getCalibratedF();
UserVar[event->BaseVarIndex + 2] = P112_data->sensor.getCalibratedR();
UserVar[event->BaseVarIndex + 3] = P112_data->sensor.getCalibratedW();
} else {
eventQueue.add(RuleEvent + "410=" + P112_data->sensor.getA());
eventQueue.add(RuleEvent + "435=" + P112_data->sensor.getB());
eventQueue.add(RuleEvent + "460=" + P112_data->sensor.getC());
eventQueue.add(RuleEvent + "485=" + P112_data->sensor.getD());
eventQueue.add(RuleEvent + "510=" + P112_data->sensor.getE());
eventQueue.add(RuleEvent + "535=" + P112_data->sensor.getF());
eventQueue.add(RuleEvent + "560=" + P112_data->sensor.getG());
eventQueue.add(RuleEvent + "585=" + P112_data->sensor.getH());
eventQueue.add(RuleEvent + "610=" + P112_data->sensor.getR());
eventQueue.add(RuleEvent + "645=" + P112_data->sensor.getI());
eventQueue.add(RuleEvent + "680=" + P112_data->sensor.getS());
eventQueue.add(RuleEvent + "705=" + P112_data->sensor.getJ());
eventQueue.add(RuleEvent + "730=" + P112_data->sensor.getT());
eventQueue.add(RuleEvent + "760=" + P112_data->sensor.getU());
eventQueue.add(RuleEvent + "810=" + P112_data->sensor.getV());
eventQueue.add(RuleEvent + "860=" + P112_data->sensor.getW());
eventQueue.add(RuleEvent + "900=" + P112_data->sensor.getK());
eventQueue.add(RuleEvent + "940=" + P112_data->sensor.getL());
UserVar[event->BaseVarIndex + 0] = P112_data->sensor.getC();
UserVar[event->BaseVarIndex + 1] = P112_data->sensor.getF();
UserVar[event->BaseVarIndex + 2] = P112_data->sensor.getR();
UserVar[event->BaseVarIndex + 3] = P112_data->sensor.getW();
}
}
success = true;
break;
}
2) Setup 6 dummy devices to store all required 18 sensor readings (6 x 3 = 18) 3) Setup 18 rules to feed the dummy device readings
On System#Boot do
Let,10,0
Let,11,0
Let,80,16 // Sample switch
Let,90,12 // LED
GPIO,[INT#80],0 // Sample switch
Pulse,[INT#90],1,1000 // LED
endon
on ResetSample do
TaskValueSet,%eventvalue1%,1,0
TaskValueSet,%eventvalue1%,2,0
TaskValueSet,%eventvalue1%,3,0
TaskValueSet,%eventvalue1%,4,0
endon
on UpdateSample do
TaskValueSet,%eventvalue1%,%eventvalue2%,%eventvalue3%
Let,11,[INT#11]+1 // Reading counter
if [INT#11]=18
GPIO,[INT#80],0 // Turn sample switch off
GPIO,[INT#90],0 // Turn LED off
Let,10,0
endif
endon
on SampleSwitch#State=1 do // Sample switch active
GPIO,[INT#90],1 // Turn LED on
asyncevent,ResetSample=2 // Reset dummy device readings
asyncevent,ResetSample=3
asyncevent,ResetSample=4
asyncevent,ResetSample=5
asyncevent,ResetSample=6
asyncevent,ResetSample=7
Let,10,1 // Sample flag active
Let,11,0 // Reading counter
TaskRun,1 // Start sample
endon
on AS7265X#410 do
if [INT#10]=1 and [Spectrum_1#410]=0
asyncevent,UpdateSample=2,1,%eventvalue1%
endif
endon
on AS7265X#435 do
if [INT#10]=1 and [Spectrum_1#435]=0
asyncevent,UpdateSample=2,2,%eventvalue1%
endif
endon
on AS7265X#460 do
if [INT#10]=1 and [Spectrum_1#460]=0
asyncevent,UpdateSample=2,3,%eventvalue1%
endif
endon
on AS7265X#485 do
if [INT#10]=1 and [Spectrum_2#485]=0
asyncevent,UpdateSample=3,1,%eventvalue1%
endif
endon
on AS7265X#510 do
if [INT#10]=1 and [Spectrum_2#510]=0
asyncevent,UpdateSample=3,2,%eventvalue1%
endif
endon
on AS7265X#535 do
if [INT#10]=1 and [Spectrum_2#535]=0
asyncevent,UpdateSample=3,3,%eventvalue1%
endif
endon
on AS7265X#560 do
if [INT#10]=1 and [Spectrum_3#560]=0
asyncevent,UpdateSample=4,1,%eventvalue1%
endif
endon
on AS7265X#585 do
if [INT#10]=1 and [Spectrum_3#585]=0
asyncevent,UpdateSample=4,2,%eventvalue1%
endif
endon
on AS7265X#610 do
if [INT#10]=1 and [Spectrum_3#610]=0
asyncevent,UpdateSample=4,3,%eventvalue1%
endif
endon
on AS7265X#645 do
if [INT#10]=1 and [Spectrum_4#645]=0
asyncevent,UpdateSample=5,1,%eventvalue1%
endif
endon
on AS7265X#680 do
if [INT#10]=1 and [Spectrum_4#680]=0
asyncevent,UpdateSample=5,2,%eventvalue1%
endif
endon
on AS7265X#705 do
if [INT#10]=1 and [Spectrum_4#705]=0
asyncevent,UpdateSample=5,3,%eventvalue1%
endif
endon
on AS7265X#730 do
if [INT#10]=1 and [Spectrum_5#730]=0
asyncevent,UpdateSample=6,1,%eventvalue1%
endif
endon
on AS7265X#760 do
if [INT#10]=1 and [Spectrum_5#760]=0
asyncevent,UpdateSample=6,2,%eventvalue1%
endif
endon
on AS7265X#810 do
if [INT#10]=1 and [Spectrum_5#810]=0
asyncevent,UpdateSample=6,3,%eventvalue1%
endif
endon
on AS7265X#860 do
if [INT#10]=1 and [Spectrum_6#860]=0
asyncevent,UpdateSample=7,1,%eventvalue1%
endif
endon
on AS7265X#900 do
if [INT#10]=1 and [Spectrum_6#900]=0
asyncevent,UpdateSample=7,2,%eventvalue1%
endif
endon
on AS7265X#940 do
if [INT#10]=1 and [Spectrum_6#940]=0
asyncevent,UpdateSample=7,3,%eventvalue1%
endif
endon
Result:
If there is any way to simplify the plugin and the rules code please let me know.
With the help of this sensor you can perform simple but accurate spectral analysis over the range of visible and near infrared light spectrum without the need of really expensive spectrometers (> 4000 €)!
Further improvement with the help of UV sensors (e.g. VEML6070, VEML6075, ...) is possible. If you want I can make a pull request.
Why not doint the same as with the Eastron plugin? That plugin does use a single object to communicate and collect the data. The separate tasks then just pick their values from that single object and thus act per extra task as a very simple instance of the plugin.
Handling it via rules like this is using quite a lot of resources.
I've prepared a pull request. I've reviewed the Eastron plugin but with my limited coding experience I was not able to implement.
In addition this plugin is special: there are 3 different sensors synchronized by the main one One measurement over all 18 channels takes a couple of seconds - Initiating a measurement should only done by one single plugin instance.
Please feel free to improve - I will test and report
Hmm can you also show a screenshot of the timing stats page running this plugin? "A couple of seconds" is a big red flag for me.
But potentially there is a solution implemented within the sparkfun lib to avoid waiting till sensor readings are finished. But again my coding experiences are limited.
I've done something similar to the Dallas DS18b20 and BME280 (and some more) to actually split the reading process into several stages and make sure the task is rescheduled to perform a PLUGIN_READ
to actually delilver the values.
Close to 2 seconds blocking is not usable as it will literally block all other things running on the ESP.
This issue is no longer valid, as several alternative solutions are available. Can be closed.
I'm working on a new plugin for an 18 channel sensor:
The sensor reading are properly captured and also visible in Device vie and in json output. But the reading names are not properly stored:
Custom build based on Commits from Mar 23, 2021
Is there any peace of code which needs to be fine tuned in addition to above ? Any help is appreciated.