After calibration, incorrect data

After applying the kolibrovochny sketch. My sensor started showing values in ppm like this:<PHONE_NUMBER>0

Assuming kolibrovochny  = calibration ? you used - AGS02MA_calibrate.ino ?
Has been some time ago I used the sensor but I recall no problems with it when calibrating (I use Arduino UNO)
Can you post the output of the calibration sketch?
The manual does not give information about failing calibration, only this:

What does uint8_t  lastStatus() return?
it might be a communication error?

Assuming kolibrovochny = calibration ? you used - AGS02MA_calibrate.ino ?
Has been some time ago I used the sensor but I recall no problems with it when calibrating (I use Arduino UNO) Can you post the output of the calibration sketch?
The manual does not give information about failing calibration, only this:

What does uint8_t lastStatus() return? it might be a communication error?

No. There are no communication errors. When there is no connection, I have 0 ppb sent. Let's do the collibration again now. It will take 6 minutes and I will attach the output of the port monitor to you.

Looks OK,  every 15 seconds a timestamp
the 1 indicates that the 5 bytes for zero calibration are written to the device. (no I2C error).

Looks OK, every 15 seconds a timestamp the 1 indicates that the 5 bytes for zero calibration are written to the device. (no I2C error).

Only. When I had the sensor on the window. He fell. But I can't believe that after that it began to show exorbitant values.

That's also why I'm thinking of collibration. Before the calibration, the sensor transmitted data to the home assistant for a day. And I compared the data with sgp30. And they differed of course. But both reacted to the tvoc change.

Only. When I had the sensor on the window. He fell. But I can't believe that after that it began to show exorbitant values.

It might be possible but unlikely in my opinion. If you shake it gently do you

hear loose parts on the inside
see (big) changes in the readings
(any yes would indicate hardware problems, a no is no proof of absence of damage.)

That's also why I'm thinking of collibration. Before the calibration, the sensor transmitted data to the home assistant for a day. And I compared the data with sgp30. And they differed of course. But both reacted to the tvoc change.

