Closed cburlacu closed 2 years ago
Hi @cburlacu
Thanks for the partial fix.
The length of the packet is 16 bytes, hence the second byte of the response should be 0x0D ... The datasheet seems to be wrong...
I do not have this sensor, so I wrote the module based on the datasheet...
It is not a fix, but at least I was able to take a sample
$ pms -s /dev/ttyUSB0 -m HPMA115C0 -n 10 -i 15 serial -f hexdump 00000000: 40 0d 04 00 04 00 07 00 09 00 17 00 00 00 00 84 @............... 00000010: 40 0d 04 00 03 00 04 00 04 00 04 00 00 00 00 a0 @............... 00000020: 40 0d 04 00 04 00 06 00 06 00 07 00 00 00 00 98 @............... 00000030: 40 0d 04 00 05 00 06 00 06 00 07 00 00 00 00 97 @............... 00000040: 40 0d 04 00 04 00 05 00 05 00 05 00 00 00 00 9c @............... 00000050: 40 0d 04 00 05 00 06 00 06 00 08 00 00 00 00 96 @............... 00000060: 40 0d 04 00 05 00 07 00 07 00 08 00 00 00 00 94 @............... 00000070: 40 0d 04 00 05 00 07 00 07 00 08 00 00 00 00 94 @............... 00000080: 40 0d 04 00 04 00 06 00 06 00 07 00 00 00 00 98 @............... 00000090: 40 0d 04 00 04 00 06 00 07 00 08 00 00 00 00 96 @...............
Excellent! I can use this sample to update the test suite and hopefully fix this module.
I need to find some spare time to look into this, so pleas be patient.
Hi @cburlacu
I pushed a patch a few days ago. Could you test this new version? You can install it straight from github with the following command:
pip install --force-reinstall git+https://github.com/avaldebe/PyPMS.git@6409565
Hi,
cezar@laptop: /tmp $ virtualenv -p $(which python3) venv
created virtual environment CPython3.9.7.final.0-64 in 77ms
creator CPython3Posix(dest=/tmp/venv, clear=False, no_vcs_ignore=False, global=False)
seeder FromAppData(download=False, pip=bundle, setuptools=bundle, wheel=bundle, via=copy, app_data_dir=/home/cezar/.local/share/virtualenv)
added seed packages: pip==21.2.4, setuptools==58.1.0, wheel==0.37.0
activators BashActivator,CShellActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator
cezar@laptop: /tmp $ source venv/bin/activate
(venv) cezar@laptop: /tmp $ pip install --force-reinstall git+https://github.com/avaldebe/PyPMS.git@6409565
Collecting git+https://github.com/avaldebe/PyPMS.git@6409565
Cloning https://github.com/avaldebe/PyPMS.git (to revision 6409565) to ./pip-req-build-i9ux5xi1
Running command git clone -q https://github.com/avaldebe/PyPMS.git /tmp/pip-req-build-i9ux5xi1
WARNING: Did not find branch or tag '6409565', assuming revision or ref.
Running command git checkout -q 6409565
Resolved https://github.com/avaldebe/PyPMS.git to commit 6409565
Installing build dependencies ... done
Getting requirements to build wheel ... done
Preparing wheel metadata ... done
Collecting importlib-metadata>=3.6
Using cached importlib_metadata-4.8.1-py3-none-any.whl (17 kB)
Collecting typer>=0.3
Using cached typer-0.4.0-py3-none-any.whl (27 kB)
Collecting pyserial>=3.0
Using cached pyserial-3.5-py2.py3-none-any.whl (90 kB)
Collecting zipp>=0.5
Using cached zipp-3.6.0-py3-none-any.whl (5.3 kB)
Collecting click<9.0.0,>=7.1.1
Using cached click-8.0.3-py3-none-any.whl (97 kB)
Building wheels for collected packages: pypms
Building wheel for pypms (PEP 517) ... done
Created wheel for pypms: filename=pypms-0.6.1-py3-none-any.whl size=35945 sha256=b926f3a04ea3ae54da3f61d85b51c46219322d98662a3c964f465c957c648352
Stored in directory: /tmp/pip-ephem-wheel-cache-y02an920/wheels/3c/62/15/56d88fa6e105e2fcc419fdccc82a4efe0b6965cab9c85275e1
Successfully built pypms
Installing collected packages: zipp, click, typer, pyserial, importlib-metadata, pypms
Successfully installed click-8.0.3 importlib-metadata-4.8.1 pypms-0.6.1 pyserial-3.5 typer-0.4.0 zipp-3.6.0
WARNING: You are using pip version 21.2.4; however, version 21.3 is available.
You should consider upgrading via the '/tmp/venv/bin/python -m pip install --upgrade pip' command.
(venv) cezar@laptop: /tmp $ which pms
/tmp/venv/bin/pms
(venv) cezar@laptop: /tmp $ pms -s /dev/ttyUSB1 -m HPMA115C0 -n 10 -i 15 serial -f hexdump
zsh: correct 'pms' to 'ps' [nyae]? n
Traceback (most recent call last):
File "/tmp/venv/bin/pms", line 8, in <module>
sys.exit(main())
File "/tmp/venv/lib/python3.9/site-packages/typer/main.py", line 214, in __call__
return get_command(self)(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
return self.main(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/typer/main.py", line 500, in wrapper
return callback(**use_params) # type: ignore
File "/tmp/venv/lib/python3.9/site-packages/pms/cli.py", line 84, in serial
with reader:
File "/tmp/venv/lib/python3.9/site-packages/pms/core/reader.py", line 124, in __enter__
if not self.sensor.check(buffer, "passive_mode"): # pragma: no cover
File "/tmp/venv/lib/python3.9/site-packages/pms/core/sensor.py", line 87, in check
self.Message.decode(buffer, self.command(command))
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/base.py", line 59, in decode
return cls.unpack(message, header, length)[cls.data_records] # type: ignore[call-overload]
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/base.py", line 41, in unpack
msg = cls._validate(message, header, length)
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/honeywell/hpma115s0.py", line 47, in _validate
assert len(header) == 3, f"wrong header length {len(header)}"
AssertionError: wrong header length 2
As far as I remember the issue is that it would call validate for the start command response ack: i.e. 68 01 01 96
--> A5 A5
and this still fails...
Thanks for checking. I'll try to figure the problem
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/honeywell/hpma115s0.py", line 47, in _validate assert len(header) == 3, f"wrong header length {len(header)}" AssertionError: wrong header length 2
As far as I remember the issue is that it would call validate for the start command response ack: i.e.
68 01 01 96
-->A5 A5
and this still fails...
I see, it seems that the datasheet was inaccurate again and there is an ACK
message before the measurement message.
Apparently still fails:
Traceback (most recent call last):
File "/tmp/venv/bin/pms", line 8, in <module>
sys.exit(main())
File "/tmp/venv/lib/python3.9/site-packages/typer/main.py", line 214, in __call__
return get_command(self)(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
return self.main(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/tmp/venv/lib/python3.9/site-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "/tmp/venv/lib/python3.9/site-packages/typer/main.py", line 500, in wrapper
return callback(**use_params) # type: ignore
File "/tmp/venv/lib/python3.9/site-packages/pms/cli.py", line 84, in serial
with reader:
File "/tmp/venv/lib/python3.9/site-packages/pms/core/reader.py", line 124, in __enter__
if not self.sensor.check(buffer, "passive_mode"): # pragma: no cover
File "/tmp/venv/lib/python3.9/site-packages/pms/core/sensor.py", line 87, in check
self.Message.decode(buffer, self.command(command))
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/base.py", line 59, in decode
return cls.unpack(message, header, length)[cls.data_records] # type: ignore[call-overload]
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/base.py", line 41, in unpack
msg = cls._validate(message, header, length)
File "/tmp/venv/lib/python3.9/site-packages/pms/sensors/honeywell/hpma115s0.py", line 47, in _validate
assert message == header
AssertionError
As far as I understand it, there are issued 2 commands and the result is concatenated:
logger.debug(f"wake {self.sensor}")
buffer = self._cmd("wake")
self._pre_heat()
buffer += self._cmd("passive_mode")
logger.debug(f"buffer length: {len(buffer)}")
so in hpma115s0.py: _validate
the message is b'\xa5\xa5\xa5\xa5'
while the header is b'\xa5\xa5'
...
Maybe buffer = self._cmd("passive_mode")
if the check is only the for passive command: if not self.sensor.check(buffer, "passive_mode"):
? If needed add a separate check for the "wake" command before the "passive_mode"?
I happen to have one of these hooked up on my desk right now and it does seem to work:
DEBUG:pms:message hex: 400d04000000000000000000000000af DEBUG:pms:message empty: warming up sensor DEBUG:pms:message hex: 400d04000100030003000400000000a4 DEBUG:pms:message payload: (1, 3, 3, 4, 0, 0) 2022-05-26 17:16:46: PM1 1.0, PM2.5 3.0, PM4 3.0, PM10 4.0 μg/m3 DEBUG:pms:message hex: 400d04000100020002000200000000a8 DEBUG:pms:message payload: (1, 2, 2, 2, 0, 0) 2022-05-26 17:17:46: PM1 1.0, PM2.5 2.0, PM4 2.0, PM10 2.0 μg/m3 DEBUG:pms:message hex: 400d04000000010001000100000000ac DEBUG:pms:message payload: (0, 1, 1, 1, 0, 0) 2022-05-26 17:18:46: PM1 0.0, PM2.5 1.0, PM4 1.0, PM10 1.0 μg/m3
One separate issue is that you're assuming zero values being returned mean the sensor is warming up. This isn't always the case. Here I had to wave an incense stick around for a few seconds in order to create enough pollution to get a reading. Let me know if you need any info to close the issue. I have a logic analyzer hooked up to it as well.
Hi @KovairSoftware
I happen to have one of these hooked up on my desk right now and it does seem to work:
That is great news. Thanks fort letting me know, so I can close the issue.
One separate issue is that you're assuming zero values being returned mean the sensor is warming up. This isn't always the case. Here I had to wave an incense stick around for a few seconds in order to create enough pollution to get a reading. Let me know if you need any info to close the issue. I have a logic analyzer hooked up to it as well.
I see it more like a feature. Some of the supported sensors report zero PM if they are queried too soon after powering up, and I one would have to manually filter out such measurements.
In any case, please open a separate issue about this "feature" so we can discuss how to address it.
Thanks again, Á
I agree it's really a CR, I'll open it as you suggest. FYI it's been running 4 days without any issues. I appreciate your project!
Hi, There are some issues while trying to connect to this PM sensor:
The length of the packet is 16 bytes, hence the second byte of the response should be 0x0D ... The datasheet seems to be wrong...
Also, when receiving the ack from passive mode command it fails (wrong header length - it receives 0xA5 0xA5) - it is validated as a message (in s0 _validate)...
It is not a fix, but at least I was able to take a sample