Factor 10 difference is quite large. Is that difference constant?
Do you power the sensor with 3V3 or with 5V?  (5V is more stable as 3V3 is the minimum for the sensor

No.  No damage.  I disassembled the case.  But I thought that the dust could get into a small hole.  Washed it in alcohol and left to dry. I'll check it out in 6 hours and report back.  Also, if possible, check your calibrate.19.04.2022, 12:58, "Rob Tillaart" @.***>:
Only. When I had the sensor on the window. He fell. But I can't believe that after that it began to show exorbitant values.
It might be possible but unlikely in my opinion. If you shake it gently do you
hear loose parts on the inside
see (big) changes in the readings
(any yes would indicate hardware problems, a no is no proof of absence of damage.)
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you authored the thread.Message ID: @.***>

That's also why I'm thinking of collibration. Before the calibration, the sensor transmitted data to the home assistant for a day. And I compared the data with sgp30. And they differed of course. But both reacted to the tvoc change.

Factor 10 difference is quite large. Is that difference constant?
Do you power the sensor with 3V3 or with 5V? (5V is more stable as 3V3 is the minimum for the sensor

I washed the sensor, dried it. It didn't give any results. I used esp32. I decided to try it on arduino Uno. I recolibrated, other values began to be shown. They are also not faithful

The calibration command in the library is exact according to the datasheet.
It could have triggered some other bug in the sensor.
just a thought:
Can you check if the UNO gives other values than the ESP?
if so it might point toward problems with power supply.

The calibration command in the library is exact according to the datasheet. It could have triggered some other bug in the sensor.
just a thought: Can you check if the UNO gives other values than the ESP? if so it might point toward problems with power supply.

Yes. The values are different. ESP32 has:99999 And uno has: 34343

Q: did you read the other issue - https://github.com/RobTillaart/AGS02MA/issues/11
It is closed, but it shows that there are at least two versions of the sensor V17 and V18.
Can you check which version you have (I have only V17).

The calibration command in the library is exact according to the datasheet. It could have triggered some other bug in the sensor.
just a thought: Can you check if the UNO gives other values than the ESP? if so it might point toward problems with power supply.

Yes. The values are different. ESP32 has:99999 And uno has: 34343

So there are two important observations:

The sensor gives different data depending on the board that is requesting data. (could be power issue)
The values reported are too constant, I would expect small but detectable noise (+-1) on the signal.

The calibration command in the library is exact according to the datasheet. It could have triggered some other bug in the sensor.
just a thought: Can you check if the UNO gives other values than the ESP? if so it might point toward problems with power supply.

Yes. The values are different. ESP32 has:99999 And uno has: 34343

So there are two important observations:

The sensor gives different data depending on the board that is requesting data. (could be power issue)
The values reported are too constant, I would expect small but detectable noise (+-1) on the signal.

Could it be that due to the fact that the version of the sensor is different, the calibration has overwritten everything and now it is faulty? and do I need to program it somehow?

yes. The version is really 118((((. And what should I do now?

My experience with version 18 is limited to what is mentioned in issue #11  Lets ask Beanow who also has a v 18.

Could it be that due to the fact that the version of the sensor is different, the calibration has overwritten everything and now it is faulty? and do I need to program it somehow?

In theory that could be the case, however calibration is a process the sensor does internally.
In this process the sensor makes a lot of measurements until these stabilizes (that is why it takes time to calibrate).
The calibration command itself is typical a command that stores the found (stabile) values in internal EEPROM for later use.
When the sensor is making new measurements it can refer to that zero point, to calculate the right value.
The zero level is typical used as an offset for a raw measurement.
I have two slightly different datasheets of the sensor and both have the same command for the calibration.
None is mentioning that there are differences between versions.
In fact we tries to contact the manufacturer of the sensor (in issue #11 ) and got no new information about V 18.
You might check chapter 8 of the datasheet which mentions several pages of possible problems with the sensor.
They are pretty sensitive to almost anything.
I do not know if there is a way to manually provide calibration data. There are registers in the sensor that are not documented and these might include calibration values (seems logical). No info on this.

Could it be that due to the fact that the version of the sensor is different, the calibration has overwritten everything and now it is faulty? and do I need to program it somehow?

In theory that could be the case, however calibration is a process the sensor does internally. In this process the sensor makes a lot of measurements until these stabilizes (that is why it takes time to calibrate). The calibration command itself is typical a command that stores the found (stabile) values in internal EEPROM for later use. When the sensor is making new measurements it can refer to that zero point, to calculate the right value. The zero level is typical used as an offset for a raw measurement.
I have two slightly different datasheets of the sensor and both have the same command for the calibration. None is mentioning that there are differences between versions. In fact we tries to contact the manufacturer of the sensor (in issue #11 ) and got no new information about V 18.
You might check chapter 8 of the datasheet which mentions several pages of possible problems with the sensor. They are pretty sensitive to almost anything.
I do not know if there is a way to manually provide calibration data. There are registers in the sensor that are not documented and these might include calibration values (seems logical). No info on this.

The sensor worked exactly out of the box. As soon as I started the calibration, the values became the same and constant and very high.Yes, he fell at me. But I disassembled it, there's nothing to break from the impact.

After my previous experience with the device, and having no different sensor types or controlled environment to compare, I didn't touch the calibration function. But I can test it later.
Voltage
Some things I can say up front, I've had no noticeable issues running on the ESP32's 3.3v, or seen different values for 5v.
I'm even sharing the 3.3v, ground and I2C wires with a BME sensor (board I have requires 3.3v, hence using that).
Too constant
Like @RobTillaart mentioned,

The values reported are too constant, I would expect small but detectable noise (+-1) on the signal.

I agree, even for bad quality readings I normally see fluctuations all the time.
Here's what I got in the past 24h of 1s interval raw data from one. This is indoors and it roughly corresponds to outside air quality and ventilation, but don't have means to determine accuracy properly.

About alcohol

Washed it in alcohol and left to dry.

Keep in mind that the sensor responds to alcohol fumes. Since the datasheet suggests 5 minutes of "fresh air". However they define fresh (Cleanroom levels of controlled environment fresh? Outside urban air fresh?). I wouldn't try calibrating when the alcohol might still spike the readings.
Here's the chart when I hold the sensor directly above an open bottle of 99,9% isopropyl alcohol.
Peak nearly 34k PPB. 10 minutes later still not back to the stable reading from before.

Warmup period
One reason I can think of why you might have had this 10x reading, is warmup period.

In my experience, when the sensor has been powered off for some time (a few days or more). It can take very very long for values to come down to normal. It can sometimes take multiple hours of leaving the sensor running before the reading stabilizes.
For something like calibration, I would suggest you leave the sensor powered on and polling values for something like 10h or more, and then calibrate. I think the datasheet's 5 minutes is extremely optimistic.
Because your values are so extreme, suspicious and constant (99,999 / 34,343). Maybe the internal readings it got were just bad due to warmup issues that the chip is running into some type of integer overflow problems.

After my previous experience with the device, and having no different sensor types or controlled environment to compare, I didn't touch the calibration function. But I can test it later.
Voltage
Some things I can say up front, I've had no noticeable issues running on the ESP32's 3.3v, or seen different values for 5v. I'm even sharing the 3.3v, ground and I2C wires with a BME sensor (board I have requires 3.3v, hence using that).
Too constant
Like @RobTillaart mentioned,

The values reported are too constant, I would expect small but detectable noise (+-1) on the signal.

I agree, even for bad quality readings I normally see fluctuations all the time.
Here's what I got in the past 24h of 1s interval raw data from one. This is indoors and it roughly corresponds to outside air quality and ventilation, but don't have means to determine accuracy properly.

About alcohol

Washed it in alcohol and left to dry.

Keep in mind that the sensor responds to alcohol fumes. Since the datasheet suggests 5 minutes of "fresh air". However they define fresh (Cleanroom levels of controlled environment fresh? Outside urban air fresh?). I wouldn't try calibrating when the alcohol might still spike the readings.
Here's the chart when I hold the sensor directly above an open bottle of 99,9% isopropyl alcohol. Peak nearly 34k PPB. 10 minutes later still not back to the stable reading from before.

Warmup period
One reason I can think of why you might have had this 10x reading, is warmup period.
In my experience, when the sensor has been powered off for some time (a few days or more). It can take very very long for values to come down to normal. It can sometimes take multiple hours of leaving the sensor running before the reading stabilizes.
For something like calibration, I would suggest you leave the sensor powered on and polling values for something like 10h or more, and then calibrate. I think the datasheet's 5 minutes is extremely optimistic.
Because your values are so extreme, suspicious and constant (99,999 / 34,343). Maybe the internal readings it got were just bad due to warmup issues that the chip is running into some type of integer overflow problems.

It's already late. The sensor now shows nonsense all the time and the maximum values ((( But I agree with you, the values I had all night were gradually getting lower and lower.
Yes. If it is not difficult, try to calibrate. But keep in mind! you can also break the sensor(

@Beanow It's already late. The sensor now shows nonsense all the time and the maximum values ((( But I agree with you, the values I had all night were gradually getting lower and lower.
Yes. If it is not difficult, try to calibrate. But keep in mind! you can also break the sensor(

But I agree with you, the values I had all night were gradually getting lower and lower.

That looks like the warmup period. When I first connected the sensor it would go from absurdly high like 30k, down fairly quick to <1000 PPB. But going down to something like ~15 PPB on a good (urban) air quality day, would take many hours.

But keep in mind! you can also break the sensor.

Yeah. I'm fine with that. To be honest I don't trust this sensor at all. The v18 version is basically undocumented because there's no new datasheet to match the new version, the ug/m3 functionality doesn't work. The status flags don't work. I couldn't get a response from the manufacturer. Their HTTP-only website lists the old datasheet...
It's another reason why I don't care too much about the calibration, I only trust it to produce relative values. For example "how much does the value change compared to itself an hour ago, if I open the windows".

@Beanow I wanted to compare it with sgp30. That's why I decided to calibrate it. Now I don't know what to do(((

Well you said it's late there.
For now, I would upload the PPB example sketch and let it warm up overnight and try again tomorrow :smile:
If you're lucky the problem was only bad values from warmup and calibrating again later may give better results.

@Beanow  OK. I'll put it on overnight. and then I'll try to calibrate.

For some idea of what I meant with the slow warmup. Here's me replacing a warmed up sensor, for a different one that I haven't powered on in over a month.
Before switching, the warmed up sensor read about 22-24 PPB.
'Cold' sensor started from >80k, dropping very quickly in the first hour of warmup. Going down to about 150 PPB.

Second hour, from 150-ish to 95-ish PPB. Going down much slower, but 95 PPB is still nowhere near 22-24 PPB.

Clearly 2 hours wasn't enough time to warm up this sensor after being powered down longer. I'll show the stable point when it gets there.

@Beanow It's a shame that I messed up my sensor ((((

I will add a warning  to the readme with a link to this thread. For now it is the only action I can do as there is no documentation and minimal experience with the v18 version.

@Beanow The sensor stood for another day. There is no difference. I also checked the voltage on the chip. I really don't know what it should be, but it is) so I think everything is fine there.
According to this, if you had done the calibration. Then it would put an end to it and we would know for sure that it was him. Then I'll go order a new sensor((. Please check the calibration.

I am going to add the following rewrite in the readme.md
Version 118 problems
The library can request the version with getSensorVersion().
My devices all report version 117 and this version is used to develop / test this library.
There are devices reported with version 118 which behave differently.
ugM3 not supported
See  - https://github.com/RobTillaart/AGS02MA/issues/11
The version 118 seems only to support the PPB and not the ugM3 mode.
It is unclear if this is an incident, bug or a structural change in the firmware.
If you encounter similar problems with setting the mode (any version), please let me know.
That will help indicating if this is a "structural change" or incident.
Calibrate problem?
See - https://github.com/RobTillaart/AGS02MA/issues/13
In this issue a problem is reported with a version 118 sensor.
The problem exposed itself after running the calibration sketch (command) and after a fall.
It cannot be determined if the calibration or the fall or something else caused the malfunction.
As it is a single occurrence that cannot be reproduced (having no 118 sensor myself)
Additional calibration runs did not fix the problem.
Advice: be aware of the risk of calibrating a version 118.
Any experiences with calibration (any version) are welcome to investigate the root cause here.
Please report your experiences.
If you have a AGS20MA device, version 117 or 118 or other, please let me know your experiences
with the sensor and this (or other) library.

Created a PR https://github.com/RobTillaart/AGS02MA/pull/14

added text to readme.md
added warning to the calibration example.
updated the version of the library to 0.1.5

Google gave no clues,
one reference to another library here - https://forum.arduino.cc/t/ags02ma-air-quality-sensor/894906
Seems to have less functionality.

I tried it yesterday. It doesn't show anything with my sensor there at all. And there is no way to calibrate.

I tried it yesterday. It doesn't show anything with my sensor there at all. And there is no way to calibrate.

Ok, so far the manufacturer's library. Could not locate an updated version of it either.
I noticed that it reads multiple times when reading data. When time permits I try to understand the diffs.

Just a side note: - https://www.sciencedirect.com/science/article/abs/pii/S0045790622002233
Apparently the sensor is used in serious applications too.

I ordered it on Aliexpress and somewhere there it was written that it is used in some equipment.

Just a side note: - https://www.sciencedirect.com/science/article/abs/pii/S0045790622002233 Apparently the sensor is used in serious applications too.

Wouldn't call this a "serious application". The research paper is about: can we detect a thing with machine learning and TVOC data? And the researchers are associated with two collages in India. It's not uncommon for such research papers to have little budget for equipment, possibly paid for and built by students, and use hobby-grade prototype boards. Because the premise was: can we use AI this way? The sensor can be just be barely good enough to have trends show up in the data an AI can pick out.

I ordered it on Aliexpress and somewhere there it was written that it is used in some equipment.

With the Aliexpress retailer that I got them from, it had 2 reviews along the line of: "5/5 shipped fast, haven't tried it yet". I posted a negative review mentioning the v118 problems, and they relisted to product to censor the review. The blatantly abused the loopholes of the platform. Aaaanyway....
Warmup
I swapped the sensors at around 19:30 yesterday. And the first time the data had a realistic-looking upward trend, was spot on between 7:00 and 7:30. So I would say this warmup round took ~12hours.

The first steep drop is outside this chart, because it chances the Y-axis scale too much to see later data.
Calibration

According to this, if you had done the calibration. Then it would put an end to it and we would know for sure that it was him. Then I'll go order a new sensor

Like you said, if mine also goes nuts when trying to calibrate, I think we can call the v118 just generally bad. I'll test that next, making sure the sensor has warmed up before and giving the datasheet one more good read.

@Beanow I'm waiting very much for calibration)))

Ok, both sensors look warmed up to me. And the effect of max ventilation seems to also have stabilized too.
There's a big difference though. The full setup has settled on ~11 PPB. And the simple setup ~53 PPB.
I'll swap them, just to be sure it's not a problem with the code/setup.

Alright, so it's again settled on ~10 PPB and ~56 PPB.
I've modified the calibration sketch a little bit, to show version, set mode explicitly and monitor values while waiting.
//
//    FILE: AGS02MA_calibrate.ino
//  AUTHOR: Rob Tillaart
// VERSION: 0.1.0
// PURPOSE: test application
//    DATE: 2021-08-12
//     URL: https://github.com/RobTillaart/AGS02MA
//

#include "AGS02MA.h"

uint32_t start, stop;

AGS02MA AGS(26);

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);

  Serial.print("AGS02MA_LIB_VERSION: ");
  Serial.println(AGS02MA_LIB_VERSION);
  Serial.println();

  Wire.begin();

  bool b = AGS.begin();
  Serial.print("BEGIN:\t");
  Serial.println(b);

  Serial.print("VERSION:\t");
  Serial.println(AGS.getSensorVersion());

  b = AGS.setPPBMode();
  uint8_t m = AGS.getMode();
  Serial.print("MODE:\t");
  Serial.print(b);
  Serial.print("\t");
  Serial.println(m);

  Serial.println("Place the device outside in open air for 6 minutes");
  Serial.println("Take a drink and relax ;)");
  Serial.println();

  start = millis();
  while(millis() - start < 360000UL)
  {
    delay(3000);
    Serial.print("[PRE ]\t");
    readOut();
  }

  // returns 1 if successful written
  b = AGS.zeroCalibration();
  Serial.print("CALIB:\t");
  Serial.println(b);

  Serial.println("Calibration done");
}

void loop()
{
  delay(3000);
  Serial.print("[POST]\t");
  readOut();
}

void readOut()
{
  uint32_t value = AGS.readPPB();
  Serial.print("PPB:\t");
  Serial.print(value);
  Serial.print("\t");
  Serial.print(AGS.lastStatus(), HEX);
  Serial.print("\t");
  Serial.print(AGS.lastError(), HEX);
  Serial.println();
}

Starting with:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1324
ho 0 tail 12 room 4
load:0x40078000,len:13508
load:0x40080400,len:3604
entry 0x400805f0
/home/beanow/Arduino/AGS02MA_calibrate_mod/AGS02MA_calibrate_mod.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERSION:	118
MODE:	1	0
Place the device outside in open air for 6 minutes
Take a drink and relax ;)

[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0

So now I grab a drink! :coffee: :+1:
(As you can tell, I'm going to try zero calibrate the ~56 PPB one.)

Aaaaaand RIP :headstone:
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	56	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
[PRE ]	PPB:	55	0	0
CALIB:	1
Calibration done
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0

I tried to get the sensor to react at all, post calibration, by holding it close to the 99.9% IPA bottle again.
But it did not change from the 99879 value at all.
I tried to power-cycle the chip, just by taking it out and putting back into the breadboard,
and it's new favourite number became 99999. Again with no response to holding it next to alcohol.
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0

@RobTillaart the datasheet mentions zero calibration data doesn't get persisted and is lost on power off.
Does your v117 actually lose it's zero calibration when power-cycled?

I tried to get the sensor to react at all, post calibration, by holding it close to the 99.9% IPA bottle again. But it did not change from the 99879 value at all.
I tried to power-cycle the chip, just by taking it out and putting back into the breadboard, and it's new favourite number became 99999. Again with no response to holding it next to alcohol.
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99879	0	FFFFFFF4
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0
[POST]	PPB:	99999	0	0

I also noticed two values like you have 999999 and 99879. And when it shows 99879. I touch the sensor with my hand, start twirling it and it becomes 999999.

999999 PPB is the maximum listed in the datasheet.
I think the internal values just overflow and get limited to 999999.

Also, no matter what I do now (longer power-off, switch to 5v and back, move and touch it, wiggle the pins in the breadboard, etc.) I only see 999999 now. After the first power-cycle that 99879 is nowhere to be found.

Ah, I managed to reproduce it. Starting the calibration sketch again. Not very useful though.
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
[PRE ]	PPB:	99999	0	0
CALIB:	1
Calibration done
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0
[POST]	PPB:	99879	0	0

I've been turning it for two days already) I've been calibrating it from different devices) and it happened in different ways. And switched to ppm. But there is another maximum figure

Here's comparing the PPB sketch with PPM sketch, they're clearly the same underlying value:
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1324
ho 0 tail 12 room 4
load:0x40078000,len:13508
load:0x40080400,len:3604
entry 0x400805f0
/tmp/arduino_modified_sketch_721314/AGS02MA_PPM.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERSION:	118
MODE:	1	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
PPM:	99.879	0	0	0
ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1324
ho 0 tail 12 room 4
load:0x40078000,len:13508
load:0x40080400,len:3604
entry 0x400805f0
/tmp/arduino_modified_sketch_23195/AGS02MA_PPB.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERSION:	118
MODE:	1	0
VERS:	118
PPB:	99879	0	0
PPB:	99879	0	0
PPB:	99879	0	0
PPB:	99879	0	0
PPB:	99879	0	0

Btw, the datasheet's caveats department does match my warmup observations pretty closely.

Also :rotating_light:

I guess 2-24 hours is considered "super fast" recovery time for a TVOC sensor :joy:

999999 PPB is the maximum listed in the datasheet. I think the internal values just overflow and get limited to 999999.

Hang on, certainly I'm misunderstanding something about this accuracy specification.
For the typical range of 0-9999 PPB, it has 30% of full scale accuracy?
Should I read that as, a 50 PPB reading could be ±3000 PPB?
And the "extended range" of 9999-99999 PPB with 50%FS would be ±50000 PPB?

@Beanow

@RobTillaart the datasheet mentions zero calibration data doesn't get persisted and is lost on power off.
Does your v117 actually lose it's zero calibration when power-cycled?

I need to dig up my sensor so I can test - will be tomorrow - expect in the afternoon.
(Currently working on some tests of another library, want to finish those first.)
Looking at the result of your tests  (thank you for all this effort) .

the calibration let your 118 version sensor crash so I interpret that as a confirmation that the 118 cannot be calibrated.
Therefor the calibrate function in the library should be disabled for the version 118 explicitly.
(And maybe completely after I did test the 117 calibration)
Documentation should be upgraded to mention this explicitly.

Hang on, certainly I'm misunderstanding something about this accuracy specification.
For the typical range of 0-9999 PPB, it has 30% of full scale accuracy?
Should I read that as, a 50 PPB reading could be ±3000 PPB?
And the "extended range" of 9999-99999 PPB with 50%FS would be ±50000 PPB?

If that interpretation is correct it would make the sensor useless. It would make more sense if the accuracy is 30% of the given value e.g. 50 == 50 ± 15  and 900 == 900±300 or so. Not accurate but workable .

If that interpretation is correct it would make the sensor useless. It would make more sense if the accuracy is 30% of the given value e.g. 50 == 50 ± 15 and 900 == 900±300 or so. Not accurate but workable . At least the datasheet leaves a lot of questions.

Yes, however what you're talking about I think is called % of Reading.
This seems to be explicitly "%F.S" which I take as % of full scale.
https://www.ametekcalibration.com/knowledge/pressure-calibration/of-reading-vs-of-scale

@Beanow
Agree with you,
The point I tried to make was that the documentation is not good. So I expect these kind of errors in it.
thinking out loud modus
The sensor has a number of undocumented registers.

https://github.com/RobTillaart/AGS02MA/issues/11#issuecomment-1017932405

Might be interesting to see the values of the "calibrated" one.
Might even try to write those old values? If that would be possible it would be possible to dump the old values before calibrating so people can restore them.

Started test version 117
Found my sensor and started it, seems to stabilize slowly. it started at 700+ this morning and dropped already to 319.
So I wait for it to stabilize and will try to calibrate it this afternoon.

made a dump of the registers
//
//    FILE: AGS02MA_get_registers.ino
//  AUTHOR: Rob Tillaart
// PURPOSE: test application
//     URL: https://github.com/RobTillaart/AGS02MA
//
//  usage: make _readRegister() and _buffer public
//

#include "AGS02MA.h"

AGS02MA AGS(26);

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);

  Wire.begin();

  Serial.print("AGS02MA_LIB_VERSION: ");
  Serial.println(AGS02MA_LIB_VERSION);
  Serial.println();

  bool b = AGS.begin();
  Serial.print("BEGIN:\t");
  Serial.println(b);

  uint8_t version = AGS.getSensorVersion();
  Serial.print("VERS:\t");
  Serial.println(version);

  for (uint8_t reg = 0; reg < 9; reg++)
  {
    dumpRegister(reg);
  }
  dumpRegister(0x11);
  dumpRegister(0x20);
  dumpRegister(0x21);
}

void loop()
{
}

void dumpRegister(uint8_t reg)
{
  Serial.print("REG[");
  Serial.print(reg);
  Serial.print("]");

  bool b = AGS._readRegister(reg);
  for (int i = 0; i < 5; i++)
  {
    Serial.print("\t");
    Serial.print(AGS._buffer[i]);
  }
  Serial.println();
  delay(100);
}

// -- END OF FILE --

Three dumps short after each other (last column is CRC)
dump1
BEGIN:	1
VERS:	117
REG[0]	1	0	0	241	255
REG[1]	0	13	18	90	248
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	46	120	221	136
REG[8]	147	117	0	62	24
REG[17]	20	7	28	117	213
REG[32]	0	5	46	147	99
REG[33]	26	229	26	229	113

dump2
BEGIN:	1
VERS:	117
REG[0]	1	0	0	245	59
REG[1]	0	13	18	90	248
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	35	124	125	202
REG[8]	154	117	0	62	159
REG[17]	20	7	28	117	213
REG[32]	0	5	35	154	171
REG[33]	26	229	26	229	113

dump3
BEGIN:	1
VERS:	117
REG[0]	17	0	0	244	50       <<< Sensor data
REG[1]	0	13	18	90	248      <<< Zero calibration data
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	39	122	89	251
REG[8]	203	117	0	62	220
REG[17]	20	7	28	117	213      <<< date and version nr
REG[32]	0	5	39	203	103
REG[33]	26	229	26	229	113      <<<  I2C slave address

dump 4 (1 hour later)
BEGIN:	1
VERS:	117
REG[0]	1	0	0	206	20       <<< data is slightly lower - stabilizing
REG[1]	0	13	18	90	248      <<< Zero calibration data - same
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	153	106	113	85       <<< differs
REG[8]	32	117	0	67	137      <<< differs
REG[17]	20	7	28	117	213      <<< date and version nr - same
REG[32]	0	5	153	32	176      <<< differs
REG[33]	26	229	26	229	113      <<<  I2C slave address - same

only three unknown registers are different

made a dump of the registers
//
//    FILE: AGS02MA_get_registers.ino
//  AUTHOR: Rob Tillaart
// PURPOSE: test application
//     URL: https://github.com/RobTillaart/AGS02MA
//
//  usage: make _readRegister() and _buffer public
//

#include "AGS02MA.h"

AGS02MA AGS(26);

void setup()
{
  Serial.begin(115200);
  Serial.println(__FILE__);

  Wire.begin();

  Serial.print("AGS02MA_LIB_VERSION: ");
  Serial.println(AGS02MA_LIB_VERSION);
  Serial.println();

  bool b = AGS.begin();
  Serial.print("BEGIN:\t");
  Serial.println(b);

  uint8_t version = AGS.getSensorVersion();
  Serial.print("VERS:\t");
  Serial.println(version);

  for (uint8_t reg = 0; reg < 9; reg++)
  {
    dumpRegister(reg);
  }
  dumpRegister(0x11);
  dumpRegister(0x20);
  dumpRegister(0x21);
}

void loop()
{
}

void dumpRegister(uint8_t reg)
{
  Serial.print("REG[");
  Serial.print(reg);
  Serial.print("]");

  bool b = AGS._readRegister(reg);
  for (int i = 0; i < 5; i++)
  {
    Serial.print("\t");
    Serial.print(AGS._buffer[i]);
  }
  Serial.println();
  delay(100);
}

// -- END OF FILE --

Three dumps short after each other (last column is CRC)
dump1
BEGIN:	1
VERS:	117
REG[0]	1	0	0	241	255
REG[1]	0	13	18	90	248
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	46	120	221	136
REG[8]	147	117	0	62	24
REG[17]	20	7	28	117	213
REG[32]	0	5	46	147	99
REG[33]	26	229	26	229	113

dump2
BEGIN:	1
VERS:	117
REG[0]	1	0	0	245	59
REG[1]	0	13	18	90	248
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	35	124	125	202
REG[8]	154	117	0	62	159
REG[17]	20	7	28	117	213
REG[32]	0	5	35	154	171
REG[33]	26	229	26	229	113

dump3
BEGIN:	1
VERS:	117
REG[0]	17	0	0	244	50       <<< Sensor data
REG[1]	0	13	18	90	248      <<< Zero calibration data
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	39	122	89	251
REG[8]	203	117	0	62	220
REG[17]	20	7	28	117	213      <<< date and version nr
REG[32]	0	5	39	203	103
REG[33]	26	229	26	229	113      <<<  I2C slave address

(labels based upon - #11 (comment)

I tried to build a dump like you. but it gave me an error. Apparently you have a modified library.

I tried to build a dump like you. but it gave me an error. Apparently you have a modified library.

//  usage: make _readRegister() and _buffer public

Started calibration  12:27 local time

360008
CALIB:	1
Calibration done

AGS02MA_PPB_TIMING.ino
AGS02MA_LIB_VERSION: 0.2.0

BEGIN:	1
VERS:	117

Warming up (120 seconds = 24 dots)
........................
MODE:	1	0
32	11	10	0
32	12	10	0
32	12	10	0
32	11	10	0
33	11	10	0
33	12	10	0
33	12	10	0
33	12	10	0
32	12	10	0
33	12	10	0

As I calibrated in the same room as I measure now it is expected to have very low values:
So it the calibration seems to work for version 117.

This is not fair :(((

A look at the registers
AGS02MA_LIB_VERSION: 0.2.0

BEGIN:	1
VERS:	117
REG[0]	1	0	0	4	136
REG[1]	0	12	14	127	23
REG[2]	0	100	6	162	177
REG[3]	3	232	3	251	2
REG[4]	39	16	1	102	120
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	5	180	101	157	52
REG[8]	109	117	0	68	119
REG[17]	20	7	28	117	213
REG[32]	0	5	180	109	93
REG[33]	26	229	26	229	113

Writing the previous values to register 0x01 does not work.
It behaves as a read only register that can only be set by the calibration command.
I'll try a 2nd calibration to see what happens.

This is not fair :(((

Well beyond unfair, this is starting to look like a bait-and-switch. Which, since it's false advertising, could be illegal?
Can't say if it's malicious, some plausible thing I can think of, is that the v118 was a 'silicon shortage compromises' version intended for some OEM and they never made a datasheet public for that reason, and these ended up on aliexpress by "falling off a truck" :shrug:
Regardless, I don't know of a way yet to unbrick, after the calibration messes up. So you might attempt a refund @shojkeee if you purchased recently. Though you know... it's aliexpress. :crossed_fingers:
I'll add some register dumps from mine shortly.

What money. It's me own fault that  started recording something in the sensor) And it's cheap. Not so offensive)

the ZCR is almost identical
REG[1]	0	12	14	21	119

some thoughts...
if I interpret these ZCR  numbers as an uint32_t measurement
1265536 + 14256 + 127 =790143
1265536 + 14256 + 21=790037
==> a difference of 106 on 790K so roughly 1 in 10K which is "nothing"
Note this was an in house calibration of a pre calibration value of ~200.
The previous calibration was
REG[1]	0	13	18	90	248

1365536 + 18256 + 90 = 856666
So a higher ZCR gives a higher TVOC with the same level
==> so the ZCR is a sort of maximum and the real measurements are lower.
The difference 856666 - 790143 = 66523  which would represent ~200-10 = 190 units.

Here is the v118, bricked by calibration issue, not warmed up since yesterday. With about a minute between dumps.
Bricked v118 dumps
/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	1	134	159	255
REG[1]	0	125	255	243	149
REG[2]	0	100	91	95	216
REG[3]	3	232	32	158	189
REG[4]	39	16	11	164	179
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	0	244	171	233	168
REG[8]	33	118	0	11	92
REG[17]	21	2	3	118	133
REG[32]	0	0	244	33	251
REG[33]	26	229	26	229	113

/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	1	134	159	255
REG[1]	0	125	255	243	149
REG[2]	0	100	91	95	216
REG[3]	3	232	32	158	189
REG[4]	39	16	11	164	179
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	1	24	166	133	144
REG[8]	197	118	0	13	149
REG[17]	21	2	3	118	133
REG[32]	0	1	24	197	122
REG[33]	26	229	26	229	113

/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	1	134	159	255
REG[1]	0	125	255	243	149
REG[2]	0	100	91	95	216
REG[3]	3	232	32	158	189
REG[4]	39	16	11	164	179
REG[5]	238	72	35	40	205
REG[6]	26	0	0	18	213
REG[7]	1	39	166	45	185
REG[8]	24	118	0	14	102
REG[17]	21	2	3	118	133
REG[32]	0	1	39	24	25
REG[33]	26	229	26	229	113

And here's the warmed up, non-calibrated v118 that I used for comparisons before.
(Which reads about 9 PPB, before dumping)
Reference v118 dumps
/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	0	0	8	110
REG[1]	0	125	2	192	91
REG[2]	0	100	1	58	159
REG[3]	3	232	0	140	64
REG[4]	39	16	0	66	206
REG[5]	238	72	35	40	205
REG[6]	26	0	0	17	134
REG[7]	16	19	94	25	192
REG[8]	65	118	0	183	14
REG[17]	21	2	3	118	133
REG[32]	0	16	19	65	60
REG[33]	26	229	26	229	113

/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	0	0	8	110
REG[1]	0	125	2	192	91
REG[2]	0	100	1	58	159
REG[3]	3	232	0	140	64
REG[4]	39	16	0	66	206
REG[5]	238	72	35	40	205
REG[6]	26	0	0	17	134
REG[7]	16	19	94	25	192
REG[8]	65	118	0	183	14
REG[17]	21	2	3	118	133
REG[32]	0	16	19	65	60
REG[33]	26	229	26	229	113

/home/beanow/Arduino/AGS02MA_regdump/AGS02MA_regdump.ino
AGS02MA_LIB_VERSION: 0.1.4

[    12][W][Wire.cpp:204] begin(): Bus already started in Master Mode.
BEGIN:	1
VERS:	118
REG[0]	0	0	0	8	110
REG[1]	0	125	2	192	91
REG[2]	0	100	1	58	159
REG[3]	3	232	0	140	64
REG[4]	39	16	0	66	206
REG[5]	238	72	35	40	205
REG[6]	26	0	0	17	134
REG[7]	16	19	94	25	192
REG[8]	65	118	0	183	14
REG[17]	21	2	3	118	133
REG[32]	0	16	19	65	60
REG[33]	26	229	26	229	113

Thanks for the dumps v118
REG[0]	0	1	134	159	255  ==>  adds up to 65536 + 134*256 + 159 = 99.999

REG[1]	0	125	255	243	149

ZCR
125 *65536 + 255*256 + 243 = 8.257.523  is more than 10x higher than in my register above.
Assuming the raw measurement is OK (similar) the distance with the zero point is huge ==> huge TVOC.

The difference 856666 - 790143 = 66523 which would represent ~200-10 = 190 units.

this means 1 tvoc unit ~~ 350 raw units.
If one of the registers would represent the raw measurements .... (maybe later today)

The prime suspect for raw values is register 0x20

breathing dumps the value substantially,
lets find out if I can correlate this "suspect" to TVOC values.

Sadly I'm seeing 0x20 (32) change even when the PPB output doesnt.
Round:	13
REG[0]	0	0	0	14	200	u32: 14	delta: 0
REG[1]	0	125	2	192	91	u32: 8192704	delta: 0
REG[2]	0	100	1	58	159	u32: 6553914	delta: 0
REG[3]	3	232	0	140	64	u32: 65536140	delta: 0
REG[4]	39	16	0	66	206	u32: 655360066	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	delta: 0
REG[6]	26	0	0	17	134	u32: 436207633	delta: 0
REG[7]	9	102	77	13	251	u32: 157699341	delta: 1112540
REG[8]	158	118	0	106	225	u32:<PHONE_NUMBER>	delta:<PHONE_NUMBER>
REG[17]	21	2	3	118	133	u32: 352453494	delta: 0
REG[32]	0	9	102	158	234	u32: 616094	delta: 4412
REG[33]	26	229	26	229	113	u32: 451222245	delta: 0

Round:	14
REG[0]	0	0	0	14	200	u32: 14	delta: 0
REG[1]	0	125	2	192	91	u32: 8192704	delta: 0
REG[2]	0	100	1	58	159	u32: 6553914	delta: 0
REG[3]	3	232	0	140	64	u32: 65536140	delta: 0
REG[4]	39	16	0	66	206	u32: 655360066	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	delta: 0
REG[6]	26	0	0	17	134	u32: 436207633	delta: 0
REG[7]	9	124	84	193	22	u32: 159143105	delta: 1443764
REG[8]	254	118	0	107	64	u32:<PHONE_NUMBER>	delta:<PHONE_NUMBER>
REG[17]	21	2	3	118	133	u32: 352453494	delta: 0
REG[32]	0	9	124	254	209	u32: 621822	delta: 5728
REG[33]	26	229	26	229	113	u32: 451222245	delta: 0

Round:	15
REG[0]	0	0	0	13	155	u32: 13	delta: -1
REG[1]	0	125	2	192	91	u32: 8192704	delta: 0
REG[2]	0	100	1	58	159	u32: 6553914	delta: 0
REG[3]	3	232	0	140	64	u32: 65536140	delta: 0
REG[4]	39	16	0	66	206	u32: 655360066	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	delta: 0
REG[6]	26	0	0	17	134	u32: 436207633	delta: 0
REG[7]	9	154	69	229	53	u32: 161105381	delta: 1962276
REG[8]	63	118	0	108	93	u32:<PHONE_NUMBER>	delta:<PHONE_NUMBER>
REG[17]	21	2	3	118	133	u32: 352453494	delta: 0
REG[32]	0	9	154	63	139	u32: 629311	delta: 7489
REG[33]	26	229	26	229	113	u32: 451222245	delta: 0

Round:	16
REG[0]	0	0	0	13	155	u32: 13	delta: 0
REG[1]	0	125	2	192	91	u32: 8192704	delta: 0
REG[2]	0	100	1	58	159	u32: 6553914	delta: 0
REG[3]	3	232	0	140	64	u32: 65536140	delta: 0
REG[4]	39	16	0	66	206	u32: 655360066	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	delta: 0
REG[6]	26	0	0	17	134	u32: 436207633	delta: 0
REG[7]	9	192	68	205	118	u32: 163595469	delta: 2490088
REG[8]	174	118	0	110	109	u32:<PHONE_NUMBER>	delta:<PHONE_NUMBER>
REG[17]	21	2	3	118	133	u32: 352453494	delta: 0
REG[32]	0	9	192	174	138	u32: 639150	delta: 9839
REG[33]	26	229	26	229	113	u32: 451222245	delta: 0

But it does look correlated to measurements. Here's spiking it with a bit of alcohol fumes.

Think it is but not tackled the relation, maybe it is missing the 2 minutes heat up,
maybe it is quadratic, exponential or logarithmic.
We're far from understanding, but I got the feeling we're closing in.
Maybe the correlation to the ugM3 value is more visible?
Can you divide REG[32] /  REG[0]  ?  if linear that should be sort of constant.
I am now updating the PR with the insight that only V117 should calibrate,  be back in a few hours

I think the zero calibration may be two uint16 banks.
If I compare the interpretation of my two non-calibrated v118s and the borked, calibrated one:
Ref chip A
REG[0]	0	0	0	16	148	u32: 16	16.16: 0	16	8.16.8: 0	0	16	delta: 0
REG[1]	0	125	2	192	91	u32: 8192704	16.16: 125	704	8.16.8: 0	32002	192	delta: 0
REG[2]	0	100	1	58	159	u32: 6553914	16.16: 100	314	8.16.8: 0	25601	58	delta: 0
REG[3]	3	232	0	140	64	u32: 65536140	16.16: 1000	140	8.16.8: 3	59392	140	delta: 0
REG[4]	39	16	0	66	206	u32: 655360066	16.16: 10000	66	8.16.8: 39	4096	66	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	17	134	u32: 436207633	16.16: 6656	17	8.16.8: 26	0	17	delta: 0
REG[7]	7	242	166	33	33	u32: 133342753	16.16: 2034	42529	8.16.8: 7	62118	33	delta: -4062844
REG[8]	161	118	0	91	211	u32:<PHONE_NUMBER>	16.16: 41334	91	8.16.8: 161	30208	91	delta: 805306365
REG[32]	0	7	242	161	56	u32: 520865	16.16: 7	62113	8.16.8: 0	2034	161	delta: -15824

Ref chip B
REG[0]	0	0	13	116	171	u32: 3444	16.16: 0	3444	8.16.8: 0	13	116	delta: -111
REG[1]	0	125	2	117	17	u32: 8192629	16.16: 125	629	8.16.8: 0	32002	117	delta: 0
REG[2]	0	100	1	19	145	u32: 6553875	16.16: 100	275	8.16.8: 0	25601	19	delta: 0
REG[3]	3	232	0	120	6	u32: 65536120	16.16: 1000	120	8.16.8: 3	59392	120	delta: 0
REG[4]	39	16	0	58	143	u32: 655360058	16.16: 10000	58	8.16.8: 39	4096	58	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	19	228	u32: 436207635	16.16: 6656	19	8.16.8: 26	0	19	delta: 0
REG[7]	0	65	57	145	26	u32: 4274577	16.16: 65	14737	8.16.8: 0	16697	145	delta: -1976
REG[8]	254	118	0	3	66	u32:<PHONE_NUMBER>	16.16: 65142	3	8.16.8: 254	30208	3	delta: -1090519040
REG[32]	0	0	65	254	55	u32: 16894	16.16: 0	16894	8.16.8: 0	65	254	delta: 191

Calibrated "X":
REG[0]	0	1	134	159	255	u32: 99999	16.16: 1	34463	8.16.8: 0	390	159	delta: 0
REG[1]	0	125	255	243	149	u32: 8257523	16.16: 125	65523	8.16.8: 0	32255	243	delta: 0
REG[2]	0	100	91	95	216	u32: 6576991	16.16: 100	23391	8.16.8: 0	25691	95	delta: 0
REG[3]	3	232	32	158	189	u32: 65544350	16.16: 1000	8350	8.16.8: 3	59424	158	delta: 0
REG[4]	39	16	11	164	179	u32: 655362980	16.16: 10000	2980	8.16.8: 39	4107	164	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	0	71	209	5	3	u32: 4706565	16.16: 71	53509	8.16.8: 0	18385	5	delta: 193072
REG[8]	198	118	0	3	22	u32:<PHONE_NUMBER>	16.16: 50806	3	8.16.8: 198	30208	3	delta: -1023410176
REG[32]	0	0	71	198	17	u32: 18374	16.16: 0	18374	8.16.8: 0	71	198	delta: 963

Note that both refs are pretty close in factory calibration value. But the X's second bank is suspiciously close to max uint16 value.
A: 125	704
B: 125	629
X: 125	65523

Waaaait a minute. Does it just write the command's second uint16 to memory?
65523 -> 255 243 -> 0xFF 0xF3

YES, it sure does! I added this function:
bool AGS02MA::zeroCalibrationManual(uint16_t value)
{
  _buffer[0] = 0x00;
  _buffer[1] = 0x0C;
  _buffer[2] = (value >> 8);
  _buffer[3] = (value & 0xFF);
  _buffer[4] = _CRC8(_buffer, 4);
  return _writeRegister(AGS02MA_CALIBRATION);
}

You can reproduce the documented calibration function like:
AGS.zeroCalibrationManual(0xFFF3);

Or I can set it to what my other chip showed like:
AGS.zeroCalibrationManual(704);

I didn't understand. Have you revived the sensor?

So here's what the AGS.zeroCalibrationManual(0xFFF3); produced (99879 PPB)
REG[0]	0	1	134	39	249	u32: 99879	16.16: 1	34343	8.16.8: 0	390	39	delta: 0
REG[1]	0	12	255	243	252	u32: 851955	16.16: 12	65523	8.16.8: 0	3327	243	delta: 0
REG[2]	0	100	91	95	216	u32: 6576991	16.16: 100	23391	8.16.8: 0	25691	95	delta: 0
REG[3]	3	232	32	158	189	u32: 65544350	16.16: 1000	8350	8.16.8: 3	59424	158	delta: 0
REG[4]	39	16	11	164	179	u32: 655362980	16.16: 10000	2980	8.16.8: 39	4107	164	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	2	38	131	153	179	u32: 36078489	16.16: 550	33689	8.16.8: 2	9859	153	delta: -65464
REG[8]	153	118	0	26	139	u32:<PHONE_NUMBER>	16.16: 39286	26	8.16.8: 153	30208	26	delta:<PHONE_NUMBER>
REG[32]	0	2	38	153	108	u32: 140953	16.16: 2	9881	8.16.8: 0	550	153	delta: -155

And here's AGS.zeroCalibrationManual(704); (0 PPB)
REG[0]	0	0	0	0	215	u32: 0	16.16: 0	0	8.16.8: 0	0	0	delta: 0
REG[1]	0	12	2	192	50	u32: 787136	16.16: 12	704	8.16.8: 0	3074	192	delta: 0
REG[2]	0	100	0	251	29	u32: 6553851	16.16: 100	251	8.16.8: 0	25600	251	delta: 0
REG[3]	3	232	0	89	177	u32: 65536089	16.16: 1000	89	8.16.8: 3	59392	89	delta: 0
REG[4]	39	16	0	31	252	u32: 655360031	16.16: 10000	31	8.16.8: 39	4096	31	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	2	44	129	105	54	u32: 36471145	16.16: 556	33129	8.16.8: 2	11393	105	delta: 64928
REG[8]	126	118	0	26	120	u32:<PHONE_NUMBER>	16.16: 32374	26	8.16.8: 126	30208	26	delta: 771751936
REG[32]	0	2	44	126	212	u32: 142462	16.16: 2	11390	8.16.8: 0	556	126	delta: 302

And AGS.zeroCalibrationManual(629); (0 PPB)
REG[0]	0	0	0	0	215	u32: 0	16.16: 0	0	8.16.8: 0	0	0	delta: 0
REG[1]	0	12	2	117	120	u32: 787061	16.16: 12	629	8.16.8: 0	3074	117	delta: 0
REG[2]	0	100	0	224	180	u32: 6553824	16.16: 100	224	8.16.8: 0	25600	224	delta: 0
REG[3]	3	232	0	79	84	u32: 65536079	16.16: 1000	79	8.16.8: 3	59392	79	delta: 0
REG[4]	39	16	0	28	175	u32: 655360028	16.16: 10000	28	8.16.8: 39	4096	28	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	2	45	130	121	30	u32: 36536953	16.16: 557	33401	8.16.8: 2	11650	121	delta: -816
REG[8]	161	118	0	26	223	u32:<PHONE_NUMBER>	16.16: 41334	26	8.16.8: 161	30208	26	delta: -1761607680
REG[32]	0	2	45	161	10	u32: 142753	16.16: 2	11681	8.16.8: 0	557	161	delta: 151

Notice how the other registers (2, 3 and 4) are also affected by changing the input value I give it.
However these values were without power-cycling the sensor. Like how doing AGS.zeroCalibrationManual(0xFFF3); first produces 99879 PPB and after power-cycle produces 99999 PPB...
Here's AGS.zeroCalibrationManual(704); and then power cycling it (59 PPB!):
REG[0]	0	0	0	59	248	u32: 59	16.16: 0	59	8.16.8: 0	0	59	delta: 0
REG[1]	0	125	2	192	91	u32: 8192704	16.16: 125	704	8.16.8: 0	32002	192	delta: 0
REG[2]	0	100	0	251	29	u32: 6553851	16.16: 100	251	8.16.8: 0	25600	251	delta: 0
REG[3]	3	232	0	89	177	u32: 65536089	16.16: 1000	89	8.16.8: 3	59392	89	delta: 0
REG[4]	39	16	0	31	252	u32: 655360031	16.16: 10000	31	8.16.8: 39	4096	31	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	2	68	135	117	139	u32: 38045557	16.16: 580	34677	8.16.8: 2	17543	117	delta: 130576
REG[8]	86	118	0	27	37	u32:<PHONE_NUMBER>	16.16: 22134	27	8.16.8: 86	30208	27	delta: -922746880
REG[32]	0	2	68	86	137	u32: 148566	16.16: 2	17494	8.16.8: 0	580	86	delta: 457

I didn't understand. Have you revived the sensor?

Yes! I did revive it. Although it's very questionable how good the data is now, because I'm just guessing the calibration value based off the other chip's registers.
But basically:

Call AGS.zeroCalibrationManual(704);
Power-cycle the chip.
Readings come back!

And some crude tests, like with alcohol do change the PPB value.

Found quadratic correlation between the raw register 32  and register 0

A rough linear correlation

note that 0.001324 == 1/755  and 755 is close to your 704.  (8% might be coincidence ...)

Sorry. I can't find AGS.zeroCalibrationManual();

And I think the first half of the register contains status flags of some kind.
In Rob's comment https://github.com/RobTillaart/AGS02MA/issues/13#issuecomment-1105086742
He mentioned both 0 12 and 0 13.
In my dumps, I also see 0 12 when I've just initiated the calibration call and get the 0 / 99879 PPB results.
But after power-cycling I see 0 125.
If you view that in other formats:
0000 1100 | 0x0C | 12
0000 1101 | 0x0D | 13
0111 1101 | 0x7D | 125

If I try writing those, it doesn't work though. Anything other than 0x0C and it seems to ignore the command.

Sorry. I can't find AGS.zeroCalibrationManual();

It's not currently in the library, see https://github.com/RobTillaart/AGS02MA/issues/13#issuecomment-1105408380

Never mind! I found it. AGS.zeroCalibrationManual(0); is automatic!
Here are two dumps after AGS.zeroCalibrationManual(0);
Found 713 this time.
REG[0]	0	0	0	0	215	u32: 0	16.16: 0	0	8.16.8: 0	0	0	delta: -125
REG[1]	0	12	2	201	186	u32: 787145	16.16: 12	713	8.16.8: 0	3074	201	delta: 0
REG[2]	0	100	0	254	232	u32: 6553854	16.16: 100	254	8.16.8: 0	25600	254	delta: 0
REG[3]	3	232	0	90	226	u32: 65536090	16.16: 1000	90	8.16.8: 3	59392	90	delta: 0
REG[4]	39	16	0	32	23	u32: 655360032	16.16: 10000	32	8.16.8: 39	4096	32	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	1	39	142	205	147	u32: 19369677	16.16: 295	36557	8.16.8: 1	10126	205	delta: 1112996
REG[8]	56	118	0	13	69	u32: 947257357	16.16: 14454	13	8.16.8: 56	30208	13	delta: -1711276032
REG[32]	0	1	39	56	159	u32: 75576	16.16: 1	10040	8.16.8: 0	295	56	delta: 4250

And next call found 806.
REG[0]	0	0	0	0	215	u32: 0	16.16: 0	0	8.16.8: 0	0	0	delta: 0
REG[1]	0	12	3	38	161	u32: 787238	16.16: 12	806	8.16.8: 0	3075	38	delta: 0
REG[2]	0	100	1	31	236	u32: 6553887	16.16: 100	287	8.16.8: 0	25601	31	delta: 0
REG[3]	3	232	0	102	90	u32: 65536102	16.16: 1000	102	8.16.8: 3	59392	102	delta: 0
REG[4]	39	16	0	36	211	u32: 655360036	16.16: 10000	36	8.16.8: 39	4096	36	delta: 0
REG[5]	238	72	35	40	205	u32:<PHONE_NUMBER>	16.16: 61000	9000	8.16.8: 238	18467	40	delta: 0
REG[6]	26	0	0	18	213	u32: 436207634	16.16: 6656	18	8.16.8: 26	0	18	delta: 0
REG[7]	1	97	137	229	85	u32: 23169509	16.16: 353	35301	8.16.8: 1	24969	229	delta: 785236
REG[8]	223	118	0	16	185	u32:<PHONE_NUMBER>	16.16: 57206	16	8.16.8: 223	30208	16	delta: -234881024
REG[32]	0	1	97	223	26	u32: 90591	16.16: 1	25055	8.16.8: 0	353	223	delta: 3058

A rough linear correlation

note that 0.001324 == 1/755 and 755 is close to your 704. (8% might be coincidence ...)

This -565,51 is also close to REG[7]'s first uint16. Which is changing. Mine is currently hovering between 600-605, but I've seen 500's. So this may be a measured or derived value?

Maybe for v118 we need a different inverse to trigger the calibration?

The trick of the inverse number is also used in setting the I2C address, so they might use the inverse in more commands.
would imply something like
bool AGS02MA::zeroCalibrationManual(uint16_t value)
{
  _buffer[0] = ~(value >> 8);
  _buffer[1] = ~(value & 0xFF);
  _buffer[2] = (value >> 8);
  _buffer[3] = (value & 0xFF);
  _buffer[4] = _CRC8(_buffer, 4);
  return _writeRegister(AGS02MA_CALIBRATION);
}

// and that would make
bool AGS02MA::zeroCalibration()
{
  return zeroCalibrationManual(0xFFF3);
}

@RobTillaart so far my previous version is working:
bool AGS02MA::zeroCalibrationManual(uint16_t value)
{
  _buffer[0] = 0x00;
  _buffer[1] = 0x0C;
  _buffer[2] = (value >> 8);
  _buffer[3] = (value & 0xFF);
  _buffer[4] = _CRC8(_buffer, 4);
  return _writeRegister(AGS02MA_CALIBRATION);
}

Where:
// Automatic for v117
AGS.zeroCalibrationManual(0xFFF3);

// Automatic for v118
AGS.zeroCalibrationManual(0);

// Manual for v118 [1 - 0xFFFF]
AGS.zeroCalibrationManual(456);

It might be that one of the changes in v118 is adding the ability to manually write calibration values like this.
What does the v117 do with a manual value? And for value 0?

  b = AGS.zeroCalibrationManual(0);   (no 5 minute wait as the sensor is already up whole day)
registers
BEGIN:	1
VERS:	117
REG[0]	1	0	0	14	16777230
REG[1]	0	12	14	21	790037
REG[2]	0	100	6	162	6555298
REG[3]	3	232	3	251	65537019
REG[4]	39	16	1	102	655360358
REG[5]	238	72	35	40<PHONE_NUMBER>
REG[6]	26	0	0	18	436207634
REG[7]	5	85	84	125	89478269
REG[8]	146	117	0	63<PHONE_NUMBER>
REG[17]	20	7	28	117	336010357
REG[32]	0	5	85	146	349586
REG[33]	26	229	26	229	451222245

previous
AGS02MA_LIB_VERSION: 0.2.0

BEGIN:	1
VERS:	117
REG[0]	1	0	0	4	differs
REG[1]	0	12	14	127	differs only last byte
REG[2]	0	100	6	162
REG[3]	3	232	3	251
REG[4]	39	16	1	102
REG[5]	238	72	35	40
REG[6]	26	0	0	18
REG[7]	5	180	101	157	differs
REG[8]	109	117	0	68	differs
REG[17]	20	7	28	117	same
REG[32]	0	5	180	109	differs
REG[33]	26	229	26	229	same

So the value 0 seems to work

yep sensor just works
AGS02MA_LIB_VERSION: 0.2.0

BEGIN:	1
VERS:	117

Warming up (120 seconds = 24 dots)
MODE:	1	0
33	26	10	0
33	26	10	0
33	25	10	0
33	26	10	0
33	94	10	0   <<<< me breathing :)
33	119	10	0
33	108	10	0
32	89	10	0
31	76	10	0
32	67	10	0
32	60	10	0
33	56	10	0
33	51	10	0
33	47	10	0
33	45	10	0
33	43	10	0
33	41	10	0

Do you get different calibration results after every 0 input, similar to FFF3?
And what about manual values? Does it stick them in the register as-is?
I do notice some quirks with the automatic calibration for mine, for one it's a lot more responsive to differences.
With the factory defaults one, I get 8 PPB ambient. Breathing on it increases to 9-10 PPB.
With the zeroCalibrationManual(0) one ambient is about 3 PPB, and one breath on it easily spikes it to 20-30 PPB.
However when I power cycle, it flips from the 12 to 125 status flags(?) and after warmup, the ambient goes up to like 120 PPB and breathing jumps to 150 PPB. :thinking:

b = AGS.zeroCalibrationManual(400);
registers
AGS02MA_LIB_VERSION: 0.2.0

BEGIN:	1
VERS:	117
REG[0]	1	0	0	28	differs = data
REG[1]	0	12	14	21	differs (last byte)
REG[2]	0	100	6	162
REG[3]	3	232	3	251
REG[4]	39	16	1	102
REG[5]	238	72	35	40
REG[6]	26	0	0	18
REG[7]	5	32	87	1	differs
REG[8]	176	117	0	61	differs
REG[17]	20	7	28	117
REG[32]	0	5	32	176	differs  (raw)
REG[33]	26	229	26	229

Do you get different calibration results after every 0 input, similar to FFF3?

The zero does actually a recalibrate just as the 0xFFF3 does.  Values look alike (diff in last byte)

And what about manual values? Does it stick them in the register as-is?
The manual values do not stick into the register. (see above -400 should be  x x 1 144    but it is  12 14 21

Seemed to be ignored and a normal calibration (like FFF3) is executed.
Maybe it triggers on the 00 0C part in the command....

It's interesting how your registers 2-4 don't change with calibration either.
What about register 1's first half. Can you get it to change off of 0 12 by power cycling for instance?
And you've had 0 13 in some previous dumps, can you reproduce them? :thinking:

Actually the v117 behavior looks promising

The zero does actually a recalibrate just as the 0xFFF3 does. Values look alike (diff in last byte)

That would mean AGS.zeroCalibrationManual(0) is supported by both versions as being one way to do automatic.
And attempting manual input would just default to being automatic as well for v117?
In other words, if we just make the function like so, we can fix v118 keep API compatible, plus add a v118 exclusive feature :open_mouth:
bool zeroCalibration(uint16_t value = 0);

It's interesting how your registers 2-4 don't change with calibration either.

There are  100  1000  and  10.000  that seem to be useful constants.
The other parts of those 3 registers are just magic numbers.

Well my thinking is, perhaps they have got a full blown formula for their raw value to PPB mapping, and the 100-1k-10k are just precomputed points / ranges, so it's easier to apply?

That would mean AGS.zeroCalibrationManual(0) is supported by both versions as being one way to do automatic.
And attempting manual input would just default to being automatic as well for v117?

Yes and we could just hardcode it
bool AGS02MA::zeroCalibration()
  _buffer[0] = 0x00;
  _buffer[1] = 0x0C;
  _buffer[2] = 0x00;
  _buffer[3] = 0x00;
  _buffer[4] = _CRC8(_buffer, 4);
  return _writeRegister(AGS02MA_CALIBRATION);
}

Yes and we could just hardcode it

Well that wouldn't support the additional feature of the v118 of being able to set it manually :shrug:
It's kind of interesting actually.
With the factory calibration hitting 600-800 range, but my automatic now go as much as 1500 and gives bad results after the power cycle (~120 PPB ambient). Being able to manually set it back to something the manufacturer found sane is handy.

You could also try to use it to compensate for the bad behavior when it's got the 125 status, if you like the calibration results from an automatic run, you could put the value it found in your sketch and reapply it every time you don't have the 12 status.

Well my thinking is, perhaps they have got a full blown formula for their raw value to PPB mapping, and the 100-1k-10k are just precomputed points / ranges, so it's easier to apply?

thinking out loud
If I would make such sensor, I would have some physics that gave me a raw value X (typically a voltage)
To convert that to a value Y = aX + b  would mean that calibration needs to find the value for a and b.
a = the slope and that might be related to the area of the sensor (a bigger area gives typical more raw value)  This is typical factory calibrated.
b = related to the zero point.  This is the value to find.
And to prevent floating point operations all measurements are scaled up a factor F to make them integer.
That is where those 100, 1000 and 10000 come in I think.
(we did not think of registers as floating point values ...)

Well that wouldn't support the additional feature of the v118 of being able to set it manually 🤷
It's kind of interesting actually.

Agree, the manual version will be added to the library, but explicit for the user.
My current thought is:
bool AGS02MA::zeroCalibrationManual(uint16_t value = 0)
{
  _buffer[0] = 0x00;
  _buffer[1] = 0x0C;
  _buffer[2] = (value >> 8);
  _buffer[3] = (value & 0xFF);
  _buffer[4] = _CRC8(_buffer, 4);
  return _writeRegister(AGS02MA_CALIBRATION);
}

bool AGS02MA::zeroCalibration()
{
  return zeroCalibrationManual(0);
}

Well my thinking is, perhaps they have got a full blown formula for their raw value to PPB mapping, and the 100-1k-10k are just precomputed points / ranges, so it's easier to apply?

You mean that these are points for non-linear interpolation  - different ranges, - different parameters.?

Agree, the manual version will be added to the library, but explicit for the user.

Yeah, I think that makes sense. And we should probably add more helper functions to read it too.
At least the current zeroCalibration value, (REG[1] bank B), maybe the status part too.

Sounds like I have some coding to do tomorrow :)

You guys are very cool.  Thank you, you are the best.

I can set up a PR as a starting point.
As a sidenote, I don't think I will be needing all three of the sensors I have. If you're interested I can send you a v118 for comparing.

Tinytronics.nl
they said they have version 117 in stock

we need

bool AGS02MA::zeroCalibrationManual(uint16_t value = 0)
uint32_t getRegister(uint8_t reg)
uint16_t getRegisterMSB(uint8_t reg) get 2 MSB bytes
uint16_t getRegisterLSB(uint8_t reg) get 2 LSB bytes
uint32_t getZeroCalibrationRegister(); wrapper around getRegister(1)

calibration sketch

reads and prints the version of the library
reads and prints the version number of the sensor (1 byte)
read 5x PPB values before
reads and prints current calibration (4 bytes)
asks for automatic / manual calibration
manual => asks value (0 .. 0xFFFF ?)
reads calibration afterwards (4 bytes).
read 5x PPB values afterwards to see results

interactive example (do we need this?)

calibrate
switch mode
read values
read registers
etc

Haha ok tomorrow it is,

uint32_t getRegister(uint8_t reg)
uint16_t getRegisterMSB(uint8_t reg) get 2 MSB bytes
uint16_t getRegisterLSB(uint8_t reg) get 2 LSB bytes

One thought though, I assume this would be private? I think if people were to extensively rely on directly reading registers, they wouldn't need the library anyway and may just cherrypick I2C protocol code they need :shrug:
I feel like the most useful functions are when they do the interpreting for you.
Like getSensorVersion() and readPPB() which add context to an otherwise opaque registers like
[undocumented date | version byte] or [status flags + 24 bit integer]
Such context I think would look more like:

uint16_t getZeroCalibrationStatusFlags(); = getRegisterMSB(1);
uint16_t getZeroCalibrationValue(); = getRegisterLSB(1);
bool setZeroCalibrationValue(uint16_t value);

@Beanow
Please prepare a PR - version may be bumped to 0.2.0

PR is up! Have a look #15

@Beanow
follow up thought about interpolation,
from above

REG[1]	0	12	14	21
REG[2]	0	100	6	162
REG[3]	3	232	3	251
REG[4]	39	16	1	102

if I interpret these as (x,y) we have { (18, 3605) ,  (100,1698), (1000, 1019), (10000, 350) }  == some exp(-x) function?
All the register dumps I have seen show this decreasing Y pattern (both 118 and 117 version).
So yes, all dumps are in line with this hypothesis

Q: can it help convert a raw measurement to something "cooked"?

@RobTillaart that's exactly what I have in mind for #16
Because the register dumping and interpretation happens in the example sketch, it should be easy for ourselves and others to hack around and add more interpretations, without needing to modify the library itself quite yet.
For example, going with the previous interpretation of: maybe they're instead of storing floats.
REG[0x0]	0	0	3	30	C: 166		Sensor data:	0	798
REG[0x1]	0	125	5	129	C: 249		Calibration:	125	1409
REG[0x2]	0	100	1	247	C: 148		Internal LUT:	100	503	y/x:	5.03000
REG[0x3]	3	232	0	179	C: 171		Internal LUT:	1000	179	y/x:	0.17900
REG[0x4]	39	16	0	63	C: 122		Internal LUT:	10000	63	y/x:	0.00630
REG[0x5]	238	72	35	40	C: 205
REG[0x6]	26	0	0	18	C: 213
REG[0x7]	0	219	160	169	C: 71
REG[0x8]	130	118	0	10	C: 112
REG[0x11]	21	2	3	118	C: 133		Version:	118
REG[0x20]	0	0	219	130	C: 17
REG[0x21]	26	229	26	229	C: 113		I2C address:	0x1A

Btw, would like to complete the PRs before going down the rabbit hole too much :sweat_smile:.

Q: can it help convert a raw measurement to something "cooked"?

Or if you meant, using logic in the library to find a PPB value based on the raw data in reg x20. Perhaps that is worth splitting out from the main library. With #16 it would be possible to access the data. Adding a bunch of math to use the raw value and/or maybe an AQI score would probably add code that not everyone is interested in using.
In my case, I use the PPB readings, send it over MQTT it would make just as much sense to do AQI scoring on the server.

Agree, lets keep it simple

@shojkeee @Beanow
This issue is closed as the calibration code for 118 is merged into the 0.2.0 version of the library.
If needed it can be reopened, but I prefer a new issue if needed.

Closed?( I have not waited for calibration for version 118(((

@shojkeee
Beanow also has a 118 version sensor tested and it worked for him. For me enough reason to merge the code.
If you still have problems with calibration please reopen this issue.

So I didn't understand anything. You haven't released a new version yet. Where can I get a sketch for the calibration?? I'm completely confused.

https://github.com/RobTillaart/AGS02MA

It takes a while before the Arduino library manager copies new versions of libraries.
Fastest was within an hour slowest was days even weeks.

sorry. release 22 minutes ago. I missed((I just watched it a couple of hours ago, there was another version.

No problem, I just hope it solves your problem (it should)

Looks like 0.2.0 is available in the arduino library manager, try updating and see if the updated example sketches for calibration solve your issue. :ok_hand:

Yes. Thank you. I updated and calibrated everything yesterday! Thank you all. Very helpful. But I still ordered the sensor))


cannot delete image

garbage icon cannot be reached.

related to https://github.com/microsoft/microcode/issues/163


New Magic Prompt being applied to each ADetailer prompt

Hello all,
The ask: can magic prompt be disabled for ADetailer prompts in the same way that it can be for negative prompts?
I've noticed that when Magic Prompt is enabled, it applies a new set of prompts to each detected item in the same picture, resulting in some interesting styles specific to certain body parts.
For example, with a prompt that just says "hands" when three were detected:

There is already an option "Don't apply to negative prompts".
I wonder whether a similar option can be added along the lines of "Don't apply to ADetailer prompts"?
Additionally, should the default behaviour when it is enabled be to use the same magic prompts as the main image, rather than generate new ones for each ADetailer prompt?
Thank you in advance.

I haven't used ADetailer and I don't know how it does its thing (all I know it interacts in many strange ways with this extension).
"Don't apply to negative prompts" is easy, because we simply have a different list of prompts and negative prompts: https://github.com/adieyal/sd-dynamic-prompts/blob/main/sd_dynamic_prompts/dynamic_prompting.py#L464-L468
but this extension is utterly unaware of ADetailer at all.

Ah okay.
I can tell you the arguments in ADetailer appear to be ad_prompt and ad_negative_prompt but whether those can be disapplied in this extension or it's just an inherent incompatibility, I shall defer to your expertise!


Assign task - Workspace employee B has permission to edit title, description, reassign task

If you haven’t already, check out our contributing guidelines for onboarding and email<EMAIL_ADDRESS>to request to join our Slack channel!

Action Performed:
Precondition: for the following tests prepare 3 accounts
• A workspace admin (workspace creator)
• A workspace employee A (task creator)
• A workspace employee B
All accounts should be added to the workspace of the workspace admin

Go to https://staging.new.expensify.com/
Login as the workspace employee A
Navigate to the workspace #Announce room
Create a task and Assign to yourself
Log out from the workspace employee A
Login as the workspace employee B
Navigate to the workspace
Click on the task created by the workspace employee A

Expected Result:
Workspace employee B has no permission to edit the title of the task, reassign the task, edit the description of the task. Only Workspace admins should have permission to edit and reassign tasks created by employees of the workspace
Actual Result:
Workspace employee B has permission to edit the title of the task, reassign the task, edit the description of the task
Unknown
Platforms:

Which of our officially supported platforms is this issue occurring on?

[x] Android / native
[x] Android / Chrome
[x] iOS / native
[x] iOS / Safari
[x] Windows / Chrome
[x] MacOS / Desktop

Version Number: 1.3.66-3
Reproducible in staging?: Yes
Reproducible in production?: Yes
If this was caught during regression testing, add the test name, ID and link from TestRail:
Email or phone of affected tester (no customers):
Logs: https://stackoverflow.com/c/expensify/questions/4856
Notes/Photos/Videos: Any additional supporting documentation
https://github.com/Expensify/App/assets/78819774/7b35b207-d0f5-4cbe-ae3e-9178110f08d0
Expensify/Expensify Issue URL:
Issue reported by: Applause - Internal Team
Slack conversation:
View all open jobs on GitHub

Closing as I believe this is by design.


Add product_version to cont. server validation

What does this PR change?
Add the product_version grain to the containerized server tests. We also have this defined in the normal server tests.
Necessary for e.g. https://github.com/uyuni-project/sumaform/pull/1475

Ok, then I would leave it as is.


Doesn't work on single word domains

Tested it a little bit on any domain I can think of. Noticed it doesn't work on a single word developer domain such as localhost or some other local defined name. Otherwise, it seems to work with anything I could throw at it.

Closed, due to no intent to fix.


Linked List: Add Two Numbers in C++

https://leetcode.com/problems/add-two-numbers/

can you assign this to me

Could you please assign this to me?


Error when pasting a blueprint on a pole

I got this stack trace when placing a bunch of solar panels on a pole:
System.IndexOutOfRangeException: Index was outside the bounds of the array.
  at GalacticScale.PatchOnPlanetGrid.DetermineLongitudeSegmentCount (PlanetGrid __instance, System.Int32 latitudeIndex, System.Int32 segment, System.Int32& __result) [0x0007b] in <91fc5bf28e8c4542a4f8d2262c114014>:0
  at PlanetGrid.DetermineLongitudeSegmentCount (System.Int32 latitudeIndex, System.Int32 segment) [0x00005] in <ee3f7728a4054543a91656140ca60f7c>:0
  at BlueprintUtils.GetLongitudeSegmentCount (System.Int32 _latitudeGridIdx, System.Int32 _segmentCnt) [0x00011] in <ee3f7728a4054543a91656140ca60f7c>:0
  at BlueprintUtils.SnapTropic (PlayerAction_Build _actionBuild, BlueprintData _blueprintData, UnityEngine.Vector3[] _dots, System.Int32 _dotsCursor, System.Single _yaw, System.Int32 _segmentCnt) [0x00136] in <ee3f7728a4054543a91656140ca60f7c>:0
  at BuildTool_BlueprintPaste.OperatingPrestage () [0x0016d] in <ee3f7728a4054543a91656140ca60f7c>:0
  at BuildTool_BlueprintPaste._OnTick (System.Int64 time) [0x0004f] in <ee3f7728a4054543a91656140ca60f7c>:0
  at BuildTool._GameTick (System.Int64 time) [0x000cf] in <ee3f7728a4054543a91656140ca60f7c>:0

I've spent days on this bug and haven't come up with a solution yet. Will keep trying

If it helps you any, I was able to trigger the bug twice in the same way, so I might have a reliable way of triggering it.

Start on a planet of size ~350-400.
Place solar panels on the pole as following: one in the middle aligned with cardinal directions, then 4 adjacent in cardinal directions, then 4-5 full circles of solar panels, pressing '+' and '-' as appropriate for them to fit.
Copy the solar panels then try to paste them on the opposite pole with an incorrect alignment (not aligned to cardinal directions).

Fixed in 2.3.14 I hope
https://dsp.thunderstore.io/package/download/Galactic_Scale/GalacticScale_Experimental/2.3.14/


Linear Layers on Graphs

❓ Questions & Help
Hi,
I am simply trying to add a simple Linear layer at the end of a convolutional encoder, but I as soon as I add this layer my model stops training.
So my Encoder output is a graph of shape (B * N, C), where B is batch_size, N and C are nodes and channels that are the same along each graph.
I have:
self.flatten = lambda x : x.flatten().reshape(-1, N * C) # I saw that the function utils.to_dense_batch can achieve the same thing
self.fc = torch.nn.Linear(N * C, 8)

Then I should simply be able to run:
x = self.fc(self.flatten(x))
Am I doing something inherently wrong?
Posteriorly I run the "inverse" operation to feed to a decoder:
self.dfc = torch.nn.Linear(8, N * C)
self.reshape = lambda x : x.reshape(-1, C)

x = self.reshape(self.dfc(x))

Thanks and sorry for the silly question

Is your graph-permutation invariant? Because then it might not be the best idea to input N * C features into your linear layer, but instead move the node dimension to the batch dimension and aggregate node features afterwards (using something like mean, sum, or max).

What do you mean by permutation invariant? I don't think so, my dataset comes from a set of meshes in correspondence, and the topology is always shared between data in each layer of my network.

Ok, so this should theoretically work. Personally, it is hard to judge why your model stops training. Hidden latent dim seems quite low-dimensional though.


Cannot open HLS stream URL with yt-dlp and OpenCV

DO NOT REMOVE OR SKIP THE ISSUE TEMPLATE

[X] I understand that I will be blocked if I intentionally remove or skip any mandatory* field

Checklist

[X] I'm reporting that yt-dlp is broken on a supported site
[X] I've verified that I have updated yt-dlp to nightly or master (update instructions)
[X] I've checked that all provided URLs are playable in a browser with the same IP and same login details
[X] I've checked that all URLs and arguments with special characters are properly quoted or escaped
[X] I've searched known issues and the bugtracker for similar issues including closed ones. DO NOT post duplicates
[X] I've read the guidelines for opening an issue
[X] I've read about sharing account credentials and I'm willing to share it if required

Region
Taiwan
Provide a description that is worded well enough to be understood
I am trying to capture a live HLS stream from YouTube using yt-dlp to get the stream URL and then using OpenCV to process the stream. However, I encounter an error when attempting to open the stream URL obtained from yt-dlp.
Here are the steps I followed and the issues I encountered:
Steps to Reproduce

Get stream URL using yt-dlp:
import subprocess

def get_stream_url(youtube_url):
    cmd_get_url = [
        'yt-dlp',
        '-g',  # Get the live stream URL
        youtube_url
    ]
    result = subprocess.run(cmd_get_url, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    if result.returncode != 0:
        raise Exception(f"yt-dlp error: {result.stderr.decode('utf-8')}")
    stream_url = result.stdout.decode('utf-8').strip()
    return stream_url

Play the stream using OpenCV:
import cv2
import time

def play_stream(stream_url):
    cap = cv2.VideoCapture(stream_url)

    if not cap.isOpened():
        print("Cannot open stream")
        return

    fps = cap.get(cv2.CAP_PROP_FPS)
    if fps == 0:
        fps = 30

    delay = int(1000 / fps)

    while True:
        ret, frame = cap.read()
        if not ret:
            print("Cannot receive frame (stream end?). Exiting ...")
            break

        cv2.imshow('Live Stream', frame)

        if cv2.waitKey(delay) == ord('q'):
            break

        time.sleep(0.01)

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    youtube_url = 'https://www.youtube.com/watch?v=_U-h0wsUxy0'
    try:
        stream_url = get_stream_url(youtube_url)
        play_stream(stream_url)
    except Exception as e:
        print(e)

It works yesterday, but error today...
Provide verbose output that clearly demonstrates the problem

[X] Run your yt-dlp command with -vU flag added (yt-dlp -vU <your command line>)
[X] If using API, add 'verbose': True to YoutubeDL params instead
[X] Copy the WHOLE output (starting with [debug] Command-line config) and insert it below

Complete Verbose Output
[hls @ 0x1c9f400] Error when loading first segment 'https://rr1---sn-u5oxu-u2xs.googlevideo.com/videoplayback/id/_U-h0wsUxy0.1/itag/270/source/yt_live_broadcast/expire/1723126670/ei/Ln-0ZobVLbjw7OsPn6nw0Ag/ip/<IP_ADDRESS>/requiressl/yes/ratebypass/yes/live/1/sgovp/gir%3Dyes%3Bitag%3D137/rqh/1/hdlc/1/hls_chunk_host/rr1---sn-u5oxu-u2xs.googlevideo.com/xpc/EgVo2aDSNQ%3D%3D/playlist_duration/900/manifest_duration/900/vprv/1/playlist_type/DVR/initcwndbps/516250/mh/L7/mm/44/mn/sn-u5oxu-u2xs/ms/lva/mv/m/mvi/1/pl/17/keepalive/yes/mt/1723104761/sparams/expire,ei,ip,id,itag,source,requiressl,ratebypass,live,sgovp,rqh,hdlc,xpc,playlist_duration,manifest_duration,vprv,playlist_type/sig/AJfQdSswRAIgFUQB2fXWwdEs7O8Bf3NKzO4VX_fJM9Clqfys0Kz3u30CIHr5KyL1TdqwS8GV3YXWYW-FeUk8PB6y5aZ9Ez7ub0qC/lsparams/hls_chunk_host,initcwndbps,mh,mm,mn,ms,mv,mvi,pl/lsig/AGtxev0wRgIhAPS7Z6V0NBLpGz7aQ59erB7UGsrkOgX8ou9QkQl-GIixAiEAu5TMDtm66_oaqP-r18AxxPOMy7JrEkOY8GJ_e3imLMU%3D/playlist/index.m3u8https:/api/manifest/hls_playlist/expire/1723126670/ei/Ln-0ZobVLbjw7OsPn6nw0Ag/ip/<IP_ADDRESS>/id/_U-h0wsUxy0.1/itag/234/source/yt_live_broadcast/requiressl/yes/ratebypass/yes/live/1/goi/133/sgoap/gir/yes%3Bitag%3D140%3Drqh/1/hdlc/1/hls_chunk_host/rr1---sn-u5oxu-u2xs.googlevideo.com/xpc/EgVo2aDSNQ/%3D%3Dplaylist_duration/900/manifest_duration/900/vprv/1/playlist_type/DVR/initcwndbps/516250/mh/L7/mm/44/mn/sn-u5oxu-u2xs/ms/lva/mv/m/mvi/1/pl/17/dover/13/pacing/0/short_key/1/keepalive/yes/mt/1723104761/sparams/expire,ei,ip,id,itag,source,requiressl,ratebypass,live,goi,sgoap,rqh,hdlc,xpc,playlist_duration,manifest_duration,vprv,playlist_type/sig/AJfQdSswRgIhAMeDRNp_o2aaxV1jia5MfhTHtQqyxfVzBUbyzqgkGPOmAiEAq8rxAhAsV0ujEscsvflHPueW8vU2RdIXQkCTUSJksus/%3Dlsparams/hls_chunk_host,initcwndbps,mh,mm,mn,ms,mv,mvi,pl/lsig/AGtxev0wRQIgUDu_qiI7lj_9K8i6HuDYkYtZRkkVf5aQIOsa1Y81p00CIQCZO-cO1BGuLlNqh6-wmaxsT6ZhJTNmwlk-Vv1rasJB1g/%3D%3Dplaylist/index.m3u8//sq/12808/lmt/1/govp/lmt%3D1/dur/2.000/file/seg.ts'
[<EMAIL_ADDRESS>global cap.cpp:164 open VIDEOIO(CV_IMAGES): raised OpenCV exception:

OpenCV(4.10.0) /io/opencv/modules/videoio/src/cap_images.cpp:244: error: (-5:Bad argument) in function 'icvExtractPattern'
> CAP_IMAGES: error, expected '0?[1-9][du]' pattern, got: https://manifest.googlevideo.com/api/manifest/hls_playlist/expire/1723126670/ei/Ln-0ZobVLbjw7OsPn6nw0Ag/ip/<IP_ADDRESS>/id/_U-h0wsUxy0.1/itag/270/source/yt_live_broadcast/requiressl/yes/ratebypass/yes/live/1/sgovp/gir%3Dyes%3Bitag%3D137/rqh/1/hdlc/1/hls_chunk_host/rr1---sn-u5oxu-u2xs.googlevideo.com/xpc/EgVo2aDSNQ%3D%3D/playlist_duration/900/manifest_duration/900/vprv/1/playlist_type/DVR/initcwndbps/516250/mh/L7/mm/44/mn/sn-u5oxu-u2xs/ms/lva/mv/m/mvi/1/pl/17/dover/13/pacing/0/short_key/1/keepalive/yes/mt/1723104761/sparams/expire,ei,ip,id,itag,source,requiressl,ratebypass,live,sgovp,rqh,hdlc,xpc,playlist_duration,manifest_duration,vprv,playlist_type/sig/AJfQdSswRAIgFUQB2fXWwdEs7O8Bf3NKzO4VX_fJM9Clqfys0Kz3u30CIHr5KyL1TdqwS8GV3YXWYW-FeUk8PB6y5aZ9Ez7ub0qC/lsparams/hls_chunk_host,initcwndbps,mh,mm,mn,ms,mv,mvi,pl/lsig/AGtxev0wRgIhAPS7Z6V0NBLpGz7aQ59erB7UGsrkOgX8ou9QkQl-GIixAiEAu5TMDtm66_oaqP-r18AxxPOMy7JrEkOY8GJ_e3imLMU%3D/playlist/index.m3u8
> https://manifest.googlevideo.com/api/manifest/hls_playlist/expire/1723126670/ei/Ln-0ZobVLbjw7OsPn6nw0Ag/ip/<IP_ADDRESS>/id/_U-h0wsUxy0.1/itag/234/source/yt_live_broadcast/requiressl/yes/ratebypass/yes/live/1/goi/133/sgoap/gir%3Dyes%3Bitag%3D140/rqh/1/hdlc/1/hls_chunk_host/rr1---sn-u5oxu-u2xs.googlevideo.com/xpc/EgVo2aDSNQ%3D%3D/playlist_duration/900/manifest_duration/900/vprv/1/playlist_type/DVR/initcwndbps/516250/mh/L7/mm/44/mn/sn-u5oxu-u2xs/ms/lva/mv/m/mvi/1/pl/17/dover/13/pacing/0/short_key/1/keepalive/yes/mt/1723104761/sparams/expire,ei,ip,id,itag,source,requiressl,ratebypass,live,goi,sgoap,rqh,hdlc,xpc,playlist_duration,manifest_duration,vprv,playlist_type/sig/AJfQdSswRgIhAMeDRNp_o2aaxV1jia5MfhTHtQqyxfVzBUbyzqgkGPOmAiEAq8rxAhAsV0ujEscsvflHPueW8vU2RdIXQkCTUSJksus%3D/lsparams/hls_chunk_host,initcwndbps,mh,mm,mn,ms,mv,mvi,pl/lsig/AGtxev0wRQIgUDu_qiI7lj_9K8i6HuDYkYtZRkkVf5aQIOsa1Y81p00CIQCZO-cO1BGuLlNqh6-wmaxsT6ZhJTNmwlk-Vv1rasJB1g%3D%3D/playlist/index.m3u8

this is an issue with opencv, not yt-dlp

if you believe it is a yt-dlp issue, then provide full verbose output


Linking errors if client.target=ios-sim

Currently there will be linking error when I try to build HelloWorld sample targeting ios-sim.
In the plugin debug log I see that target for clang is x86_64 while
native-image is used with -Dsvm.platform=org.graalvm.nativeimage.Platform$DARWIN_AARCH64

ios-sim is not supported yet.


Change License to MIT

This pull request changes the project's license from the Apache License 2.0 / Eclipse Public License 2.0 dual-licensing model to an MIT single license model.
This change is reflected in the license header of each source file as
well as in the NOTICE and README.md files.
The resulting merge commit should note the approval of all contributors, namely:

Sebastian Heppner<EMAIL_ADDRESS>Torben Miny (b. Deppe<EMAIL_ADDRESS>Leon Möller<EMAIL_ADDRESS>Michael Thies<EMAIL_ADDRESS>Igor Garmaev<EMAIL_ADDRESS>

Looks good to me

@FrankSchnicke This PR is ready for merge. Feel free to have a look if it suits you. If you merge, please state the approval of all current contributors in the resulting merge commit, as noted above in the description. Thanks!


Wrong wording in HTTPRange doc

https://github.com/Azure/azure-sdk-for-go/blob/9858c485b320dd70ac8464bf83820baea133efbb/sdk/storage/azblob/internal/exported/exported.go#L14-L16
Shouldn't it say

An HTTPRange which has an offset but a zero value count indicates from the offset to the resource's end.
?

"A zero-value HTTPRange indicates the entire resource." : it mentions the same, which part you feel is wrong here ?

The last sentence in the doc which I believe refers to the case when Offset > 1 and Count == 0 however the doc says but no zero value count which I interpret as Count != 0.

@tomyl, thanks for pointing this. The doc has been updated.


Refresh of pbit file errors

Hi
Firstly good work, this is really useful.
Ran the script with no errors, all files were created and reports downloaded.  When opening the pbit file, I get these errors when it does the refresh. Did I miss a step somewhere?
Errors from refresh:
Model Object Hierarchy
Query 'All Models' (step 'Added Custom6') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
PBI Snapshot Date
Query 'Connections' (step 'Added Index') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
All Models
Query 'All Models' (step 'Added Custom6') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
All Dataflows
Query 'All Dataflows' (step 'Removed Columns1') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
All Model Sources
Query 'All Model Sources' (step 'Renamed Columns1') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
All Measure Dependencies
Query 'All Measure Dependencies' (step 'Removed Columns') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
All Model Refresh History
Query 'All Model Refresh History' (step 'Added Custom1') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Measure Lineage - Dependents
Query 'Measure Lineage - Dependents' (step 'Removed Columns') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Measure Lineage - Parents
Query 'Measure Lineage - Parents' (step 'Changed Type4') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Measure Lineage
Query 'Measure Lineage' (step 'Changed Type3') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.
Report Hierarchy
Query 'Workspace & Model Mapping' (step 'Removed Duplicates') references other queries or steps, so it may not directly access a data source. Please rebuild this data combination.

Those errors are likely all because of 1 query/step that is failing and the rest just stop.
Within VisualObjectLayer.xlsx, is there data in each tab? If not, which are missing?
Same question for ModelDetail.xlsx?
I have steps that account for certain tabs missing data - but perhaps I need to account for more?

All the tabs were populated in both files.  I have since deleted everything and rerun - looks to be ok now.

Great catch on this. I do have the global setting of ignoring privacy settings. I just tested moving it back to the 'default' and get the same error. I would have thought it at least would ask me about privacy settings for each excel file but doesn't.
If I can't find a permanent workaround or save the template to handle it, I'll add that to the instructions as a requirement.

I've updated the model template to ignore privacy settings for excel files. I've also added the potential step if anyone sees the error in the readme.
(This still requires the user's Power BI Desktop Global privacy settings to be EITHER "Combine data according to each file's Privacy Level settings" or "Always ignore Privacy Level settings")
But at least if the Global setting is set to 'each file', they won't have to then set the template to ignore.


Strings must use singlequote

As you see, github actions suceeds and this PR has a green checkmark.

Nice, thanks!


WIP: v1

This is a complete rewrite of Polynom. I plan to use the following tools:

https://github.com/zeit/next.js (Routing, SSR, Dynamic imports, etc)
https://github.com/styled-components/styled-components (CSS-in-JS)
https://github.com/apollographql/react-apollo (GraphQL client)
https://www.prisma.io/ (GraphQL server)
https://github.com/anthonydugois/polynomic (predictive manipulation of SVG paths)

Just curious, what is the advantage for this project to use GraphQL over REST, binary messaging, etc?
(I know the pros for GraphQL in general; trying to talk a friend who is re-engineering a major medical system to use GraphQL vs bunch of REST endpoints.)

Oh, you're adding lots of bells & whistles!  Sounds fun :)


add Simplified Chinese support

add Simplified Chinese support

@kitloong Can I join the team and submit a pull request?

Hi @bestwxc , thank you for the PR.
I don't plan to add every translation to this repository, but I see no reason not to add the simplified Chinese translation you have already made.
I will update the API from my side.

Here's the preview link: https://nextjs-dashboard-hhoxjgdvw-kitloongs-projects.vercel.app/


Timeouts

The API documentation notes "There is currently no exposed way to set the timeouts, though patches are welcome.". On the other hand response on issues and pull requests is minimal to say the least. So @tarm, are you still maintaining this project?
Proposal
How about the following 3 methods from net.Conn?
    // SetDeadline sets the read and write deadlines associated
    // with the connection. It is equivalent to calling both
    // SetReadDeadline and SetWriteDeadline.
    //
    // A deadline is an absolute time after which I/O operations
    // fail with a timeout (see type Error) instead of
    // blocking. The deadline applies to all future and pending
    // I/O, not just the immediately following call to Read or
    // Write. After a deadline has been exceeded, the connection
    // can be refreshed by setting a deadline in the future.
    //
    // An idle timeout can be implemented by repeatedly extending
    // the deadline after successful Read or Write calls.
    //
    // A zero value for t means I/O operations will not time out.
    SetDeadline(t time.Time) error

    // SetReadDeadline sets the deadline for future Read calls
    // and any currently-blocked Read call.
    // A zero value for t means Read will not time out.
    SetReadDeadline(t time.Time) error

    // SetWriteDeadline sets the deadline for future Write calls
    // and any currently-blocked Write call.
    // Even if write times out, it may return n > 0, indicating that
    // some of the data was successfully written.
    // A zero value for t means Write will not time out.
    SetWriteDeadline(t time.Time) error

Unmaintained indeed. For now I made timeouts work with https://github.com/pascaldekloe/nbio.

The package works for me and is feature complete for my needs, so I am not actively making changes to it.  The package has and does transfer millions of bytes in production systems and I have an active interest in making sure it continues to do so.
From my perspective, it does what I need it to, but if other people have other needs, then pull requests that are well designed and work across all platforms will be accepted.
Read timeouts already exist in the package, but they are have a different API than net.Conn.  Search for timeout in https://godoc.org/github.com/tarm/serial  The documentation of timeouts could be better (part of the docs say that still need to be implemented).  The low level serial timeouts work differently than socket based timeouts and work differently on different platforms, so I suspect implementing the net.Conn timeout API would either be very complicated or would be misleading to people.

Now I see that the read timeout is per request. 🔔
“Implementations of Read are discouraged from returning a zero byte count with a nil error”
… and:
“Callers should treat a return of 0 and nil as indicating that nothing happened”
— https://godoc.org/io#Reader
Therefore a dedicated error is required such as the following.
https://godoc.org/github.com/pascaldekloe/nbio#ErrNoData
Do you agree @tarm?
PS
Maybe the "works for me" and the pull request barrier should be in the README to prevent disappointment? ;-)

@pascaldekloe if you wait a little (go 1.10 I guess) you will get this for free: https://go-review.googlesource.com/c/go/+/71770

Indeed, the proposed convention seems to be the way to go. However I'm still waiting on @tarm to respond, again…

status on this one @tarm ?


JSON API compatible?

Is it possible to work with the JSON API format in angular-rails-resource?

Nope. Rails way of doing REST-ish JSON APIs is not the same.
If it is a real need, check out the stuff on http://jsonapi.org/implementations/ - e.g. https://github.com/jakubrohleder/angular-jsonapi